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 #include "lwip/opt.h"
00044
00045 #if LWIP_TCP
00046
00047 #include "lwip/def.h"
00048 #include "lwip/mem.h"
00049 #include "lwip/memp.h"
00050 #include "lwip/snmp.h"
00051 #include "lwip/tcp.h"
00052 #include "lwip/tcp_impl.h"
00053 #include "lwip/debug.h"
00054 #include "lwip/stats.h"
00055
00056 #include <string.h>
00057
00058 #ifndef TCP_LOCAL_PORT_RANGE_START
00059
00060
00061 #define TCP_LOCAL_PORT_RANGE_START 0xc000
00062 #define TCP_LOCAL_PORT_RANGE_END 0xffff
00063 #define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START)
00064 #endif
00065
00066 #if LWIP_TCP_KEEPALIVE
00067 #define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl)
00068 #define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl)
00069 #else
00070 #define TCP_KEEP_DUR(pcb) TCP_MAXIDLE
00071 #define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT
00072 #endif
00073
00074 const char * const tcp_state_str[] = {
00075 "CLOSED",
00076 "LISTEN",
00077 "SYN_SENT",
00078 "SYN_RCVD",
00079 "ESTABLISHED",
00080 "FIN_WAIT_1",
00081 "FIN_WAIT_2",
00082 "CLOSE_WAIT",
00083 "CLOSING",
00084 "LAST_ACK",
00085 "TIME_WAIT"
00086 };
00087
00088
00089 static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START;
00090
00091
00092 u32_t tcp_ticks;
00093 const u8_t tcp_backoff[13] =
00094 { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
00095
00096 const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 };
00097
00098
00099
00100
00101 struct tcp_pcb *tcp_bound_pcbs;
00102
00103 union tcp_listen_pcbs_t tcp_listen_pcbs;
00104
00105
00106 struct tcp_pcb *tcp_active_pcbs;
00107
00108 struct tcp_pcb *tcp_tw_pcbs;
00109
00110 #define NUM_TCP_PCB_LISTS 4
00111 #define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3
00112
00113 struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
00114 &tcp_active_pcbs, &tcp_tw_pcbs};
00115
00116
00117 struct tcp_pcb *tcp_tmp_pcb;
00118
00119 u8_t tcp_active_pcbs_changed;
00120
00121
00122 static u8_t tcp_timer;
00123 static u8_t tcp_timer_ctr;
00124 static u16_t tcp_new_port(void);
00125
00126
00127
00128
00129 void
00130 tcp_init(void)
00131 {
00132 #if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND)
00133 tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
00134 #endif
00135 }
00136
00137
00138
00139
00140 void
00141 tcp_tmr(void)
00142 {
00143
00144 tcp_fasttmr();
00145
00146 if (++tcp_timer & 1) {
00147
00148
00149 tcp_slowtmr();
00150 }
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 static err_t
00170 tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
00171 {
00172 err_t err;
00173
00174 if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) {
00175 if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) {
00176
00177
00178 LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED);
00179
00180
00181
00182 tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
00183 pcb->local_port, pcb->remote_port);
00184
00185 tcp_pcb_purge(pcb);
00186 TCP_RMV_ACTIVE(pcb);
00187 if (pcb->state == ESTABLISHED) {
00188
00189 pcb->state = TIME_WAIT;
00190 TCP_REG(&tcp_tw_pcbs, pcb);
00191 } else {
00192
00193 memp_free(MEMP_TCP_PCB, pcb);
00194 }
00195 return ERR_OK;
00196 }
00197 }
00198
00199 switch (pcb->state) {
00200 case CLOSED:
00201
00202
00203
00204
00205
00206
00207
00208 err = ERR_OK;
00209 if (pcb->local_port != 0) {
00210 TCP_RMV(&tcp_bound_pcbs, pcb);
00211 }
00212 memp_free(MEMP_TCP_PCB, pcb);
00213 pcb = NULL;
00214 break;
00215 case LISTEN:
00216 err = ERR_OK;
00217 tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
00218 memp_free(MEMP_TCP_PCB_LISTEN, pcb);
00219 pcb = NULL;
00220 break;
00221 case SYN_SENT:
00222 err = ERR_OK;
00223 TCP_PCB_REMOVE_ACTIVE(pcb);
00224 memp_free(MEMP_TCP_PCB, pcb);
00225 pcb = NULL;
00226 snmp_inc_tcpattemptfails();
00227 break;
00228 case SYN_RCVD:
00229 err = tcp_send_fin(pcb);
00230 if (err == ERR_OK) {
00231 snmp_inc_tcpattemptfails();
00232 pcb->state = FIN_WAIT_1;
00233 }
00234 break;
00235 case ESTABLISHED:
00236 err = tcp_send_fin(pcb);
00237 if (err == ERR_OK) {
00238 snmp_inc_tcpestabresets();
00239 pcb->state = FIN_WAIT_1;
00240 }
00241 break;
00242 case CLOSE_WAIT:
00243 err = tcp_send_fin(pcb);
00244 if (err == ERR_OK) {
00245 snmp_inc_tcpestabresets();
00246 pcb->state = LAST_ACK;
00247 }
00248 break;
00249 default:
00250
00251 err = ERR_OK;
00252 pcb = NULL;
00253 break;
00254 }
00255
00256 if (pcb != NULL && err == ERR_OK) {
00257
00258
00259
00260
00261
00262
00263
00264
00265 tcp_output(pcb);
00266 }
00267 return err;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 err_t
00285 tcp_close(struct tcp_pcb *pcb)
00286 {
00287 #if TCP_DEBUG
00288 LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in "));
00289 tcp_debug_print_state(pcb->state);
00290 #endif
00291
00292 if (pcb->state != LISTEN) {
00293
00294 pcb->flags |= TF_RXCLOSED;
00295 }
00296
00297 return tcp_close_shutdown(pcb, 1);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 err_t
00313 tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx)
00314 {
00315 if (pcb->state == LISTEN) {
00316 return ERR_CONN;
00317 }
00318 if (shut_rx) {
00319
00320 pcb->flags |= TF_RXCLOSED;
00321 if (shut_tx) {
00322
00323 return tcp_close_shutdown(pcb, 1);
00324 }
00325
00326 if (pcb->refused_data != NULL) {
00327 pbuf_free(pcb->refused_data);
00328 pcb->refused_data = NULL;
00329 }
00330 }
00331 if (shut_tx) {
00332
00333
00334 switch (pcb->state) {
00335 case SYN_RCVD:
00336 case ESTABLISHED:
00337 case CLOSE_WAIT:
00338 return tcp_close_shutdown(pcb, shut_rx);
00339 default:
00340
00341
00342 return ERR_CONN;
00343 }
00344 }
00345 return ERR_OK;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 void
00357 tcp_abandon(struct tcp_pcb *pcb, int reset)
00358 {
00359 u32_t seqno, ackno;
00360 #if LWIP_CALLBACK_API
00361 tcp_err_fn errf;
00362 #endif
00363 void *errf_arg;
00364
00365
00366 LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs",
00367 pcb->state != LISTEN);
00368
00369
00370
00371 if (pcb->state == TIME_WAIT) {
00372 tcp_pcb_remove(&tcp_tw_pcbs, pcb);
00373 memp_free(MEMP_TCP_PCB, pcb);
00374 } else {
00375 seqno = pcb->snd_nxt;
00376 ackno = pcb->rcv_nxt;
00377 #if LWIP_CALLBACK_API
00378 errf = pcb->errf;
00379 #endif
00380 errf_arg = pcb->callback_arg;
00381 TCP_PCB_REMOVE_ACTIVE(pcb);
00382 if (pcb->unacked != NULL) {
00383 tcp_segs_free(pcb->unacked);
00384 }
00385 if (pcb->unsent != NULL) {
00386 tcp_segs_free(pcb->unsent);
00387 }
00388 #if TCP_QUEUE_OOSEQ
00389 if (pcb->ooseq != NULL) {
00390 tcp_segs_free(pcb->ooseq);
00391 }
00392 #endif
00393 if (reset) {
00394 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
00395 tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port);
00396 }
00397 memp_free(MEMP_TCP_PCB, pcb);
00398 TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
00399 }
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 void
00413 tcp_abort(struct tcp_pcb *pcb)
00414 {
00415 tcp_abandon(pcb, 1);
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 err_t
00433 tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
00434 {
00435 int i;
00436 int max_pcb_list = NUM_TCP_PCB_LISTS;
00437 struct tcp_pcb *cpcb;
00438
00439 LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
00440
00441 #if SO_REUSE
00442
00443
00444
00445
00446
00447 if (ip_get_option(pcb, SOF_REUSEADDR)) {
00448 max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
00449 }
00450 #endif
00451
00452 if (port == 0) {
00453 port = tcp_new_port();
00454 if (port == 0) {
00455 return ERR_BUF;
00456 }
00457 }
00458
00459
00460 for (i = 0; i < max_pcb_list; i++) {
00461 for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
00462 if (cpcb->local_port == port) {
00463 #if SO_REUSE
00464
00465
00466
00467 if (!ip_get_option(pcb, SOF_REUSEADDR) ||
00468 !ip_get_option(cpcb, SOF_REUSEADDR))
00469 #endif
00470 {
00471 if (ip_addr_isany(&(cpcb->local_ip)) ||
00472 ip_addr_isany(ipaddr) ||
00473 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00474 return ERR_USE;
00475 }
00476 }
00477 }
00478 }
00479 }
00480
00481 if (!ip_addr_isany(ipaddr)) {
00482 pcb->local_ip = *ipaddr;
00483 }
00484 pcb->local_port = port;
00485 TCP_REG(&tcp_bound_pcbs, pcb);
00486 LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port));
00487 return ERR_OK;
00488 }
00489 #if LWIP_CALLBACK_API
00490
00491
00492
00493 static err_t
00494 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
00495 {
00496 LWIP_UNUSED_ARG(arg);
00497 LWIP_UNUSED_ARG(pcb);
00498 LWIP_UNUSED_ARG(err);
00499
00500 return ERR_ABRT;
00501 }
00502 #endif
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 struct tcp_pcb *
00519 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
00520 {
00521 struct tcp_pcb_listen *lpcb;
00522
00523 LWIP_UNUSED_ARG(backlog);
00524 LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
00525
00526
00527 if (pcb->state == LISTEN) {
00528 return pcb;
00529 }
00530 #if SO_REUSE
00531 if (ip_get_option(pcb, SOF_REUSEADDR)) {
00532
00533
00534
00535 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
00536 if (lpcb->local_port == pcb->local_port) {
00537 if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) {
00538
00539 return NULL;
00540 }
00541 }
00542 }
00543 }
00544 #endif
00545 lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN);
00546 if (lpcb == NULL) {
00547 return NULL;
00548 }
00549 lpcb->callback_arg = pcb->callback_arg;
00550 lpcb->local_port = pcb->local_port;
00551 lpcb->state = LISTEN;
00552 lpcb->prio = pcb->prio;
00553 lpcb->so_options = pcb->so_options;
00554 ip_set_option(lpcb, SOF_ACCEPTCONN);
00555 lpcb->ttl = pcb->ttl;
00556 lpcb->tos = pcb->tos;
00557 ip_addr_copy(lpcb->local_ip, pcb->local_ip);
00558 if (pcb->local_port != 0) {
00559 TCP_RMV(&tcp_bound_pcbs, pcb);
00560 }
00561 memp_free(MEMP_TCP_PCB, pcb);
00562 #if LWIP_CALLBACK_API
00563 lpcb->accept = tcp_accept_null;
00564 #endif
00565 #if TCP_LISTEN_BACKLOG
00566 lpcb->accepts_pending = 0;
00567 lpcb->backlog = (backlog ? backlog : 1);
00568 #endif
00569 TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb);
00570 return (struct tcp_pcb *)lpcb;
00571 }
00572
00573
00574
00575
00576
00577
00578
00579 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb)
00580 {
00581 u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd;
00582
00583 if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) {
00584
00585 pcb->rcv_ann_wnd = pcb->rcv_wnd;
00586 return new_right_edge - pcb->rcv_ann_right_edge;
00587 } else {
00588 if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) {
00589
00590
00591 pcb->rcv_ann_wnd = 0;
00592 } else {
00593
00594 u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt;
00595 LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff);
00596 pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd;
00597 }
00598 return 0;
00599 }
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 void
00611 tcp_recved(struct tcp_pcb *pcb, u16_t len)
00612 {
00613 int wnd_inflation;
00614
00615
00616 LWIP_ASSERT("don't call tcp_recved for listen-pcbs",
00617 pcb->state != LISTEN);
00618 LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n",
00619 len <= 0xffff - pcb->rcv_wnd );
00620
00621 pcb->rcv_wnd += len;
00622 if (pcb->rcv_wnd > TCP_WND) {
00623 pcb->rcv_wnd = TCP_WND;
00624 }
00625
00626 wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
00627
00628
00629
00630
00631
00632 if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) {
00633 tcp_ack_now(pcb);
00634 tcp_output(pcb);
00635 }
00636
00637 LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n",
00638 len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
00639 }
00640
00641
00642
00643
00644
00645
00646 static u16_t
00647 tcp_new_port(void)
00648 {
00649 u8_t i;
00650 u16_t n = 0;
00651 struct tcp_pcb *pcb;
00652
00653 again:
00654 if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) {
00655 tcp_port = TCP_LOCAL_PORT_RANGE_START;
00656 }
00657
00658 for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
00659 for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
00660 if (pcb->local_port == tcp_port) {
00661 if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) {
00662 return 0;
00663 }
00664 goto again;
00665 }
00666 }
00667 }
00668 return tcp_port;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 err_t
00684 tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
00685 tcp_connected_fn connected)
00686 {
00687 err_t ret;
00688 u32_t iss;
00689 u16_t old_local_port;
00690
00691 LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
00692
00693 LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
00694 if (ipaddr != NULL) {
00695 pcb->remote_ip = *ipaddr;
00696 } else {
00697 return ERR_VAL;
00698 }
00699 pcb->remote_port = port;
00700
00701
00702 if (ip_addr_isany(&(pcb->local_ip))) {
00703
00704 struct netif *netif = ip_route(&(pcb->remote_ip));
00705 if (netif == NULL) {
00706
00707
00708 return ERR_RTE;
00709 }
00710
00711 ip_addr_copy(pcb->local_ip, netif->ip_addr);
00712 }
00713
00714 old_local_port = pcb->local_port;
00715 if (pcb->local_port == 0) {
00716 pcb->local_port = tcp_new_port();
00717 if (pcb->local_port == 0) {
00718 return ERR_BUF;
00719 }
00720 }
00721 #if SO_REUSE
00722 if (ip_get_option(pcb, SOF_REUSEADDR)) {
00723
00724
00725 struct tcp_pcb *cpcb;
00726 int i;
00727
00728 for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
00729 for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
00730 if ((cpcb->local_port == pcb->local_port) &&
00731 (cpcb->remote_port == port) &&
00732 ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) &&
00733 ip_addr_cmp(&cpcb->remote_ip, ipaddr)) {
00734
00735 return ERR_USE;
00736 }
00737 }
00738 }
00739 }
00740 #endif
00741 iss = tcp_next_iss();
00742 pcb->rcv_nxt = 0;
00743 pcb->snd_nxt = iss;
00744 pcb->lastack = iss - 1;
00745 pcb->snd_lbb = iss - 1;
00746 pcb->rcv_wnd = TCP_WND;
00747 pcb->rcv_ann_wnd = TCP_WND;
00748 pcb->rcv_ann_right_edge = pcb->rcv_nxt;
00749 pcb->snd_wnd = TCP_WND;
00750
00751
00752 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
00753 #if TCP_CALCULATE_EFF_SEND_MSS
00754 pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr);
00755 #endif
00756 pcb->cwnd = 1;
00757 pcb->ssthresh = pcb->mss * 10;
00758 #if LWIP_CALLBACK_API
00759 pcb->connected = connected;
00760 #else
00761 LWIP_UNUSED_ARG(connected);
00762 #endif
00763
00764
00765 ret = tcp_enqueue_flags(pcb, TCP_SYN);
00766 if (ret == ERR_OK) {
00767
00768 pcb->state = SYN_SENT;
00769 if (old_local_port != 0) {
00770 TCP_RMV(&tcp_bound_pcbs, pcb);
00771 }
00772 TCP_REG_ACTIVE(pcb);
00773 snmp_inc_tcpactiveopens();
00774
00775 tcp_output(pcb);
00776 }
00777 return ret;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787 void
00788 tcp_slowtmr(void)
00789 {
00790 struct tcp_pcb *pcb, *prev;
00791 u16_t eff_wnd;
00792 u8_t pcb_remove;
00793 u8_t pcb_reset;
00794 err_t err;
00795
00796 err = ERR_OK;
00797
00798 ++tcp_ticks;
00799 ++tcp_timer_ctr;
00800
00801 tcp_slowtmr_start:
00802
00803 prev = NULL;
00804 pcb = tcp_active_pcbs;
00805 if (pcb == NULL) {
00806 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
00807 }
00808 while (pcb != NULL) {
00809 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
00810 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
00811 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
00812 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
00813 if (pcb->last_timer == tcp_timer_ctr) {
00814
00815 pcb = pcb->next;
00816 continue;
00817 }
00818 pcb->last_timer = tcp_timer_ctr;
00819
00820 pcb_remove = 0;
00821 pcb_reset = 0;
00822
00823 if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
00824 ++pcb_remove;
00825 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
00826 }
00827 else if (pcb->nrtx == TCP_MAXRTX) {
00828 ++pcb_remove;
00829 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
00830 } else {
00831 if (pcb->persist_backoff > 0) {
00832
00833
00834 pcb->persist_cnt++;
00835 if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) {
00836 pcb->persist_cnt = 0;
00837 if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) {
00838 pcb->persist_backoff++;
00839 }
00840 tcp_zero_window_probe(pcb);
00841 }
00842 } else {
00843
00844 if(pcb->rtime >= 0) {
00845 ++pcb->rtime;
00846 }
00847
00848 if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
00849
00850 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F
00851 " pcb->rto %"S16_F"\n",
00852 pcb->rtime, pcb->rto));
00853
00854
00855
00856 if (pcb->state != SYN_SENT) {
00857 pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
00858 }
00859
00860
00861 pcb->rtime = 0;
00862
00863
00864 eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd);
00865 pcb->ssthresh = eff_wnd >> 1;
00866 if (pcb->ssthresh < (pcb->mss << 1)) {
00867 pcb->ssthresh = (pcb->mss << 1);
00868 }
00869 pcb->cwnd = pcb->mss;
00870 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F
00871 " ssthresh %"U16_F"\n",
00872 pcb->cwnd, pcb->ssthresh));
00873
00874
00875
00876 tcp_rexmit_rto(pcb);
00877 }
00878 }
00879 }
00880
00881 if (pcb->state == FIN_WAIT_2) {
00882
00883 if (pcb->flags & TF_RXCLOSED) {
00884
00885
00886 if ((u32_t)(tcp_ticks - pcb->tmr) >
00887 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
00888 ++pcb_remove;
00889 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
00890 }
00891 }
00892 }
00893
00894
00895 if(ip_get_option(pcb, SOF_KEEPALIVE) &&
00896 ((pcb->state == ESTABLISHED) ||
00897 (pcb->state == CLOSE_WAIT))) {
00898 if((u32_t)(tcp_ticks - pcb->tmr) >
00899 (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL)
00900 {
00901 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n",
00902 ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip),
00903 ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip)));
00904
00905 ++pcb_remove;
00906 ++pcb_reset;
00907 }
00908 else if((u32_t)(tcp_ticks - pcb->tmr) >
00909 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb))
00910 / TCP_SLOW_INTERVAL)
00911 {
00912 tcp_keepalive(pcb);
00913 pcb->keep_cnt_sent++;
00914 }
00915 }
00916
00917
00918
00919
00920 #if TCP_QUEUE_OOSEQ
00921 if (pcb->ooseq != NULL &&
00922 (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) {
00923 tcp_segs_free(pcb->ooseq);
00924 pcb->ooseq = NULL;
00925 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
00926 }
00927 #endif
00928
00929
00930 if (pcb->state == SYN_RCVD) {
00931 if ((u32_t)(tcp_ticks - pcb->tmr) >
00932 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
00933 ++pcb_remove;
00934 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
00935 }
00936 }
00937
00938
00939 if (pcb->state == LAST_ACK) {
00940 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
00941 ++pcb_remove;
00942 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n"));
00943 }
00944 }
00945
00946
00947 if (pcb_remove) {
00948 struct tcp_pcb *pcb2;
00949 tcp_err_fn err_fn;
00950 void *err_arg;
00951 tcp_pcb_purge(pcb);
00952
00953 if (prev != NULL) {
00954 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
00955 prev->next = pcb->next;
00956 } else {
00957
00958 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
00959 tcp_active_pcbs = pcb->next;
00960 }
00961
00962 if (pcb_reset) {
00963 tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
00964 pcb->local_port, pcb->remote_port);
00965 }
00966
00967 err_fn = pcb->errf;
00968 err_arg = pcb->callback_arg;
00969 pcb2 = pcb;
00970 pcb = pcb->next;
00971 memp_free(MEMP_TCP_PCB, pcb2);
00972
00973 tcp_active_pcbs_changed = 0;
00974 TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT);
00975 if (tcp_active_pcbs_changed) {
00976 goto tcp_slowtmr_start;
00977 }
00978 } else {
00979
00980 prev = pcb;
00981 pcb = pcb->next;
00982
00983
00984 ++prev->polltmr;
00985 if (prev->polltmr >= prev->pollinterval) {
00986 prev->polltmr = 0;
00987 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
00988 tcp_active_pcbs_changed = 0;
00989 TCP_EVENT_POLL(prev, err);
00990 if (tcp_active_pcbs_changed) {
00991 goto tcp_slowtmr_start;
00992 }
00993
00994 if (err == ERR_OK) {
00995 tcp_output(prev);
00996 }
00997 }
00998 }
00999 }
01000
01001
01002
01003 prev = NULL;
01004 pcb = tcp_tw_pcbs;
01005 while (pcb != NULL) {
01006 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
01007 pcb_remove = 0;
01008
01009
01010 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
01011 ++pcb_remove;
01012 }
01013
01014
01015
01016
01017 if (pcb_remove) {
01018 struct tcp_pcb *pcb2;
01019 tcp_pcb_purge(pcb);
01020
01021 if (prev != NULL) {
01022 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
01023 prev->next = pcb->next;
01024 } else {
01025
01026 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
01027 tcp_tw_pcbs = pcb->next;
01028 }
01029 pcb2 = pcb;
01030 pcb = pcb->next;
01031 memp_free(MEMP_TCP_PCB, pcb2);
01032 } else {
01033 prev = pcb;
01034 pcb = pcb->next;
01035 }
01036 }
01037 }
01038
01039
01040
01041
01042
01043
01044
01045 void
01046 tcp_fasttmr(void)
01047 {
01048 struct tcp_pcb *pcb;
01049
01050 ++tcp_timer_ctr;
01051
01052 tcp_fasttmr_start:
01053 pcb = tcp_active_pcbs;
01054
01055 while(pcb != NULL) {
01056 if (pcb->last_timer != tcp_timer_ctr) {
01057 struct tcp_pcb *next;
01058 pcb->last_timer = tcp_timer_ctr;
01059
01060 if (pcb->flags & TF_ACK_DELAY) {
01061 LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
01062 tcp_ack_now(pcb);
01063 tcp_output(pcb);
01064 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
01065 }
01066
01067 next = pcb->next;
01068
01069
01070 if (pcb->refused_data != NULL) {
01071 tcp_active_pcbs_changed = 0;
01072 tcp_process_refused_data(pcb);
01073 if (tcp_active_pcbs_changed) {
01074
01075 goto tcp_fasttmr_start;
01076 }
01077 }
01078 pcb = next;
01079 }
01080 }
01081 }
01082
01083
01084 err_t
01085 tcp_process_refused_data(struct tcp_pcb *pcb)
01086 {
01087 err_t err;
01088 u8_t refused_flags = pcb->refused_data->flags;
01089
01090
01091 struct pbuf *refused_data = pcb->refused_data;
01092 pcb->refused_data = NULL;
01093
01094 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
01095 TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err);
01096 if (err == ERR_OK) {
01097
01098 if (refused_flags & PBUF_FLAG_TCP_FIN) {
01099
01100
01101 if (pcb->rcv_wnd != TCP_WND) {
01102 pcb->rcv_wnd++;
01103 }
01104 TCP_EVENT_CLOSED(pcb, err);
01105 if (err == ERR_ABRT) {
01106 return ERR_ABRT;
01107 }
01108 }
01109 } else if (err == ERR_ABRT) {
01110
01111
01112
01113 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
01114 return ERR_ABRT;
01115 } else {
01116
01117 pcb->refused_data = refused_data;
01118 }
01119 return ERR_OK;
01120 }
01121
01122
01123
01124
01125
01126
01127 void
01128 tcp_segs_free(struct tcp_seg *seg)
01129 {
01130 while (seg != NULL) {
01131 struct tcp_seg *next = seg->next;
01132 tcp_seg_free(seg);
01133 seg = next;
01134 }
01135 }
01136
01137
01138
01139
01140
01141
01142 void
01143 tcp_seg_free(struct tcp_seg *seg)
01144 {
01145 if (seg != NULL) {
01146 if (seg->p != NULL) {
01147 pbuf_free(seg->p);
01148 #if TCP_DEBUG
01149 seg->p = NULL;
01150 #endif
01151 }
01152 memp_free(MEMP_TCP_SEG, seg);
01153 }
01154 }
01155
01156
01157
01158
01159
01160
01161
01162 void
01163 tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
01164 {
01165 pcb->prio = prio;
01166 }
01167
01168 #if TCP_QUEUE_OOSEQ
01169
01170
01171
01172
01173
01174
01175
01176 struct tcp_seg *
01177 tcp_seg_copy(struct tcp_seg *seg)
01178 {
01179 struct tcp_seg *cseg;
01180
01181 cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
01182 if (cseg == NULL) {
01183 return NULL;
01184 }
01185 SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg));
01186 pbuf_ref(cseg->p);
01187 return cseg;
01188 }
01189 #endif
01190
01191 #if LWIP_CALLBACK_API
01192
01193
01194
01195
01196 err_t
01197 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
01198 {
01199 LWIP_UNUSED_ARG(arg);
01200 if (p != NULL) {
01201 tcp_recved(pcb, p->tot_len);
01202 pbuf_free(p);
01203 } else if (err == ERR_OK) {
01204 return tcp_close(pcb);
01205 }
01206 return ERR_OK;
01207 }
01208 #endif
01209
01210
01211
01212
01213
01214
01215
01216 static void
01217 tcp_kill_prio(u8_t prio)
01218 {
01219 struct tcp_pcb *pcb, *inactive;
01220 u32_t inactivity;
01221 u8_t mprio;
01222
01223
01224 mprio = TCP_PRIO_MAX;
01225
01226
01227 inactivity = 0;
01228 inactive = NULL;
01229 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01230 if (pcb->prio <= prio &&
01231 pcb->prio <= mprio &&
01232 (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
01233 inactivity = tcp_ticks - pcb->tmr;
01234 inactive = pcb;
01235 mprio = pcb->prio;
01236 }
01237 }
01238 if (inactive != NULL) {
01239 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n",
01240 (void *)inactive, inactivity));
01241 tcp_abort(inactive);
01242 }
01243 }
01244
01245
01246
01247
01248
01249 static void
01250 tcp_kill_timewait(void)
01251 {
01252 struct tcp_pcb *pcb, *inactive;
01253 u32_t inactivity;
01254
01255 inactivity = 0;
01256 inactive = NULL;
01257
01258 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01259 if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
01260 inactivity = tcp_ticks - pcb->tmr;
01261 inactive = pcb;
01262 }
01263 }
01264 if (inactive != NULL) {
01265 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n",
01266 (void *)inactive, inactivity));
01267 tcp_abort(inactive);
01268 }
01269 }
01270
01271
01272
01273
01274
01275
01276
01277 struct tcp_pcb *
01278 tcp_alloc(u8_t prio)
01279 {
01280 struct tcp_pcb *pcb;
01281 u32_t iss;
01282
01283 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01284 if (pcb == NULL) {
01285
01286 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
01287 tcp_kill_timewait();
01288
01289 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01290 if (pcb == NULL) {
01291
01292 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio));
01293 tcp_kill_prio(prio);
01294
01295 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
01296 if (pcb != NULL) {
01297
01298 MEMP_STATS_DEC(err, MEMP_TCP_PCB);
01299 }
01300 }
01301 if (pcb != NULL) {
01302
01303 MEMP_STATS_DEC(err, MEMP_TCP_PCB);
01304 }
01305 }
01306 if (pcb != NULL) {
01307 memset(pcb, 0, sizeof(struct tcp_pcb));
01308 pcb->prio = prio;
01309 pcb->snd_buf = TCP_SND_BUF;
01310 pcb->snd_queuelen = 0;
01311 pcb->rcv_wnd = TCP_WND;
01312 pcb->rcv_ann_wnd = TCP_WND;
01313 pcb->tos = 0;
01314 pcb->ttl = TCP_TTL;
01315
01316
01317 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS;
01318 pcb->rto = 3000 / TCP_SLOW_INTERVAL;
01319 pcb->sa = 0;
01320 pcb->sv = 3000 / TCP_SLOW_INTERVAL;
01321 pcb->rtime = -1;
01322 pcb->cwnd = 1;
01323 iss = tcp_next_iss();
01324 pcb->snd_wl2 = iss;
01325 pcb->snd_nxt = iss;
01326 pcb->lastack = iss;
01327 pcb->snd_lbb = iss;
01328 pcb->tmr = tcp_ticks;
01329 pcb->last_timer = tcp_timer_ctr;
01330
01331 pcb->polltmr = 0;
01332
01333 #if LWIP_CALLBACK_API
01334 pcb->recv = tcp_recv_null;
01335 #endif
01336
01337
01338 pcb->keep_idle = TCP_KEEPIDLE_DEFAULT;
01339
01340 #if LWIP_TCP_KEEPALIVE
01341 pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT;
01342 pcb->keep_cnt = TCP_KEEPCNT_DEFAULT;
01343 #endif
01344
01345 pcb->keep_cnt_sent = 0;
01346 }
01347 return pcb;
01348 }
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362 struct tcp_pcb *
01363 tcp_new(void)
01364 {
01365 return tcp_alloc(TCP_PRIO_NORMAL);
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375 void
01376 tcp_arg(struct tcp_pcb *pcb, void *arg)
01377 {
01378
01379
01380 pcb->callback_arg = arg;
01381 }
01382 #if LWIP_CALLBACK_API
01383
01384
01385
01386
01387
01388
01389
01390
01391 void
01392 tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv)
01393 {
01394 LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN);
01395 pcb->recv = recv;
01396 }
01397
01398
01399
01400
01401
01402
01403
01404
01405 void
01406 tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent)
01407 {
01408 LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN);
01409 pcb->sent = sent;
01410 }
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420 void
01421 tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
01422 {
01423 LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN);
01424 pcb->errf = err;
01425 }
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435 void
01436 tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept)
01437 {
01438
01439
01440 pcb->accept = accept;
01441 }
01442 #endif
01443
01444
01445
01446
01447
01448
01449
01450
01451 void
01452 tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval)
01453 {
01454 LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN);
01455 #if LWIP_CALLBACK_API
01456 pcb->poll = poll;
01457 #else
01458 LWIP_UNUSED_ARG(poll);
01459 #endif
01460 pcb->pollinterval = interval;
01461 }
01462
01463
01464
01465
01466
01467
01468
01469 void
01470 tcp_pcb_purge(struct tcp_pcb *pcb)
01471 {
01472 if (pcb->state != CLOSED &&
01473 pcb->state != TIME_WAIT &&
01474 pcb->state != LISTEN) {
01475
01476 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
01477
01478 #if TCP_LISTEN_BACKLOG
01479 if (pcb->state == SYN_RCVD) {
01480
01481 struct tcp_pcb_listen *lpcb;
01482 LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
01483 tcp_listen_pcbs.listen_pcbs != NULL);
01484 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
01485 if ((lpcb->local_port == pcb->local_port) &&
01486 (ip_addr_isany(&lpcb->local_ip) ||
01487 ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
01488
01489 LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
01490 lpcb->accepts_pending > 0);
01491 lpcb->accepts_pending--;
01492 break;
01493 }
01494 }
01495 }
01496 #endif
01497
01498
01499 if (pcb->refused_data != NULL) {
01500 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n"));
01501 pbuf_free(pcb->refused_data);
01502 pcb->refused_data = NULL;
01503 }
01504 if (pcb->unsent != NULL) {
01505 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
01506 }
01507 if (pcb->unacked != NULL) {
01508 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
01509 }
01510 #if TCP_QUEUE_OOSEQ
01511 if (pcb->ooseq != NULL) {
01512 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
01513 }
01514 tcp_segs_free(pcb->ooseq);
01515 pcb->ooseq = NULL;
01516 #endif
01517
01518
01519
01520 pcb->rtime = -1;
01521
01522 tcp_segs_free(pcb->unsent);
01523 tcp_segs_free(pcb->unacked);
01524 pcb->unacked = pcb->unsent = NULL;
01525 #if TCP_OVERSIZE
01526 pcb->unsent_oversize = 0;
01527 #endif
01528 }
01529 }
01530
01531
01532
01533
01534
01535
01536
01537 void
01538 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
01539 {
01540 TCP_RMV(pcblist, pcb);
01541
01542 tcp_pcb_purge(pcb);
01543
01544
01545 if (pcb->state != TIME_WAIT &&
01546 pcb->state != LISTEN &&
01547 pcb->flags & TF_ACK_DELAY) {
01548 pcb->flags |= TF_ACK_NOW;
01549 tcp_output(pcb);
01550 }
01551
01552 if (pcb->state != LISTEN) {
01553 LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL);
01554 LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL);
01555 #if TCP_QUEUE_OOSEQ
01556 LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL);
01557 #endif
01558 }
01559
01560 pcb->state = CLOSED;
01561
01562 LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
01563 }
01564
01565
01566
01567
01568
01569
01570 u32_t
01571 tcp_next_iss(void)
01572 {
01573 static u32_t iss = 6510;
01574
01575 iss += tcp_ticks;
01576 return iss;
01577 }
01578
01579 #if TCP_CALCULATE_EFF_SEND_MSS
01580
01581
01582
01583
01584
01585 u16_t
01586 tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr)
01587 {
01588 u16_t mss_s;
01589 struct netif *outif;
01590
01591 outif = ip_route(addr);
01592 if ((outif != NULL) && (outif->mtu != 0)) {
01593 mss_s = outif->mtu - IP_HLEN - TCP_HLEN;
01594
01595
01596
01597
01598 sendmss = LWIP_MIN(sendmss, mss_s);
01599 }
01600 return sendmss;
01601 }
01602 #endif
01603
01604 const char*
01605 tcp_debug_state_str(enum tcp_state s)
01606 {
01607 return tcp_state_str[s];
01608 }
01609
01610 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
01611
01612
01613
01614
01615
01616 void
01617 tcp_debug_print(struct tcp_hdr *tcphdr)
01618 {
01619 LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n"));
01620 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01621 LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n",
01622 ntohs(tcphdr->src), ntohs(tcphdr->dest)));
01623 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01624 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n",
01625 ntohl(tcphdr->seqno)));
01626 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01627 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n",
01628 ntohl(tcphdr->ackno)));
01629 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01630 LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (",
01631 TCPH_HDRLEN(tcphdr),
01632 TCPH_FLAGS(tcphdr) >> 5 & 1,
01633 TCPH_FLAGS(tcphdr) >> 4 & 1,
01634 TCPH_FLAGS(tcphdr) >> 3 & 1,
01635 TCPH_FLAGS(tcphdr) >> 2 & 1,
01636 TCPH_FLAGS(tcphdr) >> 1 & 1,
01637 TCPH_FLAGS(tcphdr) & 1,
01638 ntohs(tcphdr->wnd)));
01639 tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
01640 LWIP_DEBUGF(TCP_DEBUG, ("), win)\n"));
01641 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01642 LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n",
01643 ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
01644 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01645 }
01646
01647
01648
01649
01650
01651
01652 void
01653 tcp_debug_print_state(enum tcp_state s)
01654 {
01655 LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s]));
01656 }
01657
01658
01659
01660
01661
01662
01663 void
01664 tcp_debug_print_flags(u8_t flags)
01665 {
01666 if (flags & TCP_FIN) {
01667 LWIP_DEBUGF(TCP_DEBUG, ("FIN "));
01668 }
01669 if (flags & TCP_SYN) {
01670 LWIP_DEBUGF(TCP_DEBUG, ("SYN "));
01671 }
01672 if (flags & TCP_RST) {
01673 LWIP_DEBUGF(TCP_DEBUG, ("RST "));
01674 }
01675 if (flags & TCP_PSH) {
01676 LWIP_DEBUGF(TCP_DEBUG, ("PSH "));
01677 }
01678 if (flags & TCP_ACK) {
01679 LWIP_DEBUGF(TCP_DEBUG, ("ACK "));
01680 }
01681 if (flags & TCP_URG) {
01682 LWIP_DEBUGF(TCP_DEBUG, ("URG "));
01683 }
01684 if (flags & TCP_ECE) {
01685 LWIP_DEBUGF(TCP_DEBUG, ("ECE "));
01686 }
01687 if (flags & TCP_CWR) {
01688 LWIP_DEBUGF(TCP_DEBUG, ("CWR "));
01689 }
01690 LWIP_DEBUGF(TCP_DEBUG, ("\n"));
01691 }
01692
01693
01694
01695
01696 void
01697 tcp_debug_print_pcbs(void)
01698 {
01699 struct tcp_pcb *pcb;
01700 LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
01701 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01702 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01703 pcb->local_port, pcb->remote_port,
01704 pcb->snd_nxt, pcb->rcv_nxt));
01705 tcp_debug_print_state(pcb->state);
01706 }
01707 LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
01708 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
01709 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01710 pcb->local_port, pcb->remote_port,
01711 pcb->snd_nxt, pcb->rcv_nxt));
01712 tcp_debug_print_state(pcb->state);
01713 }
01714 LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
01715 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01716 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ",
01717 pcb->local_port, pcb->remote_port,
01718 pcb->snd_nxt, pcb->rcv_nxt));
01719 tcp_debug_print_state(pcb->state);
01720 }
01721 }
01722
01723
01724
01725
01726 s16_t
01727 tcp_pcbs_sane(void)
01728 {
01729 struct tcp_pcb *pcb;
01730 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01731 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
01732 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
01733 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
01734 }
01735 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01736 LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
01737 }
01738 return 1;
01739 }
01740 #endif
01741
01742 #endif