/**
 * @file
 *
 * Transmission Control Protocol, incoming traffic
 */

/*
 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 *
 * Author: Adam Dunkels <adam@sics.se>
 *
 */


/* tcp_input.c
 *
 * The input processing functions of TCP.
 *
 * These functions are generally called in the order (ip_input() ->) tcp_input() ->
 * tcp_process() -> tcp_receive() (-> application).
 *
 */



#include "lwip/def.h"
#include "lwip/opt.h"

#include "lwip/netif.h"
#include "lwip/mem.h"
#include "lwip/memp.h"

#include "lwip/inet.h"
#include "lwip/tcp.h"

#include "lwip/stats.h"

#include "arch/perf.h"
#if LWIP_TCP
/* These variables are global to all functions involved in the input
   processing of TCP segments. They are set by the tcp_input()
   function. */
static struct tcp_seg inseg;
static struct tcp_hdr *tcphdr;
static struct ip_hdr *iphdr;
static u32_t seqno, ackno;
static u8_t flags;
static u16_t tcplen;

static u8_t recv_flags;
static struct pbuf *recv_data;

struct tcp_pcb *tcp_input_pcb;

/* Forward declarations. */
static err_t tcp_process(struct tcp_pcb *pcb);
static void tcp_receive(struct tcp_pcb *pcb);
static void tcp_parseopt(struct tcp_pcb *pcb);

static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
static err_t tcp_timewait_input(struct tcp_pcb *pcb);


/* tcp_input:
 *
 * The initial input processing of TCP. It verifies the TCP header, demultiplexes
 * the segment between the PCBs and passes it on to tcp_process(), which implements
 * the TCP finite state machine. This function is called by the IP layer (in
 * ip_input()).
 */

void
tcp_input(struct pbuf *p, struct netif *inp)
{
  struct tcp_pcb *pcb, *prev;
  struct tcp_pcb_listen *lpcb;
  u8_t hdrlen;
  err_t err;

#ifdef SO_REUSE
  struct tcp_pcb *pcb_temp;
  int reuse = 0;
  int reuse_port = 0;
#endif /* SO_REUSE */

  PERF_START;

  TCP_STATS_INC(tcp.recv);

  iphdr = p->payload;
  tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);

#if TCP_INPUT_DEBUG
  tcp_debug_print(tcphdr);
#endif

  /* remove header from payload */
  if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
    /* drop short packets */
    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%u bytes) discarded\n", p->tot_len));
    TCP_STATS_INC(tcp.lenerr);
    TCP_STATS_INC(tcp.drop);
    pbuf_free(p);
    return;
  }

  /* Don't even process incoming broadcasts/multicasts. */
  if (ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) ||
     ip_addr_ismulticast(&(iphdr->dest))) {
    pbuf_free(p);
    return;
  }

  /* Verify TCP checksum. */
  if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
      (struct ip_addr *)&(iphdr->dest),
      IP_PROTO_TCP, p->tot_len) != 0) {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n",
        inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest),
      IP_PROTO_TCP, p->tot_len)));
#if TCP_DEBUG
    tcp_debug_print(tcphdr);
#endif /* TCP_DEBUG */
    TCP_STATS_INC(tcp.chkerr);
    TCP_STATS_INC(tcp.drop);

    pbuf_free(p);
    return;
  }


  /* Move the payload pointer in the pbuf so that it points to the
     TCP data instead of the TCP header. */
  hdrlen = TCPH_HDRLEN(tcphdr);
  pbuf_header(p, -(hdrlen * 4));

  /* Convert fields in TCP header to host byte order. */
  tcphdr->src = ntohs(tcphdr->src);
  tcphdr->dest = ntohs(tcphdr->dest);
  seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
  ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
  tcphdr->wnd = ntohs(tcphdr->wnd);

  flags = TCPH_FLAGS(tcphdr) & TCP_FLAGS;
  tcplen = p->tot_len + ((flags & TCP_FIN || flags & TCP_SYN)? 1: 0);

  /* Demultiplex an incoming segment. First, we check if it is destined
     for an active connection. */
  prev = NULL;

#ifdef SO_REUSE
  pcb_temp = tcp_active_pcbs;
  
 again_1:
  
  /* Iterate through the TCP pcb list for a fully matching pcb */
  for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
#else  /* SO_REUSE */
  for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
