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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tcp_out.c

?? stm32+ucos-ii
?? C
?? 第 1 頁 / 共 3 頁
字號:

  /* Now that the data to be enqueued has been broken up into TCP
  segments in the queue variable, we add them to the end of the
  pcb->unsent queue. */
  if (pcb->unsent == NULL) {
    useg = NULL;
  }
  else {
    for (useg = pcb->unsent; useg->next != NULL; useg = useg->next);
  }
  /* { useg is last segment on the unsent queue, NULL if list is empty } */

  /* If there is room in the last pbuf on the unsent queue,
  chain the first pbuf on the queue together with that. */
  if (useg != NULL &&
    TCP_TCPLEN(useg) != 0 &&
    !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) &&
    !(flags & (TCP_SYN | TCP_FIN)) &&
    /* fit within max seg size */
    (useg->len + queue->len <= pcb->mss) &&
    /* only concatenate segments with the same options */
    (useg->flags == queue->flags)) {
    /* Remove TCP header from first segment of our to-be-queued list */
    if(pbuf_header(queue->p, -(TCP_HLEN + optlen))) {
      /* Can we cope with this failing?  Just assert for now */
      LWIP_ASSERT("pbuf_header failed\n", 0);
      TCP_STATS_INC(tcp.err);
      goto memerr;
    }
    if (queue->p->len == 0) {
      /* free the first (header-only) pbuf if it is now empty (contained only headers) */
      struct pbuf *old_q = queue->p;
      queue->p = queue->p->next;
      old_q->next = NULL;
      queuelen--;
      pbuf_free(old_q);
    }
    LWIP_ASSERT("zero-length pbuf", (queue->p != NULL) && (queue->p->len > 0));
    pbuf_cat(useg->p, queue->p);
    useg->len += queue->len;
    useg->next = queue->next;

    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len));
    if (seg == queue) {
      seg = useg;
      seglen = useg->len;
    }
    memp_free(MEMP_TCP_SEG, queue);
  }
  else {
    /* empty list */
    if (useg == NULL) {
      /* initialize list with this segment */
      pcb->unsent = queue;
    }
    /* enqueue segment */
    else {
      useg->next = queue;
    }
  }
  if ((flags & TCP_SYN) || (flags & TCP_FIN)) {
    ++len;
  }
  if (flags & TCP_FIN) {
    pcb->flags |= TF_FIN;
  }
  pcb->snd_lbb += len;

  pcb->snd_buf -= len;

  /* update number of segments on the queues */
  pcb->snd_queuelen = queuelen;
  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen));
  if (pcb->snd_queuelen != 0) {
    LWIP_ASSERT("tcp_enqueue: valid queue length",
      pcb->unacked != NULL || pcb->unsent != NULL);
  }

  /* Set the PSH flag in the last segment that we enqueued, but only
  if the segment has data (indicated by seglen > 0). */
  if (seg != NULL && seglen > 0 && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) {
    TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
  }

  return ERR_OK;
memerr:
  pcb->flags |= TF_NAGLEMEMERR;
  TCP_STATS_INC(tcp.memerr);

  if (queue != NULL) {
    tcp_segs_free(queue);
  }
  if (pcb->snd_queuelen != 0) {
    LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL ||
      pcb->unsent != NULL);
  }
  LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
  return ERR_MEM;
}


#if LWIP_TCP_TIMESTAMPS
/* Build a timestamp option (12 bytes long) at the specified options pointer)
 *
 * @param pcb tcp_pcb
 * @param opts option pointer where to store the timestamp option
 */
static void
tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts)
{
  /* Pad with two NOP options to make everything nicely aligned */
  opts[0] = htonl(0x0101080A);
  opts[1] = htonl(sys_now());
  opts[2] = htonl(pcb->ts_recent);
}
#endif


/**
 * Find out what we can send and send it
 *
 * @param pcb Protocol control block for the TCP connection to send data
 * @return ERR_OK if data has been sent or nothing to send
 *         another err_t on error
 */
