Sólo en lwip-1.4.0_window_scaling/src/core: flags
diff -rc lwip-1.4.0/src/core/init.c lwip-1.4.0_window_scaling/src/core/init.c
*** lwip-1.4.0/src/core/init.c	2011-05-06 10:51:25.000000000 +0200
--- lwip-1.4.0_window_scaling/src/core/init.c	2012-10-04 21:41:24.000000000 +0200
***************
*** 99,110 ****
--- 99,121 ----
  #if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
    #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
  #endif
+ #if LWIP_WND_SCALE
+ #if (LWIP_TCP && (TCP_WND > 0xffffffff))
+   #error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h"
+ #endif
+ #if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffffffff))
+   #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u32_t, so, you have to reduce it in your lwipopts.h"
+ #endif
+ #else
  #if (LWIP_TCP && (TCP_WND > 0xffff))
    #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
  #endif
  #if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
    #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
  #endif
+ #endif
+ 
+ 
  #if (LWIP_TCP && (TCP_SND_QUEUELEN < 2))
    #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
  #endif
diff -rc lwip-1.4.0/src/core/memp.c lwip-1.4.0_window_scaling/src/core/memp.c
*** lwip-1.4.0/src/core/memp.c	2011-05-06 10:51:25.000000000 +0200
--- lwip-1.4.0_window_scaling/src/core/memp.c	2012-10-04 21:41:24.000000000 +0200
***************
*** 126,143 ****
--- 126,157 ----
  #if !MEM_USE_POOLS && !MEMP_MEM_MALLOC
  static
  #endif
+ #if LWIP_WND_SCALE
  const u16_t memp_sizes[MEMP_MAX] = {
  #define LWIP_MEMPOOL(name,num,size,desc)  LWIP_MEM_ALIGN_SIZE(size),
  #include "lwip/memp_std.h"
  };
+ #else
+ const u32_t memp_sizes[MEMP_MAX] = {
+ #define LWIP_MEMPOOL(name,num,size,desc)  LWIP_MEM_ALIGN_SIZE(size),
+ #include "lwip/memp_std.h"
+ };
+ #endif
  
  #if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
  
  /** This array holds the number of elements in each pool. */
+ #if LWIP_WND_SCALE
+ static const u32_t memp_num[MEMP_MAX] = {
+ #define LWIP_MEMPOOL(name,num,size,desc)  (num),
+ #include "lwip/memp_std.h"
+ };
+ #else
  static const u16_t memp_num[MEMP_MAX] = {
  #define LWIP_MEMPOOL(name,num,size,desc)  (num),
  #include "lwip/memp_std.h"
  };
+ #endif
  
  /** This array holds a textual description of each pool. */
  #ifdef LWIP_DEBUG
