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

_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to