err_t
tcp_output(struct tcp_pcb *pcb)
{
  struct pbuf *p;
  struct tcp_hdr *tcphdr;
  struct tcp_seg *seg, *useg;
  u32_t wnd, snd_nxt;
#if TCP_CWND_DEBUG
  s16_t i = 0;
#endif /* TCP_CWND_DEBUG */
  u8_t optlen = 0;

  /* First, check if we are invoked by the TCP input processing
     code. If so, we do not output anything. Instead, we rely on the
     input processing code to call us when input processing is done
     with. */
  if (tcp_input_pcb == pcb) {
    return ERR_OK;
  }

  wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd);

  seg = pcb->unsent;

  /* useg should point to last segment on unacked queue */
  useg = pcb->unacked;
  if (useg != NULL) {
    for (; useg->next != NULL; useg = useg->next);
  }

  /* If the TF_ACK_NOW flag is set and no data will be sent (either
   * because the ->unsent queue is empty or because the window does
   * not allow it), construct an empty ACK segment and send it.
   *
   * If data is to be sent, we will just piggyback the ACK (see below).
   */
  if (pcb->flags & TF_ACK_NOW &&
     (seg == NULL ||
      ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) {
#if LWIP_TCP_TIMESTAMPS
    if (pcb->flags & TF_TIMESTAMP)
      optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS);
#endif
    p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_RAM);
    if (p == NULL) {
      LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n"));
      return ERR_BUF;
    }
    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, 
                ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt));
    /* remove ACK flags from the PCB, as we send an empty ACK now */
    pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);

    tcphdr = tcp_output_set_header(pcb, p, optlen, htonl(pcb->snd_nxt));

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

#if CHECKSUM_GEN_TCP
    tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
          IP_PROTO_TCP, p->tot_len);
#endif
#if LWIP_NETIF_HWADDRHINT
    ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
        IP_PROTO_TCP, &(pcb->addr_hint));
#else /* LWIP_NETIF_HWADDRHINT*/
    ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
        IP_PROTO_TCP);
#endif /* LWIP_NETIF_HWADDRHINT*/
    pbuf_free(p);

    return ERR_OK;
  }

#if TCP_OUTPUT_DEBUG
  if (seg == NULL) {
    LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n",
                                   (void*)pcb->unsent));
  }
#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,
                 ntohl(seg->tcphdr->seqno), pcb->lastack));
  }
#endif /* TCP_CWND_DEBUG */
  /* data available and window allows it to be sent? */
  while (seg != NULL &&
         ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
    LWIP_ASSERT("RST not expected here!", 
                (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
    /* Stop sending if the nagle algorithm would prevent it
     * Don't stop:
     * - if tcp_enqueue had a memory error before (prevent delayed ACK timeout) or
     * - if FIN was already enqueued for this PCB (SYN is always alone in a segment -
     *   either seg->next != NULL or pcb->unacked == NULL;
     *   RST is no sent using tcp_enqueue/tcp_output.
     */
    if((tcp_do_output_nagle(pcb) == 0) &&
      ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){
      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,
                            ntohl(seg->tcphdr->seqno), pcb->lastack, i));
    ++i;
#endif /* TCP_CWND_DEBUG */

    pcb->unsent = seg->next;

    if (pcb->state != SYN_SENT) {
      TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
      pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
    }

    tcp_output_segment(seg, pcb);
    snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg);
    if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
      pcb->snd_nxt = snd_nxt;
    }
    /* put segment on unacknowledged list if length > 0 */
    if (TCP_TCPLEN(seg) > 0) {
      seg->next = NULL;
      /* unacked list is empty? */
      if (pcb->unacked == NULL) {
        pcb->unacked = seg;
        useg = seg;
      /* unacked list is not empty? */
      } else {
        /* In the case of fast retransmit, the packet should not go to the tail
         * of the unacked queue, but rather somewhere before it. We need to check for
         * this case. -STJ Jul 27, 2004 */
        if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){
          /* add segment to before tail of unacked list, keeping the list sorted */
          struct tcp_seg **cur_seg = &(pcb->unacked);
          while (*cur_seg &&
            TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) {
              cur_seg = &((*cur_seg)->next );
          }
          seg->next = (*cur_seg);
          (*cur_seg) = seg;
        } else {
          /* add segment to tail of unacked list */
          useg->next = seg;
          useg = useg->next;
        }
      }
    /* do not queue empty segments on the unacked list */
    } else {
      tcp_seg_free(seg);
    }
    seg = pcb->unsent;
  }

  if (seg != NULL && pcb->persist_backoff == 0 && 
      ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) {
    /* prepare for persist timer */
    pcb->persist_cnt = 0;
    pcb->persist_backoff = 1;
  }

  pcb->flags &= ~TF_NAGLEMEMERR;
  return ERR_OK;
}

