diff options
author | bz <bz@FreeBSD.org> | 2011-03-12 21:46:37 +0000 |
---|---|---|
committer | bz <bz@FreeBSD.org> | 2011-03-12 21:46:37 +0000 |
commit | 524448845cfdfa08a56ba5dc26d7dc9ca075ec30 (patch) | |
tree | 2c624cee0eb5ca0598a24a7eb17008dbe6b098de /sys/netinet6/in6_src.c | |
parent | 1a54928233f948c8094d9a0856433a960ffd840d (diff) | |
download | FreeBSD-src-524448845cfdfa08a56ba5dc26d7dc9ca075ec30.zip FreeBSD-src-524448845cfdfa08a56ba5dc26d7dc9ca075ec30.tar.gz |
Merge the two identical implementations for local port selections from
in_pcbbind_setup() and in6_pcbsetport() in a single in_pcb_lport().
MFC after: 2 weeks
Diffstat (limited to 'sys/netinet6/in6_src.c')
-rw-r--r-- | sys/netinet6/in6_src.c | 74 |
1 files changed, 7 insertions, 67 deletions
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 2bf99fe..b491e0e 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -850,9 +850,11 @@ int in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred) { struct socket *so = inp->inp_socket; - u_int16_t lport = 0, first, last, *lastport; - int count, error, wild = 0, dorandom; + u_int16_t lport = 0; + int error, wild = 0; +#ifdef INVARIANTS struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; +#endif INP_INFO_WLOCK_ASSERT(pcbinfo); INP_WLOCK_ASSERT(inp); @@ -868,71 +870,9 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred) inp->inp_flags |= INP_ANONPORT; - if (inp->inp_flags & INP_HIGHPORT) { - first = V_ipport_hifirstauto; /* sysctl */ - last = V_ipport_hilastauto; - lastport = &pcbinfo->ipi_lasthi; - } else if (inp->inp_flags & INP_LOWPORT) { - error = priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT, 0); - if (error) - return error; - first = V_ipport_lowfirstauto; /* 1023 */ - last = V_ipport_lowlastauto; /* 600 */ - lastport = &pcbinfo->ipi_lastlow; - } else { - first = V_ipport_firstauto; /* sysctl */ - last = V_ipport_lastauto; - lastport = &pcbinfo->ipi_lastport; - } - - /* - * For UDP, use random port allocation as long as the user - * allows it. For TCP (and as of yet unknown) connections, - * use random port allocation only if the user allows it AND - * ipport_tick() allows it. - */ - if (V_ipport_randomized && - (!V_ipport_stoprandom || pcbinfo == &V_udbinfo)) - dorandom = 1; - else - dorandom = 0; - /* - * It makes no sense to do random port allocation if - * we have the only port available. - */ - if (first == last) - dorandom = 0; - /* Make sure to not include UDP packets in the count. */ - if (pcbinfo != &V_udbinfo) - V_ipport_tcpallocs++; - - /* - * Instead of having two loops further down counting up or down - * make sure that first is always <= last and go with only one - * code path implementing all logic. - */ - if (first > last) { - u_int16_t aux; - - aux = first; - first = last; - last = aux; - } - - if (dorandom) - *lastport = first + (arc4random() % (last - first)); - - count = last - first; - - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - ++*lastport; - if (*lastport < first || *lastport > last) - *lastport = first; - lport = htons(*lastport); - } while (in6_pcblookup_local(pcbinfo, &inp->in6p_laddr, - lport, wild, cred)); + error = in_pcb_lport(inp, NULL, &lport, cred, wild); + if (error != 0) + return (error); inp->inp_lport = lport; if (in_pcbinshash(inp) != 0) { |