***************
*** 337,343 ****
  memp_init(void)
  {
    struct memp *memp;
!   u16_t i, j;
  
    for (i = 0; i < MEMP_MAX; ++i) {
      MEMP_STATS_AVAIL(used, i, 0);
--- 351,361 ----
  memp_init(void)
  {
    struct memp *memp;
! #if LWIP_WND_SCALE
!   u32_t i, j;
! #else
!   u16_t i,j;
! #endif
  
    for (i = 0; i < MEMP_MAX; ++i) {
      MEMP_STATS_AVAIL(used, i, 0);
diff -rc lwip-1.4.0/src/core/tcp.c lwip-1.4.0_window_scaling/src/core/tcp.c
*** lwip-1.4.0/src/core/tcp.c	2011-05-06 10:51:25.000000000 +0200
--- lwip-1.4.0_window_scaling/src/core/tcp.c	2012-10-05 12:27:19.000000000 +0200
***************
*** 556,563 ****
--- 556,567 ----
      } else {
        /* keep the right edge of window constant */
        u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
+ #if LWIP_WND_SCALE
+       pcb->rcv_ann_wnd = new_rcv_ann_wnd;
+ #else
        LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
        pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd;
+ #endif
      }
      return 0;
    }
***************
*** 576,583 ****
  {
    int wnd_inflation;
  
!   LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
!               len <= 0xffff - pcb->rcv_wnd );
  
    pcb->rcv_wnd += len;
    if (pcb->rcv_wnd > TCP_WND) {
--- 580,590 ----
  {
    int wnd_inflation;
  
! #if LWIP_WND_SCALE
!   LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", len <= 0xffffffffU - pcb->rcv_wnd );
! #else
!   LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", len <= 0xffff - pcb->rcv_wnd );
! #endif
  
    pcb->rcv_wnd += len;
    if (pcb->rcv_wnd > TCP_WND) {
***************
*** 750,756 ****
--- 757,767 ----
  tcp_slowtmr(void)
  {
    struct tcp_pcb *pcb, *prev;
+ #if LWIP_WND_SCALE
+   u32_t eff_wnd;
+ #else
    u16_t eff_wnd;
+ #endif
    u8_t pcb_remove;      /* flag if a PCB should be removed */
    u8_t pcb_reset;       /* flag if a RST should be sent when removing */
    err_t err;
***************
*** 820,828 ****
--- 831,845 ----
              pcb->ssthresh = (pcb->mss << 1);
            }
            pcb->cwnd = pcb->mss;
+ #if LWIP_WND_SCALE	  
+           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U32_F
+                                        " ssthresh %"U32_F"\n",
+                                        pcb->cwnd, pcb->ssthresh));
+ #else
            LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
                                         " ssthresh %"U16_F"\n",
                                         pcb->cwnd, pcb->ssthresh));
+ #endif
   
            /* The following needs to be called AFTER cwnd is set to one
               mss - STJ */
***************
*** 1212,1217 ****
--- 1229,1238 ----
      pcb->snd_queuelen = 0;
      pcb->rcv_wnd = TCP_WND;
      pcb->rcv_ann_wnd = TCP_WND;
+ #if LWIP_WND_SCALE
+     pcb->snd_scale = 0;
+     pcb->rcv_scale = 0;
+ #endif    
      pcb->tos = 0;
      pcb->ttl = TCP_TTL;
      /* As initial send MSS, we use TCP_MSS but limit it to 536.
***************
*** 1228,1234 ****
      pcb->lastack = iss;
      pcb->snd_lbb = iss;   
      pcb->tmr = tcp_ticks;
- 
      pcb->polltmr = 0;
  
  #if LWIP_CALLBACK_API
--- 1249,1254 ----
diff -rc lwip-1.4.0/src/core/tcp_in.c lwip-1.4.0_window_scaling/src/core/tcp_in.c
*** lwip-1.4.0/src/core/tcp_in.c	2011-05-06 10:51:25.000000000 +0200
--- lwip-1.4.0_window_scaling/src/core/tcp_in.c	2012-10-04 21:41:24.000000000 +0200
***************
*** 481,493 ****
      npcb->state = SYN_RCVD;
      npcb->rcv_nxt = seqno + 1;
      npcb->rcv_ann_right_edge = npcb->rcv_nxt;
-     npcb->snd_wnd = tcphdr->wnd;
-     npcb->ssthresh = npcb->snd_wnd;
      npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
      npcb->callback_arg = pcb->callback_arg;
  #if LWIP_CALLBACK_API
      npcb->accept = pcb->accept;
  #endif /* LWIP_CALLBACK_API */
      /* inherit socket options */
      npcb->so_options = pcb->so_options & SOF_INHERITED;
      /* Register the new PCB so that we can begin receiving segments
--- 481,492 ----
      npcb->state = SYN_RCVD;
      npcb->rcv_nxt = seqno + 1;
      npcb->rcv_ann_right_edge = npcb->rcv_nxt;
      npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
      npcb->callback_arg = pcb->callback_arg;
  #if LWIP_CALLBACK_API
      npcb->accept = pcb->accept;
  #endif /* LWIP_CALLBACK_API */
+ 
      /* inherit socket options */
      npcb->so_options = pcb->so_options & SOF_INHERITED;
      /* Register the new PCB so that we can begin receiving segments
***************
*** 496,501 ****
--- 495,503 ----
  
      /* Parse any options in the SYN. */
      tcp_parseopt(npcb);
+     npcb->snd_wnd = SND_WND_SCALE(npcb, tcphdr->wnd);
+     npcb->ssthresh = npcb->snd_wnd;
+     
  #if TCP_CALCULATE_EFF_SEND_MSS
      npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
  #endif /* TCP_CALCULATE_EFF_SEND_MSS */
***************
*** 632,638 ****
        pcb->rcv_nxt = seqno + 1;
        pcb->rcv_ann_right_edge = pcb->rcv_nxt;
        pcb->lastack = ackno;
!       pcb->snd_wnd = tcphdr->wnd;
        pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
        pcb->state = ESTABLISHED;
  
--- 634,640 ----
        pcb->rcv_nxt = seqno + 1;
        pcb->rcv_ann_right_edge = pcb->rcv_nxt;
        pcb->lastack = ackno;
!       pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);
        pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
        pcb->state = ESTABLISHED;
  
***************
*** 647,653 ****
--- 649,659 ----
        pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
        LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
        --pcb->snd_queuelen;
+ #ifdef LWIP_WND_SCALE
+       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U32_F"\n", (u32_t)pcb->snd_queuelen));
+ #else
        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
+ #endif      
        rseg = pcb->unacked;
        pcb->unacked = rseg->next;
  
