Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/in_pcb.c
Show First 20 Lines • Show All 1,049 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(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred, | in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred, | ||||
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); | ||||
lport = inp->inp_lport; | lport = inp->inp_lport; | ||||
laddr = inp->inp_laddr.s_addr; | laddr = inp->inp_laddr.s_addr; | ||||
anonport = (lport == 0); | anonport = (lport == 0); | ||||
error = in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport, | error = in_pcbconnect_setup(inp, sin, &laddr, &lport, &faddr, &fport, | ||||
NULL, cred); | NULL, cred); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* Do the initial binding of the local address if required. */ | /* Do the initial binding of the local address if required. */ | ||||
if (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) { | if (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) { | ||||
KASSERT(rehash == true, | KASSERT(rehash == true, | ||||
("Rehashing required for unbound inps")); | ("Rehashing required for unbound inps")); | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | |||||
* and port. These are not updated in the error case. | * and port. These are not updated in the error case. | ||||
* | * | ||||
* If the operation fails because the connection already exists, | * If the operation fails because the connection already exists, | ||||
* *oinpp will be set to the PCB of that connection so that the | * *oinpp will be set to the PCB of that connection so that the | ||||
* caller can decide to override it. In all other cases, *oinpp | * caller can decide to override it. In all other cases, *oinpp | ||||
* is set to NULL. | * is set to NULL. | ||||
*/ | */ | ||||
int | int | ||||
in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, | in_pcbconnect_setup(struct inpcb *inp, struct sockaddr_in *sin, | ||||
in_addr_t *laddrp, u_short *lportp, in_addr_t *faddrp, u_short *fportp, | in_addr_t *laddrp, u_short *lportp, in_addr_t *faddrp, u_short *fportp, | ||||
struct inpcb **oinpp, struct ucred *cred) | struct inpcb **oinpp, struct ucred *cred) | ||||
{ | { | ||||
struct sockaddr_in *sin = (struct sockaddr_in *)nam; | |||||
struct in_ifaddr *ia; | struct in_ifaddr *ia; | ||||
struct inpcb *oinp; | struct inpcb *oinp; | ||||
struct in_addr laddr, faddr; | struct in_addr laddr, faddr; | ||||
u_short lport, fport; | u_short lport, fport; | ||||
int error; | int error; | ||||
KASSERT(sin->sin_family == AF_INET, | KASSERT(sin->sin_family == AF_INET, | ||||
("%s: invalid address family for %p", __func__, sin)); | ("%s: invalid address family for %p", __func__, sin)); | ||||
▲ Show 20 Lines • Show All 1,997 Lines • Show Last 20 Lines |