diff options
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) { |