#endif  /* SO_REUSE */
    LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
    LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
    LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
    if (pcb->remote_port == tcphdr->src &&
       pcb->local_port == tcphdr->dest &&
       ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
       ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {

#ifdef SO_REUSE
      if(pcb->so_options & SOF_REUSEPORT) {
        if(reuse) {
          /* We processed one PCB already */
          LWIP_DEBUGF(TCP_INPUT_DEBUG,("tcp_input: second or later PCB and SOF_REUSEPORT set.\n"));
        } else {
          /* First PCB with this address */
          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: first PCB and SOF_REUSEPORT set.\n"));
          reuse = 1;
        }
        
        reuse_port = 1; 
        p->ref++;
        
        /* We want to search on next socket after receiving */
        pcb_temp = pcb->next;
        
        LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: reference counter on PBUF set to %i\n", p->ref));
      } else  {
        if(reuse) {
          /* We processed one PCB already */
          LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
        }
      }
#endif /* SO_REUSE */

      /* Move this PCB to the front of the list so that subsequent
   lookups will be faster (we exploit locality in TCP segment
   arrivals). */
      LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
      if (prev != NULL) {
  prev->next = pcb->next;
  pcb->next = tcp_active_pcbs;
  tcp_active_pcbs = pcb;
      }
      LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
      break;
    }
    prev = pcb;
  }

  if (pcb == NULL) {
    /* If it did not go to an active connection, we check the connections
       in the TIME-WAIT state. */

    for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
      LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
      if (pcb->remote_port == tcphdr->src &&
   pcb->local_port == tcphdr->dest &&
   ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
         ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
  /* We don't really care enough to move this PCB to the front
     of the list since we are not very likely to receive that
     many segments for connections in TIME-WAIT. */
  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
  tcp_timewait_input(pcb);
  pbuf_free(p);
  return;
      }
    }

  /* Finally, if we still did not get a match, we check all PCBs that
     are LISTENing for incoming connections. */
    prev = NULL;
    for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
      if ((ip_addr_isany(&(lpcb->local_ip)) ||
    ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
   lpcb->local_port == tcphdr->dest) {
  /* Move this PCB to the front of the list so that subsequent
     lookups will be faster (we exploit locality in TCP segment
     arrivals). */
  if (prev != NULL) {
    ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
          /* our successor is the remainder of the listening list */
    lpcb->next = tcp_listen_pcbs;
          /* put this listening pcb at the head of the listening list */
    tcp_listen_pcbs = lpcb;
  }

  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
  tcp_listen_input(lpcb);
  pbuf_free(p);
  return;
      }
      prev = (struct tcp_pcb *)lpcb;
    }
  }

#if TCP_INPUT_DEBUG
  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
  tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
#endif /* TCP_INPUT_DEBUG */


  if (pcb != NULL) {
    /* The incoming segment belongs to a connection. */
#if TCP_INPUT_DEBUG
#if TCP_DEBUG
    tcp_debug_print_state(pcb->state);
#endif /* TCP_DEBUG */
#endif /* TCP_INPUT_DEBUG */

    /* Set up a tcp_seg structure. */
    inseg.next = NULL;
    inseg.len = p->tot_len;
    inseg.dataptr = p->payload;
    inseg.p = p;
    inseg.tcphdr = tcphdr;

    recv_data = NULL;
    recv_flags = 0;

    tcp_input_pcb = pcb;
    err = tcp_process(pcb);
    tcp_input_pcb = NULL;
    /* A return value of ERR_ABRT means that tcp_abort() was called
       and that the pcb has been freed. If so, we don't do anything. */
    if (err != ERR_ABRT) {
      if (recv_flags & TF_RESET) {
  /* TF_RESET means that the connection was reset by the other
     end. We then call the error callback to inform the
     application that the connection is dead before we
     deallocate the PCB. */
  TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
  tcp_pcb_remove(&tcp_active_pcbs, pcb);
  memp_free(MEMP_TCP_PCB, pcb);
      } else if (recv_flags & TF_CLOSED) {
  /* The connection has been closed and we will deallocate the
     PCB. */
  tcp_pcb_remove(&tcp_active_pcbs, pcb);
  memp_free(MEMP_TCP_PCB, pcb);
      } else {
  err = ERR_OK;
  /* If the application has registered a "sent" function to be
     called when new send buffer space is available, we call it
     now. */
  if (pcb->acked > 0) {
    TCP_EVENT_SENT(pcb, pcb->acked, err);
  }

  if (recv_data != NULL) {
    /* Notify application that data has been received. */
    TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
  }

  /* If a FIN segment was received, we call the callback
     function with a NULL buffer to indicate EOF. */
  if (recv_flags & TF_GOT_FIN) {
    TCP_EVENT_RECV(pcb, NULL, ERR_OK, err);
  }
  /* If there were no errors, we try to send something out. */
  if (err == ERR_OK) {
    tcp_output(pcb);
  }
      }
    }


    /* We deallocate the incoming pbuf. If it was buffered by the
       application, the application should have called pbuf_ref() to
       increase the reference counter in the pbuf. If so, the buffer
       isn't actually deallocated by the call to pbuf_free(), only the
       reference count is decreased. */
    pbuf_free(inseg.p);
#if TCP_INPUT_DEBUG
#if TCP_DEBUG
    tcp_debug_print_state(pcb->state);
#endif /* TCP_DEBUG */
#endif /* TCP_INPUT_DEBUG */
#ifdef SO_REUSE
    /* First socket should receive now */
    if(reuse_port) {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));
      reuse_port = 0;
      
      /* We are searching connected sockets */
      goto again_1;
    }
