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

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

?? tcp_in.c

?? 一個(gè)輕量tcpip協(xié)議在移植在ucOS2系統(tǒng)上運(yùn)行
?? C
?? 第 1 頁 / 共 3 頁
字號(hào):
          pcb->snd_nxt = htonl(pcb->unsent->tcphdr->seqno);
        }
      }
      
    /* End of ACK for new data processing. */
    
    DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %d 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;

      DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %d ticks (%d 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;
      
      DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %d (%d 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 */
	
	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) {
	  DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN."));
	  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_chain(recv_data, cseg->p);
	    } else {
	      recv_data = cseg->p;
	    }
	    cseg->p = NULL;
	  }
	  if(flags & TCP_FIN) {
	    DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN."));
	    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_OFFSET(tcphdr) & 0xf0) > 0x50) {
    for(c = 0; c < ((TCPH_OFFSET(tcphdr) >> 4) - 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 */
/*-----------------------------------------------------------------------------------*/
  

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲欧洲成人精品av97| 91欧美一区二区| 日韩视频一区二区三区在线播放 | 亚洲视频一二区| a级精品国产片在线观看| 中文字幕亚洲成人| 一本久道久久综合中文字幕| 一区二区三区小说| 欧美日韩免费观看一区三区| 丝袜美腿高跟呻吟高潮一区| 欧美一区二区三区在线| 精品一区二区av| 欧美高清在线精品一区| 色综合久久88色综合天天| 一区二区三区在线免费观看| 欧美高清激情brazzers| 蜜桃一区二区三区在线观看| 久久精品视频免费观看| 91在线码无精品| 天天综合天天综合色| 欧美videos中文字幕| 成人av片在线观看| 亚洲成人激情av| 精品日韩在线观看| 97超碰欧美中文字幕| 日韩和欧美一区二区| 国产日韩高清在线| 欧美在线高清视频| 国产真实乱对白精彩久久| 亚洲欧美激情视频在线观看一区二区三区| 欧美系列亚洲系列| 精品无人码麻豆乱码1区2区| 亚洲欧美自拍偷拍色图| 日韩一区二区精品葵司在线| 成人av一区二区三区| 婷婷久久综合九色综合伊人色| 久久夜色精品国产噜噜av| 色综合一个色综合亚洲| 韩国成人福利片在线播放| ...av二区三区久久精品| 日韩欧美精品三级| 91麻豆精品在线观看| 国内欧美视频一区二区| 一区二区免费在线播放| 久久精品视频一区二区三区| 91精品欧美一区二区三区综合在| av福利精品导航| 久久国产尿小便嘘嘘| 亚洲国产成人av| 中文字幕一区二区日韩精品绯色| 日韩免费一区二区三区在线播放| 91农村精品一区二区在线| 久久99精品久久久久久久久久久久| 亚洲综合一区在线| 国产精品嫩草影院av蜜臀| 日韩美女主播在线视频一区二区三区| 在线观看亚洲专区| av在线一区二区三区| 国产一区二区精品久久| 日本怡春院一区二区| 一区二区三区精品在线| 国产精品久久久久影院色老大| 欧美成人精品高清在线播放 | 高清不卡一二三区| 久久精品免费观看| 婷婷六月综合网| 亚洲国产va精品久久久不卡综合 | 欧美午夜精品理论片a级按摩| 风间由美一区二区三区在线观看| 久久国产精品99久久久久久老狼 | 久久99深爱久久99精品| 奇米影视7777精品一区二区| 亚洲成av人**亚洲成av**| 亚洲美女视频一区| 亚洲欧美日韩国产综合在线| 国产精品灌醉下药二区| 欧美国产精品v| 中文欧美字幕免费| 国产精品污污网站在线观看 | 一区二区三区四区不卡视频| 成人免费在线播放视频| 国产精品伦一区二区三级视频| 国产欧美日本一区二区三区| 国产日韩欧美综合在线| 国产欧美日韩中文久久| 国产精品久线观看视频| 亚洲三级小视频| 亚洲综合色视频| 视频在线观看一区二区三区| 日本亚洲三级在线| 理论电影国产精品| 国产一区二区三区电影在线观看| 国产一区二区精品在线观看| 成人一区二区在线观看| av在线不卡观看免费观看| 色偷偷成人一区二区三区91| 在线观看日韩一区| 91精品国产91久久综合桃花| 日韩天堂在线观看| 国产三区在线成人av| 国产精品久久久爽爽爽麻豆色哟哟| 亚洲四区在线观看| 亚洲国产一区二区a毛片| 日韩国产成人精品| 国产一区视频网站| 91网站最新网址| 欧美卡1卡2卡| 精品成人私密视频| 日韩理论片一区二区| 亚洲成人资源网| 国模一区二区三区白浆| 国产精品69久久久久水密桃| 色八戒一区二区三区| 日韩欧美成人午夜| 中文字幕一区二区三区在线不卡| 一区av在线播放| 国产在线播放一区| 色999日韩国产欧美一区二区| 日韩一区二区在线观看视频播放 | 亚洲欧美日韩在线不卡| 天堂久久久久va久久久久| 国产精品1区2区3区在线观看| 欧美一a一片一级一片| 久久综合九色综合97婷婷 | 欧美妇女性影城| 亚洲国产精品成人综合| 日韩在线观看一区二区| 国产精品99久久久| 欧美一区二区三区在线观看| 亚洲欧美综合另类在线卡通| 久久99深爱久久99精品| 欧美中文字幕一区| 国产日韩欧美高清在线| 日本人妖一区二区| 一本久道久久综合中文字幕| 26uuu亚洲综合色欧美| 亚洲h精品动漫在线观看| 成人av综合在线| 久久久美女艺术照精彩视频福利播放| 亚洲综合丁香婷婷六月香| 国产91丝袜在线18| 精品久久久久久久人人人人传媒| 亚洲精品成人在线| 国产91精品精华液一区二区三区| 51精品秘密在线观看| 亚洲男人的天堂在线观看| 国产成人亚洲精品狼色在线| 宅男噜噜噜66一区二区66| 亚洲欧洲韩国日本视频| 国产成人免费在线观看| 亚洲精品一线二线三线无人区| 视频在线观看一区| 欧美视频中文字幕| 尤物av一区二区| 91视频免费播放| 亚洲图片另类小说| www.视频一区| 国产精品欧美极品| 成人av资源站| 中文字幕日韩一区二区| 国产成人福利片| 久久在线观看免费| 国产在线麻豆精品观看| 精品国产污污免费网站入口| 蜜臀久久久久久久| 欧美一区二区三区小说| 免费成人在线视频观看| 91精品久久久久久蜜臀| 日韩不卡手机在线v区| 欧美精品视频www在线观看 | 精品欧美黑人一区二区三区| 免费成人av在线播放| 91精品国产91久久综合桃花| 青青草原综合久久大伊人精品优势| 欧美丰满嫩嫩电影| 蜜桃在线一区二区三区| 欧美大片在线观看一区二区| 精品一区二区在线免费观看| 精品国产电影一区二区| 国产美女视频91| 欧美国产日韩a欧美在线观看| 成人动漫av在线| 一区二区三区精品在线| 欧美日韩国产乱码电影| 免费av网站大全久久| 欧美mv日韩mv国产网站app| 国产自产v一区二区三区c| 国产欧美日韩在线看| 97精品超碰一区二区三区| 亚洲一区二区三区激情| 69av一区二区三区| 国内成+人亚洲+欧美+综合在线| 久久亚洲一区二区三区四区| 高清成人免费视频| 亚洲国产你懂的| 日韩欧美国产高清| 成人av在线一区二区三区| 亚洲一区二区三区美女| 欧美精品一区男女天堂| av亚洲精华国产精华|