lwip-devel
[Top][All Lists]
Advanced

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

[lwip-devel] [bug #50837] TCP: zero window probe doesn't timeout


From: Joel Cunningham
Subject: [lwip-devel] [bug #50837] TCP: zero window probe doesn't timeout
Date: Thu, 18 May 2017 10:56:49 -0400 (EDT)
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0

Follow-up Comment #34, bug #50837 (project lwip):

Fayek,

>From your wireshark cpature, the backport looks to be working correctly.  The
zero window probing begins at time 170.718 (packet #1692) and gets restarted a
number of times due to Windows sending window probe ACKs with an increasing
SEQ.  Then at time 188.719 (packet #1713), LwIP starts its final run of
probes.  I think your capture doesn't include all the probes.  See my attached
spreadsheet, but there should have been 6 more probes before connection
closing

Simon,

These captures have highlighted an issue in the following code in
tcp_receive:


    /* Update window. */
    if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
       (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
       (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) >
pcb->snd_wnd)) {
      pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
      /* keep track of the biggest window announced by the remote host to
calculate
         the maximum segment size */
      if (pcb->snd_wnd_max < pcb->snd_wnd) {
        pcb->snd_wnd_max = pcb->snd_wnd;
      }
      pcb->snd_wl1 = seqno;
      pcb->snd_wl2 = ackno;
      if (pcb->snd_wnd == 0) {
        if (pcb->persist_backoff == 0) {
          /* start persist timer */
          pcb->persist_cnt = 0;
          pcb->persist_backoff = 1;
          pcb->persist_probe = 0;
        }
      } else if (pcb->persist_backoff > 0) {
        /* stop persist timer */
        pcb->persist_backoff = 0;
      }


What's happening in these captures is that pcb->persist_backoff is being
cleared when seqno increases, but snd_wnd doesn't increase and is: 0 < snd_wnd
< pcb->unsent->len (remember LwIP now treats this case as zero window).  LwIP
calls tcp_output() after input processing and this restarts
pcb->persist_backoff.

I'm wondering if we should have an additional check before clearing
pcb->persist_backoff to ensure that the previous non-zero small window which
prevented sending pcb->unsent, has resolved.  Something like


      if (pcb->snd_wnd == 0) {
        if (pcb->persist_backoff == 0) {
          /* start persist timer */
          pcb->persist_cnt = 0;
          pcb->persist_backoff = 1;
          pcb->persist_probe = 0;
        }
      } else if ((pcb->persist_backoff > 0) &&
                 (pcb->unsent == NULL ||
                  (lwip_ntohl(pcb->unsent->tcphdr->seqno) - pcb->lastack +
pcb->unsent->len > pcb->snd_wnd))) {
        /* stop persist timer */
        pcb->persist_backoff = 0;
      }


(file #40733)
    _______________________________________________________

Additional Item Attachment:

File name: bug-50837-zero-win-probes -2.xlsx Size:9 KB


    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?50837>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.nongnu.org/




reply via email to

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