#endif /* SO_REUSE */

  } else {
#ifdef SO_REUSE
    if(reuse) {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));
      pbuf_free(p);
      goto end;
    }
#endif /* SO_REUSE */
    /* If no matching PCB was found, send a TCP RST (reset) to the
       sender. */
    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
    if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
      TCP_STATS_INC(tcp.proterr);
      TCP_STATS_INC(tcp.drop);
      tcp_rst(ackno, seqno + tcplen,
        &(iphdr->dest), &(iphdr->src),
        tcphdr->dest, tcphdr->src);
    }
    pbuf_free(p);
  }
#ifdef SO_REUSE
 end:
#endif /* SO_REUSE */
  LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
  PERF_STOP("tcp_input");
}

/* tcp_listen_input():
 *
 * Called by tcp_input() when a segment arrives for a listening
 * connection.
 */

static err_t
tcp_listen_input(struct tcp_pcb_listen *pcb)
{
  struct tcp_pcb *npcb;
  u32_t optdata;

  /* In the LISTEN state, we check for incoming SYN segments,
     creates a new PCB, and responds with a SYN|ACK. */
  if (flags & TCP_ACK) {
    /* For incoming segments with the ACK flag set, respond with a
       RST. */
    LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
    tcp_rst(ackno + 1, seqno + tcplen,
      &(iphdr->dest), &(iphdr->src),
      tcphdr->dest, tcphdr->src);
  } else if (flags & TCP_SYN) {
    LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest));
    npcb = tcp_alloc(pcb->prio);
    /* If a new PCB could not be created (probably due to lack of memory),
       we don't do anything, but rely on the sender will retransmit the
       SYN at a time when we have more memory available. */
    if (npcb == NULL) {
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
      TCP_STATS_INC(tcp.memerr);
      return ERR_MEM;
    }
    /* Set up the new PCB. */
    ip_addr_set(&(npcb->local_ip), &(iphdr->dest));
    npcb->local_port = pcb->local_port;
    ip_addr_set(&(npcb->remote_ip), &(iphdr->src));
    npcb->remote_port = tcphdr->src;
    npcb->state = SYN_RCVD;
    npcb->rcv_nxt = seqno + 1;
    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_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER);
    /* Register the new PCB so that we can begin receiving segments
       for it. */
    TCP_REG(&tcp_active_pcbs, npcb);

    /* Parse any options in the SYN. */
    tcp_parseopt(npcb);

    /* Build an MSS option. */
    optdata = htonl(((u32_t)2 << 24) |
        ((u32_t)4 << 16) |
        (((u32_t)npcb->mss / 256) << 8) |
        (npcb->mss & 255));
    /* Send a SYN|ACK together with the MSS option. */
    tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, (u8_t *)&optdata, 4);
    return tcp_output(npcb);
  }
  return ERR_OK;
}

/* tcp_timewait_input():
 *
 * Called by tcp_input() when a segment arrives for a connection in
 * TIME_WAIT.
 */

static err_t
tcp_timewait_input(struct tcp_pcb *pcb)
{
  if (TCP_SEQ_GT(seqno + tcplen, pcb->rcv_nxt)) {
    pcb->rcv_nxt = seqno + tcplen;
  }
  if (tcplen > 0) {
    tcp_ack_now(pcb);
  }
  return tcp_output(pcb);
}

