lwip-users
[Top][All Lists]
Advanced

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

[lwip-users] TCP client side problems using netconn api


From: Ben Bobbitt
Subject: [lwip-users] TCP client side problems using netconn api
Date: Wed, 15 Apr 2009 00:10:45 -0400

Hi all,

 

I’m trying to write a fairly simple HTTP proxy on the atmel avr32 using 1.3.0 of lwIP

 

Try as I might, I’m unable to find much in the way of example code for CLIENT side TCP using the netconn api. 

 

The behavior I’m seeing is pretty strange.  I can get through 3, sometimes 4 iterations of:

 

netconn_new(TCP)

netconn_connect

netconn_write

netconn_recv  (x N segments )

netconn_close

netconn_disconnect

netconn _delete

 

 

I’ve had a couple of failure modes.  I’ve made changes to try and resolve the issue, but it seems to only force the problem deeper.     I’m able to send my http request, receive my responses, etc…. for only a few iterations. Then I experience one of two failure modes.      The first thing I saw was that  start getting ( -3) “connection aborted” error codes on the netconn_connect() call. 

 

This seems to be happening in the tcp stack and the code is being returned in response to a max syn retries condition.   It is pretty consistent at 3 successes and then failure, never to recover until reset of the system.  

 

I moved some stuff around  - and now I get another pretty consistent failure.  I honestly don’t know if the two are related, other than the seeming coincidence of things working for about 3 iterations before trouble starts. This one appears to be a problem in the tcp stack with the ack sequence numbers during the disconnect process.  I don’t know much about TCP, but I’ve got wireshark running on the webserver side and I was able to capture the data and compare the sequence of events during a successful series vs. the last  success prior to failure city.

 

The sequence of events during a normal sequence is as follows:

 

Server  FIN, ACK   seq 433 ack 70

Client   ACK            seq 70   ack 434     < - note the ack # is +1 of the seq prior

Client   FIN, ACK  seq 70  ack 434

Server ACK           seq 434 ack 71

 

In a connection that isn’t going away properly – and results in a system that I can’t get usable without a reset:

 

Server  FIN, ACK   seq 433 ack 70

Client   ACK            seq 70   ack 433     < - note the ack # is == seq prior

Client   FIN, ACK  seq 70  ack 434

Server ACK           seq 434 ack 71

 

Then I get retransmits from the server of the FIN, ACK because the client side messed up the ACK to the FIN ACK message.  The client then gets confused by the new FIN, ACK and basically ignores it for a while, then tries sending his own FIN, ACK…. Anyway, it gets ugly. 

 

 

I’ve got other tasks on the system running TCP server side and UDP connections, without issues.  

 

Am I using the netconn correctly?  I am deleting the netconn after each use, because I was running into similar problems trying to reuse the same netconn. I think I’ve tried a dozen permutations on this thing.   

 

Also, I am formatting the HTTP requests with the ‘Connection: close’ option, so that the server should be initiating the close as soon as the response is sent. 

 

Any insights or examples of TCP client side operations would be most appreciated. 

 

Here’s the pertinent section of my thread

 

       // waits here for a semaphore to signal a request needs to be sent

 

       pxConnection = 0;

        while(!pxConnection)  // create a netconn for our use

        {

          vTaskDelayUntil( &xLastFocusTime, xDelayLength );

          pxConnection = netconn_new(NETCONN_TCP);

        }

      

        err = netconn_connect(pxConnection,&server_addr,80);

        if(err != 0)

        {

          free(httpbuffer);

          while(netconn_delete(pxConnection) != 0)

          {

            vTaskDelayUntil( &xLastFocusTime, xDelayLength );

          }

          xSemaphoreGive(IBMsgList.xMutex);

          continue;

        }

        err = netconn_write(pxConnection,httpbuffer,strlen(httpbuffer),NETCONN_COPY);

        if(err != 0)

        {

          free(httpbuffer);

          while(netconn_delete(pxConnection) != 0)

          {

            vTaskDelayUntil( &xLastFocusTime, xDelayLength );

          }

          xSemaphoreGive(IBMsgList.xMutex);

          continue;

        }

       

       

        // wait for the response from server

        segcount = 0;

 

        offset = 0;

        while((pxRxBuffer = netconn_recv(pxConnection)) != 0)

        { 

          if(pxRxBuffer < 0)

          {

            free(httpbuffer);

            while(netconn_delete(pxConnection) != 0)

            {

              vTaskDelayUntil( &xLastFocusTime, xDelayLength );

            }

            continue;

          }

          segcount++;  

          len = netbuf_len(pxRxBuffer);

          if((len + offset) > (MAXHTTPRESPLEN -1))

            len = (MAXHTTPRESPLEN - (offset+1));

          netbuf_copy(pxRxBuffer,(void*)&httpbuffer[offset],len);

          httpbuffer[offset+len] = 0; // make sure it's NULL terminated

          offset +=len;

        }

       

        if(offset == 0)

        {

          // connection down

          connected = 0;

          free(httpbuffer);

          netconn_close(pxConnection);

          while(netconn_delete(pxConnection) != 0)

          {

            vTaskDelayUntil( &xLastFocusTime, xDelayLength );

          }

          netbuf_delete(pxRxBuffer);

          pxConnection = 0;  // for other modules

          xSemaphoreGive(IBMsgList.xMutex);

          continue;

        }

       

        err = netconn_disconnect(pxConnection);

        err = netconn_close(pxConnection);

        netbuf_delete(pxRxBuffer);

        while(netconn_delete(pxConnection) != 0)

        {

          vTaskDelayUntil( &xLastFocusTime, xDelayLength );

        }

        // process the HTTP response

        rc = process_http_response(httpbuffer, offset, hdr);

      

        // resets the semaphore and goes back up and waits to be signaled again

 

 

Thanks for sticking with me on this rather long post.

 

-Ben

 


reply via email to

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