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