* This function is called when we get a RST for a * non-existent connection, so that we can see if the * connection is in the syn cache. If it is, zap it. * If required send a challenge ACK. */
| 605 | * If required send a challenge ACK. |
| 606 | */ |
| 607 | void |
| 608 | syncache_chkrst(struct in_conninfo *inc, struct tcphdr *th, struct mbuf *m) |
| 609 | { |
| 610 | struct syncache *sc; |
| 611 | struct syncache_head *sch; |
| 612 | char *s = NULL; |
| 613 | |
| 614 | if (syncache_cookiesonly()) |
| 615 | return; |
| 616 | sc = syncache_lookup(inc, &sch); /* returns locked sch */ |
| 617 | SCH_LOCK_ASSERT(sch); |
| 618 | |
| 619 | /* |
| 620 | * Any RST to our SYN|ACK must not carry ACK, SYN or FIN flags. |
| 621 | * See RFC 793 page 65, section SEGMENT ARRIVES. |
| 622 | */ |
| 623 | if (th->th_flags & (TH_ACK|TH_SYN|TH_FIN)) { |
| 624 | if ((s = tcp_log_addrs(inc, th, NULL, NULL))) |
| 625 | log(LOG_DEBUG, "%s; %s: Spurious RST with ACK, SYN or " |
| 626 | "FIN flag set, segment ignored\n", s, __func__); |
| 627 | TCPSTAT_INC(tcps_badrst); |
| 628 | goto done; |
| 629 | } |
| 630 | |
| 631 | /* |
| 632 | * No corresponding connection was found in syncache. |
| 633 | * If syncookies are enabled and possibly exclusively |
| 634 | * used, or we are under memory pressure, a valid RST |
| 635 | * may not find a syncache entry. In that case we're |
| 636 | * done and no SYN|ACK retransmissions will happen. |
| 637 | * Otherwise the RST was misdirected or spoofed. |
| 638 | */ |
| 639 | if (sc == NULL) { |
| 640 | if ((s = tcp_log_addrs(inc, th, NULL, NULL))) |
| 641 | log(LOG_DEBUG, "%s; %s: Spurious RST without matching " |
| 642 | "syncache entry (possibly syncookie only), " |
| 643 | "segment ignored\n", s, __func__); |
| 644 | TCPSTAT_INC(tcps_badrst); |
| 645 | goto done; |
| 646 | } |
| 647 | |
| 648 | /* |
| 649 | * If the RST bit is set, check the sequence number to see |
| 650 | * if this is a valid reset segment. |
| 651 | * |
| 652 | * RFC 793 page 37: |
| 653 | * In all states except SYN-SENT, all reset (RST) segments |
| 654 | * are validated by checking their SEQ-fields. A reset is |
| 655 | * valid if its sequence number is in the window. |
| 656 | * |
| 657 | * RFC 793 page 69: |
| 658 | * There are four cases for the acceptability test for an incoming |
| 659 | * segment: |
| 660 | * |
| 661 | * Segment Receive Test |
| 662 | * Length Window |
| 663 | * ------- ------- ------------------------------------------- |
| 664 | * 0 0 SEG.SEQ = RCV.NXT |
no test coverage detected