aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLutz Donnerhacke <donner@FreeBSD.org>2021-05-25 13:03:34 +0000
committerLutz Donnerhacke <donner@FreeBSD.org>2021-07-06 07:09:53 +0000
commite0a40dc227718f4bc62f279073baa5b6b2cd6a57 (patch)
tree6eaaab72d0b02358a6cd31f80e02bb6f6f011545
parent8b7b86fa6fe0761b7a7dc7034c078fdbfa58c4d9 (diff)
downloadsrc-e0a40dc227718f4bc62f279073baa5b6b2cd6a57.tar.gz
src-e0a40dc227718f4bc62f279073baa5b6b2cd6a57.zip
libalias: Restructure
Clean up the database handling in order to switch to more efficient data structures. The development of this patch was artificially split in to many small steps to ease reviewing. - Common search terms - Separate fully qualified search - Separate table for partial links - Cleanup _FindLinkIn - Factor out the outgoing search function - Factor out a common idiom to return found links - Reorder incoming links by grouping of common search terms - Remove LSNAT from outgoing search - Group internal structure semantically - Separate table for PPTP - Use AliasRange instead of PORT_BASE - Remove temporary state deleteAllLinks from global struct - Avoid uninitialized expiration Discussed with: Dimitry Luhtionov Differential Revision: https://reviews.freebsd.org/D30568 Differential Revision: https://reviews.freebsd.org/D30569 Differential Revision: https://reviews.freebsd.org/D30570 Differential Revision: https://reviews.freebsd.org/D30571 Differential Revision: https://reviews.freebsd.org/D30572 Differential Revision: https://reviews.freebsd.org/D30573 Differential Revision: https://reviews.freebsd.org/D30574 Differential Revision: https://reviews.freebsd.org/D30575 Differential Revision: https://reviews.freebsd.org/D30580 Differential Revision: https://reviews.freebsd.org/D30581 Differential Revision: https://reviews.freebsd.org/D30604 Differential Revision: https://reviews.freebsd.org/D30582 (cherry picked from commit d41044ddfdbc2a026570cae11d5fc2e18f5e4b92) (cherry picked from commit 32f9c2ceb3ec8266e48ec0f6d1556fd98ef12db6) (cherry picked from commit cac129e6030095c33e95c5ce1cdcb9c5c21efce9) (cherry picked from commit 19dcc4f2250b3850991366e3058ca8a64b2f135d) (cherry picked from commit d5419034381d0e8e8c99f0f678118b197144bfff) (cherry picked from commit d4ab07d2aeb13b1aae9ad5d73e5fe77131f2350c) (cherry picked from commit 492d3b7109b45ff30fd199b7eeed797447746e42) (cherry picked from commit 7b44ff4c52ce9e7a89e772566a249e5481fe0ac4) (cherry picked from commit 1178dda53d10b096e0b99e356d15b7c24390e099) (cherry picked from commit 9efcad61d8309ecad3c15392b277fd329a1e45e4) (cherry picked from commit fe83900f9fa931e3d0942ec9c0709896b887c3d7) (cherry picked from commit d989935b5bcd880353f0de89eda958c45e7e3342) (cherry picked from commit b50a4dce185481bebf8096c27588ae04a4a2fd7c) (cherry picked from commit f28455344483310cfd1aa5c0bdd4d014810c0e32)
-rw-r--r--sys/netinet/libalias/HISTORY4
-rw-r--r--sys/netinet/libalias/alias_db.c897
-rw-r--r--sys/netinet/libalias/alias_local.h16
3 files changed, 497 insertions, 420 deletions
diff --git a/sys/netinet/libalias/HISTORY b/sys/netinet/libalias/HISTORY
index c5bca59cac1f..8965290a4f27 100644
--- a/sys/netinet/libalias/HISTORY
+++ b/sys/netinet/libalias/HISTORY
@@ -143,3 +143,7 @@ Version 3.1: May, 2000 (Erik Salander, erik@whistle.com)
Version 3.2: July, 2000 (Erik Salander, erik@whistle.com and
Junichi Satoh, junichi@junichi.org)
- Added support for streaming media (RTSP and PNA) aliasing.
+
+Version 3.3: May 2021 (donner)
+ - Dropped LibAliasCheckNewLink
+ - Refactor the database handling, perfomance improvements.
diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index 2759c5170b27..b056f55b56a5 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -318,14 +318,23 @@ struct alias_link {
#define LINK_UNFIREWALLED 0x08
int timestamp; /* Time link was last accessed */
- int expire_time; /* Expire time for link */
#ifndef NO_USE_SOCKETS
int sockfd; /* socket descriptor */
#endif
/* Linked list of pointers for input and output lookup tables */
- LIST_ENTRY (alias_link) list_out;
- LIST_ENTRY (alias_link) list_in;
- TAILQ_ENTRY (alias_link) list_expire;
+ union {
+ struct {
+ LIST_ENTRY(alias_link) in;
+ LIST_ENTRY(alias_link) out;
+ } all;
+ struct {
+ LIST_ENTRY(alias_link) list;
+ } pptp;
+ };
+ struct {
+ TAILQ_ENTRY(alias_link) list;
+ int time; /* Expire time for link */
+ } expire;
/* Auxiliary data */
union {
char *frag_ptr;
@@ -378,12 +387,10 @@ Miscellaneous:
*/
/* Local prototypes */
-static u_int StartPointIn(struct in_addr, u_short, int);
-
-static u_int
-StartPointOut(struct in_addr, struct in_addr,
- u_short, u_short, int);
-
+static struct group_in *
+StartPointIn(struct libalias *, struct in_addr, u_short, int, int);
+static u_int
+StartPointOut(struct in_addr, struct in_addr, u_short, u_short, int);
static int SeqDiff(u_long, u_long);
#ifndef NO_FW_PUNCH
@@ -401,19 +408,46 @@ static void UninitPacketAliasLog(struct libalias *);
void SctpShowAliasStats(struct libalias *la);
-static u_int
-StartPointIn(struct in_addr alias_addr,
- u_short alias_port,
- int link_type)
+#define INGUARD \
+ if (grp->alias_port != alias_port || \
+ grp->link_type != link_type || \
+ grp->alias_addr.s_addr != alias_addr.s_addr) \
+ continue;
+
+static struct group_in *
+StartPointIn(struct libalias *la,
+ struct in_addr alias_addr, u_short alias_port, int link_type,
+ int create)
{
u_int n;
+ struct group_in *grp, *tmp;
n = alias_addr.s_addr;
- if (link_type != LINK_PPTP)
- n += alias_port;
+ n += alias_port;
n += link_type;
- return (n % LINK_TABLE_IN_SIZE);
-}
+ n %= LINK_TABLE_IN_SIZE;
+
+ LIST_FOREACH_SAFE(grp, &la->groupTableIn[n], group_in, tmp) {
+ /* Auto cleanup */
+ if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) {
+ LIST_REMOVE(grp, group_in);
+ free(grp);
+ } else {
+ INGUARD;
+ return (grp);
+ }
+ }
+ if (!create || (grp = malloc(sizeof(*grp))) == NULL)
+ return (grp);
+ grp->alias_addr = alias_addr;
+ grp->alias_port = alias_port;
+ grp->link_type = link_type;
+ LIST_INIT(&grp->full);
+ LIST_INIT(&grp->partial);
+ LIST_INSERT_HEAD(&la->groupTableIn[n], grp, group_in);
+ return (grp);
+}
+#undef INGUARD
static u_int
StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
@@ -423,10 +457,8 @@ StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
n = src_addr.s_addr;
n += dst_addr.s_addr;
- if (link_type != LINK_PPTP) {
- n += src_port;
- n += dst_port;
- }
+ n += src_port;
+ n += dst_port;
n += link_type;
return (n % LINK_TABLE_OUT_SIZE);
@@ -525,14 +557,16 @@ static int GetNewPort(struct libalias *, struct alias_link *, int);
#ifndef NO_USE_SOCKETS
static u_short GetSocket(struct libalias *, u_short, int *, int);
#endif
-static void CleanupAliasData(struct libalias *);
-static void CleanupLink(struct libalias *, struct alias_link **);
-static void DeleteLink(struct alias_link **);
+static void CleanupAliasData(struct libalias *, int);
+static void CleanupLink(struct libalias *, struct alias_link **, int);
+static void DeleteLink(struct alias_link **, int);
+static struct alias_link *
+UseLink(struct libalias *, struct alias_link *);
static struct alias_link *
ReLink(struct alias_link *,
struct in_addr, struct in_addr, struct in_addr,
- u_short, u_short, int, int);
+ u_short, u_short, int, int, int);
static struct alias_link *
FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
@@ -540,12 +574,20 @@ FindLinkOut(struct libalias *, struct in_addr, struct in_addr, u_short, u_short,
static struct alias_link *
FindLinkIn(struct libalias *, struct in_addr, struct in_addr, u_short, u_short, int, int);
-#define ALIAS_PORT_BASE 0x08000
-#define ALIAS_PORT_MASK 0x07fff
-#define ALIAS_PORT_MASK_EVEN 0x07ffe
+static u_short _RandomPort(struct libalias *la);
+
#define GET_NEW_PORT_MAX_ATTEMPTS 20
-#define FIND_EVEN_ALIAS_BASE 1
+/* get random port in network byte order */
+static u_short
+_RandomPort(struct libalias *la) {
+ u_short port;
+
+ port = la->aliasPortLower +
+ arc4random_uniform(la->aliasPortLength);
+
+ return ntohs(port);
+}
/* GetNewPort() allocates port numbers. Note that if a port number
is already in use, that does not mean that it cannot be used by
@@ -557,8 +599,7 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
{
int i;
int max_trials;
- u_short port_sys;
- u_short port_net;
+ u_short port;
LIBALIAS_LOCK_ASSERT(la);
/*
@@ -566,41 +607,18 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
* this parameter is zero or positive, it precisely specifies
* the port number. GetNewPort() will return this number
* without check that it is in use.
-
+ *
+ * The aliasing port is automatically selected by one of
+ * two methods below:
+ *
* When this parameter is GET_ALIAS_PORT, it indicates to get
* a randomly selected port number.
*/
- if (alias_port_param == GET_ALIAS_PORT) {
- /*
- * The aliasing port is automatically selected by one of
- * two methods below:
- */
- max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
-
- if (la->packetAliasMode & PKT_ALIAS_SAME_PORTS) {
- /*
- * When the PKT_ALIAS_SAME_PORTS option is chosen,
- * the first try will be the actual source port. If
- * this is already in use, the remainder of the
- * trials will be random.
- */
- port_net = lnk->src_port;
- port_sys = ntohs(port_net);
- } else if (la->aliasPortLower) {
- /* First trial is a random port in the aliasing range. */
- port_sys = la->aliasPortLower +
- (arc4random() % la->aliasPortLength);
- port_net = htons(port_sys);
- } else {
- /* First trial and all subsequent are random. */
- port_sys = arc4random() & ALIAS_PORT_MASK;
- port_sys += ALIAS_PORT_BASE;
- port_net = htons(port_sys);
- }
- } else if (alias_port_param >= 0 && alias_port_param < 0x10000) {
+ if (alias_port_param >= 0 && alias_port_param < 0x10000) {
lnk->alias_port = (u_short) alias_port_param;
return (0);
- } else {
+ }
+ if (alias_port_param != GET_ALIAS_PORT) {
#ifdef LIBALIAS_DEBUG
fprintf(stderr, "PacketAlias/GetNewPort(): ");
fprintf(stderr, "input parameter error\n");
@@ -608,58 +626,57 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param)
return (-1);
}
+ max_trials = GET_NEW_PORT_MAX_ATTEMPTS;
+
+ /*
+ * When the PKT_ALIAS_SAME_PORTS option is chosen,
+ * the first try will be the actual source port. If
+ * this is already in use, the remainder of the
+ * trials will be random.
+ */
+ port = (la->packetAliasMode & PKT_ALIAS_SAME_PORTS)
+ ? lnk->src_port
+ : _RandomPort(la);
+
/* Port number search */
- for (i = 0; i < max_trials; i++) {
- int go_ahead;
+ for (i = 0; i < max_trials; i++, port = _RandomPort(la)) {
+ struct group_in *grp;
struct alias_link *search_result;
- search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr,
- lnk->dst_port, port_net,
- lnk->link_type, 0);
+ grp = StartPointIn(la, lnk->alias_addr, port, lnk->link_type, 0);
+ if (grp == NULL)
+ break;
+ LIST_FOREACH(search_result, &grp->full, all.in) {
+ if (lnk->dst_addr.s_addr == search_result->dst_addr.s_addr &&
+ lnk->dst_port == search_result->dst_port)
+ break; /* found match */
+ }
if (search_result == NULL)
- go_ahead = 1;
- else if (!(lnk->flags & LINK_PARTIALLY_SPECIFIED)
- && (search_result->flags & LINK_PARTIALLY_SPECIFIED))
- go_ahead = 1;
- else
- go_ahead = 0;
+ break;
+ }
- if (go_ahead) {
-#ifndef NO_USE_SOCKETS
- if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS)
- && (lnk->flags & LINK_PARTIALLY_SPECIFIED)
- && ((lnk->link_type == LINK_TCP) ||
- (lnk->link_type == LINK_UDP))) {
- if (GetSocket(la, port_net, &lnk->sockfd, lnk->link_type)) {
- lnk->alias_port = port_net;
- return (0);
- }
- } else {
+ if (i >= max_trials) {
+#ifdef LIBALIAS_DEBUG
+ fprintf(stderr, "PacketAlias/GetNewPort(): ");
+ fprintf(stderr, "could not find free port\n");
#endif
- lnk->alias_port = port_net;
- return (0);
+ return (-1);
+ }
+
#ifndef NO_USE_SOCKETS
- }
-#endif
- }
- if (la->aliasPortLower) {
- port_sys = la->aliasPortLower +
- (arc4random() % la->aliasPortLength);
- port_net = htons(port_sys);
- } else {
- port_sys = arc4random() & ALIAS_PORT_MASK;
- port_sys += ALIAS_PORT_BASE;
- port_net = htons(port_sys);
+ if ((la->packetAliasMode & PKT_ALIAS_USE_SOCKETS) &&
+ (lnk->flags & LINK_PARTIALLY_SPECIFIED) &&
+ ((lnk->link_type == LINK_TCP) ||
+ (lnk->link_type == LINK_UDP))) {
+ if (!GetSocket(la, port, &lnk->sockfd, lnk->link_type)) {
+ return (-1);
}
}
-
-#ifdef LIBALIAS_DEBUG
- fprintf(stderr, "PacketAlias/GetnewPort(): ");
- fprintf(stderr, "could not find free port\n");
#endif
+ lnk->alias_port = port;
- return (-1);
+ return (0);
}
#ifndef NO_USE_SOCKETS
@@ -726,7 +743,7 @@ FindNewPortGroup(struct libalias *la,
{
int i, j;
int max_trials;
- u_short port_sys;
+ u_short port;
int link_type;
LIBALIAS_LOCK_ASSERT(la);
@@ -758,39 +775,31 @@ FindNewPortGroup(struct libalias *la,
* try will be the actual source port. If this is already
* in use, the remainder of the trials will be random.
*/
- port_sys = ntohs(src_port);
+ port = src_port;
} else {
- /* First trial and all subsequent are random. */
- if (align == FIND_EVEN_ALIAS_BASE)
- port_sys = arc4random() & ALIAS_PORT_MASK_EVEN;
- else
- port_sys = arc4random() & ALIAS_PORT_MASK;
-
- port_sys += ALIAS_PORT_BASE;
+ port = _RandomPort(la);
}
/* Port number search */
- for (i = 0; i < max_trials; i++) {
+ for (i = 0; i < max_trials; i++, port = _RandomPort(la)) {
struct alias_link *search_result;
- for (j = 0; j < port_count; j++)
+ if (align)
+ port &= htons(0xfffe);
+
+ for (j = 0; j < port_count; j++) {
+ u_short port_j = ntohs(port) + j;
+
if ((search_result = FindLinkIn(la, dst_addr,
- alias_addr, dst_port, htons(port_sys + j),
+ alias_addr, dst_port, htons(port_j),
link_type, 0)) != NULL)
break;
+ }
/* Found a good range, return base */
if (j == port_count)
- return (htons(port_sys));
-
- /* Find a new base to try */
- if (align == FIND_EVEN_ALIAS_BASE)
- port_sys = arc4random() & ALIAS_PORT_MASK_EVEN;
- else
- port_sys = arc4random() & ALIAS_PORT_MASK;
-
- port_sys += ALIAS_PORT_BASE;
+ return (port);
}
#ifdef LIBALIAS_DEBUG
@@ -802,45 +811,65 @@ FindNewPortGroup(struct libalias *la,
}
static void
-CleanupAliasData(struct libalias *la)
+CleanupAliasData(struct libalias *la, int deletePermanent)
{
struct alias_link *lnk, *lnk_tmp;
+ u_int i;
LIBALIAS_LOCK_ASSERT(la);
/* permanent entries may stay */
- TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, list_expire, lnk_tmp)
- DeleteLink(&lnk);
+ TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, expire.list, lnk_tmp)
+ DeleteLink(&lnk, deletePermanent);
+
+ for (i = 0; i < LINK_TABLE_IN_SIZE; i++) {
+ struct group_in *grp, *grp_tmp;
+
+ LIST_FOREACH_SAFE(grp, &la->groupTableIn[i], group_in, grp_tmp)
+ if (LIST_EMPTY(&grp->full) && LIST_EMPTY(&grp->partial)) {
+ LIST_REMOVE(grp, group_in);
+ free(grp);
+ }
+ }
}
static void
-CleanupLink(struct libalias *la, struct alias_link **lnk)
+CleanupLink(struct libalias *la, struct alias_link **lnk, int deletePermanent)
{
LIBALIAS_LOCK_ASSERT(la);
if (lnk == NULL || *lnk == NULL)
return;
- if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire_time) {
- DeleteLink(lnk);
+ if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire.time) {
+ DeleteLink(lnk, deletePermanent);
if ((*lnk) == NULL)
return;
}
/* move to end, swap may fail on a single entry list */
- TAILQ_REMOVE(&la->checkExpire, (*lnk), list_expire);
- TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), list_expire);
+ TAILQ_REMOVE(&la->checkExpire, (*lnk), expire.list);
+ TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), expire.list);
+}
+
+static struct alias_link *
+UseLink(struct libalias *la, struct alias_link *lnk)
+{
+ CleanupLink(la, &lnk, 0);
+ if (lnk != NULL)
+ lnk->timestamp = LibAliasTime;
+ return (lnk);
}
static void
-DeleteLink(struct alias_link **plnk)
+DeleteLink(struct alias_link **plnk, int deletePermanent)
{
struct alias_link *lnk = *plnk;
struct libalias *la = lnk->la;
LIBALIAS_LOCK_ASSERT(la);
/* Don't do anything if the link is marked permanent */
- if (la->deleteAllLinks == 0 && lnk->flags & LINK_PERMANENT)
+ if (!deletePermanent && (lnk->flags & LINK_PERMANENT))
return;
#ifndef NO_FW_PUNCH
@@ -848,24 +877,32 @@ DeleteLink(struct alias_link **plnk)
ClearFWHole(lnk);
#endif
- /* Free memory allocated for LSNAT server pool */
- if (lnk->server != NULL) {
- struct server *head, *curr, *next;
+ switch (lnk->link_type) {
+ case LINK_PPTP:
+ LIST_REMOVE(lnk, pptp.list);
+ break;
+ default:
+ /* Free memory allocated for LSNAT server pool */
+ if (lnk->server != NULL) {
+ struct server *head, *curr, *next;
+
+ head = curr = lnk->server;
+ do {
+ next = curr->next;
+ free(curr);
+ } while ((curr = next) != head);
+ } else {
+ /* Adjust output table pointers */
+ LIST_REMOVE(lnk, all.out);
+ }
- head = curr = lnk->server;
- do {
- next = curr->next;
- free(curr);
- } while ((curr = next) != head);
+ /* Adjust input table pointers */
+ LIST_REMOVE(lnk, all.in);
+ break;
}
- /* Adjust output table pointers */
- LIST_REMOVE(lnk, list_out);
-
- /* Adjust input table pointers */
- LIST_REMOVE(lnk, list_in);
/* remove from housekeeping */
- TAILQ_REMOVE(&la->checkExpire, lnk, list_expire);
+ TAILQ_REMOVE(&la->checkExpire, lnk, expire.list);
#ifndef NO_USE_SOCKETS
/* Close socket, if one has been allocated */
@@ -923,133 +960,148 @@ AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr,
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
+
lnk = malloc(sizeof(struct alias_link));
- if (lnk != NULL) {
- /* Basic initialization */
- lnk->la = la;
- lnk->src_addr = src_addr;
- lnk->dst_addr = dst_addr;
- lnk->alias_addr = alias_addr;
- lnk->proxy_addr.s_addr = INADDR_ANY;
- lnk->src_port = src_port;
- lnk->dst_port = dst_port;
- lnk->proxy_port = 0;
- lnk->server = NULL;
- lnk->link_type = link_type;
+ if (lnk == NULL) {
+#ifdef LIBALIAS_DEBUG
+ fprintf(stderr, "PacketAlias/AddLink(): ");
+ fprintf(stderr, "malloc() call failed.\n");
+#endif
+ return (NULL);
+ }
+ /* Basic initialization */
+ lnk->la = la;
+ lnk->src_addr = src_addr;
+ lnk->dst_addr = dst_addr;
+ lnk->alias_addr = alias_addr;
+ lnk->proxy_addr.s_addr = INADDR_ANY;
+ lnk->src_port = src_port;
+ lnk->dst_port = dst_port;
+ lnk->proxy_port = 0;
+ lnk->server = NULL;
+ lnk->link_type = link_type;
#ifndef NO_USE_SOCKETS
- lnk->sockfd = -1;
+ lnk->sockfd = -1;
#endif
- lnk->flags = 0;
- lnk->pflags = 0;
- lnk->timestamp = LibAliasTime;
+ lnk->flags = 0;
+ lnk->pflags = 0;
+ lnk->timestamp = LibAliasTime;
- /* Expiration time */
- switch (link_type) {
- case LINK_ICMP:
- lnk->expire_time = ICMP_EXPIRE_TIME;
- break;
- case LINK_UDP:
- lnk->expire_time = UDP_EXPIRE_TIME;
- break;
- case LINK_TCP:
- lnk->expire_time = TCP_EXPIRE_INITIAL;
- break;
- case LINK_PPTP:
- lnk->flags |= LINK_PERMANENT; /* no timeout. */
- break;
- case LINK_FRAGMENT_ID:
- lnk->expire_time = FRAGMENT_ID_EXPIRE_TIME;
- break;
- case LINK_FRAGMENT_PTR:
- lnk->expire_time = FRAGMENT_PTR_EXPIRE_TIME;
- break;
- case LINK_ADDR:
- break;
- default:
- lnk->expire_time = PROTO_EXPIRE_TIME;
- break;
- }
+ /* Expiration time */
+ switch (link_type) {
+ case LINK_ICMP:
+ lnk->expire.time = ICMP_EXPIRE_TIME;
+ break;
+ case LINK_UDP:
+ lnk->expire.time = UDP_EXPIRE_TIME;
+ break;
+ case LINK_TCP:
+ lnk->expire.time = TCP_EXPIRE_INITIAL;
+ break;
+ case LINK_FRAGMENT_ID:
+ lnk->expire.time = FRAGMENT_ID_EXPIRE_TIME;
+ break;
+ case LINK_FRAGMENT_PTR:
+ lnk->expire.time = FRAGMENT_PTR_EXPIRE_TIME;
+ break;
+ default:
+ lnk->expire.time = PROTO_EXPIRE_TIME;
+ break;
+ }
+
+ /* Determine alias flags */
+ if (dst_addr.s_addr == INADDR_ANY)
+ lnk->flags |= LINK_UNKNOWN_DEST_ADDR;
+ if (dst_port == 0)
+ lnk->flags |= LINK_UNKNOWN_DEST_PORT;
- /* Determine alias flags */
- if (dst_addr.s_addr == INADDR_ANY)
- lnk->flags |= LINK_UNKNOWN_DEST_ADDR;
- if (dst_port == 0)
- lnk->flags |= LINK_UNKNOWN_DEST_PORT;
+ /* Determine alias port */
+ if (GetNewPort(la, lnk, alias_port_param) != 0) {
+ free(lnk);
+ return (NULL);
+ }
+ /* Link-type dependent initialization */
+ switch (link_type) {
+ case LINK_ICMP:
+ la->icmpLinkCount++;
+ break;
+ case LINK_UDP:
+ la->udpLinkCount++;
+ break;
+ case LINK_TCP: {
+ struct tcp_dat *aux_tcp;
+ int i;
- /* Determine alias port */
- if (GetNewPort(la, lnk, alias_port_param) != 0) {
+ aux_tcp = malloc(sizeof(struct tcp_dat));
+ if (aux_tcp == NULL) {
+#ifdef LIBALIAS_DEBUG
+ fprintf(stderr, "PacketAlias/AddLink: ");
+ fprintf(stderr, " cannot allocate auxiliary TCP data\n");
+#endif
free(lnk);
return (NULL);
}
- /* Link-type dependent initialization */
- switch (link_type) {
- struct tcp_dat *aux_tcp;
- case LINK_ICMP:
- la->icmpLinkCount++;
- break;
- case LINK_UDP:
- la->udpLinkCount++;
- break;
- case LINK_TCP:
- aux_tcp = malloc(sizeof(struct tcp_dat));
- if (aux_tcp != NULL) {
- int i;
-
- la->tcpLinkCount++;
- aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED;
- aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
- aux_tcp->state.index = 0;
- aux_tcp->state.ack_modified = 0;
- for (i = 0; i < N_LINK_TCP_DATA; i++)
- aux_tcp->ack[i].active = 0;
- aux_tcp->fwhole = -1;
- lnk->data.tcp = aux_tcp;
- } else {
-#ifdef LIBALIAS_DEBUG
- fprintf(stderr, "PacketAlias/AddLink: ");
- fprintf(stderr, " cannot allocate auxiliary TCP data\n");
-#endif
- free(lnk);
- return (NULL);
- }
- break;
- case LINK_PPTP:
- la->pptpLinkCount++;
- break;
- case LINK_FRAGMENT_ID:
- la->fragmentIdLinkCount++;
- break;
- case LINK_FRAGMENT_PTR:
- la->fragmentPtrLinkCount++;
- break;
- case LINK_ADDR:
- break;
- default:
- la->protoLinkCount++;
- break;
+ la->tcpLinkCount++;
+ aux_tcp->state.in = ALIAS_TCP_STATE_NOT_CONNECTED;
+ aux_tcp->state.out = ALIAS_TCP_STATE_NOT_CONNECTED;
+ aux_tcp->state.index = 0;
+ aux_tcp->state.ack_modified = 0;
+ for (i = 0; i < N_LINK_TCP_DATA; i++)
+ aux_tcp->ack[i].active = 0;
+ aux_tcp->fwhole = -1;
+ lnk->data.tcp = aux_tcp;
+ }
+ break;
+ case LINK_PPTP:
+ la->pptpLinkCount++;
+ break;
+ case LINK_FRAGMENT_ID:
+ la->fragmentIdLinkCount++;
+ break;
+ case LINK_FRAGMENT_PTR:
+ la->fragmentPtrLinkCount++;
+ break;
+ case LINK_ADDR:
+ break;
+ default:
+ la->protoLinkCount++;
+ break;
+ }
+
+ switch (link_type) {
+ case LINK_PPTP:
+ LIST_INSERT_HEAD(&la->pptpList, lnk, pptp.list);
+ break;
+ default: {
+ struct group_in *grp;
+
+ grp = StartPointIn(la, alias_addr, lnk->alias_port, link_type, 1);
+ if (grp == NULL) {
+ free(lnk);
+ return (NULL);
}
/* Set up pointers for output lookup table */
start_point = StartPointOut(src_addr, dst_addr,
src_port, dst_port, link_type);
- LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, list_out);
+ LIST_INSERT_HEAD(&la->linkTableOut[start_point], lnk, all.out);
/* Set up pointers for input lookup table */
- start_point = StartPointIn(alias_addr, lnk->alias_port, link_type);
- LIST_INSERT_HEAD(&la->linkTableIn[start_point], lnk, list_in);
-
- /* Include the element into the housekeeping list */
- TAILQ_INSERT_TAIL(&la->checkExpire, lnk, list_expire);
- } else {
-#ifdef LIBALIAS_DEBUG
- fprintf(stderr, "PacketAlias/AddLink(): ");
- fprintf(stderr, "malloc() call failed.\n");
-#endif
+ if (lnk->flags & LINK_PARTIALLY_SPECIFIED)
+ LIST_INSERT_HEAD(&grp->partial, lnk, all.in);
+ else
+ LIST_INSERT_HEAD(&grp->full, lnk, all.in);
}
- if (la->packetAliasMode & PKT_ALIAS_LOG) {
- ShowAliasStats(la);
+ break;
}
+
+ /* Include the element into the housekeeping list */
+ TAILQ_INSERT_TAIL(&la->checkExpire, lnk, expire.list);
+
+ if (la->packetAliasMode & PKT_ALIAS_LOG)
+ ShowAliasStats(la);
+
return (lnk);
}
@@ -1065,7 +1117,8 @@ ReLink(struct alias_link *old_lnk,
u_short src_port,
u_short dst_port,
int alias_port_param,
- int link_type)
+ int link_type,
+ int deletePermanent)
{
struct alias_link *new_lnk;
struct libalias *la = old_lnk->la;
@@ -1081,10 +1134,39 @@ ReLink(struct alias_link *old_lnk,
PunchFWHole(new_lnk);
}
#endif
- DeleteLink(&old_lnk);
+ DeleteLink(&old_lnk, deletePermanent);
return (new_lnk);
}
+
+#define OUTGUARD \
+ if (lnk->src_port != src_port || \
+ lnk->src_addr.s_addr != src_addr.s_addr || \
+ lnk->dst_addr.s_addr != dst_addr.s_addr || \
+ lnk->dst_port != dst_port || \
+ lnk->link_type != link_type) \
+ continue;
+
+static struct alias_link *
+_SearchLinkOut(struct libalias *la, struct in_addr src_addr,
+ struct in_addr dst_addr,
+ u_short src_port,
+ u_short dst_port,
+ int link_type) {
+ u_int i;
+ struct alias_link *lnk;
+
+ i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
+ LIST_FOREACH(lnk, &la->linkTableOut[i], all.out) {
+ OUTGUARD;
+ return (UseLink(la, lnk));
+ }
+
+ return (NULL);
+}
+
+#undef OUTGUARD
+
static struct alias_link *
_FindLinkOut(struct libalias *la, struct in_addr src_addr,
struct in_addr dst_addr,
@@ -1093,45 +1175,31 @@ _FindLinkOut(struct libalias *la, struct in_addr src_addr,
int link_type,
int replace_partial_links)
{
- u_int i;
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
- i = StartPointOut(src_addr, dst_addr, src_port, dst_port, link_type);
- LIST_FOREACH(lnk, &la->linkTableOut[i], list_out) {
- if (lnk->dst_addr.s_addr == dst_addr.s_addr &&
- lnk->src_addr.s_addr == src_addr.s_addr &&
- lnk->src_port == src_port &&
- lnk->dst_port == dst_port &&
- lnk->link_type == link_type &&
- lnk->server == NULL)
- break;
- }
-
- CleanupLink(la, &lnk);
- if (lnk != NULL)
- lnk->timestamp = LibAliasTime;
+ lnk = _SearchLinkOut(la, src_addr, dst_addr, src_port, dst_port, link_type);
+ if (lnk != NULL || !replace_partial_links)
+ return (lnk);
/* Search for partially specified links. */
- if (lnk == NULL && replace_partial_links) {
- if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) {
- lnk = _FindLinkOut(la, src_addr, dst_addr, src_port, 0,
- link_type, 0);
- if (lnk == NULL)
- lnk = _FindLinkOut(la, src_addr, ANY_ADDR, src_port,
- dst_port, link_type, 0);
- }
- if (lnk == NULL &&
- (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) {
- lnk = _FindLinkOut(la, src_addr, ANY_ADDR, src_port, 0,
- link_type, 0);
- }
- if (lnk != NULL) {
- lnk = ReLink(lnk,
- src_addr, dst_addr, lnk->alias_addr,
- src_port, dst_port, lnk->alias_port,
- link_type);
- }
+ if (dst_port != 0 && dst_addr.s_addr != INADDR_ANY) {
+ lnk = _SearchLinkOut(la, src_addr, dst_addr, src_port, 0,
+ link_type);
+ if (lnk == NULL)
+ lnk = _SearchLinkOut(la, src_addr, ANY_ADDR, src_port,
+ dst_port, link_type);
+ }
+ if (lnk == NULL &&
+ (dst_port != 0 || dst_addr.s_addr != INADDR_ANY)) {
+ lnk = _SearchLinkOut(la, src_addr, ANY_ADDR, src_port, 0,
+ link_type);
+ }
+ if (lnk != NULL) {
+ lnk = ReLink(lnk,
+ src_addr, dst_addr, lnk->alias_addr,
+ src_port, dst_port, lnk->alias_port,
+ link_type, 0);
}
return (lnk);
}
@@ -1175,16 +1243,16 @@ _FindLinkIn(struct libalias *la, struct in_addr dst_addr,
int replace_partial_links)
{
int flags_in;
- u_int start_point;
+ struct group_in *grp;
struct alias_link *lnk;
- struct alias_link *lnk_fully_specified;
struct alias_link *lnk_unknown_all;
struct alias_link *lnk_unknown_dst_addr;
struct alias_link *lnk_unknown_dst_port;
+ struct in_addr src_addr;
+ u_short src_port;
LIBALIAS_LOCK_ASSERT(la);
/* Initialize pointers */
- lnk_fully_specified = NULL;
lnk_unknown_all = NULL;
lnk_unknown_dst_addr = NULL;
lnk_unknown_dst_port = NULL;
@@ -1198,83 +1266,82 @@ _FindLinkIn(struct libalias *la, struct in_addr dst_addr,
flags_in |= LINK_UNKNOWN_DEST_PORT;
/* Search loop */
- start_point = StartPointIn(alias_addr, alias_port, link_type);
- LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) {
- int flags;
-
- flags = flags_in | lnk->flags;
- if (!(flags & LINK_PARTIALLY_SPECIFIED)) {
- if (lnk->alias_addr.s_addr == alias_addr.s_addr
- && lnk->alias_port == alias_port
- && lnk->dst_addr.s_addr == dst_addr.s_addr
- && lnk->dst_port == dst_port
- && lnk->link_type == link_type) {
- lnk_fully_specified = lnk;
+ grp = StartPointIn(la, alias_addr, alias_port, link_type, 0);
+ if (grp == NULL)
+ return (NULL);
+
+ switch (flags_in) {
+ case 0:
+ LIST_FOREACH(lnk, &grp->full, all.in) {
+ if (lnk->dst_addr.s_addr == dst_addr.s_addr &&
+ lnk->dst_port == dst_port)
+ return (UseLink(la, lnk));
+ }
+ break;
+ case LINK_UNKNOWN_DEST_PORT:
+ LIST_FOREACH(lnk, &grp->full, all.in) {
+ if(lnk->dst_addr.s_addr == dst_addr.s_addr) {
+ lnk_unknown_dst_port = lnk;
break;
}
- } else if ((flags & LINK_UNKNOWN_DEST_ADDR)
- && (flags & LINK_UNKNOWN_DEST_PORT)) {
- if (lnk->alias_addr.s_addr == alias_addr.s_addr
- && lnk->alias_port == alias_port
- && lnk->link_type == link_type) {
- if (lnk_unknown_all == NULL)
- lnk_unknown_all = lnk;
- }
- } else if (flags & LINK_UNKNOWN_DEST_ADDR) {
- if (lnk->alias_addr.s_addr == alias_addr.s_addr
- && lnk->alias_port == alias_port
- && lnk->link_type == link_type
- && lnk->dst_port == dst_port) {
- if (lnk_unknown_dst_addr == NULL)
- lnk_unknown_dst_addr = lnk;
+ }
+ break;
+ case LINK_UNKNOWN_DEST_ADDR:
+ LIST_FOREACH(lnk, &grp->full, all.in) {
+ if(lnk->dst_port == dst_port) {
+ lnk_unknown_dst_addr = lnk;
+ break;
}
- } else if (flags & LINK_UNKNOWN_DEST_PORT) {
- if (lnk->alias_addr.s_addr == alias_addr.s_addr
- && lnk->alias_port == alias_port
- && lnk->link_type == link_type
- && lnk->dst_addr.s_addr == dst_addr.s_addr) {
- if (lnk_unknown_dst_port == NULL)
- lnk_unknown_dst_port = lnk;
+ }
+ break;
+ case LINK_PARTIALLY_SPECIFIED:
+ lnk_unknown_all = LIST_FIRST(&grp->full);
+ break;
+ }
+
+ if (lnk_unknown_dst_port == NULL) {
+ LIST_FOREACH(lnk, &grp->partial, all.in) {
+ int flags = (flags_in | lnk->flags) & LINK_PARTIALLY_SPECIFIED;
+
+ if (flags == LINK_PARTIALLY_SPECIFIED &&
+ lnk_unknown_all == NULL)
+ lnk_unknown_all = lnk;
+ if (flags == LINK_UNKNOWN_DEST_ADDR &&
+ lnk->dst_port == dst_port &&
+ lnk_unknown_dst_addr == NULL)
+ lnk_unknown_dst_addr = lnk;
+ if (flags == LINK_UNKNOWN_DEST_PORT &&
+ lnk->dst_addr.s_addr == dst_addr.s_addr) {
+ lnk_unknown_dst_port = lnk;
+ break;
}
}
}
- CleanupLink(la, &lnk_fully_specified);
- if (lnk_fully_specified != NULL) {
- lnk_fully_specified->timestamp = LibAliasTime;
- lnk = lnk_fully_specified;
- } else if (lnk_unknown_dst_port != NULL)
- lnk = lnk_unknown_dst_port;
- else if (lnk_unknown_dst_addr != NULL)
- lnk = lnk_unknown_dst_addr;
- else if (lnk_unknown_all != NULL)
- lnk = lnk_unknown_all;
- else
- return (NULL);
+ lnk = (lnk_unknown_dst_port != NULL) ? lnk_unknown_dst_port
+ : (lnk_unknown_dst_addr != NULL) ? lnk_unknown_dst_addr
+ : lnk_unknown_all;
- if (replace_partial_links &&
- (lnk->flags & LINK_PARTIALLY_SPECIFIED || lnk->server != NULL)) {
- struct in_addr src_addr;
- u_short src_port;
+ if (lnk == NULL || !replace_partial_links)
+ return (lnk);
- if (lnk->server != NULL) { /* LSNAT link */
- src_addr = lnk->server->addr;
- src_port = lnk->server->port;
- lnk->server = lnk->server->next;
- } else {
- src_addr = lnk->src_addr;
- src_port = lnk->src_port;
- }
+ if (lnk->server != NULL) { /* LSNAT link */
+ src_addr = lnk->server->addr;
+ src_port = lnk->server->port;
+ lnk->server = lnk->server->next;
+ } else {
+ src_addr = lnk->src_addr;
+ src_port = lnk->src_port;
+ }
- if (link_type == LINK_SCTP) {
- lnk->src_addr = src_addr;
- lnk->src_port = src_port;
- return (lnk);
- }
+ if (link_type == LINK_SCTP) {
+ lnk->src_addr = src_addr;
+ lnk->src_port = src_port;
+ } else {
lnk = ReLink(lnk,
src_addr, dst_addr, alias_addr,
src_port, dst_port, alias_port,
- link_type);
+ link_type, 0);
}
return (lnk);
}
@@ -1565,20 +1632,16 @@ FindPptpOutByCallId(struct libalias *la, struct in_addr src_addr,
struct in_addr dst_addr,
u_int16_t src_call_id)
{
- u_int i;
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
- i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
- LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
- if (lnk->link_type == LINK_PPTP &&
- lnk->src_addr.s_addr == src_addr.s_addr &&
+ LIST_FOREACH(lnk, &la->pptpList, pptp.list)
+ if (lnk->src_addr.s_addr == src_addr.s_addr &&
lnk->dst_addr.s_addr == dst_addr.s_addr &&
lnk->src_port == src_call_id)
break;
- CleanupLink(la, &lnk);
- return (lnk);
+ return (UseLink(la, lnk));
}
struct alias_link *
@@ -1586,20 +1649,16 @@ FindPptpOutByPeerCallId(struct libalias *la, struct in_addr src_addr,
struct in_addr dst_addr,
u_int16_t dst_call_id)
{
- u_int i;
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
- i = StartPointOut(src_addr, dst_addr, 0, 0, LINK_PPTP);
- LIST_FOREACH(lnk, &la->linkTableOut[i], list_out)
- if (lnk->link_type == LINK_PPTP &&
- lnk->src_addr.s_addr == src_addr.s_addr &&
+ LIST_FOREACH(lnk, &la->pptpList, pptp.list)
+ if (lnk->src_addr.s_addr == src_addr.s_addr &&
lnk->dst_addr.s_addr == dst_addr.s_addr &&
lnk->dst_port == dst_call_id)
break;
- CleanupLink(la, &lnk);
- return (lnk);
+ return (UseLink(la, lnk));
}
struct alias_link *
@@ -1607,20 +1666,17 @@ FindPptpInByCallId(struct libalias *la, struct in_addr dst_addr,
struct in_addr alias_addr,
u_int16_t dst_call_id)
{
- u_int i;
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
- i = StartPointIn(alias_addr, 0, LINK_PPTP);
- LIST_FOREACH(lnk, &la->linkTableIn[i], list_in)
- if (lnk->link_type == LINK_PPTP &&
+
+ LIST_FOREACH(lnk, &la->pptpList, pptp.list)
+ if (lnk->dst_port == dst_call_id &&
lnk->dst_addr.s_addr == dst_addr.s_addr &&
- lnk->alias_addr.s_addr == alias_addr.s_addr &&
- lnk->dst_port == dst_call_id)
+ lnk->alias_addr.s_addr == alias_addr.s_addr)
break;
- CleanupLink(la, &lnk);
- return (lnk);
+ return (UseLink(la, lnk));
}
struct alias_link *
@@ -1631,9 +1687,11 @@ FindPptpInByPeerCallId(struct libalias *la, struct in_addr dst_addr,
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
- lnk = FindLinkIn(la, dst_addr, alias_addr,
- 0 /* any */ , alias_call_id,
- LINK_PPTP, 0);
+ LIST_FOREACH(lnk, &la->pptpList, pptp.list)
+ if (lnk->alias_port == alias_call_id &&
+ lnk->dst_addr.s_addr == dst_addr.s_addr &&
+ lnk->alias_addr.s_addr == alias_addr.s_addr)
+ break;
return (lnk);
}
@@ -1770,13 +1828,13 @@ SetStateIn(struct alias_link *lnk, int state)
switch (state) {
case ALIAS_TCP_STATE_DISCONNECTED:
if (lnk->data.tcp->state.out != ALIAS_TCP_STATE_CONNECTED)
- lnk->expire_time = TCP_EXPIRE_DEAD;
+ lnk->expire.time = TCP_EXPIRE_DEAD;
else
- lnk->expire_time = TCP_EXPIRE_SINGLEDEAD;
+ lnk->expire.time = TCP_EXPIRE_SINGLEDEAD;
break;
case ALIAS_TCP_STATE_CONNECTED:
if (lnk->data.tcp->state.out == ALIAS_TCP_STATE_CONNECTED)
- lnk->expire_time = TCP_EXPIRE_CONNECTED;
+ lnk->expire.time = TCP_EXPIRE_CONNECTED;
break;
default:
#ifdef _KERNEL
@@ -1795,13 +1853,13 @@ SetStateOut(struct alias_link *lnk, int state)
switch (state) {
case ALIAS_TCP_STATE_DISCONNECTED:
if (lnk->data.tcp->state.in != ALIAS_TCP_STATE_CONNECTED)
- lnk->expire_time = TCP_EXPIRE_DEAD;
+ lnk->expire.time = TCP_EXPIRE_DEAD;
else
- lnk->expire_time = TCP_EXPIRE_SINGLEDEAD;
+ lnk->expire.time = TCP_EXPIRE_SINGLEDEAD;
break;
case ALIAS_TCP_STATE_CONNECTED:
if (lnk->data.tcp->state.in == ALIAS_TCP_STATE_CONNECTED)
- lnk->expire_time = TCP_EXPIRE_CONNECTED;
+ lnk->expire.time = TCP_EXPIRE_CONNECTED;
break;
default:
#ifdef _KERNEL
@@ -2046,11 +2104,11 @@ SetExpire(struct alias_link *lnk, int expire)
{
if (expire == 0) {
lnk->flags &= ~LINK_PERMANENT;
- DeleteLink(&lnk);
+ DeleteLink(&lnk, 0);
} else if (expire == -1) {
lnk->flags |= LINK_PERMANENT;
} else if (expire > 0) {
- lnk->expire_time = expire;
+ lnk->expire.time = expire;
} else {
#ifdef LIBALIAS_DEBUG
fprintf(stderr, "PacketAlias/SetExpire(): ");
@@ -2074,13 +2132,9 @@ GetProtocolFlags(struct alias_link *lnk)
void
SetDestCallId(struct alias_link *lnk, u_int16_t cid)
{
- struct libalias *la = lnk->la;
-
- LIBALIAS_LOCK_ASSERT(la);
- la->deleteAllLinks = 1;
+ LIBALIAS_LOCK_ASSERT(lnk->la);
ReLink(lnk, lnk->src_addr, lnk->dst_addr, lnk->alias_addr,
- lnk->src_port, cid, lnk->alias_port, lnk->link_type);
- la->deleteAllLinks = 0;
+ lnk->src_port, cid, lnk->alias_port, lnk->link_type, 1);
}
/* Miscellaneous Functions
@@ -2139,7 +2193,7 @@ HouseKeeping(struct libalias *la)
if (packets < (la->udpLinkCount + la->tcpLinkCount)) {
struct alias_link * lnk = TAILQ_FIRST(&la->checkExpire);
- CleanupLink(la, &lnk);
+ CleanupLink(la, &lnk, 0);
}
}
@@ -2258,7 +2312,14 @@ LibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr ad
LIBALIAS_LOCK(la);
(void)la;
- server = malloc(sizeof(struct server));
+ switch (lnk->link_type) {
+ case LINK_PPTP:
+ server = NULL;
+ break;
+ default:
+ server = malloc(sizeof(struct server));
+ break;
+ }
if (server != NULL) {
struct server *head;
@@ -2267,9 +2328,11 @@ LibAliasAddServer(struct libalias *la, struct alias_link *lnk, struct in_addr ad
server->port = port;
head = lnk->server;
- if (head == NULL)
+ if (head == NULL) {
server->next = server;
- else {
+ /* not usable for outgoing connections */
+ LIST_REMOVE(lnk, all.out);
+ } else {
struct server *s;
for (s = head; s->next != head; s = s->next)
@@ -2366,9 +2429,8 @@ void
LibAliasRedirectDelete(struct libalias *la, struct alias_link *lnk)
{
LIBALIAS_LOCK(la);
- la->deleteAllLinks = 1;
- DeleteLink(&lnk);
- la->deleteAllLinks = 0;
+ (void)la;
+ DeleteLink(&lnk, 1);
LIBALIAS_UNLOCK(la);
}
@@ -2378,7 +2440,7 @@ LibAliasSetAddress(struct libalias *la, struct in_addr addr)
LIBALIAS_LOCK(la);
if (la->packetAliasMode & PKT_ALIAS_RESET_ON_ADDR_CHANGE
&& la->aliasAddress.s_addr != addr.s_addr)
- CleanupAliasData(la);
+ CleanupAliasData(la, 0);
la->aliasAddress = addr;
LIBALIAS_UNLOCK(la);
@@ -2389,9 +2451,15 @@ LibAliasSetAliasPortRange(struct libalias *la, u_short port_low,
u_short port_high)
{
LIBALIAS_LOCK(la);
- la->aliasPortLower = port_low;
- /* Add 1 to the aliasPortLength as modulo has range of 1 to n-1 */
- la->aliasPortLength = port_high - port_low + 1;
+ if (port_low) {
+ la->aliasPortLower = port_low;
+ /* Add 1 to the aliasPortLength as modulo has range of 1 to n-1 */
+ la->aliasPortLength = port_high - port_low + 1;
+ } else {
+ /* Set default values */
+ la->aliasPortLower = 0x8000;
+ la->aliasPortLength = 0x8000;
+ }
LIBALIAS_UNLOCK(la);
}
@@ -2441,7 +2509,8 @@ LibAliasInit(struct libalias *la)
for (i = 0; i < LINK_TABLE_OUT_SIZE; i++)
LIST_INIT(&la->linkTableOut[i]);
for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
- LIST_INIT(&la->linkTableIn[i]);
+ LIST_INIT(&la->groupTableIn[i]);
+ LIST_INIT(&la->pptpList);
TAILQ_INIT(&la->checkExpire);
#ifdef _KERNEL
AliasSctpInit(la);
@@ -2450,9 +2519,7 @@ LibAliasInit(struct libalias *la)
LIBALIAS_LOCK(la);
} else {
LIBALIAS_LOCK(la);
- la->deleteAllLinks = 1;
- CleanupAliasData(la);
- la->deleteAllLinks = 0;
+ CleanupAliasData(la, 1);
#ifdef _KERNEL
AliasSctpTerm(la);
AliasSctpInit(la);
@@ -2461,6 +2528,8 @@ LibAliasInit(struct libalias *la)
la->aliasAddress.s_addr = INADDR_ANY;
la->targetAddress.s_addr = INADDR_ANY;
+ la->aliasPortLower = 0x8000;
+ la->aliasPortLength = 0x8000;
la->icmpLinkCount = 0;
la->udpLinkCount = 0;
@@ -2494,9 +2563,7 @@ LibAliasUninit(struct libalias *la)
#ifdef _KERNEL
AliasSctpTerm(la);
#endif
- la->deleteAllLinks = 1;
- CleanupAliasData(la);
- la->deleteAllLinks = 0;
+ CleanupAliasData(la, 1);
UninitPacketAliasLog(la);
#ifndef NO_FW_PUNCH
UninitPunchFW(la);
diff --git a/sys/netinet/libalias/alias_local.h b/sys/netinet/libalias/alias_local.h
index f1b40f0438da..5628adac203e 100644
--- a/sys/netinet/libalias/alias_local.h
+++ b/sys/netinet/libalias/alias_local.h
@@ -80,6 +80,14 @@
struct proxy_entry;
+struct group_in {
+ struct in_addr alias_addr;
+ u_short alias_port;
+ int link_type;
+ LIST_ENTRY(group_in) group_in;
+ LIST_HEAD(, alias_link) full, partial;
+};
+
struct libalias {
LIST_ENTRY(libalias) instancelist;
/* Mode flags documented in alias.h */
@@ -92,8 +100,9 @@ struct libalias {
/* Lookup table of pointers to chains of link records.
* Each link record is doubly indexed into input and
* output lookup tables. */
- LIST_HEAD (, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE];
- LIST_HEAD (, alias_link) linkTableIn[LINK_TABLE_IN_SIZE];
+ LIST_HEAD (, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE];
+ LIST_HEAD (, group_in) groupTableIn[LINK_TABLE_IN_SIZE];
+ LIST_HEAD (, alias_link) pptpList;
/* HouseKeeping */
TAILQ_HEAD (, alias_link) checkExpire;
/* Link statistics */
@@ -105,9 +114,6 @@ struct libalias {
unsigned int fragmentIdLinkCount;
unsigned int fragmentPtrLinkCount;
unsigned int sockCount;
- /* If equal to zero, DeleteLink()
- * will not remove permanent links */
- int deleteAllLinks;
/* log descriptor */
#ifdef _KERNEL
char *logDesc;