tcp_close() (like tcp_write()) only enqueues a segment (containing a FIN
only, in this case) to be sent. This segment (like all other data) is
re-sent until an ACK is received for it. Only after this ACK has been
received, the connection actually goes into a real closing state.
However, that still doesn't explain why close_conn() is called twice or
why arg is NULL.
As I said, the previous problem with 2 close_conn() being called was due to
a previous setup I had trying to use the "len" count to determine when to
close. I'm past that, not using the "len" param now. That is not the issue
I don't see arg being null in any of the functions.
Perhaps you didn't understand my last post or the data. The debug output
shows each function being entered, and what the values are of the ptrs.
Again note the following:
CON>close_conn: pcb=0x40006468 hs=0x40004E64 ToSendCnt=2437
CON>http_sent: pcb=0x40006468 hs=0x00000000 len=2437
CON>http_sent: pcb=0x40006468 hs=0x00000000 len=1
Note that close is called, and the arg(hs) is still alive then.
close_conn() frees arg(hs). Then the http_sent() cb is fired 2 times after
that and both times arg(hs) is now NULL of course. The first time shows
the remaining data length having been sent 2437 bytes, and the 2nd time is
the lwip ACK 1 byte representation. So all that makes sense to me.
The above is produced by calling close_conn() in my send_data() routine,
after all data to go out has been sent to tcp_write(). There are no polls,
or any FIN_WAITs, or Aborts, etc. with this confirguation. It finishes
clean every browser refresh, no matter how fast I click the browser refresh.
Contrib code behavior
Now for kicks, I changed it over to the stock contrib setup.
In this case the following debug output results:
CON>http_sent: /lx777.ssi pcb=0x4000791C Remaining: 0
CON>close_conn: pcb=0x4000791C hs=0x40004B70 ToSendCnt=0
CON>http_poll: pcb=0x4000791C hs=0x00000000 pcb_state=FIN_WAIT_2
CON>http_poll: abort pcb=0x4000791C hs=0x00000000
CON>conn_err: Connection aborted.
In the Contrib code example, the close_conn() is called inside http_sent(),
after all data has been queued. The first call above shows http_sent()
being called, and then it calls close_conn(), which frees hs(arg). Now you
see the POLL function being activated, hs(arg)=NULL and it aborts the
connection. This works, but it's not right.
I see the cleanest behavior by calling close_conn() from the send_data()
function. The same thing is done in the other 2 references I cited. There
are no Polls, FINs, Aborts, or Resets shown in Wireshark. Conversely, the
Contrib code setup calling close_conn() from http_sent() shows all of those
lwip-users mailing list