00001
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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #include "lwip/opt.h"
00057 #include "lwip/def.h"
00058 #include "lwip/mem.h"
00059 #include "lwip/memp.h"
00060
00061 #include "lwip/tcp.h"
00062
00063 #define htons HTONS
00064 #define htonl HTONL
00065
00066 #if LWIP_TCP
00067
00068
00069
00070 u32_t tcp_ticks;
00071 const u8_t tcp_backoff[13] =
00072 { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
00073
00074
00075 struct tcp_pcb_listen *tcp_listen_pcbs;
00076 struct tcp_pcb *tcp_active_pcbs;
00077
00078
00079 struct tcp_pcb *tcp_tw_pcbs;
00080
00081 struct tcp_pcb *tcp_tmp_pcb;
00082
00083 #define MIN(x,y) (x) < (y)? (x): (y)
00084
00085 static u8_t tcp_timer;
00086
00087 static u16_t tcp_new_port(void);
00088
00089
00090
00091
00092
00093
00094
00095
00096 void
00097 tcp_init(void)
00098 {
00099
00100 tcp_listen_pcbs = NULL;
00101 tcp_active_pcbs = NULL;
00102 tcp_tw_pcbs = NULL;
00103 tcp_tmp_pcb = NULL;
00104
00105
00106 tcp_ticks = 0;
00107 tcp_timer = 0;
00108
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118 void
00119 tcp_tmr(void)
00120 {
00121 ++tcp_timer;
00122 if(tcp_timer == 10) {
00123 tcp_timer = 0;
00124 }
00125
00126 if(tcp_timer & 1) {
00127
00128
00129 tcp_fasttmr();
00130 }
00131 if(tcp_timer == 0 || tcp_timer == 5) {
00132
00133
00134 tcp_slowtmr();
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145 err_t
00146 tcp_close(struct tcp_pcb *pcb)
00147 {
00148 err_t err;
00149
00150 #if TCP_DEBUG
00151 DEBUGF(TCP_DEBUG, ("tcp_close: closing in state "));
00152 tcp_debug_print_state(pcb->state);
00153 DEBUGF(TCP_DEBUG, ("\n"));
00154 #endif
00155 switch(pcb->state) {
00156 case LISTEN:
00157 err = ERR_OK;
00158 tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs, pcb);
00159 memp_free(MEMP_TCP_PCB_LISTEN, pcb);
00160 pcb = NULL;
00161 break;
00162 case SYN_SENT:
00163 err = ERR_OK;
00164 tcp_pcb_remove(&tcp_active_pcbs, pcb);
00165 memp_free(MEMP_TCP_PCB, pcb);
00166 pcb = NULL;
00167 break;
00168 case SYN_RCVD:
00169 err = tcp_send_ctrl(pcb, TCP_FIN);
00170 if(err == ERR_OK) {
00171 pcb->state = FIN_WAIT_1;
00172 }
00173 break;
00174 case ESTABLISHED:
00175 err = tcp_send_ctrl(pcb, TCP_FIN);
00176 if(err == ERR_OK) {
00177 pcb->state = FIN_WAIT_1;
00178 }
00179 break;
00180 case CLOSE_WAIT:
00181 err = tcp_send_ctrl(pcb, TCP_FIN);
00182 if(err == ERR_OK) {
00183 pcb->state = LAST_ACK;
00184 }
00185 break;
00186 default:
00187
00188 err = ERR_OK;
00189 pcb = NULL;
00190 break;
00191 }
00192
00193 if(pcb != NULL && err == ERR_OK) {
00194 err = tcp_output(pcb);
00195 }
00196 return err;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 void
00209 tcp_abort(struct tcp_pcb *pcb)
00210 {
00211 u32_t seqno, ackno;
00212 u16_t remote_port, local_port;
00213 struct ip_addr remote_ip, local_ip;
00214 #if LWIP_CALLBACK_API
00215 void (* errf)(void *arg, err_t err);
00216 #endif
00217 void *errf_arg;
00218
00219
00220
00221
00222
00223 if(pcb->state == TIME_WAIT) {
00224 tcp_pcb_remove(&tcp_tw_pcbs, pcb);
00225 memp_free(MEMP_TCP_PCB, pcb);
00226 } else {
00227 seqno = pcb->snd_nxt;
00228 ackno = pcb->rcv_nxt;
00229 ip_addr_set(&local_ip, &(pcb->local_ip));
00230 ip_addr_set(&remote_ip, &(pcb->remote_ip));
00231 local_port = pcb->local_port;
00232 remote_port = pcb->remote_port;
00233 #if LWIP_CALLBACK_API
00234 errf = pcb->errf;
00235 #endif
00236 errf_arg = pcb->callback_arg;
00237 tcp_pcb_remove(&tcp_active_pcbs, pcb);
00238 if(pcb->unacked != NULL) {
00239 tcp_segs_free(pcb->unacked);
00240 }
00241 if(pcb->unsent != NULL) {
00242 tcp_segs_free(pcb->unsent);
00243 }
00244 #if TCP_QUEUE_OOSEQ
00245 if(pcb->ooseq != NULL) {
00246 tcp_segs_free(pcb->ooseq);
00247 }
00248 #endif
00249 memp_free(MEMP_TCP_PCB, pcb);
00250 TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT);
00251 DEBUGF(TCP_RST_DEBUG, ("tcp_abort: sending RST\n"));
00252 tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port);
00253 }
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 err_t
00266 tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
00267 {
00268 struct tcp_pcb *cpcb;
00269
00270 if(port == 0) {
00271 port = tcp_new_port();
00272 }
00273
00274
00275 for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs;
00276 cpcb != NULL; cpcb = cpcb->next) {
00277 if(cpcb->local_port == port) {
00278 if(ip_addr_isany(&(cpcb->local_ip)) ||
00279 ip_addr_isany(ipaddr) ||
00280 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00281 return ERR_USE;
00282 }
00283 }
00284 }
00285 for(cpcb = tcp_active_pcbs;
00286 cpcb != NULL; cpcb = cpcb->next) {
00287 if(cpcb->local_port == port) {
00288 if(ip_addr_isany(&(cpcb->local_ip)) ||
00289 ip_addr_isany(ipaddr) ||
00290 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
00291 return ERR_USE;
00292 }
00293 }
00294 }
00295 if(!ip_addr_isany(ipaddr)) {
00296 pcb->local_ip = *ipaddr;
00297 }
00298 pcb->local_port = port;
00299 DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %u\n", port));
00300 return ERR_OK;
00301 }
00302 #if LWIP_CALLBACK_API
00303 static err_t
00304 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err)
00305 {
00306 return ERR_ABRT;
00307 }
00308 #endif
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 struct tcp_pcb *
00321 tcp_listen(struct tcp_pcb *pcb)
00322 {
00323 struct tcp_pcb_listen *lpcb;
00324
00325
00326 if(pcb->state == LISTEN) {
00327 return pcb;
00328 }
00329 lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN);
00330 if(lpcb == NULL) {
00331 return NULL;
00332 }
00333 lpcb->callback_arg = pcb->callback_arg;
00334 lpcb->local_port = pcb->local_port;
00335 lpcb->state = LISTEN;
00336 ip_addr_set(&lpcb->local_ip, &pcb->local_ip);
00337 memp_free(MEMP_TCP_PCB, pcb);
00338 #if LWIP_CALLBACK_API
00339 lpcb->accept = tcp_accept_null;
00340 #endif
00341 TCP_REG(&tcp_listen_pcbs, lpcb);
00342 return (struct tcp_pcb *)lpcb;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 void
00355 tcp_recved(struct tcp_pcb *pcb, u16_t len)
00356 {
00357 pcb->rcv_wnd += len;
00358 if(pcb->rcv_wnd > TCP_WND) {
00359 pcb->rcv_wnd = TCP_WND;
00360 }
00361 if(!(pcb->flags & TF_ACK_DELAY) &&
00362 !(pcb->flags & TF_ACK_NOW)) {
00363 tcp_ack(pcb);
00364 }
00365 DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %u bytes, wnd %u (%u).\n",
00366 len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd));
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376 static u16_t
00377 tcp_new_port(void)
00378 {
00379 struct tcp_pcb *pcb;
00380 #ifndef TCP_LOCAL_PORT_RANGE_START
00381 #define TCP_LOCAL_PORT_RANGE_START 4096
00382 #define TCP_LOCAL_PORT_RANGE_END 0x7fff
00383 #endif
00384 static u16_t port = TCP_LOCAL_PORT_RANGE_START;
00385
00386 again:
00387 if(++port > TCP_LOCAL_PORT_RANGE_END) {
00388 port = TCP_LOCAL_PORT_RANGE_START;
00389 }
00390
00391 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00392 if(pcb->local_port == port) {
00393 goto again;
00394 }
00395 }
00396 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
00397 if(pcb->local_port == port) {
00398 goto again;
00399 }
00400 }
00401 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) {
00402 if(pcb->local_port == port) {
00403 goto again;
00404 }
00405 }
00406 return port;
00407 }
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 err_t
00418 tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port,
00419 err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err))
00420 {
00421 u32_t optdata;
00422 err_t ret;
00423 u32_t iss;
00424
00425 DEBUGF(TCP_DEBUG, ("tcp_connect to port %u\n", port));
00426 if(ipaddr != NULL) {
00427 pcb->remote_ip = *ipaddr;
00428 } else {
00429 return ERR_VAL;
00430 }
00431 pcb->remote_port = port;
00432 if(pcb->local_port == 0) {
00433 pcb->local_port = tcp_new_port();
00434 }
00435 iss = tcp_next_iss();
00436 pcb->rcv_nxt = 0;
00437 pcb->snd_nxt = iss;
00438 pcb->lastack = iss - 1;
00439 pcb->snd_lbb = iss - 1;
00440 pcb->rcv_wnd = TCP_WND;
00441 pcb->snd_wnd = TCP_WND;
00442 pcb->mss = TCP_MSS;
00443 pcb->cwnd = 1;
00444 pcb->ssthresh = pcb->mss * 10;
00445 pcb->state = SYN_SENT;
00446 #if LWIP_CALLBACK_API
00447 pcb->connected = connected;
00448 #endif
00449 TCP_REG(&tcp_active_pcbs, pcb);
00450
00451
00452 optdata = htonl(((u32_t)2 << 24) |
00453 ((u32_t)4 << 16) |
00454 (((u32_t)pcb->mss / 256) << 8) |
00455 (pcb->mss & 255));
00456
00457 ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4);
00458 if(ret == ERR_OK) {
00459 tcp_output(pcb);
00460 }
00461 return ret;
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 void
00473 tcp_slowtmr(void)
00474 {
00475 struct tcp_pcb *pcb, *pcb2, *prev;
00476 u32_t eff_wnd;
00477 u8_t pcb_remove;
00478 err_t err;
00479
00480 err = ERR_OK;
00481
00482 ++tcp_ticks;
00483
00484
00485 prev = NULL;
00486 pcb = tcp_active_pcbs;
00487 if (pcb == NULL) DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
00488 while(pcb != NULL) {
00489 DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
00490 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
00491 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
00492 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
00493
00494 pcb_remove = 0;
00495
00496 if(pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
00497 ++pcb_remove;
00498 DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
00499 }
00500 else if(pcb->nrtx == TCP_MAXRTX) {
00501 ++pcb_remove;
00502 DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
00503 } else {
00504 ++pcb->rtime;
00505 if(pcb->unacked != NULL && pcb->rtime >= pcb->rto) {
00506
00507
00508 DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %u pcb->rto %u\n",
00509 pcb->rtime, pcb->rto));
00510
00511
00512
00513 if(pcb->state != SYN_SENT) {
00514 pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx];
00515 }
00516
00517 tcp_rexmit(pcb);
00518
00519
00520 eff_wnd = MIN(pcb->cwnd, pcb->snd_wnd);
00521 pcb->ssthresh = eff_wnd >> 1;
00522 if(pcb->ssthresh < pcb->mss) {
00523 pcb->ssthresh = pcb->mss * 2;
00524 }
00525 pcb->cwnd = pcb->mss;
00526
00527 DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %u ssthresh %u\n",
00528 pcb->cwnd, pcb->ssthresh));
00529 }
00530 }
00531
00532
00533 if(pcb->state == FIN_WAIT_2) {
00534 if((u32_t)(tcp_ticks - pcb->tmr) >
00535 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) {
00536 ++pcb_remove;
00537 DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n"));
00538 }
00539 }
00540
00541
00542
00543
00544 #if TCP_QUEUE_OOSEQ
00545 if(pcb->ooseq != NULL &&
00546 (u32_t)tcp_ticks - pcb->tmr >=
00547 pcb->rto * TCP_OOSEQ_TIMEOUT) {
00548 tcp_segs_free(pcb->ooseq);
00549 pcb->ooseq = NULL;
00550 DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n"));
00551 }
00552 #endif
00553
00554
00555 if(pcb->state == SYN_RCVD) {
00556 if((u32_t)(tcp_ticks - pcb->tmr) >
00557 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) {
00558 ++pcb_remove;
00559 DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n"));
00560 }
00561 }
00562
00563
00564
00565 if(pcb_remove) {
00566 tcp_pcb_purge(pcb);
00567
00568 if(prev != NULL) {
00569 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
00570 prev->next = pcb->next;
00571 } else {
00572
00573 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
00574 tcp_active_pcbs = pcb->next;
00575 }
00576
00577 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
00578
00579 pcb2 = pcb->next;
00580 memp_free(MEMP_TCP_PCB, pcb);
00581 pcb = pcb2;
00582 } else {
00583
00584
00585 ++pcb->polltmr;
00586 if(pcb->polltmr >= pcb->pollinterval) {
00587 pcb->polltmr = 0;
00588 DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
00589 TCP_EVENT_POLL(pcb, err);
00590 if(err == ERR_OK) {
00591 tcp_output(pcb);
00592 }
00593 }
00594
00595 prev = pcb;
00596 pcb = pcb->next;
00597 }
00598 }
00599
00600
00601
00602 prev = NULL;
00603 pcb = tcp_tw_pcbs;
00604 while(pcb != NULL) {
00605 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
00606 pcb_remove = 0;
00607
00608
00609 if((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) {
00610 ++pcb_remove;
00611 }
00612
00613
00614
00615
00616 if(pcb_remove) {
00617 tcp_pcb_purge(pcb);
00618
00619 if(prev != NULL) {
00620 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs);
00621 prev->next = pcb->next;
00622 } else {
00623
00624 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
00625 tcp_tw_pcbs = pcb->next;
00626 }
00627 pcb2 = pcb->next;
00628 memp_free(MEMP_TCP_PCB, pcb);
00629 pcb = pcb2;
00630 } else {
00631 prev = pcb;
00632 pcb = pcb->next;
00633 }
00634 }
00635 }
00636
00637
00638
00639
00640
00641
00642
00643 void
00644 tcp_fasttmr(void)
00645 {
00646 struct tcp_pcb *pcb;
00647
00648
00649 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00650 if(pcb->flags & TF_ACK_DELAY) {
00651 DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
00652 tcp_ack_now(pcb);
00653 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW);
00654 }
00655 }
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665 u8_t
00666 tcp_segs_free(struct tcp_seg *seg)
00667 {
00668 u8_t count = 0;
00669 struct tcp_seg *next;
00670 again:
00671 if(seg != NULL) {
00672 next = seg->next;
00673 count += tcp_seg_free(seg);
00674 seg = next;
00675 goto again;
00676 }
00677 return count;
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687 u8_t
00688 tcp_seg_free(struct tcp_seg *seg)
00689 {
00690 u8_t count = 0;
00691
00692 if(seg != NULL) {
00693 if(seg->p == NULL) {
00694 memp_free(MEMP_TCP_SEG, seg);
00695 } else {
00696 count = pbuf_free(seg->p);
00697 #if TCP_DEBUG
00698 seg->p = NULL;
00699 #endif
00700 memp_free(MEMP_TCP_SEG, seg);
00701 }
00702 }
00703 return count;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713 void
00714 tcp_setprio(struct tcp_pcb *pcb, u8_t prio)
00715 {
00716 pcb->prio = prio;
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726 struct tcp_seg *
00727 tcp_seg_copy(struct tcp_seg *seg)
00728 {
00729 struct tcp_seg *cseg;
00730
00731 cseg = memp_malloc(MEMP_TCP_SEG);
00732 if(cseg == NULL) {
00733 return NULL;
00734 }
00735 memcpy((char *)cseg, (const char *)seg, sizeof(struct tcp_seg));
00736 pbuf_ref(cseg->p);
00737 return cseg;
00738 }
00739
00740 #if LWIP_CALLBACK_API
00741 static err_t
00742 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
00743 {
00744 arg = arg;
00745 if(p != NULL) {
00746 pbuf_free(p);
00747 } else if(err == ERR_OK) {
00748 return tcp_close(pcb);
00749 }
00750 return ERR_OK;
00751 }
00752 #endif
00753
00754 static void
00755 tcp_kill_prio(u8_t prio)
00756 {
00757 struct tcp_pcb *pcb, *inactive;
00758 u32_t inactivity;
00759 u8_t mprio;
00760
00761
00762 mprio = TCP_PRIO_MAX;
00763
00764
00765
00766 inactivity = 0;
00767 inactive = NULL;
00768 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
00769 if(pcb->prio <= prio &&
00770 pcb->prio <= mprio &&
00771 (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
00772 inactivity = tcp_ticks - pcb->tmr;
00773 inactive = pcb;
00774 mprio = pcb->prio;
00775 }
00776 }
00777 if(inactive != NULL) {
00778 DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB 0x%p (%ld)\n",
00779 (void *)inactive, inactivity));
00780 tcp_abort(inactive);
00781 }
00782 }
00783
00784
00785 static void
00786 tcp_kill_timewait(void)
00787 {
00788 struct tcp_pcb *pcb, *inactive;
00789 u32_t inactivity;
00790
00791 inactivity = 0;
00792 inactive = NULL;
00793 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
00794 if((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) {
00795 inactivity = tcp_ticks - pcb->tmr;
00796 inactive = pcb;
00797 }
00798 }
00799 if(inactive != NULL) {
00800 DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB 0x%p (%ld)\n",
00801 (void *)inactive, inactivity));
00802 tcp_abort(inactive);
00803 }
00804 }
00805
00806
00807
00808 struct tcp_pcb *
00809 tcp_alloc(u8_t prio)
00810 {
00811 struct tcp_pcb *pcb;
00812 u32_t iss;
00813
00814 pcb = memp_malloc(MEMP_TCP_PCB);
00815 if(pcb == NULL) {
00816
00817 DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n"));
00818 tcp_kill_timewait();
00819 pcb = memp_malloc(MEMP_TCP_PCB);
00820 if(pcb == NULL) {
00821 tcp_kill_prio(prio);
00822 pcb = memp_malloc(MEMP_TCP_PCB);
00823 }
00824 }
00825 if(pcb != NULL) {
00826 memset(pcb, 0, sizeof(struct tcp_pcb));
00827 pcb->prio = TCP_PRIO_NORMAL;
00828 pcb->snd_buf = TCP_SND_BUF;
00829 pcb->snd_queuelen = 0;
00830 pcb->rcv_wnd = TCP_WND;
00831 pcb->mss = TCP_MSS;
00832 pcb->rto = 3000 / TCP_SLOW_INTERVAL;
00833 pcb->sa = 0;
00834 pcb->sv = 3000 / TCP_SLOW_INTERVAL;
00835 pcb->rtime = 0;
00836 pcb->cwnd = 1;
00837 iss = tcp_next_iss();
00838 pcb->snd_wl2 = iss;
00839 pcb->snd_nxt = iss;
00840 pcb->snd_max = iss;
00841 pcb->lastack = iss;
00842 pcb->snd_lbb = iss;
00843 pcb->tmr = tcp_ticks;
00844
00845 pcb->polltmr = 0;
00846
00847 #if LWIP_CALLBACK_API
00848 pcb->recv = tcp_recv_null;
00849 #endif
00850 }
00851 return pcb;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 struct tcp_pcb *
00863 tcp_new(void)
00864 {
00865 return tcp_alloc(TCP_PRIO_NORMAL);
00866 }
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 void
00877 tcp_arg(struct tcp_pcb *pcb, void *arg)
00878 {
00879 pcb->callback_arg = arg;
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890 #if LWIP_CALLBACK_API
00891 void
00892 tcp_recv(struct tcp_pcb *pcb,
00893 err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err))
00894 {
00895 pcb->recv = recv;
00896 }
00897 #endif
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 #if LWIP_CALLBACK_API
00908 void
00909 tcp_sent(struct tcp_pcb *pcb,
00910 err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len))
00911 {
00912 pcb->sent = sent;
00913 }
00914 #endif
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924 #if LWIP_CALLBACK_API
00925 void
00926 tcp_err(struct tcp_pcb *pcb,
00927 void (* errf)(void *arg, err_t err))
00928 {
00929 pcb->errf = errf;
00930 }
00931 #endif
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 void
00943 tcp_poll(struct tcp_pcb *pcb,
00944 err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval)
00945 {
00946 #if LWIP_CALLBACK_API
00947 pcb->poll = poll;
00948 #endif
00949 pcb->pollinterval = interval;
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 #if LWIP_CALLBACK_API
00961 void
00962 tcp_accept(struct tcp_pcb *pcb,
00963 err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err))
00964 {
00965 ((struct tcp_pcb_listen *)pcb)->accept = accept;
00966 }
00967 #endif
00968
00969
00970
00971
00972
00973
00974
00975
00976 void
00977 tcp_pcb_purge(struct tcp_pcb *pcb)
00978 {
00979 if(pcb->state != CLOSED &&
00980 pcb->state != TIME_WAIT &&
00981 pcb->state != LISTEN) {
00982
00983 DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
00984
00985 #if TCP_DEBUG
00986 if(pcb->unsent != NULL) {
00987 DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
00988 }
00989 if(pcb->unacked != NULL) {
00990 DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n"));
00991 }
00992 #if TCP_QUEUE_OOSEQ
00993 if(pcb->ooseq != NULL) {
00994 DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
00995 }
00996 #endif
00997 #endif
00998 tcp_segs_free(pcb->unsent);
00999 #if TCP_QUEUE_OOSEQ
01000 tcp_segs_free(pcb->ooseq);
01001 #endif
01002 tcp_segs_free(pcb->unacked);
01003 pcb->unacked = pcb->unsent =
01004 #if TCP_QUEUE_OOSEQ
01005 pcb->ooseq =
01006 #endif
01007 NULL;
01008 }
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018 void
01019 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
01020 {
01021 TCP_RMV(pcblist, pcb);
01022
01023 tcp_pcb_purge(pcb);
01024
01025
01026 if(pcb->state != TIME_WAIT &&
01027 pcb->state != LISTEN &&
01028 pcb->flags & TF_ACK_DELAY) {
01029 pcb->flags |= TF_ACK_NOW;
01030 tcp_output(pcb);
01031 }
01032 pcb->state = CLOSED;
01033
01034 LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
01035 }
01036
01037
01038
01039
01040
01041
01042
01043
01044 u32_t
01045 tcp_next_iss(void)
01046 {
01047 static u32_t iss = 6510;
01048
01049 iss += tcp_ticks;
01050 return iss;
01051 }
01052
01053 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
01054 void
01055 tcp_debug_print(struct tcp_hdr *tcphdr)
01056 {
01057 DEBUGF(TCP_DEBUG, ("TCP header:\n"));
01058 DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01059 DEBUGF(TCP_DEBUG, ("| %04x | %04x | (src port, dest port)\n",
01060 tcphdr->src, tcphdr->dest));
01061 DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01062 DEBUGF(TCP_DEBUG, ("| %08lu | (seq no)\n",
01063 tcphdr->seqno));
01064 DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01065 DEBUGF(TCP_DEBUG, ("| %08lu | (ack no)\n",
01066 tcphdr->ackno));
01067 DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01068 DEBUGF(TCP_DEBUG, ("| %2u | |%u%u%u%u%u| %5u | (offset, flags (",
01069 TCPH_OFFSET(tcphdr),
01070 TCPH_FLAGS(tcphdr) >> 4 & 1,
01071 TCPH_FLAGS(tcphdr) >> 4 & 1,
01072 TCPH_FLAGS(tcphdr) >> 3 & 1,
01073 TCPH_FLAGS(tcphdr) >> 2 & 1,
01074 TCPH_FLAGS(tcphdr) >> 1 & 1,
01075 TCPH_FLAGS(tcphdr) & 1,
01076 tcphdr->wnd));
01077 tcp_debug_print_flags(TCPH_FLAGS(tcphdr));
01078 DEBUGF(TCP_DEBUG, ("), win)\n"));
01079 DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01080 DEBUGF(TCP_DEBUG, ("| 0x%04x | %5u | (chksum, urgp)\n",
01081 ntohs(tcphdr->chksum), ntohs(tcphdr->urgp)));
01082 DEBUGF(TCP_DEBUG, ("+-------------------------------+\n"));
01083 }
01084
01085 void
01086 tcp_debug_print_state(enum tcp_state s)
01087 {
01088 DEBUGF(TCP_DEBUG, ("State: "));
01089 switch(s) {
01090 case CLOSED:
01091 DEBUGF(TCP_DEBUG, ("CLOSED\n"));
01092 break;
01093 case LISTEN:
01094 DEBUGF(TCP_DEBUG, ("LISTEN\n"));
01095 break;
01096 case SYN_SENT:
01097 DEBUGF(TCP_DEBUG, ("SYN_SENT\n"));
01098 break;
01099 case SYN_RCVD:
01100 DEBUGF(TCP_DEBUG, ("SYN_RCVD\n"));
01101 break;
01102 case ESTABLISHED:
01103 DEBUGF(TCP_DEBUG, ("ESTABLISHED\n"));
01104 break;
01105 case FIN_WAIT_1:
01106 DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n"));
01107 break;
01108 case FIN_WAIT_2:
01109 DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n"));
01110 break;
01111 case CLOSE_WAIT:
01112 DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n"));
01113 break;
01114 case CLOSING:
01115 DEBUGF(TCP_DEBUG, ("CLOSING\n"));
01116 break;
01117 case LAST_ACK:
01118 DEBUGF(TCP_DEBUG, ("LAST_ACK\n"));
01119 break;
01120 case TIME_WAIT:
01121 DEBUGF(TCP_DEBUG, ("TIME_WAIT\n"));
01122 break;
01123 }
01124 }
01125
01126 void
01127 tcp_debug_print_flags(u8_t flags)
01128 {
01129 if(flags & TCP_FIN) {
01130 DEBUGF(TCP_DEBUG, ("FIN "));
01131 }
01132 if(flags & TCP_SYN) {
01133 DEBUGF(TCP_DEBUG, ("SYN "));
01134 }
01135 if(flags & TCP_RST) {
01136 DEBUGF(TCP_DEBUG, ("RST "));
01137 }
01138 if(flags & TCP_PSH) {
01139 DEBUGF(TCP_DEBUG, ("PSH "));
01140 }
01141 if(flags & TCP_ACK) {
01142 DEBUGF(TCP_DEBUG, ("ACK "));
01143 }
01144 if(flags & TCP_URG) {
01145 DEBUGF(TCP_DEBUG, ("URG "));
01146 }
01147 }
01148
01149 void
01150 tcp_debug_print_pcbs(void)
01151 {
01152 struct tcp_pcb *pcb;
01153 DEBUGF(TCP_DEBUG, ("Active PCB states:\n"));
01154 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01155 DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
01156 pcb->local_port, pcb->remote_port,
01157 pcb->snd_nxt, pcb->rcv_nxt));
01158 tcp_debug_print_state(pcb->state);
01159 }
01160 DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
01161 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) {
01162 DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
01163 pcb->local_port, pcb->remote_port,
01164 pcb->snd_nxt, pcb->rcv_nxt));
01165 tcp_debug_print_state(pcb->state);
01166 }
01167 DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n"));
01168 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01169 DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
01170 pcb->local_port, pcb->remote_port,
01171 pcb->snd_nxt, pcb->rcv_nxt));
01172 tcp_debug_print_state(pcb->state);
01173 }
01174 }
01175
01176 int
01177 tcp_pcbs_sane(void)
01178 {
01179 struct tcp_pcb *pcb;
01180 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
01181 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED);
01182 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN);
01183 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
01184 }
01185 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
01186 LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
01187 }
01188 return 1;
01189 }
01190 #endif
01191 #endif
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201