lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [bug #30561] Failed assert in tcp_in.c:tcp_receive()


From: Iordan Neshev
Subject: [lwip-devel] [bug #30561] Failed assert in tcp_in.c:tcp_receive()
Date: Tue, 27 Jul 2010 10:27:07 +0000
User-agent: Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.00

URL:
  <http://savannah.nongnu.org/bugs/?30561>

                 Summary: Failed assert in tcp_in.c:tcp_receive()
                 Project: lwIP - A Lightweight TCP/IP stack
            Submitted by: iordan_neshev
            Submitted on: Tue 27 Jul 2010 10:27:06 AM GMT
                Category: None
                Severity: 3 - Normal
              Item Group: Faulty Behaviour
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
         Planned Release: 
            lwIP version: CVS Head

    _______________________________________________________

Details:

This assertion failed while I was closing a connection:

if (pcb->snd_queuelen != 0) {
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL
||pcb->unsent != NULL);
}

This is what I do:
1. I send the HEADER of a short POST request to a HTTP server.

2. I got TCP_EVENT_SENT for this request.

3. I put the application in Idle state for 5 sec.

4. While the application is idle (these 5 seconds) the server sends back a
long answer (the HTTP HEADER with Error 404), which I was constantly refusing
just for the test (by returning ERR_MEM in the receive callback).

5. Because the application is simple at this stage, it does not bother to
check if the server rejects the POST request. It assumes that it can send the
BODY because step 2 was successful.

6. I send the BODY (which is 20 bytes long) and wait for the server's TCP/IP
stack to ACK it.

7. I would expect to get this ACK (TCP_EVENT_SENT to fire) in a short time,
but I don't. Instead lwip is still calling the recv callback, desperately
trying to deliver the HEADER. The application keeps refusing it.

8. After e certain timeout the application gives up waiting for the BODY to
be ACKed. (During all this time the input data is refused)

9. Now I clear the flag that forces the recv callback to refuse the data.
Then I put the application in idle state for 5 seconds. Now the application
"consumes" the HEADER which lwip was trying to deliver so many times.

10. Now the application is idle again for a couple of seconds. Nothing
happens. I would expect to get the ACK for the BODY of the request.

11. I try to close the connection (from within the poll handler if it
matters) using the following code:

tcp_pcb_purge();
err = tcp_close();
//tcp_close returned ERR_OK

12. Now the application waits for the recv callback to be called with
(p==NULL), which would indicate that the peer has closed the connection from
its side.

13. At this moment the assertion fired. Later I split it in two ASSERTs to
check which condition was not satisfied. It turned out that they both fail.
Both unacked and unsent were NULL.

14. Now I finally got the ACK for the BODY I sent at step 6.

15. I keep waiting for the recv callback to fire with p==NULL, but this did
not happen. The temporary flag for refusing is already cleared, so I am not
skipping this code, as someone may suspect.

16. After a certain timeout I give up waiting for p==NULL and the connection
is aborted.

I know that such stupid application must not be released in the final product
(and it will not be), but this showed that lwip is not behaving properly:

 - At step 7 TCP_EVENT_SENT (probably) should be called. The presence of
refused data in the *input* direction should not keep the application away
from the fact that the peer has ACKed  the *output* data.

 - Even if the upper statement is not correct, at step 10, when there is no
more refused data, TCP_EVENT_SENT should fire. There is something that does
not allow lwip to do this. After calling tcp_pcb_purge() and tcp_close() lwip
is able to do what it had to do.

 - As a consequence (?) of what happened till now, the recv callback with
p==NULL is not called.

I will be able to investigate this further after a couple of days. I really
hope that the fault is mine. Otherwise this problem will delay a bit the
release of lwip 1.4.

If the cost for fixing this (as code size) is too high, I'm OK to live with
such limitation, as long as we are aware of it.





    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?30561>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]