This patch is provided to fix a couple of deployment issues observed
in the field. In one situation, one end of the TCP connection sends a back-to-back RST packet, with delayed ack, the last_ack_sent variable has not been update yet. When tcp_insecure_rst is turned off, the code treats the RST as invalid because last_ack_sent instead of rcv_nxt is compared against th_seq. Apparently there is some kind of firewall that sits in between the two ends and that RST packet is the only RST packet received. With short lived HTTP connections, the symptom is a large accumulation of connections over a short period of time . The +/-(1) factor is to take care of implementations out there that generate RST packets with these types of sequence numbers. This behavior has also been observed in live environments. Reviewed by: silby, Mike Karels MFC after: 1 week
This commit is contained in:
parent
b533eb28f1
commit
fb4a7a64bd
@ -1655,9 +1655,8 @@ tcp_input(m, off0)
|
||||
* RFC 1337.
|
||||
*/
|
||||
if (thflags & TH_RST) {
|
||||
if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) &&
|
||||
SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) ||
|
||||
(tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) {
|
||||
if (SEQ_GEQ(th->th_seq, tp->last_ack_sent - 1) &&
|
||||
SEQ_LEQ(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) {
|
||||
switch (tp->t_state) {
|
||||
|
||||
case TCPS_SYN_RECEIVED:
|
||||
@ -1665,8 +1664,11 @@ tcp_input(m, off0)
|
||||
goto close;
|
||||
|
||||
case TCPS_ESTABLISHED:
|
||||
if (tp->last_ack_sent != th->th_seq &&
|
||||
tcp_insecure_rst == 0) {
|
||||
if (tcp_insecure_rst == 0 &&
|
||||
!(SEQ_GEQ(th->th_seq, tp->rcv_nxt - 1) &&
|
||||
SEQ_LEQ(th->th_seq, tp->rcv_nxt + 1)) &&
|
||||
!(SEQ_GEQ(th->th_seq, tp->last_ack_sent - 1) &&
|
||||
SEQ_LEQ(th->th_seq, tp->last_ack_sent + 1))) {
|
||||
tcpstat.tcps_badrst++;
|
||||
goto drop;
|
||||
}
|
||||
|
@ -1655,9 +1655,8 @@ tcp_input(m, off0)
|
||||
* RFC 1337.
|
||||
*/
|
||||
if (thflags & TH_RST) {
|
||||
if ((SEQ_GEQ(th->th_seq, tp->last_ack_sent) &&
|
||||
SEQ_LT(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) ||
|
||||
(tp->rcv_wnd == 0 && tp->last_ack_sent == th->th_seq)) {
|
||||
if (SEQ_GEQ(th->th_seq, tp->last_ack_sent - 1) &&
|
||||
SEQ_LEQ(th->th_seq, tp->last_ack_sent + tp->rcv_wnd)) {
|
||||
switch (tp->t_state) {
|
||||
|
||||
case TCPS_SYN_RECEIVED:
|
||||
@ -1665,8 +1664,11 @@ tcp_input(m, off0)
|
||||
goto close;
|
||||
|
||||
case TCPS_ESTABLISHED:
|
||||
if (tp->last_ack_sent != th->th_seq &&
|
||||
tcp_insecure_rst == 0) {
|
||||
if (tcp_insecure_rst == 0 &&
|
||||
!(SEQ_GEQ(th->th_seq, tp->rcv_nxt - 1) &&
|
||||
SEQ_LEQ(th->th_seq, tp->rcv_nxt + 1)) &&
|
||||
!(SEQ_GEQ(th->th_seq, tp->last_ack_sent - 1) &&
|
||||
SEQ_LEQ(th->th_seq, tp->last_ack_sent + 1))) {
|
||||
tcpstat.tcps_badrst++;
|
||||
goto drop;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user