buglwIP - A Lightweight TCP/IP stack - Bugs: bug #26062, FIN_WAIT_2 state following...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #26062: FIN_WAIT_2 state following tcp_close should timeout eventually

Submitter:  Jeff Barber <jeffbabar>
Submitted:  Wed 01 Apr 2009 01:16:18 PM UTC
   
 
Category:  TCP Severity:  3 - Normal
Item Group:  Faulty Behaviour Status:  Fixed
Privacy:  Public Assigned to:  goldsimon
Open/Closed:  Closed Planned Release:  None
lwIP version:  CVS Head

Jump to the original submission

Sat 20 Feb 2010 06:11:25 PM UTC, comment #9: 

Fixed by not updating pcb->tmr after calling tcp_close() (i.e. in states FIN_WAIT_1, FIN_WAIT_2 and LAST_ACK.

Simon Goldschmidt <goldsimon>
Group administrator
Mon 15 Feb 2010 06:40:25 PM UTC, comment #8: 

We should continue the discussion about close vs. shutdown in task #10088 and delay this bug until that task is done.

Simon Goldschmidt <goldsimon>
Group administrator
Wed 21 Oct 2009 11:20:43 AM UTC, comment #7: 

Having close and shutdown is planned for 1.4.0, so this will be dependent on that.

Kieran Mansley <kieranm>
Group Member
Mon 19 Oct 2009 01:04:11 PM UTC, comment #6: 

I think this is actually a subtle API change that should be considered carefully.

Currently we have a tcp_close that acts like a shutdown(SHUT_WR) and we have nothing that acts like close().  If you simply modify the timer handling, we'll then have tcp_close acting like close(), but then we won't have a shutdown(SHUT_WR).

As it stands now, a NO_SYS application can rely on receiving a final recv callback with NULL pbuf argument indicating that the remote end sent a FIN.  Some applications may be relying on this behavior for cleanup of application state (mine does, for example).

IMO it would be preferable to have both a close and a shutdown as the two are distinct and both have valid uses.  Naively, it seems like a simple flag would be sufficient to distinguish the two cases but I could be overlooking many details.

(Yes, I know that I originally filed this bug report but my understanding has become more, er, nuanced since April. :-)

Jeff Barber <jeffbabar>
Sun 18 Oct 2009 09:07:11 AM UTC, comment #5: 

Would preventing to reset pcb->tmr in tcp_process for FIN_WAIT_2 and LAST_ACK states be enough to solve this?

Simon Goldschmidt <goldsimon>
Group administrator
Mon 06 Apr 2009 09:16:47 AM UTC, comment #4: 

It is mean that we have timeout error in LAST_ACK state too.

Oleg Tyshev <olegreen>
Fri 03 Apr 2009 02:27:40 PM UTC, comment #3: 

OK, that makes sense, thanks.

Kieran Mansley <kieranm>
Group Member
Fri 03 Apr 2009 01:48:16 PM UTC, comment #2: 

True but there's only a single timer ("tmr") in the pcb and it gets updated for each segment received.  So if the remote end continues to send data after we sent the FIN -- which is perfectly okay for it to do -- the session never times out.

Since the intent of tcp_close is to permanently disconnect (as opposed to "shutdown" semantics), then we should eventually force a connection close.  Otherwise, resources on both sides could remain allocated indefinitely.

Jeff Barber <jeffbabar>
Thu 02 Apr 2009 02:20:15 PM UTC, comment #1: 

There's some code in tcp_slowtmr() that seems to be intending to do this:

    /* Check if this PCB has stayed too long in FIN-WAIT-2 */
    if (pcb->state == FIN_WAIT_2) {
      if ((u32_t)(tcp_ticks - pcb->tmr) >
          TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
        ++pcb_remove;
        LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
      }
    }



Kieran Mansley <kieranm>
Group Member
Wed 01 Apr 2009 01:16:18 PM UTC, original submission:  

If an application calls tcp_close, this indicates that it no longer needs the connection (i.e. it's equivalent to closing the socket descriptor in Unix).  Hence, after a FIN is sent to the peer, the TCP session should enter a state where it is guaranteed to be destroyed eventually.  In the typical TCP implementation (see reference below), this is achieved by an additional FIN_WAIT_2 timer.  There is no such mechanism in the current lwIP implementation -- the session and associated data structure may hang around forever if the remote peer doesn't send a FIN of its own.

From "TCP/IP Illustrated Volume 2", chapter 25, section 25.1, bullet 6 (http://my.safaribooksonline.com/020163354X/ch25):
"A FIN_WAIT_2 timer. When a connection moves from the FIN_WAIT_1 state to the FIN_WAIT_2 state (Figure 24.15) and the connection cannot receive any more data (implying the process called close, instead of taking advantage of TCP's half-close with shutdown), this timer is set to 10 minutes. When this timer expires it is reset to 75 seconds, and when it expires the second time the connection is dropped. The purpose of this timer is to avoid leaving a connection in the FIN_WAIT_2 state forever, if the other end never sends a FIN. (We don't show this timeout in Figure 24.15.)"

Jeff Barber <jeffbabar>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by goldsimon (Posted a comment)
  • -email is unavailable- added by olegreen (Posted a comment)
  • -email is unavailable- added by kieranm (Posted a comment)
  • -email is unavailable- added by jeffbabar (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2010-02-20 goldsimon StatusNone Fixed
        Assigned toNone goldsimon
        Open/ClosedOpen Closed
    2009-08-20 kieranm Planned Release 1.4.0

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code