***************
*** 681,687 ****
      if (flags & TCP_ACK) {
        /* expected ACK number? */
        if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
!         u16_t old_cwnd;
          pcb->state = ESTABLISHED;
          LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
  #if LWIP_CALLBACK_API
--- 687,697 ----
      if (flags & TCP_ACK) {
        /* expected ACK number? */
        if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
! #if LWIP_WND_SCALE
!         u32_t old_cwnd;
! #else
! 	u16_t old_cwnd;	  
! #endif
          pcb->state = ESTABLISHED;
          LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
  #if LWIP_CALLBACK_API
***************
*** 861,868 ****
      if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
         (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
         (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
!       pcb->snd_wnd = tcphdr->wnd;
!       pcb->snd_wl1 = seqno;
        pcb->snd_wl2 = ackno;
        if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) {
            pcb->persist_backoff = 0;
--- 871,878 ----
      if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
         (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
         (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
! 	pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd); 
! 	pcb->snd_wl1 = seqno;
        pcb->snd_wl2 = ackno;
        if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) {
            pcb->persist_backoff = 0;
***************
*** 916,924 ****
--- 926,940 ----
                if (pcb->dupacks > 3) {
                  /* Inflate the congestion window, but not if it means that
                     the value overflows. */
+ #if LWIP_WND_SCALE
+                 if ((u32_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
+                   pcb->cwnd += pcb->mss;
+                 }
+ #else
                  if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
                    pcb->cwnd += pcb->mss;
                  }
+ #endif
                } else if (pcb->dupacks == 3) {
                  /* Do fast retransmit */
                  tcp_rexmit_fast(pcb);
***************
*** 962,979 ****
           ssthresh). */
        if (pcb->state >= ESTABLISHED) {
          if (pcb->cwnd < pcb->ssthresh) {
            if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
              pcb->cwnd += pcb->mss;
            }
!           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
          } else {
            u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
            if (new_cwnd > pcb->cwnd) {
              pcb->cwnd = new_cwnd;
            }
            LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
          }
!       }
        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
                                      ackno,
                                      pcb->unacked != NULL?
--- 978,1014 ----
           ssthresh). */
        if (pcb->state >= ESTABLISHED) {
          if (pcb->cwnd < pcb->ssthresh) {
+ #if LWIP_WND_SCALE
+           if ((u32_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
+             pcb->cwnd += pcb->mss;
+           }
+ #else
            if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
              pcb->cwnd += pcb->mss;
            }
! #endif
! #if LWIP_WND_SCALE	  
!           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U32_F"\n", pcb->cwnd));
! #else
! 	  LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));	  
! #endif
          } else {
+ #if LWIP_WND_SCALE	    
+           u32_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
+           if (new_cwnd > pcb->cwnd) {
+             pcb->cwnd = new_cwnd;
+           }
+           LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U32_F"\n", pcb->cwnd));
+ #else
            u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
            if (new_cwnd > pcb->cwnd) {
              pcb->cwnd = new_cwnd;
            }
            LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
+ #endif
          }
!       }	    
! 
        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
                                      ackno,
                                      pcb->unacked != NULL?
***************
*** 993,1001 ****
  
          next = pcb->unacked;
          pcb->unacked = pcb->unacked->next;
! 
          LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
          LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
          /* Prevent ACK for FIN to generate a sent event */
          if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
            pcb->acked--;
--- 1028,1040 ----
  
          next = pcb->unacked;
          pcb->unacked = pcb->unacked->next;
! #if LWIP_WND_SCALE
!         LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U32_F" ... ", (u32_t)pcb->snd_queuelen));
!         LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
! #else
          LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
          LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
+ #endif
          /* Prevent ACK for FIN to generate a sent event */
          if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
            pcb->acked--;
***************
*** 1004,1010 ****
--- 1043,1053 ----
          pcb->snd_queuelen -= pbuf_clen(next->p);
          tcp_seg_free(next);
  
+ #if LWIP_WND_SCALE
+ 	LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U32_F" (after freeing unacked)\n", (u32_t)pcb->snd_queuelen));
+ #else
          LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
+ #endif	
          if (pcb->snd_queuelen != 0) {
            LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
                        pcb->unsent != NULL);
***************
*** 1039,1053 ****
--- 1082,1107 ----
  
        next = pcb->unsent;
        pcb->unsent = pcb->unsent->next;
+ 
+ #if LWIP_WND_SCALE
+       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U32_F" ... ", (u32_t)pcb->snd_queuelen));
+       LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
+ #else      
        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
        LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
+ #endif
        /* Prevent ACK for FIN to generate a sent event */
        if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
          pcb->acked--;
        }
        pcb->snd_queuelen -= pbuf_clen(next->p);
        tcp_seg_free(next);
