From 9c590d0736597dbc1e5d8d3c5762121a7d6465bc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 8 Oct 2008 11:44:17 -0700 Subject: [PATCH] --- yaml --- r: 112157 b: refs/heads/master c: 9088c5609584684149f3fb5b065aa7f18dcb03ff h: refs/heads/master i: 112155: 1d604b8dc81790d526bddb2e6e921da4535b9913 v: v3 --- [refs] | 2 +- trunk/net/ipv4/udp.c | 56 ++++++++++---------------------------------- 2 files changed, 13 insertions(+), 45 deletions(-) diff --git a/[refs] b/[refs] index 2dd6c7b8156b..8bb00e2dbef8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 53e915034970935596703a6005cde27c2128b5c3 +refs/heads/master: 9088c5609584684149f3fb5b065aa7f18dcb03ff diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 85f8e8e10b1b..67d8430b4a2a 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -155,55 +155,23 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, write_lock_bh(&udp_hash_lock); if (!snum) { - int i, low, high, remaining; - unsigned rover, best, best_size_so_far; + int low, high, remaining; + unsigned rand; + unsigned short first; inet_get_local_port_range(&low, &high); remaining = (high - low) + 1; - best_size_so_far = UINT_MAX; - best = rover = net_random() % remaining + low; - - /* 1st pass: look for empty (or shortest) hash chain */ - for (i = 0; i < UDP_HTABLE_SIZE; i++) { - int size = 0; - - head = &udptable[udp_hashfn(net, rover)]; - if (hlist_empty(head)) - goto gotit; - - sk_for_each(sk2, node, head) { - if (++size >= best_size_so_far) - goto next; - } - best_size_so_far = size; - best = rover; - next: - /* fold back if end of range */ - if (++rover > high) - rover = low + ((rover - low) - & (UDP_HTABLE_SIZE - 1)); - - - } - - /* 2nd pass: find hole in shortest hash chain */ - rover = best; - for (i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++) { - if (! __udp_lib_lport_inuse(net, rover, udptable)) - goto gotit; - rover += UDP_HTABLE_SIZE; - if (rover > high) - rover = low + ((rover - low) - & (UDP_HTABLE_SIZE - 1)); + rand = net_random(); + snum = first = rand % remaining + low; + rand |= 1; + while (__udp_lib_lport_inuse(net, snum, udptable)) { + do { + snum = snum + rand; + } while (snum < low || snum > high); + if (snum == first) + goto fail; } - - - /* All ports in use! */ - goto fail; - -gotit: - snum = rover; } else { head = &udptable[udp_hashfn(net, snum)];