lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] restarting a connection with the raw api


From: Kieran Mansley
Subject: Re: [lwip-users] restarting a connection with the raw api
Date: Tue, 06 Sep 2011 10:18:43 +0100

On Sun, 2011-09-04 at 00:08 -0400, Richie Bonventre wrote:
> Hey thanks for helping out.
> It doesn't seem quite so straightforward as that. For example suppose
> you connect and then unplug the cable. If you try and tcp_close() and
> the other computer is no longer connected, the connection doesnt
> actually end because the close request is never acked

It will (eventually) time out.

> and everything
> will get messed up if you just try and tcp_connect again.

It shouldn't get messed up.  If it does, that's a bug.  Can you give
more details? 

> I've had
> problems where if you call tcp_new() or tcp_connect() at the wrong
> time, it will overwrite the current connection and repush it on to
> tcp_active_pcbs which causes pcb->next to point to itself. This causes
> lots of the lwip timers and functions to loop forever and freeze the
> code.

Can you describe your threading model?  It sounds like you might have
two threads racing here and modifying state in the core of lwIP, which
isn't supported and would cause exactly the sort of problem you
describe.

> Other times, even if the other computer is still connected and
> the closing is completely acked and everything, when you try and
> tcp_connect again on the same connection, it no longer seems to get
> any response from the other computer. It seems like even though the
> connection makes it all the way to the CLOSED state, the other
> computer isn't completely aware that the connection is done and wont
> accept another request from the same connection.

If you can get a packet capture of this I'll take a look.  by
"tcp_connect again on the same connection" are you trying to use the
same pcb after calling tcp_close()?  This isn't allowed: once
tcp_close() has returned success, you must not touch the pcb structure
as it could have been freed.

> I'm basically trying to account for 4 situations:
> 1 - A connection is established from lwip to some code on another
> machine, and then I ctrl-C the code listening on the other machine. I
> want lwip to recognize this and try to reconnect, to be ready whenever
> I restart the listener on B.

This rather depends on what happens with you ctrl-C the code on the
other machine:
1) if it closes the connection (with a FIN) then lwIP will notify the
application by calling the recv callback with zero length.
2) if it aborts the connection (with a RST) then lwIP will notify the
application by either the recv callback or the err callback (I can't
remember which off the top of my head).
3) if it doesn't send us anything, or the packet it sends it lost, then
lwIP will only notice next time it tries to send to the other side,
which will then likely cause it to send us a RST.  This could take some
time.  There is a feature in TCP called keep-alive which probes the
connection at regular intervals to see if it is still up to help deal
with the case where an idle connection is no longer being handled by the
other end.

> 2 - I attempt to connect but the cable is not plugged in between the machines.

This should time out, but it may take some time.  TCP is very tolerant
and keeps re-trying for a while.

> 3 - I attempt to connect and the cable is plugged in, but nothing is
> listening to the socket yet to accept the connection on the other
> machine.

This should fail quickly, as the other end will reply to our connection
attempt.  Your application can then wait a while and attempt to connect
again.  I would avoid putting this in a tight loop though, as it would
be rather antisocial to flood the network with repeated connection
attempts.

> 4 - I have connected successfully, and I then unplug the cable. My
> code that uses lwip periodically sends a ping packet, and if it
> doesn't get a response in time, it should close the connection and try
> to reconnect.

TCP is very tolerant of broken links and will keep trying to send your
pings for a long time before it gives up and closes the connection.
There is nothing to stop you doing as you describe and having a much
more strict time-out in your application if it doesn't receive a reply.
Just call tcp_close() and try and open a new one (although as before, be
careful you don't flood the network with connection attempts).

> So for which of these do I have to call tcp_close().

Call tcp_close() if you want to close a connection.  It is probably
safest and simplest to do this in all cases you describe, then create a
new PCB, then call tcp_connect() again.

>  which can I
> recall tcp_new() or should I reuse the old tcp_pcb

No, after you've called tcp_close(), don't touch the PCB again.  

> and what do I need
> to monitor before I call either of these or call tcp_connect() again?

See above.

> Do I need to be checking the state of the pcb or something else?

You should get all the notifications you need via the RAW api callbacks.
It shouldn't be necessary to look into the PCB internals 

Kieran




reply via email to

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