/**
 * Called by tcp_output() to actually send a TCP segment over IP.
 *
 * @param seg the tcp_seg to send
 * @param pcb the tcp_pcb for the TCP connection used to send the segment
 */
static void
tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
{
  u16_t len;
  struct netif *netif;
  u32_t *opts;

  /** @bug Exclude retransmitted segments from this count. */
  snmp_inc_tcpoutsegs();

  /* The TCP header has already been constructed, but the ackno and
   wnd fields remain. */
  seg->tcphdr->ackno = htonl(pcb->rcv_nxt);

  /* advertise our receive window size in this TCP segment */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲少妇最新在线视频| www.欧美色图| 99久久精品国产精品久久| 精品视频一区 二区 三区| 久久综合给合久久狠狠狠97色69| 亚洲人吸女人奶水| 国产综合久久久久久久久久久久| 欧美在线看片a免费观看| a4yy欧美一区二区三区| xfplay精品久久| 视频一区国产视频| 99re成人在线| 国产色产综合产在线视频| 日本在线播放一区二区三区| 色婷婷av一区二区三区软件| 亚洲国产精品av| 国产在线日韩欧美| 日韩欧美一区在线观看| 亚洲一二三区不卡| 日本乱码高清不卡字幕| 国产精品卡一卡二| 成年人网站91| 国产精品亲子乱子伦xxxx裸| 狠狠色综合播放一区二区| 欧美一级二级三级蜜桃| 视频在线观看91| 欧美日韩成人在线| 亚洲福利视频三区| 欧美精品乱码久久久久久按摩 | 一区二区三区高清不卡| 99在线精品视频| 国产精品美女久久久久久| 国产福利电影一区二区三区| 亚洲精品一区二区在线观看| 青青草国产精品97视觉盛宴| 91精品国产美女浴室洗澡无遮挡| 亚洲一区二区四区蜜桃| 在线观看日韩毛片| 丝袜诱惑亚洲看片| 日韩一区二区三区在线| 久久精品国产精品亚洲精品| 日韩欧美国产系列| 国产成人丝袜美腿| 亚洲视频免费观看| 欧美日本国产一区| 极品美女销魂一区二区三区| 久久久不卡影院| 99久久久久久99| 亚洲国产欧美日韩另类综合| 欧美丰满美乳xxx高潮www| 奇米影视7777精品一区二区| 精品国产区一区| 成人免费av网站| 亚洲精品日韩一| 日韩三级伦理片妻子的秘密按摩| 经典三级一区二区| 亚洲嫩草精品久久| 欧美一卡2卡三卡4卡5免费| 精品在线免费视频| 亚洲手机成人高清视频| 欧美人与禽zozo性伦| 国产一区在线视频| 亚洲精品乱码久久久久久日本蜜臀| 精品视频一区三区九区| 国内成人自拍视频| 亚洲伊人色欲综合网| 精品日韩一区二区三区| 91在线一区二区三区| 首页国产欧美日韩丝袜| 日本一区二区视频在线| 欧美日韩国产精选| av电影在线观看不卡 | 亚洲青青青在线视频| 91精品国产aⅴ一区二区| 成人综合在线观看| 捆绑紧缚一区二区三区视频| 中文字幕欧美国产| 欧美一区二区精品| 91福利社在线观看| 国产成人av自拍| 日韩av中文在线观看| 亚洲欧洲成人自拍| 久久精品亚洲精品国产欧美| 欧美精品久久天天躁| 99re热视频精品| 粉嫩av亚洲一区二区图片| 青娱乐精品在线视频| 亚洲美女偷拍久久| 中文无字幕一区二区三区| 91精品国产乱| 欧美日韩日日夜夜| 色94色欧美sute亚洲线路二| 国产福利精品一区| 国产精品正在播放| 蜜臀91精品一区二区三区| 亚洲电影视频在线| 亚洲综合丁香婷婷六月香| 国产精品水嫩水嫩| 国产欧美日韩一区二区三区在线观看| 欧美一区二区三区不卡| 欧美日韩亚洲不卡| 欧美性高清videossexo| 99在线精品一区二区三区| 成人综合婷婷国产精品久久蜜臀| 激情文学综合插| 免费在线欧美视频| 日精品一区二区| 亚洲在线视频免费观看| 亚洲欧美另类久久久精品2019| 欧美国产综合一区二区| 亚洲国产成人在线| 国产精品久久久久久久蜜臀| 国产欧美日韩在线看| 久久久一区二区三区| 精品国产一区二区精华| 欧美精品一区二区三区一线天视频| 日韩一区二区三区三四区视频在线观看| 欧美伊人久久久久久久久影院| 91免费看`日韩一区二区| 97久久人人超碰| 色琪琪一区二区三区亚洲区| 91成人在线精品| 欧美亚洲国产一区在线观看网站 | 亚洲三级免费电影| 亚洲色欲色欲www| 亚洲综合激情另类小说区| 亚洲va天堂va国产va久| 婷婷中文字幕综合| 捆绑变态av一区二区三区| 国产黄色精品网站| caoporen国产精品视频| 色狠狠av一区二区三区| 欧美日韩午夜在线| 精品国产凹凸成av人导航| 中文字幕不卡三区| 亚洲精品成人a在线观看| 日韩成人一级片| 国产精品一区在线| 99在线视频精品| 制服丝袜日韩国产| 国产色婷婷亚洲99精品小说| 亚洲欧美另类在线| 开心九九激情九九欧美日韩精美视频电影| 久久疯狂做爰流白浆xx| 97精品久久久午夜一区二区三区| 欧美私模裸体表演在线观看| 日韩精品一区二区三区视频| 中文字幕一区二区三区四区| 亚洲一区影音先锋| 激情综合色综合久久| 91看片淫黄大片一级| 日韩一级黄色片| 国产精品黄色在线观看| 爽好多水快深点欧美视频| 高清在线成人网| 欧美日韩一级黄| 国产精品无遮挡| 日韩和欧美一区二区| 成人激情免费视频| 日韩亚洲国产中文字幕欧美| 国产精品国产馆在线真实露脸 | 国产精品原创巨作av| 色猫猫国产区一区二在线视频| 日韩午夜精品视频| 亚洲精品综合在线| 国产九色sp调教91| 91精品国产免费| 一区二区三区在线播| 国产高清久久久久| 欧美一区二区视频在线观看2022| 中文字幕一区在线观看| 极品少妇xxxx偷拍精品少妇| 精品污污网站免费看| 亚洲欧美日韩国产另类专区| 国产剧情一区在线| 日韩欧美国产电影| 午夜精品久久久久久久99水蜜桃| a美女胸又www黄视频久久| 久久精品水蜜桃av综合天堂| 男男视频亚洲欧美| 这里只有精品电影| 亚洲电影一级片| 欧美性感一类影片在线播放| 亚洲日本丝袜连裤袜办公室| 国产iv一区二区三区| 精品国产一二三| 久久99国产精品久久99果冻传媒| 欧美中文一区二区三区| 亚洲精品你懂的| 色乱码一区二区三区88| 亚洲色欲色欲www| 色先锋资源久久综合| 专区另类欧美日韩| 成人av资源下载| 国产精品乱码人人做人人爱| 成人免费看的视频| 国产精品美女一区二区三区| 成人一区二区三区| 国产精品无遮挡| 91麻豆蜜桃一区二区三区|