* Lookup PCB in hash list, using pcbgroup tables. */
| 2246 | * Lookup PCB in hash list, using pcbgroup tables. |
| 2247 | */ |
| 2248 | static struct inpcb * |
| 2249 | in_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, |
| 2250 | struct in_addr faddr, u_int fport_arg, struct in_addr laddr, |
| 2251 | u_int lport_arg, int lookupflags, struct ifnet *ifp) |
| 2252 | { |
| 2253 | struct inpcbhead *head; |
| 2254 | struct inpcb *inp, *tmpinp; |
| 2255 | u_short fport = fport_arg, lport = lport_arg; |
| 2256 | bool locked; |
| 2257 | |
| 2258 | /* |
| 2259 | * First look for an exact match. |
| 2260 | */ |
| 2261 | tmpinp = NULL; |
| 2262 | INP_GROUP_LOCK(pcbgroup); |
| 2263 | head = &pcbgroup->ipg_hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, |
| 2264 | pcbgroup->ipg_hashmask)]; |
| 2265 | CK_LIST_FOREACH(inp, head, inp_pcbgrouphash) { |
| 2266 | #ifdef INET6 |
| 2267 | /* XXX inp locking */ |
| 2268 | if ((inp->inp_vflag & INP_IPV4) == 0) |
| 2269 | continue; |
| 2270 | #endif |
| 2271 | if (inp->inp_faddr.s_addr == faddr.s_addr && |
| 2272 | inp->inp_laddr.s_addr == laddr.s_addr && |
| 2273 | inp->inp_fport == fport && |
| 2274 | inp->inp_lport == lport) { |
| 2275 | /* |
| 2276 | * XXX We should be able to directly return |
| 2277 | * the inp here, without any checks. |
| 2278 | * Well unless both bound with SO_REUSEPORT? |
| 2279 | */ |
| 2280 | if (prison_flag(inp->inp_cred, PR_IP4)) |
| 2281 | goto found; |
| 2282 | if (tmpinp == NULL) |
| 2283 | tmpinp = inp; |
| 2284 | } |
| 2285 | } |
| 2286 | if (tmpinp != NULL) { |
| 2287 | inp = tmpinp; |
| 2288 | goto found; |
| 2289 | } |
| 2290 | |
| 2291 | #ifdef RSS |
| 2292 | /* |
| 2293 | * For incoming connections, we may wish to do a wildcard |
| 2294 | * match for an RSS-local socket. |
| 2295 | */ |
| 2296 | if ((lookupflags & INPLOOKUP_WILDCARD) != 0) { |
| 2297 | struct inpcb *local_wild = NULL, *local_exact = NULL; |
| 2298 | #ifdef INET6 |
| 2299 | struct inpcb *local_wild_mapped = NULL; |
| 2300 | #endif |
| 2301 | struct inpcb *jail_wild = NULL; |
| 2302 | struct inpcbhead *head; |
| 2303 | int injail; |
| 2304 | |
| 2305 | /* |
no test coverage detected