diff options
author | Vincent Gross <vgross@cvs.openbsd.org> | 2015-10-19 08:49:15 +0000 |
---|---|---|
committer | Vincent Gross <vgross@cvs.openbsd.org> | 2015-10-19 08:49:15 +0000 |
commit | 0b9fb83664c9dd956ce5beed1b2a84eb1cb5dbc5 (patch) | |
tree | 4f7da9ba2c3b8482a59cd3f646ba9db937318d5d /sys/netinet6 | |
parent | 6823b274a83bd80deb538081028593e1a87f3aea (diff) |
deduplicate in[6]_pcbbind() port scan loop.
ok mpi@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6_pcb.c | 74 |
1 files changed, 27 insertions, 47 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index e9e785035ad..ad203234c1c 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.78 2015/10/18 00:04:43 deraadt Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.79 2015/10/19 08:49:14 vgross Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -293,7 +293,7 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p) { struct socket *so = inp->inp_socket; struct inpcbtable *table = inp->inp_table; - u_int16_t first, last; + u_int16_t bound_a, bound_b, first, last; u_int16_t lastport = 0; u_int16_t lport = 0; int count; @@ -308,63 +308,43 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct proc *p) wild |= INPLOOKUP_WILDCARD; if (inp->inp_flags & INP_HIGHPORT) { - first = ipport_hifirstauto; /* sysctl */ - last = ipport_hilastauto; + bound_a = ipport_hifirstauto; /* sysctl */ + bound_b = ipport_hilastauto; } else if (inp->inp_flags & INP_LOWPORT) { if ((error = suser(p, 0))) return (EACCES); - first = IPPORT_RESERVED-1; /* 1023 */ - last = 600; /* not IPPORT_RESERVED/2 */ + bound_a = IPPORT_RESERVED-1; /* 1023 */ + bound_b = 600; /* not IPPORT_RESERVED/2 */ } else { - first = ipport_firstauto; /* sysctl */ - last = ipport_lastauto; + bound_a = ipport_firstauto; /* sysctl */ + bound_b = ipport_lastauto; + } + if (bound_a < bound_b) { + first = bound_a; + last = bound_b; + } else { + first = bound_b; + last = bound_a; } /* * Simple check to ensure all ports are not used up causing * a deadlock here. - * - * We split the two cases (up and down) so that the direction - * is not being tested on each round of the loop. */ - if (first > last) { - /* - * counting down - */ - count = first - last; - if (count) - lastport = first - arc4random_uniform(count); - - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - --lastport; - if (lastport > first || lastport < last) - lastport = first; - lport = htons(lastport); - } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || - in_pcblookup(table, &zeroin6_addr, 0, - &inp->inp_laddr6, lport, wild, inp->inp_rtableid)); - } else { - /* - * counting up - */ - count = last - first; - if (count) - lastport = first + arc4random_uniform(count); + count = last - first; + lastport = first + arc4random_uniform(count); - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - ++lastport; - if (lastport < first || lastport > last) - lastport = first; - lport = htons(lastport); - } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || - in_pcblookup(table, &zeroin6_addr, 0, - &inp->inp_laddr6, lport, wild, inp->inp_rtableid)); - } + do { + if (count-- < 0) /* completely used? */ + return (EADDRNOTAVAIL); + ++lastport; + if (lastport < first || lastport > last) + lastport = first; + lport = htons(lastport); + } while (in_baddynamic(lastport, so->so_proto->pr_protocol) || + in_pcblookup(table, &zeroin6_addr, 0, + &inp->inp_laddr6, lport, wild, inp->inp_rtableid)); inp->inp_lport = lport; in_pcbrehash(inp); |