Bug 102653

Summary: [tcp] TCP stack sends infinite retries for connection in LAST_ACK state
Product: Base System Reporter: Radim Kolar <hsn>
Component: kernAssignee: Andre Oppermann <andre>
Status: Closed FIXED    
Severity: Affects Only Me CC: hsn
Priority: Normal    
Version: 6.1-STABLE   
Hardware: Any   
OS: Any   

Description Radim Kolar 2006-08-29 19:20:19 UTC
I discovered that my machine sends infinite retries for these 2 connections:

tcp4       0      0  sanatana.61564         mail.xsec.it.http      LAST_ACK
tcp4       0      0  sanatana.59795         www.xiti.dk.http       LAST_ACK

it sends packets every 2 seconds or so and gets no reply from remote 
computer:

20:07:14.855393 IP sanatana.dharma.61564 > mail.xsec.it.http: . ack 1 win 0
20:07:14.855593 IP sanatana.dharma.61564 > mail.xsec.it.http: F 1:1(0) ack 1 win
 32832 <nop,nop,timestamp 42851121 1376192245>
20:07:14.855662 IP sanatana.dharma.59795 > www.xiti.gr.http: . ack 1 win 0
20:07:14.855797 IP sanatana.dharma.59795 > www.xiti.gr.http: F 1:1(0) ack 1 win
 32832 <nop,nop,timestamp 42851121 2800342>
20:07:16.726973 IP sanatana.dharma.61564 > mail.xsec.it.http: F 1:1(0) ack 1 win
 32832 <nop,nop,timestamp 42852993 1376192245>
20:07:17.214834 IP sanatana.dharma.59795 > www.xiti.gr.http: F 1:1(0) ack 1 win
 32832 <nop,nop,timestamp 42853481 2800342>
20:07:17.344771 IP sanatana.dharma.61564 > mail.xsec.it.http: F 1:1(0) ack 1 win
 32832 <nop,nop,timestamp 42853611 1376192245>
20:07:17.954631 IP sanatana.dharma.59795 > www.xiti.gr.http: F 1:1(0) ack 1 win
 32832 <nop,nop,timestamp 42854221 2800342>
20:07:18.380573 IP sanatana.dharma.61564 > mail.xsec.it.http: F 1:1(0) ack 1 win
 32832 <nop,nop,timestamp 42854647 1376192245>
20:07:19.234371 IP sanatana.dharma.59795 > www.xiti.gr.http: F 1:1(0) ack 1 win
  32832 <nop,nop,timestamp 42855501 2800342>

I watched this activity for about 15 minutes, so my guess is that bsd box never
gives up.
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2006-08-29 23:39:55 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-net

Over to maintainer(s).
Comment 2 Andre Oppermann freebsd_committer freebsd_triage 2006-09-06 18:17:10 UTC
State Changed
From-To: open->feedback

Take over. 


Comment 3 Andre Oppermann freebsd_committer freebsd_triage 2006-09-06 18:17:10 UTC
Responsible Changed
From-To: freebsd-net->andre

Take over.
Comment 4 Andre Oppermann freebsd_committer freebsd_triage 2006-09-06 18:21:51 UTC
Radim,

do you have a firewall running on this machine with stateful inspection?

-- 
Andre
Comment 5 Andre Oppermann freebsd_committer freebsd_triage 2006-09-06 20:04:40 UTC
Andre Oppermann wrote:
> Radim,
> 
> do you have a firewall running on this machine with stateful inspection?

Confirmed in private email that he indeed has.

Please try the following patch and report if the problem is fixed or still
there (it may apply with some fuzz as I've got some other changes in that
file).

-- 
Andre

Index: tcp_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.115
diff -u -p -r1.115 tcp_output.c
--- tcp_output.c	23 Feb 2006 21:14:34 -0000	1.115
+++ tcp_output.c	6 Sep 2006 18:49:59 -0000
@@ -1089,8 +1089,9 @@ timer:
  		 * We know that the packet was lost, so back out the
  		 * sequence number advance, if any.
  		 */
-		if ((tp->t_flags & TF_FORCEDATA) == 0 ||
-		    !callout_active(tp->tt_persist)) {
+		if (error != EACCES &&
+		    ((tp->t_flags & TF_FORCEDATA) == 0 ||
+		    !tcp_timer_active(tp, TT_PERSIST)) ) {
  			/*
  			 * No need to check for TH_FIN here because
  			 * the TF_SENTFIN flag handles that case.
@@ -1127,7 +1127,7 @@ out:
  			tcp_mtudisc(tp->t_inpcb, 0);
  			return 0;
  		}
-		if ((error == EHOSTUNREACH || error == ENETDOWN)
+		if ((error == EHOSTUNREACH || error == ENETDOWN || error == EACCES)
  		    && TCPS_HAVERCVDSYN(tp->t_state)) {
  			tp->t_softerror = error;
  			return (0);
Comment 6 dfilter service freebsd_committer freebsd_triage 2006-09-28 19:02:53 UTC
andre       2006-09-28 18:02:46 UTC

  FreeBSD src repository

  Modified files:
    sys/netinet          tcp_output.c 
  Log:
  When tcp_output() receives an error upon sending a packet it reverts parts
  of its internal state to ignore the failed send and try again a bit later.
  If the error is EPERM the packet got blocked by the local firewall and the
  revert may cause the session to get stuck and retry indefinitely.  This way
  we treat it like a packet loss and let the retransmit timer and timeouts
  do their work over time.
  
  The correct behavior is to drop a connection that gets an EPERM error.
  However this _may_ introduce some POLA problems and a two commit approach
  was chosen.
  
  Discussed with: glebius
  PR:             kern/25986
  PR:             kern/102653
  
  Revision  Changes    Path
  1.120     +15 -2     src/sys/netinet/tcp_output.c
_______________________________________________
cvs-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/cvs-all
To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
Comment 7 Mark Linimon freebsd_committer freebsd_triage 2007-04-24 04:35:32 UTC
State Changed
From-To: feedback->closed

Patch was committed by andre on 2006-09-28 18:02:46 UTC.
Comment 8 Mark Linimon freebsd_committer freebsd_triage 2007-05-04 00:16:51 UTC
State Changed
From-To: closed->patched

To andre: was this ever MFCed?
Comment 9 Eitan Adler freebsd_committer freebsd_triage 2011-03-01 15:14:53 UTC
State Changed
From-To: patched->closed

This PR is fixed in head, 8.x and 7.x, but will not be merged to 6.x now 
that that branch is unsupported, sorry