* Connect from a socket to a specified address. * Both address and port must be specified in argument sin. * If don't have a local address for this socket yet, * then pick one. */
| 1177 | * then pick one. |
| 1178 | */ |
| 1179 | int |
| 1180 | in_pcbconnect_mbuf(struct inpcb *inp, struct sockaddr *nam, |
| 1181 | struct ucred *cred, struct mbuf *m, bool rehash) |
| 1182 | { |
| 1183 | u_short lport, fport; |
| 1184 | in_addr_t laddr, faddr; |
| 1185 | int anonport, error; |
| 1186 | |
| 1187 | INP_WLOCK_ASSERT(inp); |
| 1188 | INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo); |
| 1189 | |
| 1190 | lport = inp->inp_lport; |
| 1191 | laddr = inp->inp_laddr.s_addr; |
| 1192 | anonport = (lport == 0); |
| 1193 | error = in_pcbconnect_setup(inp, nam, &laddr, &lport, &faddr, &fport, |
| 1194 | NULL, cred); |
| 1195 | if (error) |
| 1196 | return (error); |
| 1197 | |
| 1198 | /* Do the initial binding of the local address if required. */ |
| 1199 | if (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) { |
| 1200 | KASSERT(rehash == true, |
| 1201 | ("Rehashing required for unbound inps")); |
| 1202 | inp->inp_lport = lport; |
| 1203 | inp->inp_laddr.s_addr = laddr; |
| 1204 | if (in_pcbinshash(inp) != 0) { |
| 1205 | inp->inp_laddr.s_addr = INADDR_ANY; |
| 1206 | inp->inp_lport = 0; |
| 1207 | return (EAGAIN); |
| 1208 | } |
| 1209 | } |
| 1210 | |
| 1211 | /* Commit the remaining changes. */ |
| 1212 | inp->inp_lport = lport; |
| 1213 | inp->inp_laddr.s_addr = laddr; |
| 1214 | inp->inp_faddr.s_addr = faddr; |
| 1215 | inp->inp_fport = fport; |
| 1216 | if (rehash) { |
| 1217 | in_pcbrehash_mbuf(inp, m); |
| 1218 | } else { |
| 1219 | in_pcbinshash_mbuf(inp, m); |
| 1220 | } |
| 1221 | |
| 1222 | if (anonport) |
| 1223 | inp->inp_flags |= INP_ANONPORT; |
| 1224 | return (0); |
| 1225 | } |
| 1226 | |
| 1227 | int |
| 1228 | in_pcbconnect(struct inpcb *inp, struct sockaddr *nam, struct ucred *cred) |
no test coverage detected