00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "lwip/opt.h"
00045
00046 #if LWIP_TCP
00047
00048 #include "lwip/tcp_impl.h"
00049 #include "lwip/def.h"
00050 #include "lwip/ip_addr.h"
00051 #include "lwip/netif.h"
00052 #include "lwip/mem.h"
00053 #include "lwip/memp.h"
00054 #include "lwip/inet_chksum.h"
00055 #include "lwip/stats.h"
00056 #include "lwip/snmp.h"
00057 #include "arch/perf.h"
00058
00059
00060
00061
00062 static struct tcp_seg inseg;
00063 static struct tcp_hdr *tcphdr;
00064 static struct ip_hdr *iphdr;
00065 static u32_t seqno, ackno;
00066 static u8_t flags;
00067 static u16_t tcplen;
00068
00069 static u8_t recv_flags;
00070 static struct pbuf *recv_data;
00071
00072 struct tcp_pcb *tcp_input_pcb;
00073
00074
00075 static err_t tcp_process(struct tcp_pcb *pcb);
00076 static void tcp_receive(struct tcp_pcb *pcb);
00077 static void tcp_parseopt(struct tcp_pcb *pcb);
00078
00079 static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
00080 static err_t tcp_timewait_input(struct tcp_pcb *pcb);
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 void
00092 tcp_input(struct pbuf *p, struct netif *inp)
00093 {
00094 struct tcp_pcb *pcb, *prev;
00095 struct tcp_pcb_listen *lpcb;
00096 #if SO_REUSE
00097 struct tcp_pcb *lpcb_prev = NULL;
00098 struct tcp_pcb_listen *lpcb_any = NULL;
00099 #endif
00100 u8_t hdrlen;
00101 err_t err;
00102
00103 PERF_START;
00104
00105 TCP_STATS_INC(tcp.recv);
00106 snmp_inc_tcpinsegs();
00107
00108 iphdr = (struct ip_hdr *)p->payload;
00109 tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4);
00110
00111 #if TCP_INPUT_DEBUG
00112 tcp_debug_print(tcphdr);
00113 #endif
00114
00115
00116 if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
00117
00118 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
00119 TCP_STATS_INC(tcp.lenerr);
00120 goto dropped;
00121 }
00122
00123
00124 if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) ||
00125 ip_addr_ismulticast(¤t_iphdr_dest)) {
00126 TCP_STATS_INC(tcp.proterr);
00127 goto dropped;
00128 }
00129
00130 #if CHECKSUM_CHECK_TCP
00131
00132 if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
00133 IP_PROTO_TCP, p->tot_len) != 0) {
00134 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n",
00135 inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(),
00136 IP_PROTO_TCP, p->tot_len)));
00137 #if TCP_DEBUG
00138 tcp_debug_print(tcphdr);
00139 #endif
00140 TCP_STATS_INC(tcp.chkerr);
00141 goto dropped;
00142 }
00143 #endif
00144
00145
00146
00147 hdrlen = TCPH_HDRLEN(tcphdr);
00148 if(pbuf_header(p, -(hdrlen * 4))){
00149
00150 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n"));
00151 TCP_STATS_INC(tcp.lenerr);
00152 goto dropped;
00153 }
00154
00155
00156 tcphdr->src = ntohs(tcphdr->src);
00157 tcphdr->dest = ntohs(tcphdr->dest);
00158 seqno = tcphdr->seqno = ntohl(tcphdr->seqno);
00159 ackno = tcphdr->ackno = ntohl(tcphdr->ackno);
00160 tcphdr->wnd = ntohs(tcphdr->wnd);
00161
00162 flags = TCPH_FLAGS(tcphdr);
00163 tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
00164
00165
00166
00167 prev = NULL;
00168
00169
00170 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00171 LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
00172 LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
00173 LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
00174 if (pcb->remote_port == tcphdr->src &&
00175 pcb->local_port == tcphdr->dest &&
00176 ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) &&
00177 ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) {
00178
00179
00180
00181
00182 LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
00183 if (prev != NULL) {
00184 prev->next = pcb->next;
00185 pcb->next = tcp_active_pcbs;
00186 tcp_active_pcbs = pcb;
00187 }
00188 LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb);
00189 break;
00190 }
00191 prev = pcb;
00192 }
00193
00194 if (pcb == NULL) {
00195
00196
00197 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
00198 LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
00199 if (pcb->remote_port == tcphdr->src &&
00200 pcb->local_port == tcphdr->dest &&
00201 ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) &&
00202 ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) {
00203
00204
00205
00206 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n"));
00207 tcp_timewait_input(pcb);
00208 pbuf_free(p);
00209 return;
00210 }
00211 }
00212
00213
00214
00215 prev = NULL;
00216 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
00217 if (lpcb->local_port == tcphdr->dest) {
00218 #if SO_REUSE
00219 if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest)) {
00220
00221 break;
00222 } else if(ip_addr_isany(&(lpcb->local_ip))) {
00223
00224 lpcb_any = lpcb;
00225 lpcb_prev = prev;
00226 }
00227 #else
00228 if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) ||
00229 ip_addr_isany(&(lpcb->local_ip))) {
00230
00231 break;
00232 }
00233 #endif
00234 }
00235 prev = (struct tcp_pcb *)lpcb;
00236 }
00237 #if SO_REUSE
00238
00239 if (lpcb == NULL) {
00240
00241 lpcb = lpcb_any;
00242 prev = lpcb_prev;
00243 }
00244 #endif
00245 if (lpcb != NULL) {
00246
00247
00248
00249 if (prev != NULL) {
00250 ((struct tcp_pcb_listen *)prev)->next = lpcb->next;
00251
00252 lpcb->next = tcp_listen_pcbs.listen_pcbs;
00253
00254 tcp_listen_pcbs.listen_pcbs = lpcb;
00255 }
00256
00257 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
00258 tcp_listen_input(lpcb);
00259 pbuf_free(p);
00260 return;
00261 }
00262 }
00263
00264 #if TCP_INPUT_DEBUG
00265 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags "));
00266 tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
00267 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"));
00268 #endif
00269
00270
00271 if (pcb != NULL) {
00272
00273 #if TCP_INPUT_DEBUG
00274 #if TCP_DEBUG
00275 tcp_debug_print_state(pcb->state);
00276 #endif
00277 #endif
00278
00279
00280 inseg.next = NULL;
00281 inseg.len = p->tot_len;
00282 inseg.p = p;
00283 inseg.tcphdr = tcphdr;
00284
00285 recv_data = NULL;
00286 recv_flags = 0;
00287
00288 if (flags & TCP_PSH) {
00289 p->flags |= PBUF_FLAG_PUSH;
00290 }
00291
00292
00293 if (pcb->refused_data != NULL) {
00294 if ((tcp_process_refused_data(pcb) == ERR_ABRT) ||
00295 ((pcb->refused_data != NULL) && (tcplen > 0))) {
00296
00297
00298 TCP_STATS_INC(tcp.drop);
00299 snmp_inc_tcpinerrs();
00300 goto aborted;
00301 }
00302 }
00303 tcp_input_pcb = pcb;
00304 err = tcp_process(pcb);
00305
00306
00307 if (err != ERR_ABRT) {
00308 if (recv_flags & TF_RESET) {
00309
00310
00311
00312
00313 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
00314 tcp_pcb_remove(&tcp_active_pcbs, pcb);
00315 memp_free(MEMP_TCP_PCB, pcb);
00316 } else if (recv_flags & TF_CLOSED) {
00317
00318
00319 if (!(pcb->flags & TF_RXCLOSED)) {
00320
00321
00322
00323 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD);
00324 }
00325 tcp_pcb_remove(&tcp_active_pcbs, pcb);
00326 memp_free(MEMP_TCP_PCB, pcb);
00327 } else {
00328 err = ERR_OK;
00329
00330
00331
00332 if (pcb->acked > 0) {
00333 TCP_EVENT_SENT(pcb, pcb->acked, err);
00334 if (err == ERR_ABRT) {
00335 goto aborted;
00336 }
00337 }
00338
00339 if (recv_data != NULL) {
00340 LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
00341 if (pcb->flags & TF_RXCLOSED) {
00342
00343
00344 pbuf_free(recv_data);
00345 tcp_abort(pcb);
00346 goto aborted;
00347 }
00348
00349
00350 TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
00351 if (err == ERR_ABRT) {
00352 goto aborted;
00353 }
00354
00355
00356 if (err != ERR_OK) {
00357 pcb->refused_data = recv_data;
00358 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
00359 }
00360 }
00361
00362
00363
00364 if (recv_flags & TF_GOT_FIN) {
00365 if (pcb->refused_data != NULL) {
00366
00367 pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN;
00368 } else {
00369
00370
00371 if (pcb->rcv_wnd != TCP_WND) {
00372 pcb->rcv_wnd++;
00373 }
00374 TCP_EVENT_CLOSED(pcb, err);
00375 if (err == ERR_ABRT) {
00376 goto aborted;
00377 }
00378 }
00379 }
00380
00381 tcp_input_pcb = NULL;
00382
00383 tcp_output(pcb);
00384 #if TCP_INPUT_DEBUG
00385 #if TCP_DEBUG
00386 tcp_debug_print_state(pcb->state);
00387 #endif
00388 #endif
00389 }
00390 }
00391
00392
00393 aborted:
00394 tcp_input_pcb = NULL;
00395 recv_data = NULL;
00396
00397
00398 if (inseg.p != NULL)
00399 {
00400 pbuf_free(inseg.p);
00401 inseg.p = NULL;
00402 }
00403 } else {
00404
00405
00406
00407 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n"));
00408 if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) {
00409 TCP_STATS_INC(tcp.proterr);
00410 TCP_STATS_INC(tcp.drop);
00411 tcp_rst(ackno, seqno + tcplen,
00412 ip_current_dest_addr(), ip_current_src_addr(),
00413 tcphdr->dest, tcphdr->src);
00414 }
00415 pbuf_free(p);
00416 }
00417
00418 LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
00419 PERF_STOP("tcp_input");
00420 return;
00421 dropped:
00422 TCP_STATS_INC(tcp.drop);
00423 snmp_inc_tcpinerrs();
00424 pbuf_free(p);
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 static err_t
00440 tcp_listen_input(struct tcp_pcb_listen *pcb)
00441 {
00442 struct tcp_pcb *npcb;
00443 err_t rc;
00444
00445 if (flags & TCP_RST) {
00446
00447 return ERR_OK;
00448 }
00449
00450
00451
00452 if (flags & TCP_ACK) {
00453
00454
00455 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n"));
00456 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(),
00457 ip_current_src_addr(), tcphdr->dest, tcphdr->src);
00458 } else if (flags & TCP_SYN) {
00459 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
00460 #if TCP_LISTEN_BACKLOG
00461 if (pcb->accepts_pending >= pcb->backlog) {
00462 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest));
00463 return ERR_ABRT;
00464 }
00465 #endif
00466 npcb = tcp_alloc(pcb->prio);
00467
00468
00469
00470 if (npcb == NULL) {
00471 LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n"));
00472 TCP_STATS_INC(tcp.memerr);
00473 return ERR_MEM;
00474 }
00475 #if TCP_LISTEN_BACKLOG
00476 pcb->accepts_pending++;
00477 #endif
00478
00479 ip_addr_copy(npcb->local_ip, current_iphdr_dest);
00480 npcb->local_port = pcb->local_port;
00481 ip_addr_copy(npcb->remote_ip, current_iphdr_src);
00482 npcb->remote_port = tcphdr->src;
00483 npcb->state = SYN_RCVD;
00484 npcb->rcv_nxt = seqno + 1;
00485 npcb->rcv_ann_right_edge = npcb->rcv_nxt;
00486 npcb->snd_wnd = tcphdr->wnd;
00487 npcb->snd_wnd_max = tcphdr->wnd;
00488 npcb->ssthresh = npcb->snd_wnd;
00489 npcb->snd_wl1 = seqno - 1;
00490 npcb->callback_arg = pcb->callback_arg;
00491 #if LWIP_CALLBACK_API
00492 npcb->accept = pcb->accept;
00493 #endif
00494
00495 npcb->so_options = pcb->so_options & SOF_INHERITED;
00496
00497
00498 TCP_REG_ACTIVE(npcb);
00499
00500
00501 tcp_parseopt(npcb);
00502 #if TCP_CALCULATE_EFF_SEND_MSS
00503 npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip));
00504 #endif
00505
00506 snmp_inc_tcppassiveopens();
00507
00508
00509 rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK);
00510 if (rc != ERR_OK) {
00511 tcp_abandon(npcb, 0);
00512 return rc;
00513 }
00514 return tcp_output(npcb);
00515 }
00516 return ERR_OK;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 static err_t
00529 tcp_timewait_input(struct tcp_pcb *pcb)
00530 {
00531
00532
00533
00534
00535
00536 if (flags & TCP_RST) {
00537 return ERR_OK;
00538 }
00539
00540 if (flags & TCP_SYN) {
00541
00542
00543 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) {
00544
00545 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
00546 tcphdr->dest, tcphdr->src);
00547 return ERR_OK;
00548 }
00549 } else if (flags & TCP_FIN) {
00550
00551
00552 pcb->tmr = tcp_ticks;
00553 }
00554
00555 if ((tcplen > 0)) {
00556
00557 pcb->flags |= TF_ACK_NOW;
00558 return tcp_output(pcb);
00559 }
00560 return ERR_OK;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 static err_t
00575 tcp_process(struct tcp_pcb *pcb)
00576 {
00577 struct tcp_seg *rseg;
00578 u8_t acceptable = 0;
00579 err_t err;
00580
00581 err = ERR_OK;
00582
00583
00584 if (flags & TCP_RST) {
00585
00586 if (pcb->state == SYN_SENT) {
00587 if (ackno == pcb->snd_nxt) {
00588 acceptable = 1;
00589 }
00590 } else {
00591 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
00592 pcb->rcv_nxt+pcb->rcv_wnd)) {
00593 acceptable = 1;
00594 }
00595 }
00596
00597 if (acceptable) {
00598 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n"));
00599 LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED);
00600 recv_flags |= TF_RESET;
00601 pcb->flags &= ~TF_ACK_DELAY;
00602 return ERR_RST;
00603 } else {
00604 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
00605 seqno, pcb->rcv_nxt));
00606 LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n",
00607 seqno, pcb->rcv_nxt));
00608 return ERR_OK;
00609 }
00610 }
00611
00612 if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) {
00613
00614 tcp_ack_now(pcb);
00615 return ERR_OK;
00616 }
00617
00618 if ((pcb->flags & TF_RXCLOSED) == 0) {
00619
00620 pcb->tmr = tcp_ticks;
00621 }
00622 pcb->keep_cnt_sent = 0;
00623
00624 tcp_parseopt(pcb);
00625
00626
00627 switch (pcb->state) {
00628 case SYN_SENT:
00629 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
00630 pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
00631
00632 if ((flags & TCP_ACK) && (flags & TCP_SYN)
00633 && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
00634 pcb->snd_buf++;
00635 pcb->rcv_nxt = seqno + 1;
00636 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
00637 pcb->lastack = ackno;
00638 pcb->snd_wnd = tcphdr->wnd;
00639 pcb->snd_wnd_max = tcphdr->wnd;
00640 pcb->snd_wl1 = seqno - 1;
00641 pcb->state = ESTABLISHED;
00642
00643 #if TCP_CALCULATE_EFF_SEND_MSS
00644 pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
00645 #endif
00646
00647
00648
00649 pcb->ssthresh = pcb->mss * 10;
00650
00651 pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
00652 LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0));
00653 --pcb->snd_queuelen;
00654 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen));
00655 rseg = pcb->unacked;
00656 pcb->unacked = rseg->next;
00657 tcp_seg_free(rseg);
00658
00659
00660
00661 if(pcb->unacked == NULL)
00662 pcb->rtime = -1;
00663 else {
00664 pcb->rtime = 0;
00665 pcb->nrtx = 0;
00666 }
00667
00668
00669
00670 TCP_EVENT_CONNECTED(pcb, ERR_OK, err);
00671 if (err == ERR_ABRT) {
00672 return ERR_ABRT;
00673 }
00674 tcp_ack_now(pcb);
00675 }
00676
00677 else if (flags & TCP_ACK) {
00678
00679 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
00680 tcphdr->dest, tcphdr->src);
00681 }
00682 break;
00683 case SYN_RCVD:
00684 if (flags & TCP_ACK) {
00685
00686 if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
00687 u16_t old_cwnd;
00688 pcb->state = ESTABLISHED;
00689 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00690 #if LWIP_CALLBACK_API
00691 LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
00692 #endif
00693
00694 TCP_EVENT_ACCEPT(pcb, ERR_OK, err);
00695 if (err != ERR_OK) {
00696
00697
00698
00699 if (err != ERR_ABRT) {
00700 tcp_abort(pcb);
00701 }
00702 return ERR_ABRT;
00703 }
00704 old_cwnd = pcb->cwnd;
00705
00706
00707 tcp_receive(pcb);
00708
00709
00710 if (pcb->acked != 0) {
00711 pcb->acked--;
00712 }
00713
00714 pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss);
00715
00716 if (recv_flags & TF_GOT_FIN) {
00717 tcp_ack_now(pcb);
00718 pcb->state = CLOSE_WAIT;
00719 }
00720 } else {
00721
00722 tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(),
00723 tcphdr->dest, tcphdr->src);
00724 }
00725 } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) {
00726
00727 tcp_rexmit(pcb);
00728 }
00729 break;
00730 case CLOSE_WAIT:
00731
00732 case ESTABLISHED:
00733 tcp_receive(pcb);
00734 if (recv_flags & TF_GOT_FIN) {
00735 tcp_ack_now(pcb);
00736 pcb->state = CLOSE_WAIT;
00737 }
00738 break;
00739 case FIN_WAIT_1:
00740 tcp_receive(pcb);
00741 if (recv_flags & TF_GOT_FIN) {
00742 if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
00743 LWIP_DEBUGF(TCP_DEBUG,
00744 ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00745 tcp_ack_now(pcb);
00746 tcp_pcb_purge(pcb);
00747 TCP_RMV_ACTIVE(pcb);
00748 pcb->state = TIME_WAIT;
00749 TCP_REG(&tcp_tw_pcbs, pcb);
00750 } else {
00751 tcp_ack_now(pcb);
00752 pcb->state = CLOSING;
00753 }
00754 } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) {
00755 pcb->state = FIN_WAIT_2;
00756 }
00757 break;
00758 case FIN_WAIT_2:
00759 tcp_receive(pcb);
00760 if (recv_flags & TF_GOT_FIN) {
00761 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00762 tcp_ack_now(pcb);
00763 tcp_pcb_purge(pcb);
00764 TCP_RMV_ACTIVE(pcb);
00765 pcb->state = TIME_WAIT;
00766 TCP_REG(&tcp_tw_pcbs, pcb);
00767 }
00768 break;
00769 case CLOSING:
00770 tcp_receive(pcb);
00771 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
00772 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00773 tcp_pcb_purge(pcb);
00774 TCP_RMV_ACTIVE(pcb);
00775 pcb->state = TIME_WAIT;
00776 TCP_REG(&tcp_tw_pcbs, pcb);
00777 }
00778 break;
00779 case LAST_ACK:
00780 tcp_receive(pcb);
00781 if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
00782 LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
00783
00784 recv_flags |= TF_CLOSED;
00785 }
00786 break;
00787 default:
00788 break;
00789 }
00790 return ERR_OK;
00791 }
00792
00793 #if TCP_QUEUE_OOSEQ
00794
00795
00796
00797
00798
00799 static void
00800 tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next)
00801 {
00802 struct tcp_seg *old_seg;
00803
00804 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
00805
00806 tcp_segs_free(next);
00807 next = NULL;
00808 }
00809 else {
00810
00811
00812 while (next &&
00813 TCP_SEQ_GEQ((seqno + cseg->len),
00814 (next->tcphdr->seqno + next->len))) {
00815
00816 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
00817 TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN);
00818 }
00819 old_seg = next;
00820 next = next->next;
00821 tcp_seg_free(old_seg);
00822 }
00823 if (next &&
00824 TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) {
00825
00826 cseg->len = (u16_t)(next->tcphdr->seqno - seqno);
00827 pbuf_realloc(cseg->p, cseg->len);
00828 }
00829 }
00830 cseg->next = next;
00831 }
00832 #endif
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 static void
00847 tcp_receive(struct tcp_pcb *pcb)
00848 {
00849 struct tcp_seg *next;
00850 #if TCP_QUEUE_OOSEQ
00851 struct tcp_seg *prev, *cseg;
00852 #endif
00853 struct pbuf *p;
00854 s32_t off;
00855 s16_t m;
00856 u32_t right_wnd_edge;
00857 u16_t new_tot_len;
00858 int found_dupack = 0;
00859 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
00860 u32_t ooseq_blen;
00861 u16_t ooseq_qlen;
00862 #endif
00863
00864 LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED);
00865
00866 if (flags & TCP_ACK) {
00867 right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
00868
00869
00870 if (TCP_SEQ_LT(pcb->snd_wl1, seqno) ||
00871 (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) ||
00872 (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) {
00873 pcb->snd_wnd = tcphdr->wnd;
00874
00875
00876 if (pcb->snd_wnd_max < tcphdr->wnd) {
00877 pcb->snd_wnd_max = tcphdr->wnd;
00878 }
00879 pcb->snd_wl1 = seqno;
00880 pcb->snd_wl2 = ackno;
00881 if (pcb->snd_wnd == 0) {
00882 if (pcb->persist_backoff == 0) {
00883
00884 pcb->persist_cnt = 0;
00885 pcb->persist_backoff = 1;
00886 }
00887 } else if (pcb->persist_backoff > 0) {
00888
00889 pcb->persist_backoff = 0;
00890 }
00891 LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd));
00892 #if TCP_WND_DEBUG
00893 } else {
00894 if (pcb->snd_wnd != tcphdr->wnd) {
00895 LWIP_DEBUGF(TCP_WND_DEBUG,
00896 ("tcp_receive: no window update lastack %"U32_F" ackno %"
00897 U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n",
00898 pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2));
00899 }
00900 #endif
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 if (TCP_SEQ_LEQ(ackno, pcb->lastack)) {
00925 pcb->acked = 0;
00926
00927 if (tcplen == 0) {
00928
00929 if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){
00930
00931 if (pcb->rtime >= 0) {
00932
00933 if (pcb->lastack == ackno) {
00934 found_dupack = 1;
00935 if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) {
00936 ++pcb->dupacks;
00937 }
00938 if (pcb->dupacks > 3) {
00939
00940
00941 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
00942 pcb->cwnd += pcb->mss;
00943 }
00944 } else if (pcb->dupacks == 3) {
00945
00946 tcp_rexmit_fast(pcb);
00947 }
00948 }
00949 }
00950 }
00951 }
00952
00953
00954 if (!found_dupack) {
00955 pcb->dupacks = 0;
00956 }
00957 } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){
00958
00959
00960
00961
00962
00963 if (pcb->flags & TF_INFR) {
00964 pcb->flags &= ~TF_INFR;
00965 pcb->cwnd = pcb->ssthresh;
00966 }
00967
00968
00969 pcb->nrtx = 0;
00970
00971
00972 pcb->rto = (pcb->sa >> 3) + pcb->sv;
00973
00974
00975 pcb->acked = (u16_t)(ackno - pcb->lastack);
00976
00977 pcb->snd_buf += pcb->acked;
00978
00979
00980 pcb->dupacks = 0;
00981 pcb->lastack = ackno;
00982
00983
00984
00985 if (pcb->state >= ESTABLISHED) {
00986 if (pcb->cwnd < pcb->ssthresh) {
00987 if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) {
00988 pcb->cwnd += pcb->mss;
00989 }
00990 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd));
00991 } else {
00992 u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd);
00993 if (new_cwnd > pcb->cwnd) {
00994 pcb->cwnd = new_cwnd;
00995 }
00996 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd));
00997 }
00998 }
00999 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n",
01000 ackno,
01001 pcb->unacked != NULL?
01002 ntohl(pcb->unacked->tcphdr->seqno): 0,
01003 pcb->unacked != NULL?
01004 ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0));
01005
01006
01007
01008 while (pcb->unacked != NULL &&
01009 TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) +
01010 TCP_TCPLEN(pcb->unacked), ackno)) {
01011 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n",
01012 ntohl(pcb->unacked->tcphdr->seqno),
01013 ntohl(pcb->unacked->tcphdr->seqno) +
01014 TCP_TCPLEN(pcb->unacked)));
01015
01016 next = pcb->unacked;
01017 pcb->unacked = pcb->unacked->next;
01018
01019 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
01020 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
01021
01022 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
01023 pcb->acked--;
01024 }
01025
01026 pcb->snd_queuelen -= pbuf_clen(next->p);
01027 tcp_seg_free(next);
01028
01029 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen));
01030 if (pcb->snd_queuelen != 0) {
01031 LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||
01032 pcb->unsent != NULL);
01033 }
01034 }
01035
01036
01037
01038 if(pcb->unacked == NULL)
01039 pcb->rtime = -1;
01040 else
01041 pcb->rtime = 0;
01042
01043 pcb->polltmr = 0;
01044 } else {
01045
01046 pcb->acked = 0;
01047 }
01048
01049
01050
01051
01052
01053
01054
01055 while (pcb->unsent != NULL &&
01056 TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) +
01057 TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) {
01058 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n",
01059 ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) +
01060 TCP_TCPLEN(pcb->unsent)));
01061
01062 next = pcb->unsent;
01063 pcb->unsent = pcb->unsent->next;
01064 #if TCP_OVERSIZE
01065 if (pcb->unsent == NULL) {
01066 pcb->unsent_oversize = 0;
01067 }
01068 #endif
01069 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen));
01070 LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p)));
01071
01072 if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) {
01073 pcb->acked--;
01074 }
01075 pcb->snd_queuelen -= pbuf_clen(next->p);
01076 tcp_seg_free(next);
01077 LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen));
01078 if (pcb->snd_queuelen != 0) {
01079 LWIP_ASSERT("tcp_receive: valid queue length",
01080 pcb->unacked != NULL || pcb->unsent != NULL);
01081 }
01082 }
01083
01084
01085 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n",
01086 pcb->rttest, pcb->rtseq, ackno));
01087
01088
01089
01090
01091 if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) {
01092
01093
01094 m = (s16_t)(tcp_ticks - pcb->rttest);
01095
01096 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n",
01097 m, m * TCP_SLOW_INTERVAL));
01098
01099
01100 m = m - (pcb->sa >> 3);
01101 pcb->sa += m;
01102 if (m < 0) {
01103 m = -m;
01104 }
01105 m = m - (pcb->sv >> 2);
01106 pcb->sv += m;
01107 pcb->rto = (pcb->sa >> 3) + pcb->sv;
01108
01109 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n",
01110 pcb->rto, pcb->rto * TCP_SLOW_INTERVAL));
01111
01112 pcb->rttest = 0;
01113 }
01114 }
01115
01116
01117
01118
01119
01120 if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) {
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 off = pcb->rcv_nxt - seqno;
01173 p = inseg.p;
01174 LWIP_ASSERT("inseg.p != NULL", inseg.p);
01175 LWIP_ASSERT("insane offset!", (off < 0x7fff));
01176 if (inseg.p->len < off) {
01177 LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off));
01178 new_tot_len = (u16_t)(inseg.p->tot_len - off);
01179 while (p->len < off) {
01180 off -= p->len;
01181
01182
01183
01184 p->tot_len = new_tot_len;
01185 p->len = 0;
01186 p = p->next;
01187 }
01188 if(pbuf_header(p, (s16_t)-off)) {
01189
01190 LWIP_ASSERT("pbuf_header failed", 0);
01191 }
01192 } else {
01193 if(pbuf_header(inseg.p, (s16_t)-off)) {
01194
01195 LWIP_ASSERT("pbuf_header failed", 0);
01196 }
01197 }
01198 inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
01199 inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
01200 }
01201 else {
01202 if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){
01203
01204
01205
01206 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno));
01207 tcp_ack_now(pcb);
01208 }
01209 }
01210
01211
01212
01213
01214 if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,
01215 pcb->rcv_nxt + pcb->rcv_wnd - 1)){
01216 if (pcb->rcv_nxt == seqno) {
01217
01218
01219
01220 tcplen = TCP_TCPLEN(&inseg);
01221
01222 if (tcplen > pcb->rcv_wnd) {
01223 LWIP_DEBUGF(TCP_INPUT_DEBUG,
01224 ("tcp_receive: other end overran receive window"
01225 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
01226 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
01227 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01228
01229
01230 TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN);
01231 }
01232
01233 inseg.len = pcb->rcv_wnd;
01234 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
01235 inseg.len -= 1;
01236 }
01237 pbuf_realloc(inseg.p, inseg.len);
01238 tcplen = TCP_TCPLEN(&inseg);
01239 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
01240 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
01241 }
01242 #if TCP_QUEUE_OOSEQ
01243
01244
01245
01246 if (pcb->ooseq != NULL) {
01247 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01248 LWIP_DEBUGF(TCP_INPUT_DEBUG,
01249 ("tcp_receive: received in-order FIN, binning ooseq queue\n"));
01250
01251
01252
01253 while (pcb->ooseq != NULL) {
01254 struct tcp_seg *old_ooseq = pcb->ooseq;
01255 pcb->ooseq = pcb->ooseq->next;
01256 tcp_seg_free(old_ooseq);
01257 }
01258 } else {
01259 next = pcb->ooseq;
01260
01261
01262 while (next &&
01263 TCP_SEQ_GEQ(seqno + tcplen,
01264 next->tcphdr->seqno + next->len)) {
01265
01266 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN &&
01267 (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) {
01268 TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN);
01269 tcplen = TCP_TCPLEN(&inseg);
01270 }
01271 prev = next;
01272 next = next->next;
01273 tcp_seg_free(prev);
01274 }
01275
01276
01277 if (next &&
01278 TCP_SEQ_GT(seqno + tcplen,
01279 next->tcphdr->seqno)) {
01280
01281 inseg.len = (u16_t)(next->tcphdr->seqno - seqno);
01282 if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) {
01283 inseg.len -= 1;
01284 }
01285 pbuf_realloc(inseg.p, inseg.len);
01286 tcplen = TCP_TCPLEN(&inseg);
01287 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n",
01288 (seqno + tcplen) == next->tcphdr->seqno);
01289 }
01290 pcb->ooseq = next;
01291 }
01292 }
01293 #endif
01294
01295 pcb->rcv_nxt = seqno + tcplen;
01296
01297
01298 LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen);
01299 pcb->rcv_wnd -= tcplen;
01300
01301 tcp_update_rcv_ann_wnd(pcb);
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312 if (inseg.p->tot_len > 0) {
01313 recv_data = inseg.p;
01314
01315
01316
01317 inseg.p = NULL;
01318 }
01319 if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) {
01320 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n"));
01321 recv_flags |= TF_GOT_FIN;
01322 }
01323
01324 #if TCP_QUEUE_OOSEQ
01325
01326
01327 while (pcb->ooseq != NULL &&
01328 pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) {
01329
01330 cseg = pcb->ooseq;
01331 seqno = pcb->ooseq->tcphdr->seqno;
01332
01333 pcb->rcv_nxt += TCP_TCPLEN(cseg);
01334 LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n",
01335 pcb->rcv_wnd >= TCP_TCPLEN(cseg));
01336 pcb->rcv_wnd -= TCP_TCPLEN(cseg);
01337
01338 tcp_update_rcv_ann_wnd(pcb);
01339
01340 if (cseg->p->tot_len > 0) {
01341
01342
01343 if (recv_data) {
01344 pbuf_cat(recv_data, cseg->p);
01345 } else {
01346 recv_data = cseg->p;
01347 }
01348 cseg->p = NULL;
01349 }
01350 if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
01351 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
01352 recv_flags |= TF_GOT_FIN;
01353 if (pcb->state == ESTABLISHED) {
01354 pcb->state = CLOSE_WAIT;
01355 }
01356 }
01357
01358 pcb->ooseq = cseg->next;
01359 tcp_seg_free(cseg);
01360 }
01361 #endif
01362
01363
01364
01365 tcp_ack(pcb);
01366
01367 } else {
01368
01369 tcp_send_empty_ack(pcb);
01370 #if TCP_QUEUE_OOSEQ
01371
01372 if (pcb->ooseq == NULL) {
01373 pcb->ooseq = tcp_seg_copy(&inseg);
01374 } else {
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387 prev = NULL;
01388 for(next = pcb->ooseq; next != NULL; next = next->next) {
01389 if (seqno == next->tcphdr->seqno) {
01390
01391
01392
01393
01394 if (inseg.len > next->len) {
01395
01396
01397
01398 cseg = tcp_seg_copy(&inseg);
01399 if (cseg != NULL) {
01400 if (prev != NULL) {
01401 prev->next = cseg;
01402 } else {
01403 pcb->ooseq = cseg;
01404 }
01405 tcp_oos_insert_segment(cseg, next);
01406 }
01407 break;
01408 } else {
01409
01410
01411
01412 break;
01413 }
01414 } else {
01415 if (prev == NULL) {
01416 if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {
01417
01418
01419
01420
01421 cseg = tcp_seg_copy(&inseg);
01422 if (cseg != NULL) {
01423 pcb->ooseq = cseg;
01424 tcp_oos_insert_segment(cseg, next);
01425 }
01426 break;
01427 }
01428 } else {
01429
01430
01431 if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) {
01432
01433
01434
01435
01436
01437 cseg = tcp_seg_copy(&inseg);
01438 if (cseg != NULL) {
01439 if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) {
01440
01441 prev->len = (u16_t)(seqno - prev->tcphdr->seqno);
01442 pbuf_realloc(prev->p, prev->len);
01443 }
01444 prev->next = cseg;
01445 tcp_oos_insert_segment(cseg, next);
01446 }
01447 break;
01448 }
01449 }
01450
01451
01452
01453 if (next->next == NULL &&
01454 TCP_SEQ_GT(seqno, next->tcphdr->seqno)) {
01455 if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) {
01456
01457 break;
01458 }
01459 next->next = tcp_seg_copy(&inseg);
01460 if (next->next != NULL) {
01461 if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) {
01462
01463 next->len = (u16_t)(seqno - next->tcphdr->seqno);
01464 pbuf_realloc(next->p, next->len);
01465 }
01466
01467 if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) {
01468 LWIP_DEBUGF(TCP_INPUT_DEBUG,
01469 ("tcp_receive: other end overran receive window"
01470 "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n",
01471 seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd));
01472 if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) {
01473
01474
01475 TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN);
01476 }
01477
01478 next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno;
01479 pbuf_realloc(next->next->p, next->next->len);
01480 tcplen = TCP_TCPLEN(next->next);
01481 LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n",
01482 (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd));
01483 }
01484 }
01485 break;
01486 }
01487 }
01488 prev = next;
01489 }
01490 }
01491 #if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS
01492
01493
01494 ooseq_blen = 0;
01495 ooseq_qlen = 0;
01496 prev = NULL;
01497 for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) {
01498 struct pbuf *p = next->p;
01499 ooseq_blen += p->tot_len;
01500 ooseq_qlen += pbuf_clen(p);
01501 if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) ||
01502 (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) {
01503
01504 tcp_segs_free(next);
01505 if (prev == NULL) {
01506
01507 pcb->ooseq = NULL;
01508 } else {
01509
01510 prev->next = NULL;
01511 }
01512 break;
01513 }
01514 }
01515 #endif
01516 #endif
01517 }
01518 } else {
01519
01520 tcp_send_empty_ack(pcb);
01521 }
01522 } else {
01523
01524
01525
01526
01527 if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){
01528 tcp_ack_now(pcb);
01529 }
01530 }
01531 }
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 static void
01542 tcp_parseopt(struct tcp_pcb *pcb)
01543 {
01544 u16_t c, max_c;
01545 u16_t mss;
01546 u8_t *opts, opt;
01547 #if LWIP_TCP_TIMESTAMPS
01548 u32_t tsval;
01549 #endif
01550
01551 opts = (u8_t *)tcphdr + TCP_HLEN;
01552
01553
01554 if(TCPH_HDRLEN(tcphdr) > 0x5) {
01555 max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2;
01556 for (c = 0; c < max_c; ) {
01557 opt = opts[c];
01558 switch (opt) {
01559 case 0x00:
01560
01561 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n"));
01562 return;
01563 case 0x01:
01564
01565 ++c;
01566 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n"));
01567 break;
01568 case 0x02:
01569 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n"));
01570 if (opts[c + 1] != 0x04 || c + 0x04 > max_c) {
01571
01572 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01573 return;
01574 }
01575
01576 mss = (opts[c + 2] << 8) | opts[c + 3];
01577
01578 pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss;
01579
01580 c += 0x04;
01581 break;
01582 #if LWIP_TCP_TIMESTAMPS
01583 case 0x08:
01584 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n"));
01585 if (opts[c + 1] != 0x0A || c + 0x0A > max_c) {
01586
01587 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01588 return;
01589 }
01590
01591 tsval = (opts[c+2]) | (opts[c+3] << 8) |
01592 (opts[c+4] << 16) | (opts[c+5] << 24);
01593 if (flags & TCP_SYN) {
01594 pcb->ts_recent = ntohl(tsval);
01595 pcb->flags |= TF_TIMESTAMP;
01596 } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) {
01597 pcb->ts_recent = ntohl(tsval);
01598 }
01599
01600 c += 0x0A;
01601 break;
01602 #endif
01603 default:
01604 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n"));
01605 if (opts[c + 1] == 0) {
01606 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n"));
01607
01608
01609 return;
01610 }
01611
01612
01613 c += opts[c + 1];
01614 }
01615 }
01616 }
01617 }
01618
01619 #endif