/* tcp_process
 *
 * Implements the TCP state machine. Called by tcp_input. In some
 * states tcp_receive() is called to receive data. The tcp_seg
 * argument will be freed by the caller (tcp_input()) unless the
 * recv_data pointer in the pcb is set.
 */

static err_t
tcp_process(struct tcp_pcb *pcb)
{
  struct tcp_seg *rseg;
  u8_t acceptable = 0;
  err_t err;


  err = ERR_OK;

  /* Process incoming RST segments. */
  if (flags & TCP_RST) {
    /* First, determine if the reset is acceptable. */
    if (pcb->state == SYN_SENT) {
      if (ackno == pcb->snd_nxt) {
  acceptable = 1;
      }
    } else {
      if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
   TCP_SEQ_LEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
  acceptable = 1;
      }
    }

    if (acceptable) {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
      LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
      recv_flags = TF_RESET;
      pcb->flags &= ~TF_ACK_DELAY;
      return ERR_RST;
    } else {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
       seqno, pcb->rcv_nxt));
      LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n",
       seqno, pcb->rcv_nxt));
      return ERR_OK;
    }
  }

  /* Update the PCB (in)activity timer. */
  pcb->tmr = tcp_ticks;
  pcb->keep_cnt = 0;

  /* Do different things depending on the TCP state. */
  switch (pcb->state) {
  case SYN_SENT:
    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,
     pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
    if (flags & (TCP_ACK | TCP_SYN) &&
       ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
      pcb->rcv_nxt = seqno + 1;
      pcb->lastack = ackno;
      pcb->snd_wnd = tcphdr->wnd;
      pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
      pcb->state = ESTABLISHED;
      pcb->cwnd = pcb->mss;
      --pcb->snd_queuelen;
      LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %u\n", (unsigned int)pcb->snd_queuelen));
      rseg = pcb->unacked;
      pcb->unacked = rseg->next;
      tcp_seg_free(rseg);

      /* Parse any options in the SYNACK. */
      tcp_parseopt(pcb);

      /* Call the user specified function to call when sucessfully
       * connected. */
      TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
      tcp_ack(pcb);
    }
    break;
  case SYN_RCVD:
    if (flags & TCP_ACK &&
       !(flags & TCP_RST)) {
      if (TCP_SEQ_LT(pcb->lastack, ackno) &&
          TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
        pcb->state = ESTABLISHED;
        LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
#if LWIP_CALLBACK_API
        LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
#endif
        /* Call the accept function. */
        TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
        if (err != ERR_OK) {
          /* If the accept function returns with an error, we abort
           * the connection. */
          tcp_abort(pcb);
          return ERR_ABRT;
        }
        /* If there was any data contained within this ACK,
         * we'd better pass it on to the application as well. */
        tcp_receive(pcb);
        pcb->cwnd = pcb->mss;
      }
    }
    break;
  case CLOSE_WAIT:
    /* FALLTHROUGH */
  case ESTABLISHED:
    tcp_receive(pcb);
    if (flags & TCP_FIN) {
      tcp_ack_now(pcb);
      pcb->state = CLOSE_WAIT;
    }
    break;
  case FIN_WAIT_1:
    tcp_receive(pcb);
    if (flags & TCP_FIN) {
      if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
        LWIP_DEBUGF(DEMO_DEBUG,
         ("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
  tcp_ack_now(pcb);
  tcp_pcb_purge(pcb);
  TCP_RMV(&tcp_active_pcbs, pcb);
  pcb->state = TIME_WAIT;
  TCP_REG(&tcp_tw_pcbs, pcb);
      } else {
  tcp_ack_now(pcb);
  pcb->state = CLOSING;
      }
    } else if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
      pcb->state = FIN_WAIT_2;
    }
    break;
  case FIN_WAIT_2:
    tcp_receive(pcb);
    if (flags & TCP_FIN) {
      LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
      tcp_ack_now(pcb);
      tcp_pcb_purge(pcb);
      TCP_RMV(&tcp_active_pcbs, pcb);
      pcb->state = TIME_WAIT;
      TCP_REG(&tcp_tw_pcbs, pcb);
    }
    break;
  case CLOSING:
    tcp_receive(pcb);
    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
      LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
      tcp_ack_now(pcb);
      tcp_pcb_purge(pcb);
      TCP_RMV(&tcp_active_pcbs, pcb);
      pcb->state = TIME_WAIT;
      TCP_REG(&tcp_tw_pcbs, pcb);
    }
    break;
  case LAST_ACK:
    tcp_receive(pcb);
    if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
      LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
      pcb->state = CLOSED;
      recv_flags = TF_CLOSED;
    }
    break;
  default:
    break;
  }

  return ERR_OK;
}

