亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? tcp_in.c

?? ARM7的一些試驗程序
?? C
?? 第 1 頁 / 共 3 頁
字號:
/**
 * @file
 *
 * Transmission Control Protocol, incoming traffic
 *
 * The input processing functions of TCP.
 *
 * These functions are generally called in the order (ip_input() ->) tcp_input() ->
 * tcp_process() -> tcp_receive() (-> application).
 * 
 */

/*
 * Copyright (c) 2001-2004 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>
 *
 */

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

#include "lwip/ip_addr.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;

#if 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) ||
      ip_addr_ismulticast(&(iphdr->dest))) {
    pbuf_free(p);
    return;
  }

#if CHECKSUM_CHECK_TCP
  /* 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;
  }
#endif

  /* 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;

#if 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))) {

#if 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.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.listen_pcbs;
          /* put this listening pcb at the head of the listening list */
    tcp_listen_pcbs.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. */
    if (inseg.p != NULL) pbuf_free(inseg.p);
#if TCP_INPUT_DEBUG
#if TCP_DEBUG
    tcp_debug_print_state(pcb->state);
#endif /* TCP_DEBUG */
#endif /* TCP_INPUT_DEBUG */
#if 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 {
#if 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);
  }
#if 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. */

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产经典欧美精品| 国产精品18久久久久久vr| 成人性生交大片免费看视频在线| 欧美日韩黄色一区二区| 国产精品―色哟哟| 韩国成人在线视频| 欧美日韩一区高清| 亚洲天堂精品在线观看| 国产一区二区三区视频在线播放| 欧美三级午夜理伦三级中视频| 中文字幕一区在线观看| 美日韩黄色大片| 欧美午夜精品一区二区蜜桃| 国产精品久久久久9999吃药| 国产成人丝袜美腿| 精品福利二区三区| 青青草精品视频| 久久精品国产久精国产爱| 精油按摩中文字幕久久| 欧美日韩国产高清一区二区三区 | 日韩三级在线观看| 一区二区三区在线视频观看| 成人免费视频一区二区| 国产亚洲短视频| 韩国av一区二区三区四区| 91精品国产91久久久久久最新毛片 | 欧美三级电影网站| 亚洲日本免费电影| 成人午夜大片免费观看| 久久精品人人做人人综合| 经典三级一区二区| 日韩美一区二区三区| 麻豆专区一区二区三区四区五区| 在线欧美日韩国产| 一区二区三区自拍| 色婷婷激情综合| 亚洲欧美日韩中文播放| 99re热视频这里只精品| 国产精品福利影院| 99精品欧美一区二区三区综合在线| 亚洲国产精品黑人久久久| 成人一道本在线| 国产精品女人毛片| 成+人+亚洲+综合天堂| 国产精品久久久久久久岛一牛影视| 国产69精品久久777的优势| 国产精品午夜在线观看| 成人激情动漫在线观看| 成人欧美一区二区三区在线播放| 成+人+亚洲+综合天堂| 中文字幕一区二区三区在线观看| 99re热这里只有精品免费视频 | 欧美成人精品二区三区99精品| 另类中文字幕网| 26uuu精品一区二区在线观看| 韩国精品免费视频| 日本一区二区综合亚洲| 成人av第一页| 亚洲自拍偷拍九九九| 欧美久久高跟鞋激| 精品一区二区在线免费观看| 国产亚洲自拍一区| 91浏览器在线视频| 亚洲午夜精品久久久久久久久| 制服丝袜亚洲色图| 国产乱国产乱300精品| 中文字幕av一区 二区| 一本大道av一区二区在线播放| 亚洲h在线观看| 日韩精品一区二区三区在线观看 | 中文字幕日韩av资源站| 99re66热这里只有精品3直播| 夜夜精品浪潮av一区二区三区| 69成人精品免费视频| 国产美女av一区二区三区| 日韩美女精品在线| 欧美日韩一区精品| 国产又黄又大久久| 亚洲人快播电影网| 9191精品国产综合久久久久久| 国产原创一区二区| 亚洲美女在线国产| 日韩欧美区一区二| 91在线观看地址| 日本色综合中文字幕| 国产精品天干天干在线综合| 欧美日韩在线一区二区| 国产最新精品免费| 一区二区三区不卡视频在线观看| 欧美一区二区成人| jiyouzz国产精品久久| 午夜精品久久久久久不卡8050| 2023国产精品视频| 91久久精品网| 国产九色精品成人porny| 一区二区三区.www| 久久伊人蜜桃av一区二区| 91麻豆swag| 国产一区二区三区国产| 亚洲一区日韩精品中文字幕| 国产亚洲成av人在线观看导航 | 成人av在线影院| 视频一区在线视频| 国产精品人成在线观看免费| 欧美日韩精品一区二区三区蜜桃| 国产精一品亚洲二区在线视频| 亚洲一区在线观看免费| 国产精品网站一区| 日韩免费看网站| 精品视频在线看| 成人精品一区二区三区四区| 日本女优在线视频一区二区| 亚洲精品高清视频在线观看| 久久亚洲一级片| 91精品国产手机| 91免费在线看| 国产伦精品一区二区三区视频青涩| 亚洲国产视频一区| 国产精品成人免费| 精品成人一区二区三区四区| 精品视频在线免费看| 91在线丨porny丨国产| 国产精品亚洲成人| 青草av.久久免费一区| 亚洲一区在线观看网站| 国产精品久久久久久久岛一牛影视 | 在线视频综合导航| 成人黄色国产精品网站大全在线免费观看| 欧美aaaaaa午夜精品| 亚洲综合精品久久| 亚洲人成亚洲人成在线观看图片 | 国产网站一区二区三区| 久久99国产精品久久99| 午夜精品久久久久久不卡8050| 亚洲美女屁股眼交3| 国产精品午夜久久| 国产网站一区二区| 久久久亚洲午夜电影| 欧美岛国在线观看| 在线播放视频一区| 欧美日韩午夜在线视频| 色噜噜狠狠成人网p站| 91在线观看免费视频| av在线不卡网| gogogo免费视频观看亚洲一| 国产成人aaa| 懂色av一区二区夜夜嗨| 国产乱人伦精品一区二区在线观看| 久久国产精品免费| 美女网站在线免费欧美精品| 日本强好片久久久久久aaa| 婷婷开心久久网| 无码av中文一区二区三区桃花岛| 亚洲高清中文字幕| 亚洲777理论| 丝袜美腿亚洲一区二区图片| 午夜久久久久久久久| 亚洲va欧美va人人爽午夜| 婷婷中文字幕综合| 日日夜夜精品视频天天综合网| 日韩va欧美va亚洲va久久| 免费精品视频在线| 激情欧美一区二区三区在线观看| 久久99久久久久| 免费黄网站欧美| 国产在线播放一区| 国产91丝袜在线播放| 丰满放荡岳乱妇91ww| 91麻豆精品秘密| 欧美日韩免费电影| 欧美日韩亚洲另类| 日韩亚洲欧美成人一区| 久久久久亚洲综合| 国产精品美日韩| 伊人婷婷欧美激情| 婷婷成人激情在线网| 狠狠狠色丁香婷婷综合激情 | 一区二区三区不卡视频| 亚洲成av人综合在线观看| 三级久久三级久久久| 精品中文字幕一区二区小辣椒| 国产一区二区精品久久| heyzo一本久久综合| 欧美色国产精品| 亚洲精品一区二区三区香蕉 | 91精品麻豆日日躁夜夜躁| 欧美成人一区二区三区片免费| 国产亚洲欧美在线| 日韩美女啊v在线免费观看| 夜夜精品浪潮av一区二区三区| 日本美女视频一区二区| 国产a视频精品免费观看| 91久久免费观看| 欧美不卡一区二区| 国产精品久久久久影视| 天堂一区二区在线免费观看| 国产精品一区二区视频| 欧美亚洲一区二区在线观看| 精品国产伦一区二区三区观看方式| 欧美国产激情二区三区|