Hi, I have traced the problem to calling tcp_close on a tcp_pcb which is already in closed state. I handle client disconnection roughly like this:
if( tcp_write(client, ...); != ERR_OK) goto disconnect; // ... disconnect: tcp_close(client); The problem is that when a client explicitly disconnects the PCB is already in closed mode. A similar double-close bug has been mentioned onlist by Dinesh Pandey on 29 Oct 2015 [1]. The workaround is simple. Check if pcb->state != CLOSED before calling tcp_close. I am now unable to trigger the looping pcbs situation in any combination of opening and closing the connections, so I consider my bug gone. Happy hacking KL 1: https://mail.gnu.org/archive/html/lwip-users/2015-10/msg00072.html śr., 7 sty 2026 o 16:29 Krzysztof Lasocki <[email protected]> napisał(a): > > Hello, > > I am developing a simple datalogger using LwIP. I have a few sensor > channels and I would like to have a separate TCP stream to stream data > from them which i receive via telnet/netcat on the client side. > > I am trying to locate a bug which causes the LwIP stack to loop > infinitely because the pcb linked list encounters a pcb which points > to itself. Most strangely this is sometimes caught by the assert in > tcp_input (tcp_in.c:269) and sometimes it is not, in those cases the > for loop in tcp_in.c:251 is already infinitely looping. > > I noticed I can trigger this behavior while reconnecting to one TCP > listener while the other TCP connection is established, but besides > that I cannot locate the behavior. > > I have checked the following: > - My software calls LwIP only from the main loop, I am using NO_SYS > mode and callback api > - The incoming packets are pulled out from a circular buffer which is > filled by the PHY rx interrupt. > - The RX interrupt is not calling any LwIP functions at all, and I did > not notice any PCBs to have corrupted memory > - I've made sure that the interrupt is not happening while > board_netif.input function is called (Interrupts are disabled around > it, and there is a data synchronization barrier inserted before it) > > I initialize the TCP listener with tcp_new_ip_type, tcp_arg, tcp_bind > (upon reopen it returns ERR_USE - I am not sure what to do in that > case), then tcp_listen and then set the callback with tcp_accept. > The callback rejects multiple connections with ERR_USE. If this is the > only connection it proceeds with saving the passed pcb. Later I use > that pcb to send data with tcp_write and tcp_output. > I've also tried closing the listener PCB in the accept callback but > this does not seem to change anything > > I detect client disconnect by checking if tcp_write returned ERR_OK, > if not, it means the client disconnected and I close both the > connection and the listener PCB. > > Some things are not clear in the doxygen nor in the wiki: > - Can I re-use a struct tcp_pcb* after I tcp_close it? I am currently > creating a new tcp_pcb with tcp_new_ip_type every time > - How should i gracefully close the server after the client drops the > connection? I.e. what should I do when tcp_bind returns ERR_USE? > > Best regards > K Lasocki > > -- > Ala ma bota -- Ala ma bota _______________________________________________ lwip-users mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/lwip-users