+ 
+ #if LWIP_WND_SCALE
+       LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U32_F" (after freeing unsent)\n", (u32_t)pcb->snd_queuelen));
+ #else     
        LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
+ #endif
        if (pcb->snd_queuelen != 0) {
          LWIP_ASSERT("tcp_receive: valid queue length",
            pcb->unacked != NULL || pcb->unsent != NULL);
***************
*** 1495,1501 ****
  #if LWIP_TCP_TIMESTAMPS
    u32_t tsval;
  #endif
! 
    opts = (u8_t *)tcphdr + TCP_HLEN;
  
    /* Parse the TCP MSS option, if present. */
--- 1549,1555 ----
  #if LWIP_TCP_TIMESTAMPS
    u32_t tsval;
  #endif
!   
    opts = (u8_t *)tcphdr + TCP_HLEN;
  
    /* Parse the TCP MSS option, if present. */
***************
*** 1527,1532 ****
--- 1581,1606 ----
          /* Advance to next option */
          c += 0x04;
          break;
+ #if LWIP_WND_SCALE
+     case 0x03:
+ 	LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n"));
+         if (opts[c + 1] != 0x03 || c + 0x03 > max_c) {
+           /* Bad length */
+           LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
+           return;
+         }
+ 	/* An WND_SCALE option with the right option length. */
+ 	pcb->snd_scale = opts[c + 2];
+ 	pcb->rcv_scale = TCP_RCV_SCALE;
+ 	/* If syn was received with wnd scale option,
+ 	   activate wnd scale opt */
+ 	if( flags & TCP_SYN ) {
+ 	    pcb->flags |= TF_WND_SCALE;
+ 	}
+ 	/* Advance to next option */
+ 	c += 0x03;
+ 	break;
+ #endif
  #if LWIP_TCP_TIMESTAMPS
        case 0x08:
          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
diff -rc lwip-1.4.0/src/core/tcp_out.c lwip-1.4.0_window_scaling/src/core/tcp_out.c
*** lwip-1.4.0/src/core/tcp_out.c	2011-05-06 10:51:25.000000000 +0200
--- lwip-1.4.0_window_scaling/src/core/tcp_out.c	2012-10-04 21:41:24.000000000 +0200
***************
*** 103,109 ****
      tcphdr->seqno = seqno_be;
      tcphdr->ackno = htonl(pcb->rcv_nxt);
      TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
!     tcphdr->wnd = htons(pcb->rcv_ann_wnd);
      tcphdr->chksum = 0;
      tcphdr->urgp = 0;
  
--- 103,109 ----
      tcphdr->seqno = seqno_be;
      tcphdr->ackno = htonl(pcb->rcv_nxt);
      TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK);
!     tcphdr->wnd = htons(RCV_WND_SCALE(pcb,pcb->rcv_ann_wnd));
      tcphdr->chksum = 0;
      tcphdr->urgp = 0;
  
***************
*** 131,136 ****
--- 131,137 ----
      if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) {
        /* no SYN/FIN/RST flag in the header, we can add the FIN flag */
        TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN);
+       pcb->flags |= TF_FIN;
        return ERR_OK;
      }
    }
***************
*** 308,322 ****
      pcb->flags |= TF_NAGLEMEMERR;
      return ERR_MEM;
    }
! 
    LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
  
    /* If total number of pbufs on the unsent/unacked queues exceeds the
     * configured maximum, return an error */
    /* check for configured max queuelen and possible overflow */
    if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
        pcb->snd_queuelen, TCP_SND_QUEUELEN));
      TCP_STATS_INC(tcp.memerr);
      pcb->flags |= TF_NAGLEMEMERR;
      return ERR_MEM;
--- 309,331 ----
      pcb->flags |= TF_NAGLEMEMERR;
      return ERR_MEM;
    }
! #ifdef LWIP_WND_SCALE
!   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U32_F"\n", (u32_t)pcb->snd_queuelen));
! #else
    LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen));
+ #endif
  
    /* If total number of pbufs on the unsent/unacked queues exceeds the
     * configured maximum, return an error */
    /* check for configured max queuelen and possible overflow */
    if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
+ #ifdef LWIP_WND_SCALE
+     LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U32_F" (max %"U32_F")\n",
+       pcb->snd_queuelen, TCP_SND_QUEUELEN));      
+ #else
      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n",
        pcb->snd_queuelen, TCP_SND_QUEUELEN));
+ #endif
      TCP_STATS_INC(tcp.memerr);
      pcb->flags |= TF_NAGLEMEMERR;
      return ERR_MEM;
***************
*** 353,364 ****
    struct pbuf *concat_p = NULL;
    struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
    u16_t pos = 0; /* position in 'arg' data */
    u16_t queuelen;
    u8_t optlen = 0;
    u8_t optflags = 0;
  #if TCP_OVERSIZE
    u16_t oversize = 0;
