FreeBSD Bugzilla – Attachment 183594 Details for
Bug 220101
LibAlias: allocate NAT ports using exhaustive search
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
LibAlias: allocate NAT ports using exhaustive search
0001-Change-port-allocation-in-libalias-to-exhaustively-s.patch (text/plain), 6.85 KB, created by
Damjan Jovanovic
on 2017-06-18 09:03:44 UTC
(
hide
)
Description:
LibAlias: allocate NAT ports using exhaustive search
Filename:
MIME Type:
Creator:
Damjan Jovanovic
Created:
2017-06-18 09:03:44 UTC
Size:
6.85 KB
patch
obsolete
>From 4b54b38553fc21461ead5e56cc8f793c325f64fd Mon Sep 17 00:00:00 2001 >From: Damjan Jovanovic <damjan.jov@gmail.com> >Date: Sat, 17 Jun 2017 20:44:38 +0200 >Subject: [PATCH] Change port allocation in libalias to exhaustively search all > ports from a random point, instead of randomly picking 20 ports. > >--- > sys/netinet/libalias/alias_db.c | 160 ++++++++++++++++++++++------------------ > 1 file changed, 88 insertions(+), 72 deletions(-) > >diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c >index 4f8159b..20413ae 100644 >--- a/sys/netinet/libalias/alias_db.c >+++ b/sys/netinet/libalias/alias_db.c >@@ -559,10 +559,51 @@ static struct alias_link * > #define ALIAS_PORT_BASE 0x08000 > #define ALIAS_PORT_MASK 0x07fff > #define ALIAS_PORT_MASK_EVEN 0x07ffe >-#define GET_NEW_PORT_MAX_ATTEMPTS 20 >+#define ALIAS_PORT_MAX 0x0ffff > > #define FIND_EVEN_ALIAS_BASE 1 > >+ >+static int >+AllocatePortIfUnused(struct libalias *la, struct alias_link *lnk, u_short port_net) >+{ >+ int go_ahead; >+ struct alias_link *search_result; >+ >+ search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr, >+ lnk->dst_port, port_net, >+ lnk->link_type, 0); >+ >+ 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; >+ >+ 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 { >+#endif >+ lnk->alias_port = port_net; >+ return (0); >+#ifndef NO_USE_SOCKETS >+ } >+#endif >+ } >+ return (-1); >+} >+ >+ > /* GetNewPort() allocates port numbers. Note that if a port number > is already in use, that does not mean that it cannot be used by > another link concurrently. This is because GetNewPort() looks for >@@ -572,9 +613,7 @@ static int > 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; > > LIBALIAS_LOCK_ASSERT(la); > /* >@@ -592,7 +631,6 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) > * 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) { > /* >@@ -601,14 +639,13 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) > * this is already in use, the remainder of the > * trials will be random. > */ >- port_net = lnk->src_port; >- port_sys = ntohs(port_net); >- } else { >- /* First trial and all subsequent are random. */ >- port_sys = arc4random() & ALIAS_PORT_MASK; >- port_sys += ALIAS_PORT_BASE; >- port_net = htons(port_sys); >+ if (AllocatePortIfUnused(la, lnk, lnk->src_port) == 0) { >+ return (0); >+ } > } >+ /* First trial and all subsequent are random. */ >+ port_sys = arc4random() & ALIAS_PORT_MASK; >+ port_sys += ALIAS_PORT_BASE; > } else if (alias_port_param >= 0 && alias_port_param < 0x10000) { > lnk->alias_port = (u_short) alias_port_param; > return (0); >@@ -622,43 +659,15 @@ GetNewPort(struct libalias *la, struct alias_link *lnk, int alias_port_param) > > > /* Port number search */ >- for (i = 0; i < max_trials; i++) { >- int go_ahead; >- struct alias_link *search_result; >- >- search_result = FindLinkIn(la, lnk->dst_addr, lnk->alias_addr, >- lnk->dst_port, port_net, >- lnk->link_type, 0); >- >- 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; >- >- 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 { >-#endif >- lnk->alias_port = port_net; >- return (0); >-#ifndef NO_USE_SOCKETS >- } >-#endif >+ for (i = port_sys; i <= ALIAS_PORT_MAX; i++) { >+ if (AllocatePortIfUnused(la, lnk, htons(i)) == 0) { >+ return (0); >+ } >+ } >+ for (i = port_sys - 1; i >= ALIAS_PORT_BASE; i--) { >+ if (AllocatePortIfUnused(la, lnk, htons(i)) == 0) { >+ return (0); > } >- port_sys = arc4random() & ALIAS_PORT_MASK; >- port_sys += ALIAS_PORT_BASE; >- port_net = htons(port_sys); > } > > #ifdef LIBALIAS_DEBUG >@@ -731,10 +740,11 @@ FindNewPortGroup(struct libalias *la, > u_char proto, > u_char align) > { >- int i, j; >- int max_trials; >+ struct alias_link *search_result; >+ int i; > u_short port_sys; > int link_type; >+ int consecutive_matches; > > LIBALIAS_LOCK_ASSERT(la); > /* >@@ -757,8 +767,6 @@ FindNewPortGroup(struct libalias *la, > * 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 ALIAS_SAME_PORTS option is chosen, the first >@@ -779,27 +787,35 @@ FindNewPortGroup(struct libalias *la, > } > > /* Port number search */ >- for (i = 0; i < max_trials; i++) { >- >- struct alias_link *search_result; >- >- for (j = 0; j < port_count; j++) >- if ((search_result = FindLinkIn(la, dst_addr, >- alias_addr, dst_port, htons(port_sys + 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; >+ consecutive_matches = 0; >+ for (i = port_sys; i <= ALIAS_PORT_MAX; i++) { >+ if ((search_result = FindLinkIn(la, dst_addr, >+ alias_addr, dst_port, htons(i), >+ link_type, 0)) != NULL) { >+ consecutive_matches++; >+ if (consecutive_matches == port_count) >+ return (htons(i - port_count + 1)); >+ } else { >+ consecutive_matches = 0; >+ if (align == FIND_EVEN_ALIAS_BASE && (i % 2) == 0) >+ i++; >+ } >+ } >+ consecutive_matches = 0; >+ if (align == FIND_EVEN_ALIAS_BASE && (port_count % 2) != 0) >+ port_sys--; >+ for (i = port_sys - 1; i >= ALIAS_PORT_BASE; i--) { >+ if ((search_result = FindLinkIn(la, dst_addr, >+ alias_addr, dst_port, htons(i), >+ link_type, 0)) != NULL) { >+ consecutive_matches++; >+ if (consecutive_matches == port_count) >+ return (htons(i)); >+ } else { >+ consecutive_matches = 0; >+ if (align == FIND_EVEN_ALIAS_BASE && (i % 2) == 0) >+ i--; >+ } > } > > #ifdef LIBALIAS_DEBUG >-- >2.9.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 220101
: 183594