Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107074776
D30283.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
34 KB
Referenced Files
None
Subscribers
None
D30283.diff
View Options
Index: sys/netinet/libalias/alias_db.c
===================================================================
--- sys/netinet/libalias/alias_db.c
+++ sys/netinet/libalias/alias_db.c
@@ -220,9 +220,8 @@
#define NO_DEST_PORT 1
#define NO_SRC_PORT 1
-/* Dummy address used for FindLinkIn/Out() and AddLink().
- The value of this variable is never used. */
-static struct in_addr const NO_ADDR;
+/* Matches any/unknown address in FindLinkIn/Out() and AddLink(). */
+static struct in_addr const ANY_ADDR = { INADDR_ANY };
/* Data Structures
@@ -319,14 +318,23 @@
#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 timeout; /* Expire time for link */
+ } expire;
/* Auxiliary data */
union {
char *frag_ptr;
@@ -379,12 +387,10 @@
*/
/* 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
@@ -402,19 +408,46 @@
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,
@@ -424,10 +457,8 @@
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);
@@ -529,6 +560,8 @@
static void CleanupAliasData(struct libalias *);
static void CleanupLink(struct libalias *, struct alias_link **);
static void DeleteLink(struct alias_link **);
+static struct alias_link *
+UseLink(struct libalias *, struct alias_link *);
static struct alias_link *
ReLink(struct alias_link *,
@@ -541,12 +574,20 @@
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() % 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
@@ -558,8 +599,7 @@
{
int i;
int max_trials;
- u_short port_sys;
- u_short port_net;
+ u_short port;
LIBALIAS_LOCK_ASSERT(la);
/*
@@ -567,41 +607,18 @@
* 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");
@@ -609,58 +626,57 @@
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
@@ -727,7 +743,7 @@
{
int i, j;
int max_trials;
- u_short port_sys;
+ u_short port;
int link_type;
LIBALIAS_LOCK_ASSERT(la);
@@ -759,39 +775,31 @@
* 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
@@ -806,12 +814,23 @@
CleanupAliasData(struct libalias *la)
{
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)
+ TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, expire.list, lnk_tmp)
DeleteLink(&lnk);
+
+ 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
@@ -822,15 +841,24 @@
if (lnk == NULL || *lnk == NULL)
return;
- if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire_time) {
+ if (LibAliasTime - (*lnk)->timestamp > (*lnk)->expire.timeout) {
DeleteLink(lnk);
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);
+ if (lnk != NULL)
+ lnk->timestamp = LibAliasTime;
+ return (lnk);
}
static void
@@ -849,24 +877,32 @@
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 */
@@ -924,133 +960,150 @@
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.timeout = ICMP_EXPIRE_TIME;
+ break;
+ case LINK_UDP:
+ lnk->expire.timeout = UDP_EXPIRE_TIME;
+ break;
+ case LINK_TCP:
+ lnk->expire.timeout = TCP_EXPIRE_INITIAL;
+ break;
+ case LINK_FRAGMENT_ID:
+ lnk->expire.timeout = FRAGMENT_ID_EXPIRE_TIME;
+ break;
+ case LINK_FRAGMENT_PTR:
+ lnk->expire.timeout = FRAGMENT_PTR_EXPIRE_TIME;
+ break;
+ case LINK_ADDR:
+ break;
+ default:
+ lnk->expire.timeout = 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);
}
@@ -1086,6 +1139,35 @@
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,
@@ -1094,45 +1176,31 @@
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, NO_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, NO_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);
}
return (lnk);
}
@@ -1160,7 +1228,7 @@
*/
if (la->aliasAddress.s_addr != INADDR_ANY &&
src_addr.s_addr == la->aliasAddress.s_addr) {
- lnk = _FindLinkOut(la, NO_ADDR, dst_addr, src_port, dst_port,
+ lnk = _FindLinkOut(la, ANY_ADDR, dst_addr, src_port, dst_port,
link_type, replace_partial_links);
}
}
@@ -1176,16 +1244,16 @@
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;
@@ -1199,79 +1267,78 @@
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,
@@ -1303,7 +1370,7 @@
*/
if (la->aliasAddress.s_addr != INADDR_ANY &&
alias_addr.s_addr == la->aliasAddress.s_addr) {
- lnk = _FindLinkIn(la, dst_addr, NO_ADDR, dst_port, alias_port,
+ lnk = _FindLinkIn(la, dst_addr, ANY_ADDR, dst_port, alias_port,
link_type, replace_partial_links);
}
}
@@ -1385,7 +1452,7 @@
LINK_FRAGMENT_ID, 0);
if (lnk == NULL) {
- lnk = AddLink(la, NO_ADDR, dst_addr, alias_addr,
+ lnk = AddLink(la, ANY_ADDR, dst_addr, alias_addr,
NO_SRC_PORT, NO_DEST_PORT, ip_id,
LINK_FRAGMENT_ID);
}
@@ -1408,7 +1475,7 @@
u_short ip_id)
{
LIBALIAS_LOCK_ASSERT(la);
- return AddLink(la, NO_ADDR, dst_addr, NO_ADDR,
+ return AddLink(la, ANY_ADDR, dst_addr, ANY_ADDR,
NO_SRC_PORT, NO_DEST_PORT, ip_id,
LINK_FRAGMENT_PTR);
}
@@ -1418,7 +1485,7 @@
u_short ip_id)
{
LIBALIAS_LOCK_ASSERT(la);
- return FindLinkIn(la, dst_addr, NO_ADDR,
+ return FindLinkIn(la, dst_addr, ANY_ADDR,
NO_DEST_PORT, ip_id,
LINK_FRAGMENT_PTR, 0);
}
@@ -1566,20 +1633,16 @@
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 *
@@ -1587,20 +1650,16 @@
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 *
@@ -1608,20 +1667,17 @@
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 *
@@ -1632,9 +1688,11 @@
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);
}
@@ -1681,7 +1739,7 @@
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
- lnk = FindLinkIn(la, NO_ADDR, alias_addr,
+ lnk = FindLinkIn(la, ANY_ADDR, alias_addr,
0, 0, LINK_ADDR, 0);
if (lnk == NULL) {
la->newDefaultLink = 1;
@@ -1713,7 +1771,7 @@
struct alias_link *lnk;
LIBALIAS_LOCK_ASSERT(la);
- lnk = FindLinkOut(la, original_addr, NO_ADDR,
+ lnk = FindLinkOut(la, original_addr, ANY_ADDR,
0, 0, LINK_ADDR, 0);
if (lnk == NULL) {
return (la->aliasAddress.s_addr != INADDR_ANY) ?
@@ -1772,13 +1830,13 @@
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.timeout = TCP_EXPIRE_DEAD;
else
- lnk->expire_time = TCP_EXPIRE_SINGLEDEAD;
+ lnk->expire.timeout = 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.timeout = TCP_EXPIRE_CONNECTED;
break;
default:
#ifdef _KERNEL
@@ -1797,13 +1855,13 @@
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.timeout = TCP_EXPIRE_DEAD;
else
- lnk->expire_time = TCP_EXPIRE_SINGLEDEAD;
+ lnk->expire.timeout = 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.timeout = TCP_EXPIRE_CONNECTED;
break;
default:
#ifdef _KERNEL
@@ -2052,7 +2110,7 @@
} else if (expire == -1) {
lnk->flags |= LINK_PERMANENT;
} else if (expire > 0) {
- lnk->expire_time = expire;
+ lnk->expire.timeout = expire;
} else {
#ifdef LIBALIAS_DEBUG
fprintf(stderr, "PacketAlias/SetExpire(): ");
@@ -2256,7 +2314,14 @@
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;
@@ -2265,9 +2330,11 @@
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)
@@ -2321,7 +2388,7 @@
struct alias_link *lnk;
LIBALIAS_LOCK(la);
- lnk = AddLink(la, src_addr, NO_ADDR, alias_addr,
+ lnk = AddLink(la, src_addr, ANY_ADDR, alias_addr,
0, 0, 0,
LINK_ADDR);
@@ -2439,7 +2506,8 @@
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);
@@ -2459,6 +2527,8 @@
la->aliasAddress.s_addr = INADDR_ANY;
la->targetAddress.s_addr = INADDR_ANY;
+ la->aliasPortLower = 0x8000;
+ la->aliasPortLength = 0x8000;
la->icmpLinkCount = 0;
la->udpLinkCount = 0;
Index: sys/netinet/libalias/alias_local.h
===================================================================
--- sys/netinet/libalias/alias_local.h
+++ 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 @@
/* 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 */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 10, 5:35 PM (14 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15744555
Default Alt Text
D30283.diff (34 KB)
Attached To
Mode
D30283: libalias: Restructure searching
Attached
Detach File
Event Timeline
Log In to Comment