!   u16_t oversize_used = 0;
  #endif /* TCP_OVERSIZE */
  #if TCP_CHECKSUM_ON_COPY
    u16_t concat_chksum = 0;
--- 362,377 ----
    struct pbuf *concat_p = NULL;
    struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
    u16_t pos = 0; /* position in 'arg' data */
+ #if LWIP_WND_SCALE
+   u32_t queuelen;
+ #else
    u16_t queuelen;
+ #endif
    u8_t optlen = 0;
    u8_t optflags = 0;
  #if TCP_OVERSIZE
    u16_t oversize = 0;
!   u16_t oversize_used = 0;  
  #endif /* TCP_OVERSIZE */
  #if TCP_CHECKSUM_ON_COPY
    u16_t concat_chksum = 0;
***************
*** 386,395 ****
  #if LWIP_TCP_TIMESTAMPS
    if ((pcb->flags & TF_TIMESTAMP)) {
      optflags = TF_SEG_OPTS_TS;
-     optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
    }
  #endif /* LWIP_TCP_TIMESTAMPS */
  
  
    /*
     * TCP segmentation is done in three phases with increasing complexity:
--- 399,408 ----
  #if LWIP_TCP_TIMESTAMPS
    if ((pcb->flags & TF_TIMESTAMP)) {
      optflags = TF_SEG_OPTS_TS;
    }
  #endif /* LWIP_TCP_TIMESTAMPS */
  
+   optlen = LWIP_TCP_OPT_LENGTH( optflags );
  
    /*
     * TCP segmentation is done in three phases with increasing complexity:
***************
*** 573,579 ****
--- 586,596 ----
       * length of the queue exceeds the configured maximum or
       * overflows. */
      if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) {
+ #ifdef LWIP_WND_SCALE
+       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U32_F" (%"U32_F")\n", queuelen, TCP_SND_QUEUELEN));	
+ #else
        LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN));
+ #endif      
        pbuf_free(p);
        goto memerr;
      }
***************
*** 741,746 ****
--- 758,769 ----
      optflags |= TF_SEG_OPTS_TS;
    }
  #endif /* LWIP_TCP_TIMESTAMPS */
+ #if LWIP_WND_SCALE
+   if ((pcb->flags & TF_WND_SCALE) && ( flags & TCP_SYN ) ) {
+     optflags |= TF_SEG_OPTS_WND_SCALE;
+   }
+ #endif /* LWIP_TCP_TIMESTAMPS */
+   
    optlen = LWIP_TCP_OPT_LENGTH(optflags);
  
    /* tcp_enqueue_flags is always called with either SYN or FIN in flags.
***************
*** 777,782 ****
--- 800,806 ----
                 ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg),
                 (u16_t)flags));
  
+ 
    /* Now append seg to pcb->unsent queue */
    if (pcb->unsent == NULL) {
      pcb->unsent = seg;
***************
*** 828,833 ****
--- 852,876 ----
  }
  #endif
  
+ #if LWIP_WND_SCALE
+ /* Build a window scale option (3 bytes long) at the specified options pointer)
+  *
+  * @param pcb tcp_pcb
+  * @param opts option pointer where to store the window scale option
+  */
+ static void
+ tcp_build_wnd_scale_option(struct tcp_pcb *pcb, u32_t *opts)
+ {
+   /* Pad with one NOP option to make everything nicely aligned */
+     unsigned char* optdata = (unsigned char*) opts;
+     optdata[0] = 1; /*NOP */
+     optdata[1] = 3; /*Window Scale option code*/
+     optdata[2] = 3; /*option length*/
+     optdata[3] = TCP_RCV_SCALE; /* window scale value*/
+ }
+ #endif
+ 
+ 
  /** Send an ACK without data.
   *
   * @param pcb Protocol control block for the TCP connection to send the ACK
***************
*** 838,850 ****
    struct pbuf *p;
    struct tcp_hdr *tcphdr;
    u8_t optlen = 0;
  
  #if LWIP_TCP_TIMESTAMPS
    if (pcb->flags & TF_TIMESTAMP) {
      optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
    }
  #endif
! 
    p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
    if (p == NULL) {
      LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
--- 881,894 ----
    struct pbuf *p;
    struct tcp_hdr *tcphdr;
    u8_t optlen = 0;
+   u32_t *opts;
  
  #if LWIP_TCP_TIMESTAMPS
    if (pcb->flags & TF_TIMESTAMP) {
      optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
    }
  #endif
!   
    p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt));
    if (p == NULL) {
      LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
***************
*** 856,867 ****
    /* remove ACK flags from the PCB, as we send an empty ACK now */
    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
  
    /* NB. MSS option is only sent on SYNs, so ignore it here */
  #if LWIP_TCP_TIMESTAMPS
    pcb->ts_lastacksent = pcb->rcv_nxt;
  
    if (pcb->flags & TF_TIMESTAMP) {
!     tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1));
    }
  #endif 
  
