97 |
u8_t hdrlen; |
u8_t hdrlen; |
98 |
err_t err; |
err_t err; |
99 |
|
|
|
#if SO_REUSE |
|
|
struct tcp_pcb *pcb_temp; |
|
|
int reuse = 0; |
|
|
int reuse_port = 0; |
|
|
#endif /* SO_REUSE */ |
|
|
|
|
100 |
PERF_START; |
PERF_START; |
101 |
|
|
102 |
TCP_STATS_INC(tcp.recv); |
TCP_STATS_INC(tcp.recv); |
111 |
/* remove header from payload */ |
/* remove header from payload */ |
112 |
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { |
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { |
113 |
/* drop short packets */ |
/* drop short packets */ |
114 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%u bytes) discarded\n", p->tot_len)); |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); |
115 |
TCP_STATS_INC(tcp.lenerr); |
TCP_STATS_INC(tcp.lenerr); |
116 |
TCP_STATS_INC(tcp.drop); |
TCP_STATS_INC(tcp.drop); |
117 |
pbuf_free(p); |
pbuf_free(p); |
130 |
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), |
if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), |
131 |
(struct ip_addr *)&(iphdr->dest), |
(struct ip_addr *)&(iphdr->dest), |
132 |
IP_PROTO_TCP, p->tot_len) != 0) { |
IP_PROTO_TCP, p->tot_len) != 0) { |
133 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04x\n", |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", |
134 |
inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest), |
inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest), |
135 |
IP_PROTO_TCP, p->tot_len))); |
IP_PROTO_TCP, p->tot_len))); |
136 |
#if TCP_DEBUG |
#if TCP_DEBUG |
163 |
for an active connection. */ |
for an active connection. */ |
164 |
prev = NULL; |
prev = NULL; |
165 |
|
|
|
#if SO_REUSE |
|
|
pcb_temp = tcp_active_pcbs; |
|
|
|
|
|
again_1: |
|
166 |
|
|
|
/* Iterate through the TCP pcb list for a fully matching pcb */ |
|
|
for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) { |
|
|
#else /* SO_REUSE */ |
|
167 |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { |
|
#endif /* SO_REUSE */ |
|
168 |
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); |
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); |
169 |
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); |
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); |
170 |
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); |
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); |
173 |
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && |
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && |
174 |
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { |
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { |
175 |
|
|
|
#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 */ |
|
|
|
|
176 |
/* Move this PCB to the front of the list so that subsequent |
/* Move this PCB to the front of the list so that subsequent |
177 |
lookups will be faster (we exploit locality in TCP segment |
lookups will be faster (we exploit locality in TCP segment |
178 |
arrivals). */ |
arrivals). */ |
317 |
tcp_debug_print_state(pcb->state); |
tcp_debug_print_state(pcb->state); |
318 |
#endif /* TCP_DEBUG */ |
#endif /* TCP_DEBUG */ |
319 |
#endif /* TCP_INPUT_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; |
|
320 |
|
|
|
/* We are searching connected sockets */ |
|
|
goto again_1; |
|
|
} |
|
|
#endif /* SO_REUSE */ |
|
|
|
|
321 |
} else { |
} else { |
322 |
#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 */ |
|
323 |
/* If no matching PCB was found, send a TCP RST (reset) to the |
/* If no matching PCB was found, send a TCP RST (reset) to the |
324 |
sender. */ |
sender. */ |
325 |
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); |
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); |
332 |
} |
} |
333 |
pbuf_free(p); |
pbuf_free(p); |
334 |
} |
} |
335 |
#if SO_REUSE |
|
|
end: |
|
|
#endif /* SO_REUSE */ |
|
336 |
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); |
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); |
337 |
PERF_STOP("tcp_input"); |
PERF_STOP("tcp_input"); |
338 |
} |
} |
359 |
&(iphdr->dest), &(iphdr->src), |
&(iphdr->dest), &(iphdr->src), |
360 |
tcphdr->dest, tcphdr->src); |
tcphdr->dest, tcphdr->src); |
361 |
} else if (flags & TCP_SYN) { |
} else if (flags & TCP_SYN) { |
362 |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest)); |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); |
363 |
npcb = tcp_alloc(pcb->prio); |
npcb = tcp_alloc(pcb->prio); |
364 |
/* If a new PCB could not be created (probably due to lack of memory), |
/* If a new PCB could not be created (probably due to lack of memory), |
365 |
we don't do anything, but rely on the sender will retransmit the |
we don't do anything, but rely on the sender will retransmit the |
463 |
pcb->flags &= ~TF_ACK_DELAY; |
pcb->flags &= ~TF_ACK_DELAY; |
464 |
return ERR_RST; |
return ERR_RST; |
465 |
} else { |
} else { |
466 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n", |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", |
467 |
seqno, pcb->rcv_nxt)); |
seqno, pcb->rcv_nxt)); |
468 |
LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %lu rcv_nxt %lu\n", |
LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", |
469 |
seqno, pcb->rcv_nxt)); |
seqno, pcb->rcv_nxt)); |
470 |
return ERR_OK; |
return ERR_OK; |
471 |
} |
} |
478 |
/* Do different things depending on the TCP state. */ |
/* Do different things depending on the TCP state. */ |
479 |
switch (pcb->state) { |
switch (pcb->state) { |
480 |
case SYN_SENT: |
case SYN_SENT: |
481 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno, |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, |
482 |
pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); |
pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); |
483 |
/* received SYN ACK with expected sequence number? */ |
/* received SYN ACK with expected sequence number? */ |
484 |
if ((flags & TCP_ACK) && (flags & TCP_SYN) |
if ((flags & TCP_ACK) && (flags & TCP_SYN) |
491 |
pcb->state = ESTABLISHED; |
pcb->state = ESTABLISHED; |
492 |
pcb->cwnd = pcb->mss; |
pcb->cwnd = pcb->mss; |
493 |
--pcb->snd_queuelen; |
--pcb->snd_queuelen; |
494 |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %u\n", (unsigned int)pcb->snd_queuelen)); |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); |
495 |
rseg = pcb->unacked; |
rseg = pcb->unacked; |
496 |
pcb->unacked = rseg->next; |
pcb->unacked = rseg->next; |
497 |
tcp_seg_free(rseg); |
tcp_seg_free(rseg); |
517 |
/* expected ACK number? */ |
/* expected ACK number? */ |
518 |
if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { |
if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { |
519 |
pcb->state = ESTABLISHED; |
pcb->state = ESTABLISHED; |
520 |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
521 |
#if LWIP_CALLBACK_API |
#if LWIP_CALLBACK_API |
522 |
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); |
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); |
523 |
#endif |
#endif |
556 |
if (flags & TCP_FIN) { |
if (flags & TCP_FIN) { |
557 |
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { |
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { |
558 |
LWIP_DEBUGF(TCP_DEBUG, |
LWIP_DEBUGF(TCP_DEBUG, |
559 |
("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
560 |
tcp_ack_now(pcb); |
tcp_ack_now(pcb); |
561 |
tcp_pcb_purge(pcb); |
tcp_pcb_purge(pcb); |
562 |
TCP_RMV(&tcp_active_pcbs, pcb); |
TCP_RMV(&tcp_active_pcbs, pcb); |
573 |
case FIN_WAIT_2: |
case FIN_WAIT_2: |
574 |
tcp_receive(pcb); |
tcp_receive(pcb); |
575 |
if (flags & TCP_FIN) { |
if (flags & TCP_FIN) { |
576 |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
577 |
tcp_ack_now(pcb); |
tcp_ack_now(pcb); |
578 |
tcp_pcb_purge(pcb); |
tcp_pcb_purge(pcb); |
579 |
TCP_RMV(&tcp_active_pcbs, pcb); |
TCP_RMV(&tcp_active_pcbs, pcb); |
584 |
case CLOSING: |
case CLOSING: |
585 |
tcp_receive(pcb); |
tcp_receive(pcb); |
586 |
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { |
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { |
587 |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
588 |
tcp_ack_now(pcb); |
tcp_ack_now(pcb); |
589 |
tcp_pcb_purge(pcb); |
tcp_pcb_purge(pcb); |
590 |
TCP_RMV(&tcp_active_pcbs, pcb); |
TCP_RMV(&tcp_active_pcbs, pcb); |
595 |
case LAST_ACK: |
case LAST_ACK: |
596 |
tcp_receive(pcb); |
tcp_receive(pcb); |
597 |
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { |
if (flags & TCP_ACK && ackno == pcb->snd_nxt) { |
598 |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); |
599 |
pcb->state = CLOSED; |
pcb->state = CLOSED; |
600 |
recv_flags = TF_CLOSED; |
recv_flags = TF_CLOSED; |
601 |
} |
} |
627 |
#endif |
#endif |
628 |
struct pbuf *p; |
struct pbuf *p; |
629 |
s32_t off; |
s32_t off; |
630 |
int m; |
s16_t m; |
631 |
u32_t right_wnd_edge; |
u32_t right_wnd_edge; |
632 |
u16_t new_tot_len; |
u16_t new_tot_len; |
633 |
|
|
642 |
pcb->snd_wnd = tcphdr->wnd; |
pcb->snd_wnd = tcphdr->wnd; |
643 |
pcb->snd_wl1 = seqno; |
pcb->snd_wl1 = seqno; |
644 |
pcb->snd_wl2 = ackno; |
pcb->snd_wl2 = ackno; |
645 |
LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %lu\n", pcb->snd_wnd)); |
LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U32_F"\n", pcb->snd_wnd)); |
646 |
#if TCP_WND_DEBUG |
#if TCP_WND_DEBUG |
647 |
} else { |
} else { |
648 |
if (pcb->snd_wnd != tcphdr->wnd) { |
if (pcb->snd_wnd != tcphdr->wnd) { |
649 |
LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %lu snd_max %lu ackno %lu wl1 %lu seqno %lu wl2 %lu\n", |
LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: no window update lastack %"U32_F" snd_max %"U32_F" ackno %"U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", |
650 |
pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); |
pcb->lastack, pcb->snd_max, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); |
651 |
} |
} |
652 |
#endif /* TCP_WND_DEBUG */ |
#endif /* TCP_WND_DEBUG */ |
661 |
if (pcb->dupacks >= 3 && pcb->unacked != NULL) { |
if (pcb->dupacks >= 3 && pcb->unacked != NULL) { |
662 |
if (!(pcb->flags & TF_INFR)) { |
if (!(pcb->flags & TF_INFR)) { |
663 |
/* This is fast retransmit. Retransmit the first unacked segment. */ |
/* This is fast retransmit. Retransmit the first unacked segment. */ |
664 |
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %u (%lu), fast retransmit %lu\n", |
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupacks %"U16_F" (%"U32_F"), fast retransmit %"U32_F"\n", |
665 |
(unsigned int)pcb->dupacks, pcb->lastack, |
(u16_t)pcb->dupacks, pcb->lastack, |
666 |
ntohl(pcb->unacked->tcphdr->seqno))); |
ntohl(pcb->unacked->tcphdr->seqno))); |
667 |
tcp_rexmit(pcb); |
tcp_rexmit(pcb); |
668 |
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */ |
/* Set ssthresh to max (FlightSize / 2, 2*SMSS) */ |
686 |
} |
} |
687 |
} |
} |
688 |
} else { |
} else { |
689 |
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %lu %lu\n", |
LWIP_DEBUGF(TCP_FR_DEBUG, ("tcp_receive: dupack averted %"U32_F" %"U32_F"\n", |
690 |
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge)); |
pcb->snd_wl1 + pcb->snd_wnd, right_wnd_edge)); |
691 |
} |
} |
692 |
} else |
} else |
726 |
if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { |
if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { |
727 |
pcb->cwnd += pcb->mss; |
pcb->cwnd += pcb->mss; |
728 |
} |
} |
729 |
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %u\n", pcb->cwnd)); |
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); |
730 |
} else { |
} else { |
731 |
u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); |
u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); |
732 |
if (new_cwnd > pcb->cwnd) { |
if (new_cwnd > pcb->cwnd) { |
733 |
pcb->cwnd = new_cwnd; |
pcb->cwnd = new_cwnd; |
734 |
} |
} |
735 |
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %u\n", pcb->cwnd)); |
LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd)); |
736 |
} |
} |
737 |
} |
} |
738 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %lu, unacked->seqno %lu:%lu\n", |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", |
739 |
ackno, |
ackno, |
740 |
pcb->unacked != NULL? |
pcb->unacked != NULL? |
741 |
ntohl(pcb->unacked->tcphdr->seqno): 0, |
ntohl(pcb->unacked->tcphdr->seqno): 0, |
747 |
while (pcb->unacked != NULL && |
while (pcb->unacked != NULL && |
748 |
TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + |
TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + |
749 |
TCP_TCPLEN(pcb->unacked), ackno)) { |
TCP_TCPLEN(pcb->unacked), ackno)) { |
750 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unacked\n", |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", |
751 |
ntohl(pcb->unacked->tcphdr->seqno), |
ntohl(pcb->unacked->tcphdr->seqno), |
752 |
ntohl(pcb->unacked->tcphdr->seqno) + |
ntohl(pcb->unacked->tcphdr->seqno) + |
753 |
TCP_TCPLEN(pcb->unacked))); |
TCP_TCPLEN(pcb->unacked))); |
755 |
next = pcb->unacked; |
next = pcb->unacked; |
756 |
pcb->unacked = pcb->unacked->next; |
pcb->unacked = pcb->unacked->next; |
757 |
|
|
758 |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen)); |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); |
759 |
pcb->snd_queuelen -= pbuf_clen(next->p); |
pcb->snd_queuelen -= pbuf_clen(next->p); |
760 |
tcp_seg_free(next); |
tcp_seg_free(next); |
761 |
|
|
762 |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unacked)\n", (unsigned int)pcb->snd_queuelen)); |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); |
763 |
if (pcb->snd_queuelen != 0) { |
if (pcb->snd_queuelen != 0) { |
764 |
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || |
LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || |
765 |
pcb->unsent != NULL); |
pcb->unsent != NULL); |
779 |
TCP_SEQ_LEQ(ackno, pcb->snd_max)*/ |
TCP_SEQ_LEQ(ackno, pcb->snd_max)*/ |
780 |
TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max) |
TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + TCP_TCPLEN(pcb->unsent), pcb->snd_max) |
781 |
) { |
) { |
782 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %lu:%lu from pcb->unsent\n", |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", |
783 |
ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + |
ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + |
784 |
TCP_TCPLEN(pcb->unsent))); |
TCP_TCPLEN(pcb->unsent))); |
785 |
|
|
786 |
next = pcb->unsent; |
next = pcb->unsent; |
787 |
pcb->unsent = pcb->unsent->next; |
pcb->unsent = pcb->unsent->next; |
788 |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %u ... ", (unsigned int)pcb->snd_queuelen)); |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); |
789 |
pcb->snd_queuelen -= pbuf_clen(next->p); |
pcb->snd_queuelen -= pbuf_clen(next->p); |
790 |
tcp_seg_free(next); |
tcp_seg_free(next); |
791 |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%u (after freeing unsent)\n", (unsigned int)pcb->snd_queuelen)); |
LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); |
792 |
if (pcb->snd_queuelen != 0) { |
if (pcb->snd_queuelen != 0) { |
793 |
LWIP_ASSERT("tcp_receive: valid queue length", |
LWIP_ASSERT("tcp_receive: valid queue length", |
794 |
pcb->unacked != NULL || pcb->unsent != NULL); |
pcb->unacked != NULL || pcb->unsent != NULL); |
800 |
} |
} |
801 |
/* End of ACK for new data processing. */ |
/* End of ACK for new data processing. */ |
802 |
|
|
803 |
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %u rtseq %lu ackno %lu\n", |
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", |
804 |
pcb->rttest, pcb->rtseq, ackno)); |
pcb->rttest, pcb->rtseq, ackno)); |
805 |
|
|
806 |
/* RTT estimation calculations. This is done by checking if the |
/* RTT estimation calculations. This is done by checking if the |
809 |
if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { |
if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { |
810 |
m = tcp_ticks - pcb->rttest; |
m = tcp_ticks - pcb->rttest; |
811 |
|
|
812 |
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %u ticks (%u msec).\n", |
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", |
813 |
m, m * TCP_SLOW_INTERVAL)); |
m, m * TCP_SLOW_INTERVAL)); |
814 |
|
|
815 |
/* This is taken directly from VJs original code in his paper */ |
/* This is taken directly from VJs original code in his paper */ |
822 |
pcb->sv += m; |
pcb->sv += m; |
823 |
pcb->rto = (pcb->sa >> 3) + pcb->sv; |
pcb->rto = (pcb->sa >> 3) + pcb->sv; |
824 |
|
|
825 |
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %u (%u miliseconds)\n", |
LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" miliseconds)\n", |
826 |
pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); |
pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); |
827 |
|
|
828 |
pcb->rttest = 0; |
pcb->rttest = 0; |
911 |
/* the whole segment is < rcv_nxt */ |
/* the whole segment is < rcv_nxt */ |
912 |
/* must be a duplicate of a packet that has already been correctly handled */ |
/* must be a duplicate of a packet that has already been correctly handled */ |
913 |
|
|
914 |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %lu\n", seqno)); |
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); |
915 |
tcp_ack_now(pcb); |
tcp_ack_now(pcb); |
916 |
} |
} |
917 |
} |
} |