[PATCH 4/4] lib/socket: randomize the generated local port

Thomas Haller thaller at redhat.com
Wed Apr 9 03:08:53 PDT 2014


Instead of always trying the same order of ports when
looking for an unused port, randomize the order (naively).

As libnl-1 uses the same function, it is likely that two applications
that are using both libraries generate the same ports. By chosing a
different order how to select the local port, the chances are smaller
for this to happen (however, it cannot avoid it entirely. The user
and/or libnl3 still has to cope with the situation, that somebody
else might already use the port).

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/socket.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/lib/socket.c b/lib/socket.c
index cf0dba1..7584749 100644
--- a/lib/socket.c
+++ b/lib/socket.c
@@ -62,16 +62,37 @@ static NL_RW_LOCK(port_map_lock);
 
 static uint32_t generate_local_port(void)
 {
-	int i, n;
+	int i, j, n, m;
+	static uint16_t idx_state = 0;
 	uint32_t pid = getpid() & 0x3FFFFF;
 
 	nl_write_lock(&port_map_lock);
 
-	for (i = 0; i < 32; i++) {
+	if (idx_state == 0) {
+		/* from time to time (on average each 2^15 calls), the idx_state will
+		 * be zero again. No problem, just "seed" anew with time(). */
+		idx_state = time(NULL);
+	} else
+		idx_state = idx_state + 20011; /* add prime number */
+
+	i = idx_state >> 5;
+	n = idx_state;
+	for (j = 0; j < 32; j++) {
+		/* walk the index somewhat randomized, with always leaving the block
+		 * #0 as last. The reason is that libnl-1 will start at block #0,
+		 * so just leave the first 8 ports for libnl-1 owned sockets (this is
+		 * relevant only if the applications ends up using both versions of the
+		 * library and doesn't hurt otherwise). */
+		if (j == 31)
+			i = 0;
+		else
+			i = (((i-1) + 7) % 31) + 1;
+
 		if (used_ports_map[i] == 0xFFFFFFFF)
 			continue;
 
-		for (n = 0; n < 32; n++) {
+		for (m = 0; m < 32; m++) {
+			n = (n + 13) % 32;
 			if (1UL & (used_ports_map[i] >> n))
 				continue;
 
-- 
1.9.0




More information about the libnl mailing list