NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/48283: Drops FIN + ACK mistakenly
>Number: 48283
>Category: kern
>Synopsis: Drops FIN mistakenly
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Oct 07 06:30:00 +0000 2013
>Originator: yasuoka%iij.ad.jp@localhost
>Release: NetBSD 5.1.2
>Organization:
Internet Initiative Japan Inc.
>Environment:
System: NetBSD yasuoka-nb.tokyo.iiji.jp 5.1.2 NetBSD 5.1.2 (GENERIC) #0: Thu
Feb 2 12:12:28 UTC 2012
builds%b7.netbsd.org@localhost:/home/builds/ab/netbsd-5-1-2-RELEASE/amd64/201202021012Z-obj/home/builds/ab/netbsd-5-1-2-RELEASE/src/sys/arch/amd64/compile/GENERIC
amd64
Architecture: x86_64
Machine: amd64
>Description:
The TCP stack doesn't initialize the snd_fack field in TCPCB.
The snd_fack is used for "FACK fast recover". This causes
dropping FIN mistakenly like below
19:03:22.685693 IP Windows.54527 > NetBSD.22: S 0:0(0) win 65535 <mss
1460,nop,nop,sackOK>
19:03:22.685717 IP NetBSD.22 > Windows.54527: S 0:0(0) ack 1 win
32768 <mss 33608,sackOK,nop,nop>
19:03:22.685743 IP Windows.54527 > NetBSD.22: . ack 1 win 65535
19:03:22.696118 IP NetBSD.22 > Windows.54527: P 1:58(57) ack 1 win
32768
19:03:22.696201 IP Windows.54527 > NetBSD.22: F 1:1(0) ack 1 win 65535
19:03:22.696219 IP Windows.54527 > NetBSD.22: R 2:2(0) ack 58 win 0
19:03:22.696225 IP NetBSD.22 > Windows.54527: . ack 1 win 32768
19:03:28.701512 IP NetBSD.22 > Windows.54527: P 1:58(57) ack 1 win
32768
Windows was to terminate the TCP connection in wild way. Anyway
NetBSD must receive the FIN from Windows, but it doesn't seem
to receive the FIN.
snd_fack is always initialized by 0. If we receive a ack which
reaches below block and the snd_fack is not modified yet,
tcp_input.c:
2621 else if (tp->t_partialacks < 0
&&
2622 (++tp->t_dupacks ==
tcprexmtthresh ||
2623
TCP_FACK_FASTRECOV(tp))) {
tcp_var.h:
373 #define TCP_FACK_FASTRECOV(tp) \
374 (TCP_SACK_ENABLED(tp) && \
375 (SEQ_GT(tp->snd_fack, tp->snd_una + tcprexmtthresh *
tp->t_segsz)))
Since the snd_una is come from our TCP sequence number initialized
randomly, TCP_FACK_FASTRECOV is mistakenly true in 50%.
In my environment, this problem had caused remaining many half
opened TCP sockets.
>How-To-Repeat:
http://yasuoka.net/~yasuoka/finrst.shar.txt
>Fix:
Index: tcp_input.c
===================================================================
RCS file: /cvs/netbsd/src/sys/netinet/tcp_input.c,v
retrieving revision 1.327
diff -u -p -r1.327 tcp_input.c
--- tcp_input.c 6 Jun 2013 00:03:14 -0000 1.327
+++ tcp_input.c 7 Oct 2013 06:10:28 -0000
@@ -4200,6 +4200,7 @@ syn_cache_get(struct sockaddr *src, stru
tp->last_ack_sent = tp->rcv_nxt;
tp->t_partialacks = -1;
tp->t_dupacks = 0;
+ tp->snd_fack = tp->snd_una;
TCP_STATINC(TCP_STAT_SC_COMPLETED);
s = splsoftnet();
Home |
Main Index |
Thread Index |
Old Index