--- 900,914 ----
    /* remove ACK flags from the PCB, as we send an empty ACK now */
    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
  
+   opts = (u32_t *)(void *)(tcphdr + 1);
+ 
    /* NB. MSS option is only sent on SYNs, so ignore it here */
  #if LWIP_TCP_TIMESTAMPS
    pcb->ts_lastacksent = pcb->rcv_nxt;
  
    if (pcb->flags & TF_TIMESTAMP) {
!     tcp_build_timestamp_option(pcb, opts );
!     opts += 3;
    }
  #endif 
  
***************
*** 907,912 ****
--- 954,962 ----
  
    wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);
  
+   LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U32_F
+ 	  ", wnd %"U32_F"\n",pcb->snd_wnd, pcb->cwnd, wnd ));
+ 
    seg = pcb->unsent;
  
    /* If the TF_ACK_NOW flag is set and no data will be sent (either
***************
*** 935,947 ****
  #endif /* TCP_OUTPUT_DEBUG */
  #if TCP_CWND_DEBUG
    if (seg == NULL) {
!     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F
!                                  ", cwnd %"U16_F", wnd %"U32_F
                                   ", seg == NULL, ack %"U32_F"\n",
                                   pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
    } else {
      LWIP_DEBUGF(TCP_CWND_DEBUG, 
!                 ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F
                   ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
                   pcb->snd_wnd, pcb->cwnd, wnd,
                   ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
--- 985,997 ----
  #endif /* TCP_OUTPUT_DEBUG */
  #if TCP_CWND_DEBUG
    if (seg == NULL) {
!     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F
!                                  ", cwnd %"U32_F", wnd %"U32_F
                                   ", seg == NULL, ack %"U32_F"\n",
                                   pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack));
    } else {
      LWIP_DEBUGF(TCP_CWND_DEBUG, 
!                 ("tcp_output: snd_wnd %"U32_F", cwnd %"U32_F", wnd %"U32_F
                   ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n",
                   pcb->snd_wnd, pcb->cwnd, wnd,
                   ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len,
***************
*** 965,971 ****
        break;
      }
  #if TCP_CWND_DEBUG
!     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
                              pcb->snd_wnd, pcb->cwnd, wnd,
                              ntohl(seg->tcphdr->seqno) + seg->len -
                              pcb->lastack,
--- 1015,1021 ----
        break;
      }
  #if TCP_CWND_DEBUG
!     LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U32_F", cwnd %"U32_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n",
                              pcb->snd_wnd, pcb->cwnd, wnd,
                              ntohl(seg->tcphdr->seqno) + seg->len -
                              pcb->lastack,
***************
*** 1057,1063 ****
    seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
  
    /* advertise our receive window size in this TCP segment */
!   seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd);
  
    pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
  
--- 1107,1113 ----
    seg->tcphdr->ackno = htonl(pcb->rcv_nxt);
  
    /* advertise our receive window size in this TCP segment */
!   seg->tcphdr->wnd = htons(RCV_WND_SCALE(pcb,pcb->rcv_ann_wnd));
  
    pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd;
  
***************
*** 1077,1083 ****
      opts += 3;
    }
  #endif
! 
    /* Set retransmission timer running if it is not currently enabled 
       This must be set before checking the route. */
    if (pcb->rtime == -1) {
--- 1127,1139 ----
      opts += 3;
    }
  #endif
! #if LWIP_WND_SCALE
!   if ( seg->flags & TF_SEG_OPTS_WND_SCALE ) {
!     tcp_build_wnd_scale_option(pcb, opts);
!     opts += 1;
!   }
! #endif
!   
    /* Set retransmission timer running if it is not currently enabled 
       This must be set before checking the route. */
    if (pcb->rtime == -1) {
***************
*** 1204,1210 ****
    tcphdr->seqno = htonl(seqno);
    tcphdr->ackno = htonl(ackno);
    TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
!   tcphdr->wnd = PP_HTONS(TCP_WND);
    tcphdr->chksum = 0;
    tcphdr->urgp = 0;
  
--- 1260,1270 ----
    tcphdr->seqno = htonl(seqno);
    tcphdr->ackno = htonl(ackno);
    TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK);
! #if LWIP_WND_SCALE
!   tcphdr->wnd = PP_HTONS( ( ( TCP_WND >> TCP_RCV_SCALE ) & 0xFFFF ) );
! #else
!   tcphdr->wnd = PP_HTONS( TCP_WND );
! #endif
    tcphdr->chksum = 0;
    tcphdr->urgp = 0;
  
