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