| 2290 | } |
| 2291 | |
| 2292 | static struct syncache * |
| 2293 | syncookie_lookup(struct in_conninfo *inc, struct syncache_head *sch, |
| 2294 | struct syncache *sc, struct tcphdr *th, struct tcpopt *to, |
| 2295 | struct socket *lso) |
| 2296 | { |
| 2297 | uint32_t hash; |
| 2298 | uint8_t *secbits; |
| 2299 | tcp_seq ack, seq; |
| 2300 | int wnd, wscale = 0; |
| 2301 | union syncookie cookie; |
| 2302 | |
| 2303 | /* |
| 2304 | * Pull information out of SYN-ACK/ACK and revert sequence number |
| 2305 | * advances. |
| 2306 | */ |
| 2307 | ack = th->th_ack - 1; |
| 2308 | seq = th->th_seq - 1; |
| 2309 | |
| 2310 | /* |
| 2311 | * Unpack the flags containing enough information to restore the |
| 2312 | * connection. |
| 2313 | */ |
| 2314 | cookie.cookie = (ack & 0xff) ^ (ack >> 24); |
| 2315 | |
| 2316 | /* Which of the two secrets to use. */ |
| 2317 | secbits = V_tcp_syncache.secret.key[cookie.flags.odd_even]; |
| 2318 | |
| 2319 | hash = syncookie_mac(inc, seq, cookie.cookie, secbits, (uintptr_t)sch); |
| 2320 | |
| 2321 | /* The recomputed hash matches the ACK if this was a genuine cookie. */ |
| 2322 | if ((ack & ~0xff) != (hash & ~0xff)) |
| 2323 | return (NULL); |
| 2324 | |
| 2325 | /* Fill in the syncache values. */ |
| 2326 | sc->sc_flags = 0; |
| 2327 | bcopy(inc, &sc->sc_inc, sizeof(struct in_conninfo)); |
| 2328 | sc->sc_ipopts = NULL; |
| 2329 | |
| 2330 | sc->sc_irs = seq; |
| 2331 | sc->sc_iss = ack; |
| 2332 | |
| 2333 | switch (inc->inc_flags & INC_ISIPV6) { |
| 2334 | #ifdef INET |
| 2335 | case 0: |
| 2336 | sc->sc_ip_ttl = sotoinpcb(lso)->inp_ip_ttl; |
| 2337 | sc->sc_ip_tos = sotoinpcb(lso)->inp_ip_tos; |
| 2338 | break; |
| 2339 | #endif |
| 2340 | #ifdef INET6 |
| 2341 | case INC_ISIPV6: |
| 2342 | if (sotoinpcb(lso)->inp_flags & IN6P_AUTOFLOWLABEL) |
| 2343 | sc->sc_flowlabel = |
| 2344 | htonl(sc->sc_iss) & IPV6_FLOWLABEL_MASK; |
| 2345 | break; |
| 2346 | #endif |
| 2347 | } |
| 2348 | |
| 2349 | sc->sc_peer_mss = tcp_sc_msstab[cookie.flags.mss_idx]; |
no test coverage detected