Sólo en lwip-1.4.0_window_scaling/src/core: .tcp_out.c.swp
Sólo en lwip-1.4.0_window_scaling/src/include/lwip: .netif.h.swp
diff -rc lwip-1.4.0/src/include/lwip/opt.h lwip-1.4.0_window_scaling/src/include/lwip/opt.h
*** lwip-1.4.0/src/include/lwip/opt.h	2011-05-06 10:51:26.000000000 +0200
--- lwip-1.4.0_window_scaling/src/include/lwip/opt.h	2012-10-05 11:24:19.000000000 +0200
***************
*** 1042,1047 ****
--- 1042,1052 ----
  #define LWIP_CALLBACK_API               0
  #endif
  
+ #ifndef LWIP_WND_SCALE
+ #define LWIP_WND_SCALE			0
+ #define TCP_RCV_SCALE			0
+ #endif
+ 
  
  /*
     ----------------------------------
diff -rc lwip-1.4.0/src/include/lwip/tcp.h lwip-1.4.0_window_scaling/src/include/lwip/tcp.h
*** lwip-1.4.0/src/include/lwip/tcp.h	2011-05-06 10:51:26.000000000 +0200
--- lwip-1.4.0_window_scaling/src/include/lwip/tcp.h	2012-10-04 21:45:21.000000000 +0200
***************
*** 124,129 ****
--- 124,137 ----
   */
  typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err);
  
