* Given a LISTEN socket and an inbound SYN request, add * this to the syn cache, and send back a segment: * * to the source. * * IMPORTANT NOTE: We do _NOT_ ACK data that might accompany the SYN. * Doing so would require that we hold onto the data and deliver it * to the application. However, if we are the target of a SYN-flood * DoS attack, an attacker
| 1442 | * ACK timer expires, whichever comes first. |
| 1443 | */ |
| 1444 | int |
| 1445 | syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, |
| 1446 | struct inpcb *inp, struct socket **lsop, struct mbuf *m, void *tod, |
| 1447 | void *todctx, uint8_t iptos) |
| 1448 | { |
| 1449 | struct tcpcb *tp; |
| 1450 | struct socket *so; |
| 1451 | struct syncache *sc = NULL; |
| 1452 | struct syncache_head *sch; |
| 1453 | struct mbuf *ipopts = NULL; |
| 1454 | u_int ltflags; |
| 1455 | int win, ip_ttl, ip_tos; |
| 1456 | char *s; |
| 1457 | int rv = 0; |
| 1458 | #ifdef INET6 |
| 1459 | int autoflowlabel = 0; |
| 1460 | #endif |
| 1461 | #ifdef MAC |
| 1462 | struct label *maclabel; |
| 1463 | #endif |
| 1464 | struct syncache scs; |
| 1465 | struct ucred *cred; |
| 1466 | uint64_t tfo_response_cookie; |
| 1467 | unsigned int *tfo_pending = NULL; |
| 1468 | int tfo_cookie_valid = 0; |
| 1469 | int tfo_response_cookie_valid = 0; |
| 1470 | bool locked; |
| 1471 | |
| 1472 | INP_WLOCK_ASSERT(inp); /* listen socket */ |
| 1473 | KASSERT((th->th_flags & (TH_RST|TH_ACK|TH_SYN)) == TH_SYN, |
| 1474 | ("%s: unexpected tcp flags", __func__)); |
| 1475 | |
| 1476 | /* |
| 1477 | * Combine all so/tp operations very early to drop the INP lock as |
| 1478 | * soon as possible. |
| 1479 | */ |
| 1480 | so = *lsop; |
| 1481 | KASSERT(SOLISTENING(so), ("%s: %p not listening", __func__, so)); |
| 1482 | tp = sototcpcb(so); |
| 1483 | cred = crhold(so->so_cred); |
| 1484 | |
| 1485 | #ifdef INET6 |
| 1486 | if (inc->inc_flags & INC_ISIPV6) { |
| 1487 | if (inp->inp_flags & IN6P_AUTOFLOWLABEL) { |
| 1488 | autoflowlabel = 1; |
| 1489 | } |
| 1490 | ip_ttl = in6_selecthlim(inp, NULL); |
| 1491 | if ((inp->in6p_outputopts == NULL) || |
| 1492 | (inp->in6p_outputopts->ip6po_tclass == -1)) { |
| 1493 | ip_tos = 0; |
| 1494 | } else { |
| 1495 | ip_tos = inp->in6p_outputopts->ip6po_tclass; |
| 1496 | } |
| 1497 | } |
| 1498 | #endif |
| 1499 | #if defined(INET6) && defined(INET) |
| 1500 | else |
| 1501 | #endif |
no test coverage detected