58#if LWIP_ND6_TCP_REACHABILITY_HINTS
64#ifdef LWIP_HOOK_FILENAME
65#include LWIP_HOOK_FILENAME
69#define LWIP_TCP_CALC_INITIAL_CWND(mss) ((tcpwnd_size_t)LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)))
74static struct tcp_seg inseg;
76static u16_t tcphdr_optlen;
77static u16_t tcphdr_opt1len;
78static u8_t *tcphdr_opt2;
79static u16_t tcp_optidx;
80static u32_t seqno, ackno;
81static tcpwnd_size_t recv_acked;
85static u8_t recv_flags;
86static struct pbuf *recv_data;
88struct tcp_pcb *tcp_input_pcb;
91static err_t tcp_process(
struct tcp_pcb *pcb);
92static void tcp_receive(
struct tcp_pcb *pcb);
93static void tcp_parseopt(
struct tcp_pcb *pcb);
95static void tcp_listen_input(
struct tcp_pcb_listen *pcb);
96static void tcp_timewait_input(
struct tcp_pcb *pcb);
98static int tcp_input_delayed_close(
struct tcp_pcb *pcb);
102static void tcp_remove_sacks_lt(
struct tcp_pcb *pcb,
u32_t seq);
103#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
104static void tcp_remove_sacks_gt(
struct tcp_pcb *pcb,
u32_t seq);
120 struct tcp_pcb *pcb, *prev;
121 struct tcp_pcb_listen *lpcb;
123 struct tcp_pcb *lpcb_prev =
NULL;
124 struct tcp_pcb_listen *lpcb_any =
NULL;
159#if CHECKSUM_CHECK_TCP
176 if ((hdrlen_bytes <
TCP_HLEN) || (hdrlen_bytes >
p->tot_len)) {
186 if (
p->len >= hdrlen_bytes) {
188 tcphdr_opt1len = tcphdr_optlen;
200 tcphdr_opt1len =
p->len;
201 opt2len = (
u16_t)(tcphdr_optlen - tcphdr_opt1len);
208 if (opt2len >
p->next->len) {
216 tcphdr_opt2 = (
u8_t *)
p->next->payload;
221 p->tot_len = (
u16_t)(
p->tot_len - opt2len);
224 LWIP_ASSERT(
"p->tot_len == p->next->tot_len",
p->tot_len ==
p->next->tot_len);
238 if (tcplen < p->tot_len) {
250 for (pcb = tcp_active_pcbs; pcb !=
NULL; pcb = pcb->
next) {
251 LWIP_ASSERT(
"tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
252 LWIP_ASSERT(
"tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
253 LWIP_ASSERT(
"tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
262 if (pcb->remote_port ==
tcphdr->src &&
269 LWIP_ASSERT(
"tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
271 prev->next = pcb->next;
272 pcb->next = tcp_active_pcbs;
273 tcp_active_pcbs = pcb;
277 LWIP_ASSERT(
"tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
286 for (pcb = tcp_tw_pcbs; pcb !=
NULL; pcb = pcb->
next) {
287 LWIP_ASSERT(
"tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
295 if (pcb->remote_port ==
tcphdr->src &&
303#ifdef LWIP_HOOK_TCP_INPACKET_PCB
304 if (LWIP_HOOK_TCP_INPACKET_PCB(pcb,
tcphdr, tcphdr_optlen, tcphdr_opt1len,
308 tcp_timewait_input(pcb);
318 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb !=
NULL; lpcb = lpcb->
next) {
322 prev = (
struct tcp_pcb *)lpcb;
350 prev = (
struct tcp_pcb *)lpcb;
365 ((
struct tcp_pcb_listen *)prev)->
next = lpcb->next;
367 lpcb->next = tcp_listen_pcbs.listen_pcbs;
369 tcp_listen_pcbs.listen_pcbs = lpcb;
375#ifdef LWIP_HOOK_TCP_INPACKET_PCB
376 if (LWIP_HOOK_TCP_INPACKET_PCB((
struct tcp_pcb *)lpcb,
tcphdr, tcphdr_optlen,
377 tcphdr_opt1len, tcphdr_opt2,
p) ==
ERR_OK)
380 tcp_listen_input(lpcb);
394#ifdef LWIP_HOOK_TCP_INPACKET_PCB
395 if ((pcb !=
NULL) && LWIP_HOOK_TCP_INPACKET_PCB(pcb,
tcphdr, tcphdr_optlen,
396 tcphdr_opt1len, tcphdr_opt2,
p) !=
ERR_OK) {
404 tcp_debug_print_state(pcb->state);
409 inseg.len =
p->tot_len;
422 if (pcb->refused_data !=
NULL) {
423 if ((tcp_process_refused_data(pcb) ==
ERR_ABRT) ||
424 ((pcb->refused_data !=
NULL) && (tcplen > 0))) {
427 if (pcb->rcv_ann_wnd == 0) {
430 tcp_send_empty_ack(pcb);
438 err = tcp_process(pcb);
442 if (recv_flags & TF_RESET) {
447 TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg,
ERR_RST);
448 tcp_pcb_remove(&tcp_active_pcbs, pcb);
455 if (recv_acked > 0) {
460 u32_t acked = recv_acked;
466 acked16 = recv_acked;
468 TCP_EVENT_SENT(pcb, (
u16_t)acked16,
err);
475 if (tcp_input_delayed_close(pcb)) {
478#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
479 while (recv_data !=
NULL) {
481 pbuf_split_64k(recv_data, &rest);
483 if (recv_data !=
NULL) {
487 if (pcb->flags & TF_RXCLOSED) {
491#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
501 TCP_EVENT_RECV(pcb, recv_data,
ERR_OK,
err);
503#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
513#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
518 pcb->refused_data = recv_data;
520#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE
531 if (recv_flags & TF_GOT_FIN) {
532 if (pcb->refused_data !=
NULL) {
538 if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) {
541 TCP_EVENT_CLOSED(pcb,
err);
548 tcp_input_pcb =
NULL;
549 if (tcp_input_delayed_close(pcb)) {
556 tcp_debug_print_state(pcb->state);
564 tcp_input_pcb =
NULL;
568 if (inseg.p !=
NULL) {
585 LWIP_ASSERT(
"tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
600tcp_input_delayed_close(
struct tcp_pcb *pcb)
604 if (recv_flags & TF_CLOSED) {
607 if (!(pcb->flags & TF_RXCLOSED)) {
611 TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg,
ERR_CLSD);
613 tcp_pcb_remove(&tcp_active_pcbs, pcb);
630tcp_listen_input(
struct tcp_pcb_listen *pcb)
632 struct tcp_pcb *npcb;
653#if TCP_LISTEN_BACKLOG
654 if (pcb->accepts_pending >= pcb->backlog) {
659 npcb = tcp_alloc(pcb->prio);
671#if TCP_LISTEN_BACKLOG
672 pcb->accepts_pending++;
673 tcp_set_flags(npcb, TF_BACKLOGPEND);
678 npcb->local_port = pcb->local_port;
679 npcb->remote_port =
tcphdr->src;
680 npcb->state = SYN_RCVD;
681 npcb->rcv_nxt = seqno + 1;
682 npcb->rcv_ann_right_edge = npcb->rcv_nxt;
683 iss = tcp_next_iss(npcb);
688 npcb->snd_wl1 = seqno - 1;
689 npcb->callback_arg = pcb->callback_arg;
690#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
691 npcb->listener = pcb;
694 npcb->netif_hints.tci = pcb->netif_hints.tci;
698 npcb->netif_idx = pcb->netif_idx;
701 TCP_REG_ACTIVE(npcb);
705 npcb->snd_wnd =
tcphdr->wnd;
706 npcb->snd_wnd_max = npcb->snd_wnd;
708#if TCP_CALCULATE_EFF_SEND_MSS
709 npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip);
714#if LWIP_TCP_PCB_NUM_EXT_ARGS
715 if (tcp_ext_arg_invoke_callbacks_passive_open(pcb, npcb) !=
ERR_OK) {
716 tcp_abandon(npcb, 0);
724 tcp_abandon(npcb, 0);
742tcp_timewait_input(
struct tcp_pcb *pcb)
759 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) {
768 pcb->tmr = tcp_ticks;
791tcp_process(
struct tcp_pcb *pcb)
793 struct tcp_seg *rseg;
804 if (pcb->state == SYN_SENT) {
807 if (ackno == pcb->snd_nxt) {
813 if (seqno == pcb->rcv_nxt) {
815 }
else if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
816 pcb->rcv_nxt + pcb->rcv_wnd)) {
827 LWIP_ASSERT(
"tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
828 recv_flags |= TF_RESET;
829 tcp_clear_flags(pcb, TF_ACK_DELAY);
833 seqno, pcb->rcv_nxt));
835 seqno, pcb->rcv_nxt));
840 if ((
flags &
TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
846 if ((pcb->flags & TF_RXCLOSED) == 0) {
848 pcb->tmr = tcp_ticks;
850 pcb->keep_cnt_sent = 0;
851 pcb->persist_probe = 0;
857 if ((pcb->state != SYN_SENT) && (pcb->state != SYN_RCVD)) {
863 switch (pcb->state) {
866 ackno, pcb->snd_nxt, pcb->unacked ?
"" :
" empty:",
867 pcb->unacked ?
lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0));
870 && (ackno == pcb->lastack + 1)) {
871 pcb->rcv_nxt = seqno + 1;
872 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
873 pcb->lastack = ackno;
874 pcb->snd_wnd =
tcphdr->wnd;
875 pcb->snd_wnd_max = pcb->snd_wnd;
876 pcb->snd_wl1 = seqno - 1;
877 pcb->state = ESTABLISHED;
879#if TCP_CALCULATE_EFF_SEND_MSS
880 pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip);
883 pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
885 " ssthresh %"TCPWNDSIZE_F
"\n",
886 pcb->cwnd, pcb->ssthresh));
887 LWIP_ASSERT(
"pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
896 pcb->unsent = rseg->next;
898 pcb->unacked = rseg->next;
904 if (pcb->unacked ==
NULL) {
935 if (seqno == pcb->rcv_nxt - 1) {
941 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
942 pcb->state = ESTABLISHED;
944#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
945 if (pcb->listener ==
NULL) {
952 LWIP_ASSERT(
"pcb->listener->accept != NULL", pcb->listener->accept !=
NULL);
954 tcp_backlog_accepted(pcb);
956 TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg,
ERR_OK,
err);
972 if (recv_acked != 0) {
976 pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss);
978 " ssthresh %"TCPWNDSIZE_F
"\n",
979 pcb->cwnd, pcb->ssthresh));
981 if (recv_flags & TF_GOT_FIN) {
983 pcb->state = CLOSE_WAIT;
996 if (recv_flags & TF_GOT_FIN) {
998 pcb->state = CLOSE_WAIT;
1003 if (recv_flags & TF_GOT_FIN) {
1005 pcb->unsent ==
NULL) {
1007 (
"TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
1010 TCP_RMV_ACTIVE(pcb);
1011 pcb->state = TIME_WAIT;
1012 TCP_REG(&tcp_tw_pcbs, pcb);
1015 pcb->state = CLOSING;
1017 }
else if ((
flags &
TCP_ACK) && (ackno == pcb->snd_nxt) &&
1018 pcb->unsent ==
NULL) {
1019 pcb->state = FIN_WAIT_2;
1024 if (recv_flags & TF_GOT_FIN) {
1028 TCP_RMV_ACTIVE(pcb);
1029 pcb->state = TIME_WAIT;
1030 TCP_REG(&tcp_tw_pcbs, pcb);
1038 TCP_RMV_ACTIVE(pcb);
1039 pcb->state = TIME_WAIT;
1040 TCP_REG(&tcp_tw_pcbs, pcb);
1048 recv_flags |= TF_CLOSED;
1064tcp_oos_insert_segment(
struct tcp_seg *cseg,
struct tcp_seg *
next)
1066 struct tcp_seg *old_seg;
1072 tcp_segs_free(
next);
1078 TCP_SEQ_GEQ((seqno + cseg->len),
1079 (
next->tcphdr->seqno +
next->len))) {
1086 tcp_seg_free(old_seg);
1089 TCP_SEQ_GT(seqno + cseg->len,
next->tcphdr->seqno)) {
1091 cseg->len = (
u16_t)(
next->tcphdr->seqno - seqno);
1100static struct tcp_seg *
1101tcp_free_acked_segments(
struct tcp_pcb *pcb,
struct tcp_seg *seg_list,
const char *dbg_list_name,
1102 struct tcp_seg *dbg_other_seg_list)
1104 struct tcp_seg *
next;
1110 while (seg_list !=
NULL &&
1111 TCP_SEQ_LEQ(
lwip_ntohl(seg_list->tcphdr->seqno) +
1112 TCP_TCPLEN(seg_list), ackno)) {
1115 lwip_ntohl(seg_list->tcphdr->seqno) + TCP_TCPLEN(seg_list),
1119 seg_list = seg_list->next;
1123 (tcpwnd_size_t)pcb->snd_queuelen));
1124 LWIP_ASSERT(
"pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= clen));
1126 pcb->snd_queuelen = (
u16_t)(pcb->snd_queuelen - clen);
1127 recv_acked = (tcpwnd_size_t)(recv_acked +
next->len);
1131 (tcpwnd_size_t)pcb->snd_queuelen,
1133 if (pcb->snd_queuelen != 0) {
1135 seg_list !=
NULL || dbg_other_seg_list !=
NULL);
1154tcp_receive(
struct tcp_pcb *pcb)
1157 u32_t right_wnd_edge;
1160 LWIP_ASSERT(
"tcp_receive: wrong state", pcb->state >= ESTABLISHED);
1163 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
1166 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
1167 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
1168 (pcb->snd_wl2 == ackno && (
u32_t)SND_WND_SCALE(pcb,
tcphdr->wnd) > pcb->snd_wnd)) {
1169 pcb->snd_wnd = SND_WND_SCALE(pcb,
tcphdr->wnd);
1172 if (pcb->snd_wnd_max < pcb->snd_wnd) {
1173 pcb->snd_wnd_max = pcb->snd_wnd;
1175 pcb->snd_wl1 = seqno;
1176 pcb->snd_wl2 = ackno;
1180 if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb,
tcphdr->wnd)) {
1182 (
"tcp_receive: no window update lastack %"U32_F" ackno %"
1184 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
1210 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
1214 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) {
1216 if (pcb->rtime >= 0) {
1218 if (pcb->lastack == ackno) {
1219 if ((
u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
1222 if (pcb->dupacks > 3) {
1224 TCP_WND_INC(pcb->cwnd, pcb->mss);
1226 if (pcb->dupacks >= 3) {
1228 tcp_rexmit_fast(pcb);
1234 }
else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack + 1, pcb->snd_nxt)) {
1236 tcpwnd_size_t acked;
1241 if (pcb->flags & TF_INFR) {
1242 tcp_clear_flags(pcb, TF_INFR);
1243 pcb->cwnd = pcb->ssthresh;
1244 pcb->bytes_acked = 0;
1251 pcb->rto = (
s16_t)((pcb->sa >> 3) + pcb->sv);
1254 acked = (tcpwnd_size_t)(ackno - pcb->lastack);
1258 pcb->lastack = ackno;
1262 if (pcb->state >= ESTABLISHED) {
1263 if (pcb->cwnd < pcb->ssthresh) {
1266 u8_t num_seg = (pcb->flags & TF_RTO) ? 1 : 2;
1273 TCP_WND_INC(pcb->bytes_acked, acked);
1274 if (pcb->bytes_acked >= pcb->cwnd) {
1275 pcb->bytes_acked = (tcpwnd_size_t)(pcb->bytes_acked - pcb->cwnd);
1276 TCP_WND_INC(pcb->cwnd, pcb->mss);
1283 pcb->unacked !=
NULL ?
1285 pcb->unacked !=
NULL ?
1286 lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked) : 0));
1290 pcb->unacked = tcp_free_acked_segments(pcb, pcb->unacked,
"unacked", pcb->unsent);
1297 pcb->unsent = tcp_free_acked_segments(pcb, pcb->unsent,
"unsent", pcb->unacked);
1301 if (pcb->unacked ==
NULL) {
1310 if (pcb->unsent ==
NULL) {
1311 pcb->unsent_oversize = 0;
1315#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1316 if (ip_current_is_v6()) {
1318 nd6_reachability_hint(ip6_current_src_addr());
1322 pcb->snd_buf = (tcpwnd_size_t)(pcb->snd_buf + recv_acked);
1324 if (pcb->flags & TF_RTO) {
1329 if (pcb->unacked ==
NULL) {
1330 if ((pcb->unsent ==
NULL) ||
1331 (TCP_SEQ_LEQ(pcb->rto_end,
lwip_ntohl(pcb->unsent->tcphdr->seqno)))) {
1332 tcp_clear_flags(pcb, TF_RTO);
1334 }
else if (TCP_SEQ_LEQ(pcb->rto_end,
lwip_ntohl(pcb->unacked->tcphdr->seqno))) {
1335 tcp_clear_flags(pcb, TF_RTO);
1341 tcp_send_empty_ack(pcb);
1345 pcb->rttest, pcb->rtseq, ackno));
1350 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
1353 m = (
s16_t)(tcp_ticks - pcb->rttest);
1356 m, (
u16_t)(
m * TCP_SLOW_INTERVAL)));
1359 m = (
s16_t)(
m - (pcb->sa >> 3));
1360 pcb->sa = (
s16_t)(pcb->sa +
m);
1364 m = (
s16_t)(
m - (pcb->sv >> 2));
1365 pcb->sv = (
s16_t)(pcb->sv +
m);
1366 pcb->rto = (
s16_t)((pcb->sa >> 3) + pcb->sv);
1369 pcb->rto, (
u16_t)(pcb->rto * TCP_SLOW_INTERVAL)));
1379 if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
1410 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) {
1431 struct pbuf *
p = inseg.p;
1432 u32_t off32 = pcb->rcv_nxt - seqno;
1433 u16_t new_tot_len, off;
1439 new_tot_len = (
u16_t)(inseg.p->tot_len - off);
1440 while (
p->len < off) {
1443 p->tot_len = new_tot_len;
1449 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
1451 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) {
1463 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
1464 pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1465 if (pcb->rcv_nxt == seqno) {
1469 tcplen = TCP_TCPLEN(&inseg);
1471 if (tcplen > pcb->rcv_wnd) {
1473 (
"tcp_receive: other end overran receive window"
1475 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1482 TCPWND_CHECK16(pcb->rcv_wnd);
1483 inseg.len = (
u16_t)pcb->rcv_wnd;
1488 tcplen = TCP_TCPLEN(&inseg);
1489 LWIP_ASSERT(
"tcp_receive: segment not trimmed correctly to rcv_wnd",
1490 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1496 if (pcb->ooseq !=
NULL) {
1499 (
"tcp_receive: received in-order FIN, binning ooseq queue\n"));
1503 while (pcb->ooseq !=
NULL) {
1504 struct tcp_seg *old_ooseq = pcb->ooseq;
1505 pcb->ooseq = pcb->ooseq->next;
1506 tcp_seg_free(old_ooseq);
1509 struct tcp_seg *
next = pcb->ooseq;
1513 TCP_SEQ_GEQ(seqno + tcplen,
1514 next->tcphdr->seqno +
next->len)) {
1515 struct tcp_seg *tmp;
1520 tcplen = TCP_TCPLEN(&inseg);
1529 TCP_SEQ_GT(seqno + tcplen,
1530 next->tcphdr->seqno)) {
1532 inseg.len = (
u16_t)(
next->tcphdr->seqno - seqno);
1537 tcplen = TCP_TCPLEN(&inseg);
1538 LWIP_ASSERT(
"tcp_receive: segment not trimmed correctly to ooseq queue",
1539 (seqno + tcplen) ==
next->tcphdr->seqno);
1546 pcb->rcv_nxt = seqno + tcplen;
1549 LWIP_ASSERT(
"tcp_receive: tcplen > rcv_wnd", pcb->rcv_wnd >= tcplen);
1550 pcb->rcv_wnd -= tcplen;
1552 tcp_update_rcv_ann_wnd(pcb);
1563 if (inseg.p->tot_len > 0) {
1564 recv_data = inseg.p;
1572 recv_flags |= TF_GOT_FIN;
1578 while (pcb->ooseq !=
NULL &&
1579 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
1581 struct tcp_seg *cseg = pcb->ooseq;
1582 seqno = pcb->ooseq->tcphdr->seqno;
1584 pcb->rcv_nxt += TCP_TCPLEN(cseg);
1585 LWIP_ASSERT(
"tcp_receive: ooseq tcplen > rcv_wnd",
1586 pcb->rcv_wnd >= TCP_TCPLEN(cseg));
1587 pcb->rcv_wnd -= TCP_TCPLEN(cseg);
1589 tcp_update_rcv_ann_wnd(pcb);
1591 if (cseg->p->tot_len > 0) {
1600 recv_data = cseg->p;
1606 recv_flags |= TF_GOT_FIN;
1607 if (pcb->state == ESTABLISHED) {
1608 pcb->state = CLOSE_WAIT;
1612 pcb->ooseq = cseg->next;
1615#if LWIP_TCP_SACK_OUT
1616 if (pcb->flags & TF_SACK) {
1617 if (pcb->ooseq !=
NULL) {
1620 tcp_remove_sacks_lt(pcb, pcb->ooseq->tcphdr->seqno);
1621 }
else if (LWIP_TCP_SACK_VALID(pcb, 0)) {
1623 memset(pcb->rcv_sacks, 0,
sizeof(pcb->rcv_sacks));
1633#if LWIP_TCP_SACK_OUT
1634 if (LWIP_TCP_SACK_VALID(pcb, 0)) {
1639 tcp_send_empty_ack(pcb);
1643#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS
1644 if (ip_current_is_v6()) {
1646 nd6_reachability_hint(ip6_current_src_addr());
1655 if (pcb->ooseq ==
NULL) {
1656 pcb->ooseq = tcp_seg_copy(&inseg);
1657#if LWIP_TCP_SACK_OUT
1658 if (pcb->flags & TF_SACK) {
1660 pcb->rcv_sacks[0].left = seqno;
1661 pcb->rcv_sacks[0].right = seqno + inseg.len;
1677#if LWIP_TCP_SACK_OUT
1680 u32_t sackbeg = TCP_SEQ_LT(seqno, pcb->ooseq->tcphdr->seqno) ? seqno : pcb->ooseq->tcphdr->seqno;
1682 struct tcp_seg *
next, *prev =
NULL;
1684 if (seqno ==
next->tcphdr->seqno) {
1689 if (inseg.len >
next->len) {
1693 struct tcp_seg *cseg = tcp_seg_copy(&inseg);
1700 tcp_oos_insert_segment(cseg,
next);
1711 if (TCP_SEQ_LT(seqno,
next->tcphdr->seqno)) {
1716 struct tcp_seg *cseg = tcp_seg_copy(&inseg);
1719 tcp_oos_insert_segment(cseg,
next);
1726 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno + 1,
next->tcphdr->seqno - 1)) {
1732 struct tcp_seg *cseg = tcp_seg_copy(&inseg);
1734 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
1736 prev->len = (
u16_t)(seqno - prev->tcphdr->seqno);
1740 tcp_oos_insert_segment(cseg,
next);
1746#if LWIP_TCP_SACK_OUT
1749 if (prev !=
NULL && prev->tcphdr->seqno + prev->len !=
next->tcphdr->seqno) {
1750 sackbeg =
next->tcphdr->seqno;
1763 TCP_SEQ_GT(seqno,
next->tcphdr->seqno)) {
1768 next->next = tcp_seg_copy(&inseg);
1770 if (TCP_SEQ_GT(
next->tcphdr->seqno +
next->len, seqno)) {
1776 if (TCP_SEQ_GT((
u32_t)tcplen + seqno, pcb->rcv_nxt + (
u32_t)pcb->rcv_wnd)) {
1778 (
"tcp_receive: other end overran receive window"
1780 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
1787 next->next->len = (
u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno);
1789 tcplen = TCP_TCPLEN(
next->next);
1790 LWIP_ASSERT(
"tcp_receive: segment not trimmed correctly to rcv_wnd",
1791 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
1799#if LWIP_TCP_SACK_OUT
1800 if (pcb->flags & TF_SACK) {
1805 }
else if (prev->next !=
NULL) {
1809 if (prev->tcphdr->seqno + prev->len !=
next->tcphdr->seqno) {
1810 sackbeg =
next->tcphdr->seqno;
1818 sackend +=
next->len;
1820 tcp_add_sack(pcb, sackbeg, sackend);
1825#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
1829#ifdef TCP_OOSEQ_BYTES_LIMIT
1830 const u32_t ooseq_max_blen = TCP_OOSEQ_BYTES_LIMIT(pcb);
1831 u32_t ooseq_blen = 0;
1833#ifdef TCP_OOSEQ_PBUFS_LIMIT
1834 const u16_t ooseq_max_qlen = TCP_OOSEQ_PBUFS_LIMIT(pcb);
1835 u16_t ooseq_qlen = 0;
1837 struct tcp_seg *
next, *prev =
NULL;
1841#ifdef TCP_OOSEQ_BYTES_LIMIT
1842 ooseq_blen +=
p->tot_len;
1843 if (ooseq_blen > ooseq_max_blen) {
1847#ifdef TCP_OOSEQ_PBUFS_LIMIT
1849 if (ooseq_qlen > ooseq_max_qlen) {
1854#if LWIP_TCP_SACK_OUT
1855 if (pcb->flags & TF_SACK) {
1857 tcp_remove_sacks_gt(pcb,
next->tcphdr->seqno);
1861 tcp_segs_free(
next);
1878 tcp_send_empty_ack(pcb);
1882 tcp_send_empty_ack(pcb);
1887 if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) {
1894tcp_get_next_optbyte(
void)
1896 u16_t optidx = tcp_optidx++;
1897 if ((tcphdr_opt2 ==
NULL) || (optidx < tcphdr_opt1len)) {
1899 return opts[optidx];
1902 return tcphdr_opt2[
idx];
1915tcp_parseopt(
struct tcp_pcb *pcb)
1919#if LWIP_TCP_TIMESTAMPS
1926 if (tcphdr_optlen != 0) {
1927 for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) {
1928 u8_t opt = tcp_get_next_optbyte();
1930 case LWIP_TCP_OPT_EOL:
1934 case LWIP_TCP_OPT_NOP:
1938 case LWIP_TCP_OPT_MSS:
1940 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) {
1946 mss = (
u16_t)(tcp_get_next_optbyte() << 8);
1947 mss |= tcp_get_next_optbyte();
1952 case LWIP_TCP_OPT_WS:
1954 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) {
1960 data = tcp_get_next_optbyte();
1963 if ((
flags &
TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) {
1964 pcb->snd_scale =
data;
1965 if (pcb->snd_scale > 14U) {
1966 pcb->snd_scale = 14U;
1969 tcp_set_flags(pcb, TF_WND_SCALE);
1972 LWIP_ASSERT(
"window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(
TCP_WND));
1973 pcb->rcv_wnd = pcb->rcv_ann_wnd =
TCP_WND;
1977#if LWIP_TCP_TIMESTAMPS
1978 case LWIP_TCP_OPT_TS:
1980 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) {
1986 tsval = tcp_get_next_optbyte();
1987 tsval |= (tcp_get_next_optbyte() << 8);
1988 tsval |= (tcp_get_next_optbyte() << 16);
1989 tsval |= (tcp_get_next_optbyte() << 24);
1994 tcp_set_flags(pcb, TF_TIMESTAMP);
1995 }
else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno + tcplen)) {
1999 tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6;
2002#if LWIP_TCP_SACK_OUT
2003 case LWIP_TCP_OPT_SACK_PERM:
2005 if (tcp_get_next_optbyte() != LWIP_TCP_OPT_LEN_SACK_PERM || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_SACK_PERM) > tcphdr_optlen) {
2013 tcp_set_flags(pcb, TF_SACK);
2019 data = tcp_get_next_optbyte();
2028 tcp_optidx +=
data - 2;
2035tcp_trigger_input_pcb_close(
void)
2037 recv_flags |= TF_CLOSED;
2040#if LWIP_TCP_SACK_OUT
2058 if ((pcb->flags & TF_SACK) == 0 || !TCP_SEQ_LT(
left,
right)) {
2071 if (TCP_SEQ_LEQ(pcb->rcv_sacks[
i].right,
left) || TCP_SEQ_LEQ(
right, pcb->rcv_sacks[
i].left)) {
2072 if (unused_idx !=
i) {
2074 pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[
i];
2089 if (
i - 1 >= unused_idx) {
2091 pcb->rcv_sacks[
i].left = pcb->rcv_sacks[
i].right = 0;
2093 pcb->rcv_sacks[
i] = pcb->rcv_sacks[
i - 1];
2098 pcb->rcv_sacks[0].left =
left;
2099 pcb->rcv_sacks[0].right =
right;
2113tcp_remove_sacks_lt(
struct tcp_pcb *pcb,
u32_t seq)
2122 if (TCP_SEQ_GT(pcb->rcv_sacks[
i].right, seq)) {
2123 if (unused_idx !=
i) {
2125 pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[
i];
2128 if (TCP_SEQ_LT(pcb->rcv_sacks[unused_idx].left, seq)) {
2129 pcb->rcv_sacks[unused_idx].left = seq;
2137 pcb->rcv_sacks[
i].left = pcb->rcv_sacks[
i].right = 0;
2141#if defined(TCP_OOSEQ_BYTES_LIMIT) || defined(TCP_OOSEQ_PBUFS_LIMIT)
2153tcp_remove_sacks_gt(
struct tcp_pcb *pcb,
u32_t seq)
2162 if (TCP_SEQ_LT(pcb->rcv_sacks[
i].left, seq)) {
2163 if (unused_idx !=
i) {
2165 pcb->rcv_sacks[unused_idx] = pcb->rcv_sacks[
i];
2168 if (TCP_SEQ_GT(pcb->rcv_sacks[unused_idx].right, seq)) {
2169 pcb->rcv_sacks[unused_idx].right = seq;
2177 pcb->rcv_sacks[
i].left = pcb->rcv_sacks[
i].right = 0;
#define LWIP_DEBUGF(debug, message)
#define LWIP_ASSERT(message, assertion)
#define ip_current_src_addr()
#define ip_current_dest_addr()
#define ip_current_netif()
struct ip_globals ip_data
static void increase(int &a_)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define LWIP_UNUSED_ARG(x)
#define LWIP_ASSERT_CORE_LOCKED()
#define LWIP_TCP_MAX_SACK_NUM
void pbuf_realloc(struct pbuf *p, u16_t new_len)
void pbuf_cat(struct pbuf *h, struct pbuf *t)
u8_t pbuf_free(struct pbuf *p)
u16_t ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, const ip_addr_t *src, const ip_addr_t *dest)
#define ip_addr_isbroadcast(addr, netif)
#define ip_addr_ismulticast(ipaddr)
#define ip_addr_isany(ipaddr)
#define ip_addr_eq(addr1, addr2)
#define ip_addr_copy(dest, src)
#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)
#define IP_IS_ANY_TYPE_VAL(ipaddr)
#define TCPH_HDRLEN_BYTES(phdr)
#define TCPH_SET_FLAG(phdr, flags)
#define TCPH_FLAGS_SET(phdr, flags)
#define netif_get_index(netif)
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
u16_t pbuf_clen(const struct pbuf *p)
u8_t pbuf_remove_header(struct pbuf *p, size_t header_size_decrement)
#define PBUF_FLAG_TCP_FIN
static unsigned __int64 next
#define MIB2_STATS_INC(x)