lib/socket: randomize the generated local port
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@redhat.com>
This commit is contained in:
parent
4dd5fdd0af
commit
1f734a8f89
1 changed files with 26 additions and 3 deletions
29
lib/socket.c
29
lib/socket.c
|
@ -62,16 +62,39 @@ 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) {
|
||||
uint32_t t = time(NULL);
|
||||
|
||||
/* 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 = t ^ (t >> 16) ^ 0x3047;
|
||||
} 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 32 ports preferably 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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue