Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148482823
D30283.id89945.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D30283.id89945.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
@@ -379,12 +378,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 +399,47 @@
void SctpShowAliasStats(struct libalias *la);
-static u_int
-StartPointIn(struct in_addr alias_addr,
- u_short alias_port,
- int link_type)
+#define INGUARD \
+ if (lnk->alias_port != alias_port || \
+ lnk->link_type != link_type || \
+ lnk->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 *lnk, *tmp;
n = alias_addr.s_addr;
if (link_type != LINK_PPTP)
n += alias_port;
n += link_type;
- return (n % LINK_TABLE_IN_SIZE);
+ n %= LINK_TABLE_IN_SIZE;
+
+ LIST_FOREACH_SAFE(lnk, &la->groupTableIn[n], group_in, tmp) {
+ /* Auto cleanup */
+ if (LIST_EMPTY(&lnk->full) && LIST_EMPTY(&lnk->partial)) {
+ LIST_REMOVE(lnk, group_in);
+ free(tmp);
+ } else {
+ INGUARD;
+ return (lnk);
+ }
+ }
+ if (!create || (lnk = malloc(sizeof(*lnk))) == NULL)
+ return (lnk);
+ lnk->alias_addr = alias_addr;
+ lnk->alias_port = alias_port;
+ lnk->link_type = link_type;
+ LIST_INIT(&lnk->full);
+ LIST_INIT(&lnk->partial);
+ LIST_INSERT_HEAD(&la->groupTableIn[n], lnk, group_in);
+ return (lnk);
}
+#undef INGUARD
static u_int
StartPointOut(struct in_addr src_addr, struct in_addr dst_addr,
@@ -529,6 +554,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 *,
@@ -806,12 +833,21 @@
CleanupAliasData(struct libalias *la)
{
struct alias_link *lnk, *lnk_tmp;
+ struct group_in *grp, *grp_tmp;
+ u_int i;
LIBALIAS_LOCK_ASSERT(la);
/* permanent entries may stay */
TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, list_expire, lnk_tmp)
DeleteLink(&lnk);
+
+ for (i = 0; i < LINK_TABLE_IN_SIZE; i++)
+ 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
@@ -833,6 +869,15 @@
TAILQ_INSERT_TAIL(&la->checkExpire, (*lnk), list_expire);
}
+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
DeleteLink(struct alias_link **plnk)
{
@@ -858,9 +903,10 @@
next = curr->next;
free(curr);
} while ((curr = next) != head);
+ } else {
+ /* Adjust output table pointers */
+ LIST_REMOVE(lnk, list_out);
}
- /* Adjust output table pointers */
- LIST_REMOVE(lnk, list_out);
/* Adjust input table pointers */
LIST_REMOVE(lnk, list_in);
@@ -922,8 +968,10 @@
{
u_int start_point;
struct alias_link *lnk;
+ struct group_in *grp_in;
LIBALIAS_LOCK_ASSERT(la);
+
lnk = malloc(sizeof(struct alias_link));
if (lnk != NULL) {
/* Basic initialization */
@@ -1031,14 +1079,23 @@
break;
}
+ grp_in = StartPointIn(la, alias_addr, lnk->alias_port, link_type, 1);
+ if (grp_in == 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);
/* 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);
+ if (lnk->flags & LINK_PARTIALLY_SPECIFIED) {
+ LIST_INSERT_HEAD(&grp_in->partial, lnk, list_in);
+ } else {
+ LIST_INSERT_HEAD(&grp_in->full, lnk, list_in);
+ }
/* Include the element into the housekeeping list */
TAILQ_INSERT_TAIL(&la->checkExpire, lnk, list_expire);
@@ -1086,53 +1143,68 @@
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 *
-_FindLinkOut(struct libalias *la, struct in_addr src_addr,
+_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,
- int replace_partial_links)
-{
+ int link_type) {
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;
+ OUTGUARD;
+ return (UseLink(la, lnk));
}
- CleanupLink(la, &lnk);
- if (lnk != NULL)
- lnk->timestamp = LibAliasTime;
+ return (NULL);
+}
+
+#undef OUTGUARD
+
+static struct alias_link *
+_FindLinkOut(struct libalias *la, struct in_addr src_addr,
+ struct in_addr dst_addr,
+ u_short src_port,
+ u_short dst_port,
+ int link_type,
+ int replace_partial_links)
+{
+ struct alias_link *lnk;
+
+ LIBALIAS_LOCK_ASSERT(la);
+ 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 +1232,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 +1248,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 +1271,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, list_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, list_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, list_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, list_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 +1374,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 +1456,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 +1479,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 +1489,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);
}
@@ -1608,20 +1679,22 @@
struct in_addr alias_addr,
u_int16_t dst_call_id)
{
- u_int i;
+ struct group_in *grp;
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 &&
- lnk->dst_addr.s_addr == dst_addr.s_addr &&
- lnk->alias_addr.s_addr == alias_addr.s_addr &&
+
+ grp = StartPointIn(la, alias_addr, 0, LINK_PPTP, 0);
+ if (grp == NULL)
+ return (NULL);
+
+ LIST_FOREACH(lnk, &grp->full, list_in)
+ if (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 *
@@ -1681,7 +1754,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 +1786,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) ?
@@ -2265,9 +2338,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, list_out);
+ } else {
struct server *s;
for (s = head; s->next != head; s = s->next)
@@ -2321,7 +2396,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 +2514,7 @@
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]);
TAILQ_INIT(&la->checkExpire);
#ifdef _KERNEL
AliasSctpInit(la);
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,8 @@
/* 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];
/* HouseKeeping */
TAILQ_HEAD (, alias_link) checkExpire;
/* Link statistics */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 19, 4:30 AM (9 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29946475
Default Alt Text
D30283.id89945.diff (16 KB)
Attached To
Mode
D30283: libalias: Restructure searching
Attached
Detach File
Event Timeline
Log In to Comment