buglwIP - A Lightweight TCP/IP stack - Bugs: bug #24830, Socket never closed sometimes.

 
 

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

bug #24830: Socket never closed sometimes.

Submitter:  Homyak <onlyslon>
Submitted:  Thu 13 Nov 2008 04:55:54 PM UTC
   
 
Category:  TCP Severity:  3 - Normal
Item Group:  None Status:  Fixed
Privacy:  Public Assigned to:  kieranm
Open/Closed:  Closed Planned Release:  None
lwIP version:  CVS Head

Jump to the original submission

Mon 11 Jan 2010 04:45:04 PM UTC, comment #8: 

Kieran, I hope you don't mind me closing this as fixed:

Since the actual bug is fixed, I've added a new task to not forget implementing close() vs. shutdown() correctly:

task #10088: Sockets: Correctly implement close() vs. shutdown()

Simon Goldschmidt <goldsimon>
Group administrator
Mon 26 Oct 2009 08:36:41 AM UTC, comment #7: 

I think I have accidentally fixed part of the problem here: TCP_EVENT_RECV() did not call tcp_recved() if pcb->recv was NULL (which it is after closing a socket), which means the window closes eventually and doesn't reopen.

Another part of the problem (data being buffered in recvmbox but tcp_recved() isn't called when this data is freed) is covered by the patch for bug #26672 (close connection when receive window = 0).

However, the real flaw here is that we haven't implemented close vs. shutdown correctly. I agree that, with a complete close, lwIP should send RST when more data arrives.

However, I regard this bug as a duplicate to bug #26672, which has a better description of the problem.

Simon Goldschmidt <goldsimon>
Group administrator
Fri 01 May 2009 12:33:20 PM UTC, comment #6: 

I think that as this potentially involves changes to the lwIP API we'd be better postponing the fix till 1.4.0

Kieran Mansley <kieranm>
Group Member
Tue 31 Mar 2009 03:03:15 PM UTC, comment #5: 

Now I come to think about how to fix this, there is a minor problem: data can be buffered on RX at lots of levels in the stack (within the TCP layer, netconn layer, and sockets layer).  Therefore tcp_close() needs to know if there are any bytes buffered in the higher layers, but it would be hard for it to work this out.  I therefore think adding a parameter that gets filtered down through the layers that says "there is buffered data in the layer(s) above", and then passed to netconn_delete() and tcp_close() would be a good idea.  However, this changes the API and so causes problems that way.

It would be fairly simple to alias the existing API functions to the new ones, eg:
#define tcp_close(pcb) tcp_close_new(pcb, 0)
#define netconn_delete(conn) -> netconn_delete_new(conn, 0)
(I would choose better names than *_new() - any suggestions?)

This would result in minimal extra code, and keeps the API backwardly compatible, but is a bit ugly in the long term.

Kieran Mansley <kieranm>
Group Member
Fri 13 Feb 2009 10:16:23 AM UTC, comment #4: 

Sorry for the delay in responding to this.

There is no IP address 82.18.19.2 in the trace, but I'm assuming you meant 192.66.66.3 (the HTTP client)

The client makes an HTTP request, but then sends a FIN before the server has finished sending it.  This means the client has nothing more to send to the server, but the server is still allowed to send to the client.  The server continues to send the requested file, but the client does not provide any more window.  This is not all that surprising: the application thinks it has closed this socket, and so won't be reading from it, and so the window does not get replenished.

It is right that the stack has gone into FIN_WAIT_2, and is waiting for the other side to send FIN before continuing to TIME_WAIT and CLOSED.

The traffic you see at the end is the server using the TCP keep alive protocol to probe the connection to see if the other end is still there.  This is also fine.

What is wrong is that lwIP should have sent a RST to close the connection rather than a FIN if there were any data queued for the client when it called close, and/or it should have sent a RST when it received data after the connection had been closed.  This tells the other end that no further data will reach the client application.

The fix for this should be relatively straightforward.  It would be good to retain the current behaviour as that is what is needed for shutdown() rather than close(), and although we provide shutdown() in the API it's not separately implemented.

Thanks for spotting this.

Kieran Mansley <kieranm>
Group Member
Sat 15 Nov 2008 12:02:12 PM UTC, comment #3: 

A full session is in Attacements.

(file #16846)

Homyak <onlyslon>
Fri 14 Nov 2008 08:41:00 PM UTC, comment #2: 

I am sorry that did not specify some details.

I use existing  linux port.

lwIP - works as HTTP client and has address 82.18.19.2

For memory management I use libc (MEM_LIBC_MALLOC option).
As I understand limitations of memory with this option does not work.

This behavior occurs most often with only one socket, the remainder continued to work without visible problems.

I will try to fully record the session ASAP.

Homyak <onlyslon>
Fri 14 Nov 2008 08:53:49 AM UTC, comment #1: 

Looks like one end (not sure which, you don't say which is lwIP) has advertised a zero window and is refusing to open it.  This is probably preventing the other end from sending a FIN, and so the connection never gets closed.  If you can get a packet capture for the whole duration that would be useful.

You say you're using lwIP from CVS head.  Does that mean it is your own port, or you're using one of the existing ports?

My guess would be that lwIP is running out of memory due to a bug that is resulting in packet buffers getting leaked.  You could confirm this by turning on the lwIP stats and seeing what happens to the available memory when they are reported.

Kieran Mansley <kieranm>
Group Member
Thu 13 Nov 2008 04:55:54 PM UTC, original submission:  

Hello, I use lWip from Linux.

Sometimes there is the strange behavior of the socket.

Following the closure of the socket, he turns state FIN_WAIT_2 but never switch to TIME_WAIT or CLOSE_WAIT.

Stack infinitely (Observed 15-20 minutes) sends tcp data.

21:23:41.801474 IP 66.249.89.10.80 > 82.18.19.2.3793: . ack 1 win 11957
21:23:41.802483 IP 82.18.19.2.3793 > 66.249.89.190.80: . ack 1 win 0
21:23:43.250143 IP 66.249.89.190.80 > 82.18.19.2.3793: . ack 1 win 11957
21:23:43.250395 IP 82.18.19.2.3793 > 66.249.89.190.80: . ack 1 win 0


Unfortunately, I failed to record the entire session. This behavior occurs infrequently.

Perhaps a bug occurs because I use self-tuned lwipopts.h.


Homyak <onlyslon>

 

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

Attached Files
file #16846:  gmaps.raw added by onlyslon (26KiB - application/octet-stream)
file #16841:  lwip.pcap added by onlyslon (2KiB - application/octet-stream)

 

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 kieranm (Posted a comment)
  • -email is unavailable- added by onlyslon (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 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2010-01-11 goldsimon StatusNone Fixed
        Open/ClosedOpen Closed
    2009-05-01 kieranm Planned Release1.3.1 1.4.0
    2009-03-31 kieranm Assigned toNone kieranm
    2009-02-13 kieranm Planned Release 1.3.1
    2008-11-15 onlyslon Attached File- Added gmaps.raw, #16846
    2008-11-13 onlyslon Attached File- Added lwip.pcap, #16841

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code