+ #if LWIP_WND_SCALE
+ #define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale))
+ #define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale))
+ #else
+ #define RCV_WND_SCALE(pcb, wnd) (wnd)
+ #define SND_WND_SCALE(pcb, wnd) (wnd)
+ #endif 
+ 
  enum tcp_state {
    CLOSED      = 0,
    LISTEN      = 1,
***************
*** 175,196 ****
    /* ports are in host byte order */
    u16_t remote_port;
    
!   u8_t flags;
! #define TF_ACK_DELAY   ((u8_t)0x01U)   /* Delayed ACK. */
! #define TF_ACK_NOW     ((u8_t)0x02U)   /* Immediate ACK. */
! #define TF_INFR        ((u8_t)0x04U)   /* In fast recovery. */
! #define TF_TIMESTAMP   ((u8_t)0x08U)   /* Timestamp option enabled */
! #define TF_RXCLOSED    ((u8_t)0x10U)   /* rx closed by tcp_shutdown */
! #define TF_FIN         ((u8_t)0x20U)   /* Connection was closed locally (FIN segment enqueued). */
! #define TF_NODELAY     ((u8_t)0x40U)   /* Disable Nagle algorithm */
! #define TF_NAGLEMEMERR ((u8_t)0x80U)   /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
  
    /* the rest of the fields are in host byte order
       as we have to do some math with them */
    /* receiver variables */
    u32_t rcv_nxt;   /* next seqno expected */
    u16_t rcv_wnd;   /* receiver window available */
    u16_t rcv_ann_wnd; /* receiver window to announce */
    u32_t rcv_ann_right_edge; /* announced right edge of window */
  
    /* Timers */
--- 183,210 ----
    /* ports are in host byte order */
    u16_t remote_port;
    
!   u16_t flags;
! #define TF_ACK_DELAY   ((u16_t)0x0001U)   /* Delayed ACK. */
! #define TF_ACK_NOW     ((u16_t)0x0002U)   /* Immediate ACK. */
! #define TF_INFR        ((u16_t)0x0004U)   /* In fast recovery. */
! #define TF_TIMESTAMP   ((u16_t)0x0008U)   /* Timestamp option enabled */
! #define TF_RXCLOSED    ((u16_t)0x0010U)   /* rx closed by tcp_shutdown */
! #define TF_FIN         ((u16_t)0x0020U)   /* Connection was closed locally (FIN segment enqueued). */
! #define TF_NODELAY     ((u16_t)0x0040U)   /* Disable Nagle algorithm */
! #define TF_NAGLEMEMERR ((u16_t)0x0080U)   /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */
! #define TF_WND_SCALE   ((u16_t)0x0100U)   /* Window Scale option enabled */
  
    /* the rest of the fields are in host byte order
       as we have to do some math with them */
    /* receiver variables */
    u32_t rcv_nxt;   /* next seqno expected */
+ #if LWIP_WND_SCALE
+   u32_t rcv_wnd;   /* receiver window available */
+   u32_t rcv_ann_wnd; /* receiver window to announce */
+ #else
    u16_t rcv_wnd;   /* receiver window available */
    u16_t rcv_ann_wnd; /* receiver window to announce */
+ #endif
    u32_t rcv_ann_right_edge; /* announced right edge of window */
  
    /* Timers */
***************
*** 215,239 ****
    u8_t dupacks;
    
    /* congestion avoidance/control variables */
    u16_t cwnd;  
    u16_t ssthresh;
  
    /* sender variables */
    u32_t snd_nxt;   /* next new seqno to be sent */
    u16_t snd_wnd;   /* sender window */
    u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last
                               window update. */
    u32_t snd_lbb;       /* Sequence number of next byte to be buffered. */
  
    u16_t acked;
!   
    u16_t snd_buf;   /* Available buffer space for sending (in bytes). */
! #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
!   u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
  
  #if TCP_OVERSIZE
    /* Extra bytes available at the end of the last pbuf in unsent. */
    u16_t unsent_oversize;
  #endif /* TCP_OVERSIZE */ 
  
    /* These are ordered by sequence number: */
--- 229,277 ----
    u8_t dupacks;
    
    /* congestion avoidance/control variables */
+ #if LWIP_WND_SCALE // Luis: en el parche original no se tocan
+   u32_t cwnd;  
+   u32_t ssthresh;
+ #else
    u16_t cwnd;  
    u16_t ssthresh;
+ #endif
  
    /* sender variables */
    u32_t snd_nxt;   /* next new seqno to be sent */
+ #if LWIP_WND_SCALE  
+   u32_t snd_wnd;   /* sender window */
+ #else
    u16_t snd_wnd;   /* sender window */
+ #endif
    u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last
                               window update. */
    u32_t snd_lbb;       /* Sequence number of next byte to be buffered. */
  
    u16_t acked;
! 
! #if LWIP_WND_SCALE
!   u32_t snd_buf;   /* Available buffer space for sending (in bytes). */
! #else
    u16_t snd_buf;   /* Available buffer space for sending (in bytes). */
! #endif
!   
  
+ #if LWIP_WND_SCALE
+   #define TCP_SNDQUEUELEN_OVERFLOW (0x03ffffffU-3)
+   u32_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
+ #else
+   #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
+   u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
+ #endif
+   
  #if TCP_OVERSIZE
+   #if LWIP_WND_SCALE
    /* Extra bytes available at the end of the last pbuf in unsent. */
+   u32_t unsent_oversize;
+   #else
    u16_t unsent_oversize;
+   #endif
  #endif /* TCP_OVERSIZE */ 
  
    /* These are ordered by sequence number: */
***************
*** 277,282 ****
--- 315,325 ----
  
    /* KEEPALIVE counter */
    u8_t keep_cnt_sent;
+ 
+ #if LWIP_WND_SCALE
+   u8_t snd_scale;
+   u8_t rcv_scale;
+ #endif  
  };
  
  struct tcp_pcb_listen {  
Sólo en lwip-1.4.0_window_scaling/src/include/lwip: .tcp.h.swp
diff -rc lwip-1.4.0/src/include/lwip/tcp_impl.h lwip-1.4.0_window_scaling/src/include/lwip/tcp_impl.h
*** lwip-1.4.0/src/include/lwip/tcp_impl.h	2011-05-06 10:51:26.000000000 +0200
--- lwip-1.4.0_window_scaling/src/include/lwip/tcp_impl.h	2012-10-04 21:45:27.000000000 +0200
***************
*** 293,304 ****
  #define TF_SEG_OPTS_TS          (u8_t)0x02U /* Include timestamp option. */
  #define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is
                                                 checksummed into 'chksum' */
    struct tcp_hdr *tcphdr;  /* the TCP header */
  };
  
  #define LWIP_TCP_OPT_LENGTH(flags)              \
!   (flags & TF_SEG_OPTS_MSS ? 4  : 0) +          \
!   (flags & TF_SEG_OPTS_TS  ? 12 : 0)
  
  /** This returns a TCP header option for MSS in an u32_t */
  #define TCP_BUILD_MSS_OPTION(x) (x) = PP_HTONL(((u32_t)2 << 24) |          \
--- 293,306 ----
  #define TF_SEG_OPTS_TS          (u8_t)0x02U /* Include timestamp option. */
  #define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is
                                                 checksummed into 'chksum' */
+ #define TF_SEG_OPTS_WND_SCALE 	(u8_t)0x08U /* Include WND SCALE option */
    struct tcp_hdr *tcphdr;  /* the TCP header */
  };
  
  #define LWIP_TCP_OPT_LENGTH(flags)              \
!   (flags & TF_SEG_OPTS_MSS 	 ? 4  : 0) +    \
!   (flags & TF_SEG_OPTS_TS  	 ? 12 : 0) +    \
!   (flags & TF_SEG_OPTS_WND_SCALE ? 4  : 0)
  
  /** This returns a TCP header option for MSS in an u32_t */
  #define TCP_BUILD_MSS_OPTION(x) (x) = PP_HTONL(((u32_t)2 << 24) |          \