/* tcp_receive:
 *
 * Called by tcp_process. Checks if the given segment is an ACK for outstanding
 * data, and if so frees the memory of the buffered data. Next, is places the
 * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment
 * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until
 * i it has been removed from the buffer.
 *
 * If the incoming segment constitutes an ACK for a segment that was used for RTT
 * estimation, the RTT is estimated here as well.
 */

static void
tcp_receive(struct tcp_pcb *pcb)
{
  struct tcp_seg *next;
#if TCP_QUEUE_OOSEQ
  struct tcp_seg *prev, *cseg;
#endif
  struct pbuf *p;
  s32_t off;
  int m;
  u32_t right_wnd_edge;


  if (flags & TCP_ACK) {
    right_wnd_edge = pcb->snd_wnd + pcb->snd_wl1;

    /* 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 && tcphdr->wnd > pcb->snd_wnd)) {
      pcb->snd_wnd = tcphdr->wnd;
      pcb->snd_wl1 = seqno;
      pcb->snd_wl2 = ackno;
      LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %lu\n", pcb->snd_wnd));
#if TCP_WND_DEBUG
    } else {
      if (pcb->snd_wnd != tcphdr->wnd) {
        LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %lu snd_max %lu ackno %lu wl1 %lu seqno %lu wl2 %lu\n",
                               pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
      }
#endif /* TCP_WND_DEBUG */
    }


    if (pcb->lastack == ackno) {
      pcb->acked = 0;

      if (pcb->snd_wl1 + pcb->snd_wnd == right_wnd_edge){
  ++pcb->dupacks;
  if (pcb->dupacks >= 3 && pcb->unacked != NULL) {
    if (!(pcb->flags & TF_INFR)) {
      /* This is fast retransmit. Retransmit the first unacked segment. */
      LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %u (%lu), fast retransmit %lu\n",
          (unsigned int)pcb->dupacks, pcb->lastack,
          ntohl(pcb->unacked->tcphdr->seqno)));
      tcp_rexmit(pcb);
      /* Set ssthresh to max (FlightSize / 2, 2*SMSS) */
      pcb->ssthresh = LWIP_MAX((pcb->snd_max -
          pcb->lastack) / 2,
         2 * pcb->mss);

      pcb->cwnd = pcb->ssthresh + 3 * pcb->mss;
      pcb->flags |= TF_INFR;
    } else {
      /* Inflate the congestion window, but not if it means that
         the value overflows. */
      if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
        pcb->cwnd += pcb->mss;
      }
    }
  }
      } else {
  LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n",
            pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge));
      }
    } else if (TCP_SEQ_LT(pcb->lastack, ackno) &&
              TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
      /* We come here when the ACK acknowledges new data. */

      /* Reset the "IN Fast Retransmit" flag, since we are no longer
         in fast retransmit. Also reset the congestion window to the
         slow start threshold. */
      if (pcb->flags & TF_INFR) {
  pcb->flags &= ~TF_INFR;
  pcb->cwnd = pcb->ssthresh;
      }

      /* Reset the number of retransmissions. */
      pcb->nrtx = 0;

      /* Reset the retransmission time-out. */
      pcb->rto = (pcb->sa >> 3) + pcb->sv;

      /* Update the send buffer space. */
      pcb->acked = ackno - pcb->lastack;
      pcb->snd_buf += pcb->acked;

      /* Reset the fast retransmit variables. */
      pcb->dupacks = 0;
      pcb->lastack = ackno;

      /* Update the congestion control variables (cwnd and
         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 %u\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 %u\n", pcb->cwnd));
        }
      }
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %lu, unacked->seqno %lu:%lu\n",
                               ackno,
                               pcb->unacked != NULL?
                               ntohl(pcb->unacked->tcphdr->seqno): 0,
                               pcb->unacked != NULL?
                               ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));

      /* Remove segment from the unacknowledged list if the incoming
   ACK acknowlegdes them. */
      while (pcb->unacked != NULL &&
      TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
      TCP_TCPLEN(pcb->unacked), ackno)) {
  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n",
         ntohl(pcb->unacked->tcphdr->seqno),
         ntohl(pcb->unacked->tcphdr->seqno) +
         TCP_TCPLEN(pcb->unacked)));

  next = pcb->unacked;
  pcb->unacked = pcb->unacked->next;

  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));
  pcb->snd_queuelen -= pbuf_clen(next->p);
  tcp_seg_free(next);

  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unacked)\n", (unsigned int)pcb->snd_queuelen));
  if (pcb->snd_queuelen != 0) {
    LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
     pcb->unsent != NULL);
  }
      }
      pcb->polltmr = 0;
    }

      /* We go through the ->unsent list to see if any of the segments
         on the list are acknowledged by the ACK. This may seem
         strange since an "unsent" segment shouldn't be acked. The
         rationale is that lwIP puts all outstanding segments on the
         ->unsent list after a retransmission, so these segments may
         in fact have been sent once. */
      while (pcb->unsent != NULL &&
      TCP_SEQ_LEQ(ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent),
                        ackno) &&
      TCP_SEQ_LEQ(ackno, pcb->snd_max)) {
  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n",
         ntohl(pcb->unsent->tcphdr->seqno),
         ntohl(pcb->unsent->tcphdr->seqno) +
         TCP_TCPLEN(pcb->unsent)));

  next = pcb->unsent;
  pcb->unsent = pcb->unsent->next;
  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen));
  pcb->snd_queuelen -= pbuf_clen(next->p);
  tcp_seg_free(next);
  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unsent)\n", (unsigned int)pcb->snd_queuelen));
  if (pcb->snd_queuelen != 0) {
    LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
     pcb->unsent != NULL);
  }

        if (pcb->unsent != NULL) {
          pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
        }
      }

    /* End of ACK for new data processing. */

    LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %u rtseq %lu ackno %lu\n",
     pcb->rttest, pcb->rtseq, ackno));

    /* RTT estimation calculations. This is done by checking if the
       incoming segment acknowledges the segment we use to take a
       round-trip time measurement. */
    if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
      m = tcp_ticks - pcb->rttest;

      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %u ticks (%u msec).\n",
       m, m * TCP_SLOW_INTERVAL));

      /* This is taken directly from VJs original code in his paper */
      m = m - (pcb->sa >> 3);
      pcb->sa += m;
      if (m < 0) {
  m = -m;
      }
      m = m - (pcb->sv >> 2);
      pcb->sv += m;
      pcb->rto = (pcb->sa >> 3) + pcb->sv;

      LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %u (%u miliseconds)\n",
           pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));

      pcb->rttest = 0;
    }
  }

  /* If the incoming segment contains data, we must process it
     further. */
  if (tcplen > 0) {
    /* This code basically does three things:

     +) If the incoming segment contains data that is the next
        in-sequence data, this data is passed to the application. This
        might involve trimming the first edge of the data. The rcv_nxt
        variable and the advertised window are adjusted.

     +) If the incoming segment has data that is above the next
        sequence number expected (->rcv_nxt), the segment is placed on
        the ->ooseq queue. This is done by finding the appropriate
        place in the ->ooseq queue (which is ordered by sequence
        number) and trim the segment in both ends if needed. An
        immediate ACK is sent to indicate that we received an
        out-of-sequence segment.

     +) Finally, we check if the first segment on the ->ooseq queue
        now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If
        rcv_nxt > ooseq->seqno, we must trim the first edge of the
        segment on ->ooseq before we adjust rcv_nxt. The data in the
        segments that are now on sequence are chained onto the
        incoming segment so that we only need to call the application
        once.
    */

    /* First, we check if we must trim the first edge. We have to do
       this if the sequence number of the incoming segment is less
       than rcv_nxt, and the sequence number plus the length of the
       segment is larger than rcv_nxt. */
    if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
      if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {
  /* Trimming the first edge is done by pushing the payload
     pointer in the pbuf downwards. This is somewhat tricky since
     we do not want to discard the full contents of the pbuf up to
     the new starting point of the data since we have to keep the
     TCP header which is present in the first pbuf in the chain.

     What is done is really quite a nasty hack: the first pbuf in
     the pbuf chain is pointed to by inseg.p. Since we need to be
     able to deallocate the whole pbuf, we cannot change this
     inseg.p pointer to point to any of the later pbufs in the
     chain. Instead, we point the ->payload pointer in the first
     pbuf to data in one of the later pbufs. We also set the
     inseg.data pointer to point to the right place. This way, the
     ->p pointer will still point to the first pbuf, but the
     ->p->payload pointer will point to data in another pbuf.

     After we are done with adjusting the pbuf pointers we must
     adjust the ->data pointer in the seg and the segment
     length.*/
  off = pcb->rcv_nxt - seqno;
  if (inseg.p->len < off) {
    p = inseg.p;
    while (p->len < off) {
      off -= p->len;
      inseg.p->tot_len -= p->len;
      p->len = 0;
      p = p->next;
    }
    pbuf_header(p, -off);
  } else {
    pbuf_header(inseg.p, -off);
  }
  inseg.dataptr = inseg.p->payload;
  inseg.len -= pcb->rcv_nxt - seqno;
  inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
      }
      else{
  /* the whole segment is < rcv_nxt */
  /* must be a duplicate of a packet that has already been correctly handled */

  LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno));
  tcp_ack_now(pcb);
      }
    }

    /* The sequence number must be within the window (above rcv_nxt
       and below rcv_nxt + rcv_wnd) in order to be further
       processed. */
    if (TCP_SEQ_GEQ(seqno, pcb->rcv_nxt) &&
       TCP_SEQ_LT(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
      if (pcb->rcv_nxt == seqno) {
  /* The incoming segment is the next in sequence. We check if
           we have to trim the end of the segment and update rcv_nxt
           and pass the data to the application. */
#if TCP_QUEUE_OOSEQ
  if (pcb->ooseq != NULL &&
     TCP_SEQ_LEQ(pcb->ooseq->tcphdr->seqno, seqno + inseg.len)) {
    /* We have to trim the second edge of the incoming
             segment. */
    inseg.len = pcb->ooseq->tcphdr->seqno - seqno;
    pbuf_realloc(inseg.p, inseg.len);
  }
#endif /* TCP_QUEUE_OOSEQ */

  tcplen = TCP_TCPLEN(&inseg);

  pcb->rcv_nxt += tcplen;

  /* Update the receiver's (our) window. */
  if (pcb->rcv_wnd < tcplen) {
    pcb->rcv_wnd = 0;
  } else {
    pcb->rcv_wnd -= tcplen;
  }

  /* If there is data in the segment, we make preparations to
     pass this up to the application. The ->recv_data variable
     is used for holding the pbuf that goes to the
     application. The code for reassembling out-of-sequence data
     chains its data on this pbuf as well.

     If the segment was a FIN, we set the TF_GOT_FIN flag that will
     be used to indicate to the application that the remote side has
     closed its end of the connection. */
  if (inseg.p->tot_len > 0) {
    recv_data = inseg.p;
    /* Since this pbuf now is the responsibility of the
       application, we delete our reference to it so that we won't
       (mistakingly) deallocate it. */
    inseg.p = NULL;
  }
  if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
    LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
    recv_flags = TF_GOT_FIN;
  }

#if TCP_QUEUE_OOSEQ
  /* We now check if we have segments on the ->ooseq queue that
           is now in sequence. */
  while (pcb->ooseq != NULL &&
        pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {

    cseg = pcb->ooseq;
    seqno = pcb->ooseq->tcphdr->seqno;

    pcb->rcv_nxt += TCP_TCPLEN(cseg);
    if (pcb->rcv_wnd < TCP_TCPLEN(cseg)) {
      pcb->rcv_wnd = 0;
    } else {
      pcb->rcv_wnd -= TCP_TCPLEN(cseg);
    }
    if (cseg->p->tot_len > 0) {
      /* Chain this pbuf onto the pbuf that we will pass to
         the application. */
      if (recv_data) {
              pbuf_cat(recv_data, cseg->p);
            } else {
        recv_data = cseg->p;
      }
      cseg->p = NULL;
    }
    if (flags & TCP_FIN) {
      LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
      recv_flags = TF_GOT_FIN;
    }


    pcb->ooseq = cseg->next;
    tcp_seg_free(cseg);
  }
#endif /* TCP_QUEUE_OOSEQ */


  /* Acknowledge the segment(s). */
  tcp_ack(pcb);

      } else {
  /* We get here if the incoming segment is out-of-sequence. */
  tcp_ack_now(pcb);
#if TCP_QUEUE_OOSEQ
  /* We queue the segment on the ->ooseq queue. */
  if (pcb->ooseq == NULL) {
    pcb->ooseq = tcp_seg_copy(&inseg);
  } else {
    /* If the queue is not empty, we walk through the queue and
    try to find a place where the sequence number of the
    incoming segment is between the sequence numbers of the
    previous and the next segment on the ->ooseq queue. That is
    the place where we put the incoming segment. If needed, we
    trim the second edges of the previous and the incoming
    segment so that it will fit into the sequence.

    If the incoming segment has the same sequence number as a
    segment on the ->ooseq queue, we discard the segment that
    contains less data. */

    prev = NULL;
    for(next = pcb->ooseq; next != NULL; next = next->next) {
      if (seqno == next->tcphdr->seqno) {
        /* The sequence number of the incoming segment is the
                 same as the sequence number of the segment on
                 ->ooseq. We check the lengths to see which one to
                 discard. */
        if (inseg.len > next->len) {
    /* The incoming segment is larger than the old
                   segment. We replace the old segment with the new
                   one. */
    cseg = tcp_seg_copy(&inseg);
    if (cseg != NULL) {
      cseg->next = next->next;
      if (prev != NULL) {
        prev->next = cseg;
      } else {
        pcb->ooseq = cseg;
      }
    }
    break;
        } else {
    /* Either the lenghts are the same or the incoming
                   segment was smaller than the old one; in either
                   case, we ditch the incoming segment. */
    break;
        }
      } else {
        if (prev == NULL) {
    if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
      /* The sequence number of the incoming segment is lower
         than the sequence number of the first segment on the
         queue. We put the incoming segment first on the
         queue. */

      if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
        /* We need to trim the incoming segment. */
        inseg.len = next->tcphdr->seqno - seqno;
        pbuf_realloc(inseg.p, inseg.len);
      }
      cseg = tcp_seg_copy(&inseg);
      if (cseg != NULL) {
        cseg->next = next;
        pcb->ooseq = cseg;
      }
      break;
    }
        } else if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) &&
     TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
    /* The sequence number of the incoming segment is in
                   between the sequence numbers of the previous and
                   the next segment on ->ooseq. We trim and insert the
                   incoming segment and trim the previous segment, if
                   needed. */
    if (TCP_SEQ_GT(seqno + inseg.len, next->tcphdr->seqno)) {
      /* We need to trim the incoming segment. */
      inseg.len = next->tcphdr->seqno - seqno;
      pbuf_realloc(inseg.p, inseg.len);
    }

    cseg = tcp_seg_copy(&inseg);
    if (cseg != NULL) {
      cseg->next = next;
      prev->next = cseg;
      if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
        /* We need to trim the prev segment. */
        prev->len = seqno - prev->tcphdr->seqno;
        pbuf_realloc(prev->p, prev->len);
      }
    }
    break;
    }
        /* If the "next" segment is the last segment on the
                 ooseq queue, we add the incoming segment to the end
                 of the list. */
        if (next->next == NULL &&
     TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
    next->next = tcp_seg_copy(&inseg);
    if (next->next != NULL) {
      if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
        /* We need to trim the last segment. */
        next->len = seqno - next->tcphdr->seqno;
        pbuf_realloc(next->p, next->len);
      }
    }
    break;
        }
      }
      prev = next;
    }
  }
