Richie Bonventre wrote:
[..] In addition, the state the struct returns to is identical to the
state of a brand new tcp_pcb, "CLOSED". This caused me to believe that
I could tcp_connect() again on the same tcp_pcb. As you've said, this
is not actually ok. After tcp_close returns, lwip no longer knows
about your tcp_pcb struct, and although the memory isn't cleared, lwip
has designated that memory space as free so the next time you create a
connection with tcp_new() it may place it there and overwrite your old
tcp_pcb.
Clearing the memory would not help: it might already be re-allocated and
thus have a valid state. Plus "CLOSED" is 0, I think...
Anyway, it is documented that a pcb may not be referenced after
tcp_close() returned ERR_OK (even if the pcb might not be deallocated at
that point, it will eventually be).
So my four situations:
1) I ctrl-C the listener on the other machine.
This will send some sort of packet to your lwip machine telling you
the connection is closing. Lwip will move tcp_pcb into the CLOSE_WAIT
state, and will call the recv_callback with a NULL argument. In the
recv_callback you should then check that this packet is coming from
your currently opened connection. If it isn't, it must be from an old
connection that you already attempted to close, so you can ignore it.
If you do get a NULL-recv-callback for an older connection, it means you
haven't closed it correctly (remember to set the recv callback to NULL
before calling tcp_close - that way you won't get informed when the
remote FIN arrives, if you don't need that). However, it doesn't hurt to
always call tcp_close() when you get a NULL-recv-callback.
If it is, then you must call tcp_close() yourself. This then completes
some more acking with the other machine and eventually places the
tcp_pcb into the CLOSED state, and then calls the err_callback with
ERR_ABRT.
No, this is wrong: the err-callback is only called in an error condition
(e.g. a timeout, RST received or something like that). It is *not*
called in a normal graceful-close-scenario.
At this point, the tcp_pcb is "freed" and should not be touched again.
Again, do *not* reference the pcb after tcp_close() has returned ERR_OK,
please read the documentation (doc/rawapi.txt)!
A new tcp_pcb should be tcp_new()'d and then you can tcp_connect() again.
2) I try to connect from lwip but no cable is plugged in.
Lwip will try and send a SYN packet and wait for an ack. Until it gets
the ack, a counter is being incremented until it times out. When it
times out, it calls the err_callback with ERR_ABRT. It is not clear to
me if the tcp_pcb is CLOSED at this point, but it looks like the
memory is freed anyway.
From an application point of view, a pcb is always freed *before* the
err-callback is called.
Should I have to call tcp_close() here? Once the memory is freed in
lwip you can again tcp_new() and tcp_connect().
3) I try to connect from lwip and the cable is plugged in, but nothing
is listening.
The other machine should immediately send Lwip back a rst packet. Lwip
will then call the err_callback with ERR_RST. I noted though that at
this point when the error callback is called, the old tcp_pcb is not
yet closed nor freed.
How did you notice that? The pcb is freed after the err-callback is
called. There's no need to set the state to CLOSED before freeing the
memory. Please don't try to assume anything from reading the pcb
contents here.
Simon
_______________________________________________
lwip-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lwip-users