buglwIP - A Lightweight TCP/IP stack - Bugs: bug #45433, Endless loop in tcp_slowtmr

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #45433: Endless loop in tcp_slowtmr

Submitter:  Julian Stecklina <boelthorn>
Submitted:  Sun 28 Jun 2015 11:22:21 PM UTC
   
 
Category:  TCP Severity:  3 - Normal
Item Group:  Crash Error Status:  Works For Me
Privacy:  Public Assigned to:  None
Open/Closed:  Closed Planned Release:  None
lwIP version:  git head

Jump to the original submission

Fri 17 Mar 2017 08:55:33 AM UTC, comment #8: 

Yes. I see that now. I apologise - I genuinely did think I was running 1.4.1

Michael Tempest <mtempest>
Fri 17 Mar 2017 08:34:19 AM UTC, comment #7: 

I cannot find the code you mentioned in 1.4.1 but in 1.4.0.

This is totally outdated, please update if you want bugs fixed.

Simon Goldschmidt <goldsimon>
Group administrator
Fri 17 Mar 2017 08:27:54 AM UTC, comment #6: 

I'm using lwIP 1.4.1.

I think the problem is before the switch statement in tcp_close_shutdown, just after the comment /* TODO: to which state do we move now? */

I enabled TCP_DEBUG_PCB_LISTS and an assert fails in TCP_REG following the TODO comment.

This change seems to address the problem for me

static err_t
tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
{
  err_t err;

  if (rst_on_unacked_data && (pcb->state != LISTEN)) {
    if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) {
      /* Not all data received by application, send RST to tell the remote
         side about this. */
      LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);

      /* don't call tcp_abort here: we must not deallocate the pcb since
         that might not be expected when calling tcp_close */
      tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
        pcb->local_port, pcb->remote_port);

      tcp_pcb_purge(pcb);

      /* TODO: to which state do we move now? */

      /* move to TIME_WAIT since we close actively */
      if (pcb->state != TIME_WAIT)//MT
      {//MT
        // MT: Don't put into tcp_tw_pcbs if it is already in tcp_tw_pcbs
        TCP_RMV(&tcp_active_pcbs, pcb);
        pcb->state = TIME_WAIT;
        TCP_REG(&tcp_tw_pcbs, pcb);
      }//MT

      return ERR_OK;
    }
  }

  switch (pcb->state) {
...

Michael Tempest <mtempest>
Thu 16 Mar 2017 02:25:55 PM UTC, comment #5: 

Michael, what version of lwIP are you talking about? I cannot see how tcp_close(_shutdown) would handle a pcb in TIME_WAIT state. "switch (pcb->state)" should fall through to "default:" where the comment says "Has already been closed, do nothing."

Simon Goldschmidt <goldsimon>
Group administrator
Thu 16 Mar 2017 01:16:47 PM UTC, comment #4: 

I have encountered the same problem. I traced it to calling tcp_close whilst the pcb is in the TIME_WAIT state. tcp_close_shutdown then moves the pcb to the tcp_tw_pcbs list. Since it is already there, this creates a loop in the tcp_tw_pcbs list.

We can argue whether it is legal for the application should be calling tcp_close when in this state, but i believe that tcp_close should protect itself against this - it is easy to catch with a check and hard to debug...

Michael Tempest <mtempest>
Tue 18 Aug 2015 07:46:49 PM UTC, comment #3: 

Please reopen if you have a more detailed impression of what's going on. With the little info you provide, it's most probably a bug in your app/port.

Simon Goldschmidt <goldsimon>
Group administrator
Mon 29 Jun 2015 05:38:44 PM UTC, comment #2: 

I use lwIP single-threaded with no interrupt thread (in fact it is a Linux application with a single thread and lwIP configured with NO_SYS).

I'll spend more time debugging this sometime this week.

Julian Stecklina <boelthorn>
Mon 29 Jun 2015 07:56:32 AM UTC, comment #1: 

As usual, it looks like a broken port or usage which do not follow lwIP threading model.

Summary:

- Do NOT call anything in interrupt context, nothing, never, never,
use your OS semaphore signaling to an Ethernet/serial/… RX thread
- memp_* functions are thread-safe if SYS_LIGHTWEIGHT_PROT is
set, and again, thread safe does not mean it is interrupt safe, especially
if your hardware does nested interrupts
- Do NOT call any function from the RAW API outside lwIP thread
- Use Netconn or Socket API in others threads, but keep in mind you
should not share a Netconn/Socket control block between threads, (or use
proper locking if you really have to, of course).

Sylvain Rochet <gradator>
Group Member
Sun 28 Jun 2015 11:22:21 PM UTC, original submission:  

I encounter an endless loop in tcp_slowtmr in the while loop that removes PCBs that stayed long enough in TIME-WAIT (at comment /* Steps through all of the TIME-WAIT PCBs. */ ).

In my case there is a single PCB in the list. It's next pointer points to itself (sounds fishy) and the loop makes no progress. This situation is somehow triggered by tcp_close().

Greg Dunn had the same problem a couple of years back, but didn't get an answer:  http://lwip.100.n7.nabble.com/lwip-tcp-tw-pcbs-list-problem-in-tcp-slowtmr-tt22063.html#none

Julian Stecklina <boelthorn>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mtempest (Posted a comment)
  • -email is unavailable- added by goldsimon (Posted a comment)
  • -email is unavailable- added by gradator (Posted a comment)
  • -email is unavailable- added by boelthorn (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-08-18 goldsimon StatusNeed Info Works For Me
        Open/ClosedOpen Closed
    2015-06-29 gradator StatusNone Need Info

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code