Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/in_pcb.c
Show First 20 Lines • Show All 1,066 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Connect from a socket to a specified address. | * Connect from a socket to a specified address. | ||||
* Both address and port must be specified in argument sin. | * Both address and port must be specified in argument sin. | ||||
* If don't have a local address for this socket yet, | * If don't have a local address for this socket yet, | ||||
* then pick one. | * then pick one. | ||||
*/ | */ | ||||
int | int | ||||
in_pcbconnect_mbuf(struct inpcb *inp, struct sockaddr *nam, | in_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred, | ||||
Lint: Possible Spelling Mistake: Possible spelling error. You wrote 'nam', but did you mean 'name'? | |||||
struct ucred *cred, struct mbuf *m, bool rehash) | bool rehash) | ||||
{ | { | ||||
u_short lport, fport; | u_short lport, fport; | ||||
in_addr_t laddr, faddr; | in_addr_t laddr, faddr; | ||||
int anonport, error; | int anonport, error; | ||||
INP_WLOCK_ASSERT(inp); | INP_WLOCK_ASSERT(inp); | ||||
INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo); | INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo); | ||||
Show All 19 Lines | in_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred, | ||||
} | } | ||||
/* Commit the remaining changes. */ | /* Commit the remaining changes. */ | ||||
inp->inp_lport = lport; | inp->inp_lport = lport; | ||||
inp->inp_laddr.s_addr = laddr; | inp->inp_laddr.s_addr = laddr; | ||||
inp->inp_faddr.s_addr = faddr; | inp->inp_faddr.s_addr = faddr; | ||||
inp->inp_fport = fport; | inp->inp_fport = fport; | ||||
if (rehash) { | if (rehash) { | ||||
in_pcbrehash_mbuf(inp, m); | in_pcbrehash(inp); | ||||
} else { | } else { | ||||
in_pcbinshash_mbuf(inp, m); | in_pcbinshash(inp); | ||||
} | } | ||||
if (anonport) | if (anonport) | ||||
inp->inp_flags |= INP_ANONPORT; | inp->inp_flags |= INP_ANONPORT; | ||||
return (0); | return (0); | ||||
} | } | ||||
int | |||||
in_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred) | |||||
{ | |||||
return (in_pcbconnect_mbuf(inp, nam, cred, NULL, true)); | |||||
} | |||||
/* | /* | ||||
* Do proper source address selection on an unbound socket in case | * Do proper source address selection on an unbound socket in case | ||||
* of connect. Take jails into account as well. | * of connect. Take jails into account as well. | ||||
*/ | */ | ||||
int | int | ||||
in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr, | in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr, | ||||
struct ucred *cred) | struct ucred *cred) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,143 Lines • ▼ Show 20 Lines | in_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in_addr faddr, | ||||
return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport, | return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport, | ||||
lookupflags, ifp, m->m_pkthdr.numa_domain)); | lookupflags, ifp, m->m_pkthdr.numa_domain)); | ||||
} | } | ||||
#endif /* INET */ | #endif /* INET */ | ||||
/* | /* | ||||
* Insert PCB onto various hash lists. | * Insert PCB onto various hash lists. | ||||
*/ | */ | ||||
static int | int | ||||
in_pcbinshash_internal(struct inpcb *inp, struct mbuf *m) | in_pcbinshash(struct inpcb *inp) | ||||
{ | { | ||||
struct inpcbhead *pcbhash; | struct inpcbhead *pcbhash; | ||||
struct inpcbporthead *pcbporthash; | struct inpcbporthead *pcbporthash; | ||||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; | struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; | ||||
struct inpcbport *phd; | struct inpcbport *phd; | ||||
u_int32_t hashkey_faddr; | u_int32_t hashkey_faddr; | ||||
int so_options; | int so_options; | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | #endif | ||||
inp->inp_phd = phd; | inp->inp_phd = phd; | ||||
CK_LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist); | CK_LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist); | ||||
CK_LIST_INSERT_HEAD(pcbhash, inp, inp_hash); | CK_LIST_INSERT_HEAD(pcbhash, inp, inp_hash); | ||||
inp->inp_flags |= INP_INHASHLIST; | inp->inp_flags |= INP_INHASHLIST; | ||||
return (0); | return (0); | ||||
} | } | ||||
int | |||||
in_pcbinshash(struct inpcb *inp) | |||||
{ | |||||
return (in_pcbinshash_internal(inp, NULL)); | |||||
} | |||||
int | |||||
in_pcbinshash_mbuf(struct inpcb *inp, struct mbuf *m) | |||||
{ | |||||
return (in_pcbinshash_internal(inp, m)); | |||||
} | |||||
/* | /* | ||||
* Move PCB to the proper hash bucket when { faddr, fport } have been | * Move PCB to the proper hash bucket when { faddr, fport } have been | ||||
* changed. NOTE: This does not handle the case of the lport changing (the | * changed. NOTE: This does not handle the case of the lport changing (the | ||||
* hashed port list would have to be updated as well), so the lport must | * hashed port list would have to be updated as well), so the lport must | ||||
* not change after in_pcbinshash() has been called. | * not change after in_pcbinshash() has been called. | ||||
*/ | */ | ||||
void | void | ||||
in_pcbrehash_mbuf(struct inpcb *inp, struct mbuf *m) | in_pcbrehash(struct inpcb *inp) | ||||
{ | { | ||||
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; | struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; | ||||
struct inpcbhead *head; | struct inpcbhead *head; | ||||
u_int32_t hashkey_faddr; | u_int32_t hashkey_faddr; | ||||
INP_WLOCK_ASSERT(inp); | INP_WLOCK_ASSERT(inp); | ||||
INP_HASH_WLOCK_ASSERT(pcbinfo); | INP_HASH_WLOCK_ASSERT(pcbinfo); | ||||
KASSERT(inp->inp_flags & INP_INHASHLIST, | KASSERT(inp->inp_flags & INP_INHASHLIST, | ||||
("in_pcbrehash: !INP_INHASHLIST")); | ("in_pcbrehash: !INP_INHASHLIST")); | ||||
#ifdef INET6 | #ifdef INET6 | ||||
if (inp->inp_vflag & INP_IPV6) | if (inp->inp_vflag & INP_IPV6) | ||||
hashkey_faddr = INP6_PCBHASHKEY(&inp->in6p_faddr); | hashkey_faddr = INP6_PCBHASHKEY(&inp->in6p_faddr); | ||||
else | else | ||||
#endif | #endif | ||||
hashkey_faddr = inp->inp_faddr.s_addr; | hashkey_faddr = inp->inp_faddr.s_addr; | ||||
head = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr, | head = &pcbinfo->ipi_hashbase[INP_PCBHASH(hashkey_faddr, | ||||
inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)]; | inp->inp_lport, inp->inp_fport, pcbinfo->ipi_hashmask)]; | ||||
CK_LIST_REMOVE(inp, inp_hash); | CK_LIST_REMOVE(inp, inp_hash); | ||||
CK_LIST_INSERT_HEAD(head, inp, inp_hash); | CK_LIST_INSERT_HEAD(head, inp, inp_hash); | ||||
} | |||||
void | |||||
in_pcbrehash(struct inpcb *inp) | |||||
{ | |||||
in_pcbrehash_mbuf(inp, NULL); | |||||
} | } | ||||
/* | /* | ||||
* Remove PCB from various lists. | * Remove PCB from various lists. | ||||
*/ | */ | ||||
static void | static void | ||||
in_pcbremlists(struct inpcb *inp) | in_pcbremlists(struct inpcb *inp) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 812 Lines • Show Last 20 Lines |
Possible spelling error. You wrote 'nam', but did you mean 'name'?