--- b/sys/netinet/libalias/alias_db.c +++ b/sys/netinet/libalias/alias_db.c @@ -379,7 +379,9 @@ Lookup table starting points: */ /* Local prototypes */ -static u_int StartPointIn(struct in_addr, u_short, int); +static u_int +StartPointIn(struct in_addr, struct in_addr, + u_short, u_short, int); static u_int StartPointOut(struct in_addr, struct in_addr, @@ -403,16 +405,19 @@ 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) +StartPointIn(struct in_addr alias_addr, struct in_addr dst_addr, + u_short alias_port, u_short dst_port, int link_type) { u_int n; n = alias_addr.s_addr; - if (link_type != LINK_PPTP) + n += dst_addr.s_addr; + if (link_type != LINK_PPTP) { n += alias_port; + n += dst_port; + } n += link_type; + return (n % LINK_TABLE_IN_SIZE); } @@ -1043,7 +1048,8 @@ AddLink(struct libalias *la, struct in_addr src_addr, struct in_addr dst_addr, 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); + start_point = StartPointIn(alias_addr, dst_addr, + lnk->alias_port, dst_port, link_type); LIST_INSERT_HEAD(&la->linkTableIn[start_point], lnk, list_in); } else { #ifdef LIBALIAS_DEBUG @@ -1175,18 +1181,9 @@ _FindLinkIn(struct libalias *la, struct in_addr dst_addr, { int flags_in; u_int start_point; - 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 alias_link *lnk = NULL; LIBALIAS_LOCK_ASSERT(la); -/* Initialize pointers */ - lnk_fully_specified = NULL; - lnk_unknown_all = NULL; - lnk_unknown_dst_addr = NULL; - lnk_unknown_dst_port = NULL; /* If either the dest addr or port is unknown, the search loop will have to know about this. */ @@ -1197,58 +1194,74 @@ _FindLinkIn(struct libalias *la, struct in_addr dst_addr, if (dst_port == 0) 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; - break; + /* Search for fully specified links */ + if (!(flags_in & LINK_PARTIALLY_SPECIFIED)) { + start_point = StartPointIn(alias_addr, dst_addr, + alias_port, dst_port, link_type); + LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) { + int 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->timestamp = la->timeStamp; + 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; + } + } + + /* Search for links without destination port */ + if (lnk == NULL && !(flags_in & LINK_UNKNOWN_DEST_ADDR)) { + start_point = StartPointIn(alias_addr, dst_addr, + alias_port, 0, link_type); + LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) { + int flags = flags_in | lnk->flags; + 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) + break; } - } 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; + } + } + + /* Search for links without destination address */ + if (lnk == NULL && !(flags_in & LINK_UNKNOWN_DEST_PORT)) { + start_point = StartPointIn(alias_addr, la->nullAddress, + alias_port, dst_port, link_type); + LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) { + int flags = flags_in | lnk->flags; + 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) + 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; + } + } + + /* Search for links without destination address and port */ + if (lnk == NULL) { + start_point = StartPointIn(alias_addr, la->nullAddress, + alias_port, 0, link_type); + LIST_FOREACH(lnk, &la->linkTableIn[start_point], list_in) { + int flags = flags_in | lnk->flags; + 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) + break; } } } - if (lnk_fully_specified != NULL) { - lnk_fully_specified->timestamp = la->timeStamp; - 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 + if (lnk == NULL) return (NULL); if (replace_partial_links && @@ -1612,7 +1625,7 @@ FindPptpInByCallId(struct libalias *la, struct in_addr dst_addr, struct alias_link *lnk; LIBALIAS_LOCK_ASSERT(la); - i = StartPointIn(alias_addr, 0, LINK_PPTP); + i = StartPointIn(alias_addr, dst_addr, 0, 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 &&