Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/in_pcb.c
Show First 20 Lines • Show All 1,025 Lines • ▼ Show 20 Lines | if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { | ||||
*/ | */ | ||||
if ((inp->inp_flags & INP_BINDANY) == 0 && | if ((inp->inp_flags & INP_BINDANY) == 0 && | ||||
ifa_ifwithaddr_check((struct sockaddr *)sin) == 0) | ifa_ifwithaddr_check((struct sockaddr *)sin) == 0) | ||||
return (EADDRNOTAVAIL); | return (EADDRNOTAVAIL); | ||||
} | } | ||||
laddr = sin->sin_addr; | laddr = sin->sin_addr; | ||||
if (lport) { | if (lport) { | ||||
struct inpcb *t; | struct inpcb *t; | ||||
struct tcptw *tw; | |||||
/* GROSS */ | /* GROSS */ | ||||
if (ntohs(lport) <= V_ipport_reservedhigh && | if (ntohs(lport) <= V_ipport_reservedhigh && | ||||
ntohs(lport) >= V_ipport_reservedlow && | ntohs(lport) >= V_ipport_reservedlow && | ||||
priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT)) | priv_check_cred(cred, PRIV_NETINET_RESERVEDPORT)) | ||||
return (EACCES); | return (EACCES); | ||||
if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && | if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && | ||||
priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 0) { | priv_check_cred(inp->inp_cred, PRIV_NETINET_REUSEPORT) != 0) { | ||||
Show All 22 Lines | */ | ||||
* original socket also has to have been bound | * original socket also has to have been bound | ||||
* with BINDMULTI. | * with BINDMULTI. | ||||
*/ | */ | ||||
if (t && (! in_pcbbind_check_bindmulti(inp, t))) | if (t && (! in_pcbbind_check_bindmulti(inp, t))) | ||||
return (EADDRINUSE); | return (EADDRINUSE); | ||||
} | } | ||||
t = in_pcblookup_local(pcbinfo, sin->sin_addr, | t = in_pcblookup_local(pcbinfo, sin->sin_addr, | ||||
lport, lookupflags, cred); | lport, lookupflags, cred); | ||||
if (t && (t->inp_flags & INP_TIMEWAIT)) { | if (t && ((inp->inp_flags2 & INP_BINDMULTI) == 0) && | ||||
/* | |||||
* XXXRW: If an incpb has had its timewait | |||||
* state recycled, we treat the address as | |||||
* being in use (for now). This is better | |||||
* than a panic, but not desirable. | |||||
*/ | |||||
tw = intotw(t); | |||||
if (tw == NULL || | |||||
((reuseport & tw->tw_so_options) == 0 && | |||||
(reuseport_lb & | |||||
tw->tw_so_options) == 0)) { | |||||
return (EADDRINUSE); | |||||
} | |||||
} else if (t && | |||||
((inp->inp_flags2 & INP_BINDMULTI) == 0) && | |||||
(reuseport & inp_so_options(t)) == 0 && | (reuseport & inp_so_options(t)) == 0 && | ||||
(reuseport_lb & inp_so_options(t)) == 0) { | (reuseport_lb & inp_so_options(t)) == 0) { | ||||
#ifdef INET6 | #ifdef INET6 | ||||
if (ntohl(sin->sin_addr.s_addr) != | if (ntohl(sin->sin_addr.s_addr) != | ||||
INADDR_ANY || | INADDR_ANY || | ||||
ntohl(t->inp_laddr.s_addr) != | ntohl(t->inp_laddr.s_addr) != | ||||
INADDR_ANY || | INADDR_ANY || | ||||
(inp->inp_vflag & INP_IPV6PROTO) == 0 || | (inp->inp_vflag & INP_IPV6PROTO) == 0 || | ||||
(t->inp_vflag & INP_IPV6PROTO) == 0) | (t->inp_vflag & INP_IPV6PROTO) == 0) | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 2,350 Lines • Show Last 20 Lines |