#endif /* TCP_QUEUE_OOSEQ */

      }
    }
  } else {
    /* Segments with length 0 is taken care of here. Segments that
       fall out of the window are ACKed. */
    if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
       TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
      tcp_ack_now(pcb);
    }
  }
}

/*
 * tcp_parseopt:
 *
 * Parses the options contained in the incoming segment. (Code taken
 * from uIP with only small changes.)
 *
 */

static void
tcp_parseopt(struct tcp_pcb *pcb)
{
  u8_t c;
  u8_t *opts, opt;
  u16_t mss;

  opts = (u8_t *)tcphdr + TCP_HLEN;

  /* Parse the TCP MSS option, if present. */
  if(TCPH_HDRLEN(tcphdr) > 0x5) {
    for(c = 0; c < (TCPH_HDRLEN(tcphdr) - 5) << 2 ;) {
      opt = opts[c];
      if (opt == 0x00) {
        /* End of options. */
  break;
      } else if (opt == 0x01) {
        ++c;
        /* NOP option. */
      } else if (opt == 0x02 &&
                opts[c + 1] == 0x04) {
        /* An MSS option with the right option length. */
        mss = (opts[c + 2] << 8) | opts[c + 3];
        pcb->mss = mss > TCP_MSS? TCP_MSS: mss;

        /* And we are done processing options. */
        break;
      } else {
  if (opts[c + 1] == 0) {
          /* If the length field is zero, the options are malformed
             and we don't process them further. */
          break;
        }
        /* All other options have a length field, so that we easily
           can skip past them. */
        c += opts[c + 1];
      }
    }
  }
}
#endif /* LWIP_TCP */


