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.

Submitted by:  Homyak <onlyslon>
Submitted on:  Thu 13 Nov 2008 04:55:54 PM UTC  
 
Category: TCPSeverity: 3 - Normal
Item Group: NoneStatus: Fixed
Privacy: PublicAssigned to: Kieran Mansley <kieranm>
Open/Closed: ClosedPlanned Release: None
lwIP version: CVS Head

(Jump to the original submission 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>
Project 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>
Project 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>
Project AdministratorIn charge of this item.
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>
Project AdministratorIn charge of this item.
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>
Project AdministratorIn charge of this item.
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>
Project AdministratorIn charge of this item.
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>

 

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
  • -unavailable- added by goldsimon (Posted a comment)
  • -unavailable- added by kieranm (Posted a comment)
  • -unavailable- added by onlyslon (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 7 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Mon 11 Jan 2010 04:45:04 PM UTCgoldsimonStatusNone=>Fixed
      Open/ClosedOpen=>Closed
    Fri 01 May 2009 12:33:20 PM UTCkieranmPlanned Release1.3.1=>1.4.0
    Tue 31 Mar 2009 02:24:51 PM UTCkieranmAssigned toNone=>kieranm
    Fri 13 Feb 2009 10:16:23 AM UTCkieranmPlanned Release=>1.3.1
    Sat 15 Nov 2008 12:02:12 PM UTConlyslonAttached File-=>Added gmaps.raw, #16846
    Thu 13 Nov 2008 04:55:55 PM UTConlyslonAttached File-=>Added lwip.pcap, #16841

    Back to the top


    Powered by Savane 3.1-cleanup1