A version of LWIP, provided for backwards compatibility.
Dependents: AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more
tcp.c
00001 /** 00002 * @file 00003 * Transmission Control Protocol for IP 00004 * 00005 * This file contains common functions for the TCP implementation, such as functinos 00006 * for manipulating the data structures and the TCP timer functions. TCP functions 00007 * related to input and output is found in tcp_in.c and tcp_out.c respectively. 00008 * 00009 */ 00010 00011 /* 00012 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00013 * All rights reserved. 00014 * 00015 * Redistribution and use in source and binary forms, with or without modification, 00016 * are permitted provided that the following conditions are met: 00017 * 00018 * 1. Redistributions of source code must retain the above copyright notice, 00019 * this list of conditions and the following disclaimer. 00020 * 2. Redistributions in binary form must reproduce the above copyright notice, 00021 * this list of conditions and the following disclaimer in the documentation 00022 * and/or other materials provided with the distribution. 00023 * 3. The name of the author may not be used to endorse or promote products 00024 * derived from this software without specific prior written permission. 00025 * 00026 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00027 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00028 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00029 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00031 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00032 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00033 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00034 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00035 * OF SUCH DAMAGE. 00036 * 00037 * This file is part of the lwIP TCP/IP stack. 00038 * 00039 * Author: Adam Dunkels <adam@sics.se> 00040 * 00041 */ 00042 00043 #include "lwip/opt.h" 00044 00045 #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ 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 00053 #include <string.h> 00054 00055 /* Incremented every coarse grained timer shot (typically every 500 ms). */ 00056 u32_t tcp_ticks; 00057 const u8_t tcp_backoff[13] = 00058 { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; 00059 /* Times per slowtmr hits */ 00060 const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; 00061 00062 /* The TCP PCB lists. */ 00063 00064 /** List of all TCP PCBs bound but not yet (connected || listening) */ 00065 struct tcp_pcb *tcp_bound_pcbs; 00066 /** List of all TCP PCBs in LISTEN state */ 00067 union tcp_listen_pcbs_t tcp_listen_pcbs; 00068 /** List of all TCP PCBs that are in a state in which 00069 * they accept or send data. */ 00070 struct tcp_pcb *tcp_active_pcbs; 00071 /** List of all TCP PCBs in TIME-WAIT state */ 00072 struct tcp_pcb *tcp_tw_pcbs; 00073 00074 struct tcp_pcb *tcp_tmp_pcb; 00075 00076 static u8_t tcp_timer; 00077 static u16_t tcp_new_port(void); 00078 00079 /** 00080 * Called periodically to dispatch TCP timers. 00081 * 00082 */ 00083 void 00084 tcp_tmr(void) 00085 { 00086 /* Call tcp_fasttmr() every 250 ms */ 00087 tcp_fasttmr(); 00088 00089 if (++tcp_timer & 1) { 00090 /* Call tcp_tmr() every 500 ms, i.e., every other timer 00091 tcp_tmr() is called. */ 00092 tcp_slowtmr(); 00093 } 00094 } 00095 00096 /** 00097 * Closes the connection held by the PCB. 00098 * 00099 * Listening pcbs are freed and may not be referenced any more. 00100 * Connection pcbs are freed if not yet connected and may not be referenced 00101 * any more. If a connection is established (at least SYN received or in 00102 * a closing state), the connection is closed, and put in a closing state. 00103 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore 00104 * unsafe to reference it. 00105 * 00106 * @param pcb the tcp_pcb to close 00107 * @return ERR_OK if connection has been closed 00108 * another err_t if closing failed and pcb is not freed 00109 */ 00110 err_t 00111 tcp_close(struct tcp_pcb *pcb) 00112 { 00113 err_t err; 00114 00115 #if TCP_DEBUG 00116 LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); 00117 tcp_debug_print_state(pcb->state); 00118 #endif /* TCP_DEBUG */ 00119 00120 switch (pcb->state) { 00121 case CLOSED: 00122 /* Closing a pcb in the CLOSED state might seem erroneous, 00123 * however, it is in this state once allocated and as yet unused 00124 * and the user needs some way to free it should the need arise. 00125 * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) 00126 * or for a pcb that has been used and then entered the CLOSED state 00127 * is erroneous, but this should never happen as the pcb has in those cases 00128 * been freed, and so any remaining handles are bogus. */ 00129 err = ERR_OK; 00130 TCP_RMV(&tcp_bound_pcbs, pcb); 00131 memp_free(MEMP_TCP_PCB, pcb); 00132 pcb = NULL; 00133 break; 00134 case LISTEN: 00135 err = ERR_OK; 00136 tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb); 00137 memp_free(MEMP_TCP_PCB_LISTEN, pcb); 00138 pcb = NULL; 00139 break; 00140 case SYN_SENT: 00141 err = ERR_OK; 00142 tcp_pcb_remove(&tcp_active_pcbs, pcb); 00143 memp_free(MEMP_TCP_PCB, pcb); 00144 pcb = NULL; 00145 snmp_inc_tcpattemptfails(); 00146 break; 00147 case SYN_RCVD: 00148 err = tcp_send_ctrl(pcb, TCP_FIN); 00149 if (err == ERR_OK) { 00150 snmp_inc_tcpattemptfails(); 00151 pcb->state = FIN_WAIT_1; 00152 } 00153 break; 00154 case ESTABLISHED: 00155 err = tcp_send_ctrl(pcb, TCP_FIN); 00156 if (err == ERR_OK) { 00157 snmp_inc_tcpestabresets(); 00158 pcb->state = FIN_WAIT_1; 00159 } 00160 break; 00161 case CLOSE_WAIT: 00162 err = tcp_send_ctrl(pcb, TCP_FIN); 00163 if (err == ERR_OK) { 00164 snmp_inc_tcpestabresets(); 00165 pcb->state = LAST_ACK; 00166 } 00167 break; 00168 default: 00169 /* Has already been closed, do nothing. */ 00170 err = ERR_OK; 00171 pcb = NULL; 00172 break; 00173 } 00174 00175 if (pcb != NULL && err == ERR_OK) { 00176 /* To ensure all data has been sent when tcp_close returns, we have 00177 to make sure tcp_output doesn't fail. 00178 Since we don't really have to ensure all data has been sent when tcp_close 00179 returns (unsent data is sent from tcp timer functions, also), we don't care 00180 for the return value of tcp_output for now. */ 00181 /* @todo: When implementing SO_LINGER, this must be changed somehow: 00182 If SOF_LINGER is set, the data should be sent when tcp_close returns. */ 00183 tcp_output(pcb); 00184 } 00185 return err; 00186 } 00187 00188 /** 00189 * Abandons a connection and optionally sends a RST to the remote 00190 * host. Deletes the local protocol control block. This is done when 00191 * a connection is killed because of shortage of memory. 00192 * 00193 * @param pcb the tcp_pcb to abort 00194 * @param reset boolean to indicate whether a reset should be sent 00195 */ 00196 void 00197 tcp_abandon(struct tcp_pcb *pcb, int reset) 00198 { 00199 u32_t seqno, ackno; 00200 u16_t remote_port, local_port; 00201 struct ip_addr remote_ip, local_ip; 00202 #if LWIP_CALLBACK_API 00203 void (* errf)(void *arg, err_t err); 00204 #endif /* LWIP_CALLBACK_API */ 00205 void *errf_arg; 00206 00207 00208 /* Figure out on which TCP PCB list we are, and remove us. If we 00209 are in an active state, call the receive function associated with 00210 the PCB with a NULL argument, and send an RST to the remote end. */ 00211 if (pcb->state == TIME_WAIT) { 00212 tcp_pcb_remove(&tcp_tw_pcbs, pcb); 00213 memp_free(MEMP_TCP_PCB, pcb); 00214 } else { 00215 seqno = pcb->snd_nxt; 00216 ackno = pcb->rcv_nxt; 00217 ip_addr_set(&local_ip, &(pcb->local_ip)); 00218 ip_addr_set(&remote_ip, &(pcb->remote_ip)); 00219 local_port = pcb->local_port; 00220 remote_port = pcb->remote_port; 00221 #if LWIP_CALLBACK_API 00222 errf = pcb->errf; 00223 #endif /* LWIP_CALLBACK_API */ 00224 errf_arg = pcb->callback_arg; 00225 tcp_pcb_remove(&tcp_active_pcbs, pcb); 00226 if (pcb->unacked != NULL) { 00227 tcp_segs_free(pcb->unacked); 00228 } 00229 if (pcb->unsent != NULL) { 00230 tcp_segs_free(pcb->unsent); 00231 } 00232 #if TCP_QUEUE_OOSEQ 00233 if (pcb->ooseq != NULL) { 00234 tcp_segs_free(pcb->ooseq); 00235 } 00236 #endif /* TCP_QUEUE_OOSEQ */ 00237 memp_free(MEMP_TCP_PCB, pcb); 00238 TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); 00239 if (reset) { 00240 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); 00241 tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port); 00242 } 00243 } 00244 } 00245 00246 /** 00247 * Binds the connection to a local portnumber and IP address. If the 00248 * IP address is not given (i.e., ipaddr == NULL), the IP address of 00249 * the outgoing network interface is used instead. 00250 * 00251 * @param pcb the tcp_pcb to bind (no check is done whether this pcb is 00252 * already bound!) 00253 * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind 00254 * to any local address 00255 * @param port the local port to bind to 00256 * @return ERR_USE if the port is already in use 00257 * ERR_OK if bound 00258 */ 00259 err_t 00260 tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) 00261 { 00262 struct tcp_pcb *cpcb; 00263 00264 LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); 00265 00266 if (port == 0) { 00267 port = tcp_new_port(); 00268 } 00269 /* Check if the address already is in use. */ 00270 /* Check the listen pcbs. */ 00271 for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; 00272 cpcb != NULL; cpcb = cpcb->next) { 00273 if (cpcb->local_port == port) { 00274 if (ip_addr_isany(&(cpcb->local_ip)) || 00275 ip_addr_isany(ipaddr) || 00276 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00277 return ERR_USE; 00278 } 00279 } 00280 } 00281 /* Check the connected pcbs. */ 00282 for(cpcb = tcp_active_pcbs; 00283 cpcb != NULL; cpcb = cpcb->next) { 00284 if (cpcb->local_port == port) { 00285 if (ip_addr_isany(&(cpcb->local_ip)) || 00286 ip_addr_isany(ipaddr) || 00287 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00288 return ERR_USE; 00289 } 00290 } 00291 } 00292 /* Check the bound, not yet connected pcbs. */ 00293 for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) { 00294 if (cpcb->local_port == port) { 00295 if (ip_addr_isany(&(cpcb->local_ip)) || 00296 ip_addr_isany(ipaddr) || 00297 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00298 return ERR_USE; 00299 } 00300 } 00301 } 00302 /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah), 00303 * we have to check the pcbs in TIME-WAIT state, also: */ 00304 for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) { 00305 if (cpcb->local_port == port) { 00306 if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00307 return ERR_USE; 00308 } 00309 } 00310 } 00311 00312 if (!ip_addr_isany(ipaddr)) { 00313 pcb->local_ip = *ipaddr; 00314 } 00315 pcb->local_port = port; 00316 TCP_REG(&tcp_bound_pcbs, pcb); 00317 LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); 00318 return ERR_OK; 00319 } 00320 #if LWIP_CALLBACK_API 00321 /** 00322 * Default accept callback if no accept callback is specified by the user. 00323 */ 00324 static err_t 00325 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) 00326 { 00327 LWIP_UNUSED_ARG(arg); 00328 LWIP_UNUSED_ARG(pcb); 00329 LWIP_UNUSED_ARG(err); 00330 00331 return ERR_ABRT; 00332 } 00333 #endif /* LWIP_CALLBACK_API */ 00334 00335 /** 00336 * Set the state of the connection to be LISTEN, which means that it 00337 * is able to accept incoming connections. The protocol control block 00338 * is reallocated in order to consume less memory. Setting the 00339 * connection to LISTEN is an irreversible process. 00340 * 00341 * @param pcb the original tcp_pcb 00342 * @param backlog the incoming connections queue limit 00343 * @return tcp_pcb used for listening, consumes less memory. 00344 * 00345 * @note The original tcp_pcb is freed. This function therefore has to be 00346 * called like this: 00347 * tpcb = tcp_listen(tpcb); 00348 */ 00349 struct tcp_pcb * 00350 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) 00351 { 00352 struct tcp_pcb_listen *lpcb; 00353 00354 LWIP_UNUSED_ARG(backlog); 00355 LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); 00356 00357 /* already listening? */ 00358 if (pcb->state == LISTEN) { 00359 return pcb; 00360 } 00361 lpcb = (struct tcp_pcb_listen *)(memp_malloc(MEMP_TCP_PCB_LISTEN)); // static_cast<struct tcp_pcb_listen *>(x) 00362 if (lpcb == NULL) { 00363 return NULL; 00364 } 00365 lpcb->callback_arg = pcb->callback_arg; 00366 lpcb->local_port = pcb->local_port; 00367 lpcb->state = LISTEN; 00368 lpcb->so_options = pcb->so_options; 00369 lpcb->so_options |= SOF_ACCEPTCONN; 00370 lpcb->ttl = pcb->ttl; 00371 lpcb->tos = pcb->tos; 00372 ip_addr_set(&lpcb->local_ip, &pcb->local_ip); 00373 TCP_RMV(&tcp_bound_pcbs, pcb); 00374 memp_free(MEMP_TCP_PCB, pcb); 00375 #if LWIP_CALLBACK_API 00376 lpcb->accept = tcp_accept_null; 00377 #endif /* LWIP_CALLBACK_API */ 00378 #if TCP_LISTEN_BACKLOG 00379 lpcb->accepts_pending = 0; 00380 lpcb->backlog = (backlog ? backlog : 1); 00381 #endif /* TCP_LISTEN_BACKLOG */ 00382 TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb); 00383 return (struct tcp_pcb *)lpcb; 00384 } 00385 00386 /** 00387 * Update the state that tracks the available window space to advertise. 00388 * 00389 * Returns how much extra window would be advertised if we sent an 00390 * update now. 00391 */ 00392 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) 00393 { 00394 u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; 00395 00396 if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + pcb->mss)) { 00397 /* we can advertise more window */ 00398 pcb->rcv_ann_wnd = pcb->rcv_wnd; 00399 return new_right_edge - pcb->rcv_ann_right_edge; 00400 } else { 00401 if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { 00402 /* Can happen due to other end sending out of advertised window, 00403 * but within actual available (but not yet advertised) window */ 00404 pcb->rcv_ann_wnd = 0; 00405 } else { 00406 /* keep the right edge of window constant */ 00407 pcb->rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; 00408 } 00409 return 0; 00410 } 00411 } 00412 00413 /** 00414 * This function should be called by the application when it has 00415 * processed the data. The purpose is to advertise a larger window 00416 * when the data has been processed. 00417 * 00418 * @param pcb the tcp_pcb for which data is read 00419 * @param len the amount of bytes that have been read by the application 00420 */ 00421 void 00422 tcp_recved(struct tcp_pcb *pcb, u16_t len) 00423 { 00424 int wnd_inflation; 00425 00426 pcb->rcv_wnd += len; 00427 if (pcb->rcv_wnd > TCP_WND) 00428 pcb->rcv_wnd = TCP_WND; 00429 00430 wnd_inflation = tcp_update_rcv_ann_wnd(pcb); 00431 00432 /* If the change in the right edge of window is significant (default 00433 * watermark is TCP_WND/2), then send an explicit update now. 00434 * Otherwise wait for a packet to be sent in the normal course of 00435 * events (or more window to be available later) */ 00436 if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) 00437 tcp_ack_now(pcb); 00438 00439 LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", 00440 len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); 00441 } 00442 00443 /** 00444 * A nastly hack featuring 'goto' statements that allocates a 00445 * new TCP local port. 00446 * 00447 * @return a new (free) local TCP port number 00448 */ 00449 static u16_t 00450 tcp_new_port(void) 00451 { 00452 struct tcp_pcb *pcb; 00453 #ifndef TCP_LOCAL_PORT_RANGE_START 00454 #define TCP_LOCAL_PORT_RANGE_START 4096 00455 #define TCP_LOCAL_PORT_RANGE_END 0x7fff 00456 #endif 00457 static u16_t port = TCP_LOCAL_PORT_RANGE_START; 00458 00459 again: 00460 if (++port > TCP_LOCAL_PORT_RANGE_END) { 00461 port = TCP_LOCAL_PORT_RANGE_START; 00462 } 00463 00464 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00465 if (pcb->local_port == port) { 00466 goto again; 00467 } 00468 } 00469 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 00470 if (pcb->local_port == port) { 00471 goto again; 00472 } 00473 } 00474 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { 00475 if (pcb->local_port == port) { 00476 goto again; 00477 } 00478 } 00479 return port; 00480 } 00481 00482 /** 00483 * Connects to another host. The function given as the "connected" 00484 * argument will be called when the connection has been established. 00485 * 00486 * @param pcb the tcp_pcb used to establish the connection 00487 * @param ipaddr the remote ip address to connect to 00488 * @param port the remote tcp port to connect to 00489 * @param connected callback function to call when connected (or on error) 00490 * @return ERR_VAL if invalid arguments are given 00491 * ERR_OK if connect request has been sent 00492 * other err_t values if connect request couldn't be sent 00493 */ 00494 err_t 00495 tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port, 00496 err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err)) 00497 { 00498 err_t ret; 00499 u32_t iss; 00500 00501 LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); 00502 00503 LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); 00504 if (ipaddr != NULL) { 00505 pcb->remote_ip = *ipaddr; 00506 } else { 00507 return ERR_VAL; 00508 } 00509 pcb->remote_port = port; 00510 if (pcb->local_port == 0) { 00511 pcb->local_port = tcp_new_port(); 00512 } 00513 iss = tcp_next_iss(); 00514 pcb->rcv_nxt = 0; 00515 pcb->snd_nxt = iss; 00516 pcb->lastack = iss - 1; 00517 pcb->snd_lbb = iss - 1; 00518 pcb->rcv_wnd = TCP_WND; 00519 pcb->rcv_ann_wnd = TCP_WND; 00520 pcb->rcv_ann_right_edge = pcb->rcv_nxt; 00521 pcb->snd_wnd = TCP_WND; 00522 /* As initial send MSS, we use TCP_MSS but limit it to 536. 00523 The send MSS is updated when an MSS option is received. */ 00524 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 00525 #if TCP_CALCULATE_EFF_SEND_MSS 00526 pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); 00527 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00528 pcb->cwnd = 1; 00529 pcb->ssthresh = pcb->mss * 10; 00530 pcb->state = SYN_SENT; 00531 #if LWIP_CALLBACK_API 00532 pcb->connected = connected; 00533 #endif /* LWIP_CALLBACK_API */ 00534 TCP_RMV(&tcp_bound_pcbs, pcb); 00535 TCP_REG(&tcp_active_pcbs, pcb); 00536 00537 snmp_inc_tcpactiveopens(); 00538 00539 ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, TF_SEG_OPTS_MSS 00540 #if LWIP_TCP_TIMESTAMPS 00541 | TF_SEG_OPTS_TS 00542 #endif 00543 ); 00544 if (ret == ERR_OK) { 00545 tcp_output(pcb); 00546 } 00547 return ret; 00548 } 00549 00550 /** 00551 * Called every 500 ms and implements the retransmission timer and the timer that 00552 * removes PCBs that have been in TIME-WAIT for enough time. It also increments 00553 * various timers such as the inactivity timer in each PCB. 00554 * 00555 * Automatically called from tcp_tmr(). 00556 */ 00557 void 00558 tcp_slowtmr(void) 00559 { 00560 struct tcp_pcb *pcb, *pcb2, *prev; 00561 u16_t eff_wnd; 00562 u8_t pcb_remove; /* flag if a PCB should be removed */ 00563 err_t err; 00564 00565 err = ERR_OK; 00566 00567 ++tcp_ticks; 00568 00569 /* Steps through all of the active PCBs. */ 00570 prev = NULL; 00571 pcb = tcp_active_pcbs; 00572 if (pcb == NULL) { 00573 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); 00574 } 00575 while (pcb != NULL) { 00576 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); 00577 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); 00578 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); 00579 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); 00580 00581 pcb_remove = 0; 00582 00583 if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { 00584 ++pcb_remove; 00585 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); 00586 } 00587 else if (pcb->nrtx == TCP_MAXRTX) { 00588 ++pcb_remove; 00589 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); 00590 } else { 00591 if (pcb->persist_backoff > 0) { 00592 /* If snd_wnd is zero, use persist timer to send 1 byte probes 00593 * instead of using the standard retransmission mechanism. */ 00594 pcb->persist_cnt++; 00595 if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { 00596 pcb->persist_cnt = 0; 00597 if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { 00598 pcb->persist_backoff++; 00599 } 00600 tcp_zero_window_probe(pcb); 00601 } 00602 } else { 00603 /* Increase the retransmission timer if it is running */ 00604 if(pcb->rtime >= 0) 00605 ++pcb->rtime; 00606 00607 if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { 00608 /* Time for a retransmission. */ 00609 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F 00610 " pcb->rto %"S16_F"\n", 00611 pcb->rtime, pcb->rto)); 00612 00613 /* Double retransmission time-out unless we are trying to 00614 * connect to somebody (i.e., we are in SYN_SENT). */ 00615 if (pcb->state != SYN_SENT) { 00616 pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; 00617 } 00618 00619 /* Reset the retransmission timer. */ 00620 pcb->rtime = 0; 00621 00622 /* Reduce congestion window and ssthresh. */ 00623 eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); 00624 pcb->ssthresh = eff_wnd >> 1; 00625 if (pcb->ssthresh < pcb->mss) { 00626 pcb->ssthresh = pcb->mss * 2; 00627 } 00628 pcb->cwnd = pcb->mss; 00629 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F 00630 " ssthresh %"U16_F"\n", 00631 pcb->cwnd, pcb->ssthresh)); 00632 00633 /* The following needs to be called AFTER cwnd is set to one 00634 mss - STJ */ 00635 tcp_rexmit_rto(pcb); 00636 } 00637 } 00638 } 00639 /* Check if this PCB has stayed too long in FIN-WAIT-2 */ 00640 if (pcb->state == FIN_WAIT_2) { 00641 if ((u32_t)(tcp_ticks - pcb->tmr) > 00642 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { 00643 ++pcb_remove; 00644 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); 00645 } 00646 } 00647 00648 /* Check if KEEPALIVE should be sent */ 00649 if((pcb->so_options & SOF_KEEPALIVE) && 00650 ((pcb->state == ESTABLISHED) || 00651 (pcb->state == CLOSE_WAIT))) { 00652 #if LWIP_TCP_KEEPALIVE 00653 if((u32_t)(tcp_ticks - pcb->tmr) > 00654 (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl)) 00655 / TCP_SLOW_INTERVAL) 00656 #else 00657 if((u32_t)(tcp_ticks - pcb->tmr) > 00658 (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL) 00659 #endif /* LWIP_TCP_KEEPALIVE */ 00660 { 00661 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", 00662 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip), 00663 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip))); 00664 00665 tcp_abort(pcb); 00666 } 00667 #if LWIP_TCP_KEEPALIVE 00668 else if((u32_t)(tcp_ticks - pcb->tmr) > 00669 (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl) 00670 / TCP_SLOW_INTERVAL) 00671 #else 00672 else if((u32_t)(tcp_ticks - pcb->tmr) > 00673 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) 00674 / TCP_SLOW_INTERVAL) 00675 #endif /* LWIP_TCP_KEEPALIVE */ 00676 { 00677 tcp_keepalive(pcb); 00678 pcb->keep_cnt_sent++; 00679 } 00680 } 00681 00682 /* If this PCB has queued out of sequence data, but has been 00683 inactive for too long, will drop the data (it will eventually 00684 be retransmitted). */ 00685 #if TCP_QUEUE_OOSEQ 00686 if (pcb->ooseq != NULL && 00687 (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { 00688 tcp_segs_free(pcb->ooseq); 00689 pcb->ooseq = NULL; 00690 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); 00691 } 00692 #endif /* TCP_QUEUE_OOSEQ */ 00693 00694 /* Check if this PCB has stayed too long in SYN-RCVD */ 00695 if (pcb->state == SYN_RCVD) { 00696 if ((u32_t)(tcp_ticks - pcb->tmr) > 00697 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { 00698 ++pcb_remove; 00699 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); 00700 } 00701 } 00702 00703 /* Check if this PCB has stayed too long in LAST-ACK */ 00704 if (pcb->state == LAST_ACK) { 00705 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { 00706 ++pcb_remove; 00707 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); 00708 } 00709 } 00710 00711 /* If the PCB should be removed, do it. */ 00712 if (pcb_remove) { 00713 tcp_pcb_purge(pcb); 00714 /* Remove PCB from tcp_active_pcbs list. */ 00715 if (prev != NULL) { 00716 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); 00717 prev->next = pcb->next; 00718 } else { 00719 /* This PCB was the first. */ 00720 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); 00721 tcp_active_pcbs = pcb->next; 00722 } 00723 00724 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT); 00725 00726 pcb2 = pcb->next; 00727 memp_free(MEMP_TCP_PCB, pcb); 00728 pcb = pcb2; 00729 } else { 00730 00731 /* We check if we should poll the connection. */ 00732 ++pcb->polltmr; 00733 if (pcb->polltmr >= pcb->pollinterval) { 00734 pcb->polltmr = 0; 00735 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); 00736 TCP_EVENT_POLL(pcb, err); 00737 if (err == ERR_OK) { 00738 tcp_output(pcb); 00739 } 00740 } 00741 00742 prev = pcb; 00743 pcb = pcb->next; 00744 } 00745 } 00746 00747 00748 /* Steps through all of the TIME-WAIT PCBs. */ 00749 prev = NULL; 00750 pcb = tcp_tw_pcbs; 00751 while (pcb != NULL) { 00752 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 00753 pcb_remove = 0; 00754 00755 /* Check if this PCB has stayed long enough in TIME-WAIT */ 00756 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { 00757 ++pcb_remove; 00758 } 00759 00760 00761 00762 /* If the PCB should be removed, do it. */ 00763 if (pcb_remove) { 00764 tcp_pcb_purge(pcb); 00765 /* Remove PCB from tcp_tw_pcbs list. */ 00766 if (prev != NULL) { 00767 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); 00768 prev->next = pcb->next; 00769 } else { 00770 /* This PCB was the first. */ 00771 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); 00772 tcp_tw_pcbs = pcb->next; 00773 } 00774 pcb2 = pcb->next; 00775 memp_free(MEMP_TCP_PCB, pcb); 00776 pcb = pcb2; 00777 } else { 00778 prev = pcb; 00779 pcb = pcb->next; 00780 } 00781 } 00782 } 00783 00784 /** 00785 * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously 00786 * "refused" by upper layer (application) and sends delayed ACKs. 00787 * 00788 * Automatically called from tcp_tmr(). 00789 */ 00790 void 00791 tcp_fasttmr(void) 00792 { 00793 struct tcp_pcb *pcb; 00794 00795 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00796 /* If there is data which was previously "refused" by upper layer */ 00797 if (pcb->refused_data != NULL) { 00798 /* Notify again application with data previously received. */ 00799 err_t err; 00800 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n")); 00801 TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); 00802 if (err == ERR_OK) { 00803 pcb->refused_data = NULL; 00804 } 00805 } 00806 00807 /* send delayed ACKs */ 00808 if (pcb->flags & TF_ACK_DELAY) { 00809 LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); 00810 tcp_ack_now(pcb); 00811 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); 00812 } 00813 } 00814 } 00815 00816 /** 00817 * Deallocates a list of TCP segments (tcp_seg structures). 00818 * 00819 * @param seg tcp_seg list of TCP segments to free 00820 * @return the number of pbufs that were deallocated 00821 */ 00822 u8_t 00823 tcp_segs_free(struct tcp_seg *seg) 00824 { 00825 u8_t count = 0; 00826 struct tcp_seg *next; 00827 while (seg != NULL) { 00828 next = seg->next; 00829 count += tcp_seg_free(seg); 00830 seg = next; 00831 } 00832 return count; 00833 } 00834 00835 /** 00836 * Frees a TCP segment (tcp_seg structure). 00837 * 00838 * @param seg single tcp_seg to free 00839 * @return the number of pbufs that were deallocated 00840 */ 00841 u8_t 00842 tcp_seg_free(struct tcp_seg *seg) 00843 { 00844 u8_t count = 0; 00845 00846 if (seg != NULL) { 00847 if (seg->p != NULL) { 00848 count = pbuf_free(seg->p); 00849 #if TCP_DEBUG 00850 seg->p = NULL; 00851 #endif /* TCP_DEBUG */ 00852 } 00853 memp_free(MEMP_TCP_SEG, seg); 00854 } 00855 return count; 00856 } 00857 00858 /** 00859 * Sets the priority of a connection. 00860 * 00861 * @param pcb the tcp_pcb to manipulate 00862 * @param prio new priority 00863 */ 00864 void 00865 tcp_setprio(struct tcp_pcb *pcb, u8_t prio) 00866 { 00867 pcb->prio = prio; 00868 } 00869 #if TCP_QUEUE_OOSEQ 00870 00871 /** 00872 * Returns a copy of the given TCP segment. 00873 * The pbuf and data are not copied, only the pointers 00874 * 00875 * @param seg the old tcp_seg 00876 * @return a copy of seg 00877 */ 00878 struct tcp_seg * 00879 tcp_seg_copy(struct tcp_seg *seg) 00880 { 00881 struct tcp_seg *cseg; 00882 00883 cseg = (struct tcp_seg *)(memp_malloc(MEMP_TCP_SEG)); // static_cast<struct tcp_seg *>(x) 00884 if (cseg == NULL) { 00885 return NULL; 00886 } 00887 SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 00888 pbuf_ref(cseg->p); 00889 return cseg; 00890 } 00891 #endif 00892 00893 #if LWIP_CALLBACK_API 00894 /** 00895 * Default receive callback that is called if the user didn't register 00896 * a recv callback for the pcb. 00897 */ 00898 static err_t 00899 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) 00900 { 00901 arg = arg; 00902 if (p != NULL) { 00903 pbuf_free(p); 00904 } else if (err == ERR_OK) { 00905 return tcp_close(pcb); 00906 } 00907 return ERR_OK; 00908 } 00909 #endif /* LWIP_CALLBACK_API */ 00910 00911 /** 00912 * Kills the oldest active connection that has lower priority than prio. 00913 * 00914 * @param prio minimum priority 00915 */ 00916 static void 00917 tcp_kill_prio(u8_t prio) 00918 { 00919 struct tcp_pcb *pcb, *inactive; 00920 u32_t inactivity; 00921 u8_t mprio; 00922 00923 00924 mprio = TCP_PRIO_MAX; 00925 00926 /* We kill the oldest active connection that has lower priority than prio. */ 00927 inactivity = 0; 00928 inactive = NULL; 00929 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00930 if (pcb->prio <= prio && 00931 pcb->prio <= mprio && 00932 (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { 00933 inactivity = tcp_ticks - pcb->tmr; 00934 inactive = pcb; 00935 mprio = pcb->prio; 00936 } 00937 } 00938 if (inactive != NULL) { 00939 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", 00940 (void *)inactive, inactivity)); 00941 tcp_abort(inactive); 00942 } 00943 } 00944 00945 /** 00946 * Kills the oldest connection that is in TIME_WAIT state. 00947 * Called from tcp_alloc() if no more connections are available. 00948 */ 00949 static void 00950 tcp_kill_timewait(void) 00951 { 00952 struct tcp_pcb *pcb, *inactive; 00953 u32_t inactivity; 00954 00955 inactivity = 0; 00956 inactive = NULL; 00957 /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ 00958 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 00959 if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { 00960 inactivity = tcp_ticks - pcb->tmr; 00961 inactive = pcb; 00962 } 00963 } 00964 if (inactive != NULL) { 00965 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", 00966 (void *)inactive, inactivity)); 00967 tcp_abort(inactive); 00968 } 00969 } 00970 00971 /** 00972 * Allocate a new tcp_pcb structure. 00973 * 00974 * @param prio priority for the new pcb 00975 * @return a new tcp_pcb that initially is in state CLOSED 00976 */ 00977 struct tcp_pcb * 00978 tcp_alloc(u8_t prio) 00979 { 00980 struct tcp_pcb *pcb; 00981 u32_t iss; 00982 00983 pcb = (struct tcp_pcb *)(memp_malloc(MEMP_TCP_PCB)); // static_cast<struct tcp_pcb *>(x) 00984 if (pcb == NULL) { 00985 /* Try killing oldest connection in TIME-WAIT. */ 00986 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); 00987 tcp_kill_timewait(); 00988 /* Try to allocate a tcp_pcb again. */ 00989 pcb = (struct tcp_pcb *)(memp_malloc(MEMP_TCP_PCB)); // static_cast<struct tcp_pcb *>(x) 00990 if (pcb == NULL) { 00991 /* Try killing active connections with lower priority than the new one. */ 00992 tcp_kill_prio(prio); 00993 /* Try to allocate a tcp_pcb again. */ 00994 pcb = (struct tcp_pcb *)(memp_malloc(MEMP_TCP_PCB)); // static_cast<struct tcp_pcb *>(x) 00995 } 00996 } 00997 if (pcb != NULL) { 00998 memset(pcb, 0, sizeof(struct tcp_pcb)); 00999 pcb->prio = TCP_PRIO_NORMAL; 01000 pcb->snd_buf = TCP_SND_BUF; 01001 pcb->snd_queuelen = 0; 01002 pcb->rcv_wnd = TCP_WND; 01003 pcb->rcv_ann_wnd = TCP_WND; 01004 pcb->tos = 0; 01005 pcb->ttl = TCP_TTL; 01006 /* As initial send MSS, we use TCP_MSS but limit it to 536. 01007 The send MSS is updated when an MSS option is received. */ 01008 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 01009 pcb->rto = 3000 / TCP_SLOW_INTERVAL; 01010 pcb->sa = 0; 01011 pcb->sv = 3000 / TCP_SLOW_INTERVAL; 01012 pcb->rtime = -1; 01013 pcb->cwnd = 1; 01014 iss = tcp_next_iss(); 01015 pcb->snd_wl2 = iss; 01016 pcb->snd_nxt = iss; 01017 pcb->snd_max = iss; 01018 pcb->lastack = iss; 01019 pcb->snd_lbb = iss; 01020 pcb->tmr = tcp_ticks; 01021 01022 pcb->polltmr = 0; 01023 01024 #if LWIP_CALLBACK_API 01025 pcb->recv = tcp_recv_null; 01026 #endif /* LWIP_CALLBACK_API */ 01027 01028 /* Init KEEPALIVE timer */ 01029 pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; 01030 01031 #if LWIP_TCP_KEEPALIVE 01032 pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; 01033 pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; 01034 #endif /* LWIP_TCP_KEEPALIVE */ 01035 01036 pcb->keep_cnt_sent = 0; 01037 } 01038 return pcb; 01039 } 01040 01041 /** 01042 * Creates a new TCP protocol control block but doesn't place it on 01043 * any of the TCP PCB lists. 01044 * The pcb is not put on any list until binding using tcp_bind(). 01045 * 01046 * @internal: Maybe there should be a idle TCP PCB list where these 01047 * PCBs are put on. Port reservation using tcp_bind() is implemented but 01048 * allocated pcbs that are not bound can't be killed automatically if wanting 01049 * to allocate a pcb with higher prio (@see tcp_kill_prio()) 01050 * 01051 * @return a new tcp_pcb that initially is in state CLOSED 01052 */ 01053 struct tcp_pcb * 01054 tcp_new(void) 01055 { 01056 return tcp_alloc(TCP_PRIO_NORMAL); 01057 } 01058 01059 /** 01060 * Used to specify the argument that should be passed callback 01061 * functions. 01062 * 01063 * @param pcb tcp_pcb to set the callback argument 01064 * @param arg void pointer argument to pass to callback functions 01065 */ 01066 void 01067 tcp_arg(struct tcp_pcb *pcb, void *arg) 01068 { 01069 pcb->callback_arg = arg; 01070 } 01071 #if LWIP_CALLBACK_API 01072 01073 /** 01074 * Used to specify the function that should be called when a TCP 01075 * connection receives data. 01076 * 01077 * @param pcb tcp_pcb to set the recv callback 01078 * @param recv callback function to call for this pcb when data is received 01079 */ 01080 void 01081 tcp_recv(struct tcp_pcb *pcb, 01082 err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)) 01083 { 01084 pcb->recv = recv; 01085 } 01086 01087 /** 01088 * Used to specify the function that should be called when TCP data 01089 * has been successfully delivered to the remote host. 01090 * 01091 * @param pcb tcp_pcb to set the sent callback 01092 * @param sent callback function to call for this pcb when data is successfully sent 01093 */ 01094 void 01095 tcp_sent(struct tcp_pcb *pcb, 01096 err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len)) 01097 { 01098 pcb->sent = sent; 01099 } 01100 01101 /** 01102 * Used to specify the function that should be called when a fatal error 01103 * has occured on the connection. 01104 * 01105 * @param pcb tcp_pcb to set the err callback 01106 * @param errf callback function to call for this pcb when a fatal error 01107 * has occured on the connection 01108 */ 01109 void 01110 tcp_err(struct tcp_pcb *pcb, 01111 void (* errf)(void *arg, err_t err)) 01112 { 01113 pcb->errf = errf; 01114 } 01115 01116 /** 01117 * Used for specifying the function that should be called when a 01118 * LISTENing connection has been connected to another host. 01119 * 01120 * @param pcb tcp_pcb to set the accept callback 01121 * @param accept callback function to call for this pcb when LISTENing 01122 * connection has been connected to another host 01123 */ 01124 void 01125 tcp_accept(struct tcp_pcb *pcb, 01126 err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err)) 01127 { 01128 pcb->accept = accept; 01129 } 01130 #endif /* LWIP_CALLBACK_API */ 01131 01132 01133 /** 01134 * Used to specify the function that should be called periodically 01135 * from TCP. The interval is specified in terms of the TCP coarse 01136 * timer interval, which is called twice a second. 01137 * 01138 */ 01139 void 01140 tcp_poll(struct tcp_pcb *pcb, 01141 err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval) 01142 { 01143 #if LWIP_CALLBACK_API 01144 pcb->poll = poll; 01145 #endif /* LWIP_CALLBACK_API */ 01146 pcb->pollinterval = interval; 01147 } 01148 01149 /** 01150 * Purges a TCP PCB. Removes any buffered data and frees the buffer memory 01151 * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). 01152 * 01153 * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! 01154 */ 01155 void 01156 tcp_pcb_purge(struct tcp_pcb *pcb) 01157 { 01158 if (pcb->state != CLOSED && 01159 pcb->state != TIME_WAIT && 01160 pcb->state != LISTEN) { 01161 01162 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); 01163 01164 #if TCP_LISTEN_BACKLOG 01165 if (pcb->state == SYN_RCVD) { 01166 /* Need to find the corresponding listen_pcb and decrease its accepts_pending */ 01167 struct tcp_pcb_listen *lpcb; 01168 LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", 01169 tcp_listen_pcbs.listen_pcbs != NULL); 01170 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 01171 if ((lpcb->local_port == pcb->local_port) && 01172 (ip_addr_isany(&lpcb->local_ip) || 01173 ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) { 01174 /* port and address of the listen pcb match the timed-out pcb */ 01175 LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", 01176 lpcb->accepts_pending > 0); 01177 lpcb->accepts_pending--; 01178 break; 01179 } 01180 } 01181 } 01182 #endif /* TCP_LISTEN_BACKLOG */ 01183 01184 01185 if (pcb->refused_data != NULL) { 01186 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); 01187 pbuf_free(pcb->refused_data); 01188 pcb->refused_data = NULL; 01189 } 01190 if (pcb->unsent != NULL) { 01191 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); 01192 } 01193 if (pcb->unacked != NULL) { 01194 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); 01195 } 01196 #if TCP_QUEUE_OOSEQ /* LW */ 01197 if (pcb->ooseq != NULL) { 01198 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); 01199 } 01200 01201 /* Stop the retransmission timer as it will expect data on unacked 01202 queue if it fires */ 01203 pcb->rtime = -1; 01204 01205 tcp_segs_free(pcb->ooseq); 01206 pcb->ooseq = NULL; 01207 #endif /* TCP_QUEUE_OOSEQ */ 01208 tcp_segs_free(pcb->unsent); 01209 tcp_segs_free(pcb->unacked); 01210 pcb->unacked = pcb->unsent = NULL; 01211 } 01212 } 01213 01214 /** 01215 * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. 01216 * 01217 * @param pcblist PCB list to purge. 01218 * @param pcb tcp_pcb to purge. The pcb itself is also deallocated! 01219 */ 01220 void 01221 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) 01222 { 01223 TCP_RMV(pcblist, pcb); 01224 01225 tcp_pcb_purge(pcb); 01226 01227 /* if there is an outstanding delayed ACKs, send it */ 01228 if (pcb->state != TIME_WAIT && 01229 pcb->state != LISTEN && 01230 pcb->flags & TF_ACK_DELAY) { 01231 pcb->flags |= TF_ACK_NOW; 01232 tcp_output(pcb); 01233 } 01234 01235 if (pcb->state != LISTEN) { 01236 LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); 01237 LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); 01238 #if TCP_QUEUE_OOSEQ 01239 LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); 01240 #endif /* TCP_QUEUE_OOSEQ */ 01241 } 01242 01243 pcb->state = CLOSED; 01244 01245 LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); 01246 } 01247 01248 /** 01249 * Calculates a new initial sequence number for new connections. 01250 * 01251 * @return u32_t pseudo random sequence number 01252 */ 01253 u32_t 01254 tcp_next_iss(void) 01255 { 01256 static u32_t iss = 6510; 01257 01258 iss += tcp_ticks; /* XXX */ 01259 return iss; 01260 } 01261 01262 #if TCP_CALCULATE_EFF_SEND_MSS 01263 /** 01264 * Calcluates the effective send mss that can be used for a specific IP address 01265 * by using ip_route to determin the netif used to send to the address and 01266 * calculating the minimum of TCP_MSS and that netif's mtu (if set). 01267 */ 01268 u16_t 01269 tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr) 01270 { 01271 u16_t mss_s; 01272 struct netif *outif; 01273 01274 outif = ip_route(addr); 01275 if ((outif != NULL) && (outif->mtu != 0)) { 01276 mss_s = outif->mtu - IP_HLEN - TCP_HLEN; 01277 /* RFC 1122, chap 4.2.2.6: 01278 * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize 01279 * We correct for TCP options in tcp_enqueue(), and don't support 01280 * IP options 01281 */ 01282 sendmss = LWIP_MIN(sendmss, mss_s); 01283 } 01284 return sendmss; 01285 } 01286 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 01287 01288 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG 01289 /** 01290 * Print a tcp header for debugging purposes. 01291 * 01292 * @param tcphdr pointer to a struct tcp_hdr 01293 */ 01294 void 01295 tcp_debug_print(struct tcp_hdr *tcphdr) 01296 { 01297 LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); 01298 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01299 LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", 01300 ntohs(tcphdr->src), ntohs(tcphdr->dest))); 01301 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01302 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", 01303 ntohl(tcphdr->seqno))); 01304 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01305 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", 01306 ntohl(tcphdr->ackno))); 01307 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01308 LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", 01309 TCPH_HDRLEN(tcphdr), 01310 TCPH_FLAGS(tcphdr) >> 5 & 1, 01311 TCPH_FLAGS(tcphdr) >> 4 & 1, 01312 TCPH_FLAGS(tcphdr) >> 3 & 1, 01313 TCPH_FLAGS(tcphdr) >> 2 & 1, 01314 TCPH_FLAGS(tcphdr) >> 1 & 1, 01315 TCPH_FLAGS(tcphdr) & 1, 01316 ntohs(tcphdr->wnd))); 01317 tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); 01318 LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); 01319 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01320 LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", 01321 ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); 01322 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01323 } 01324 01325 /** 01326 * Print a tcp state for debugging purposes. 01327 * 01328 * @param s enum tcp_state to print 01329 */ 01330 void 01331 tcp_debug_print_state(enum tcp_state s) 01332 { 01333 LWIP_DEBUGF(TCP_DEBUG, ("State: ")); 01334 switch (s) { 01335 case CLOSED: 01336 LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n")); 01337 break; 01338 case LISTEN: 01339 LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n")); 01340 break; 01341 case SYN_SENT: 01342 LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n")); 01343 break; 01344 case SYN_RCVD: 01345 LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n")); 01346 break; 01347 case ESTABLISHED: 01348 LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n")); 01349 break; 01350 case FIN_WAIT_1: 01351 LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n")); 01352 break; 01353 case FIN_WAIT_2: 01354 LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n")); 01355 break; 01356 case CLOSE_WAIT: 01357 LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n")); 01358 break; 01359 case CLOSING: 01360 LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n")); 01361 break; 01362 case LAST_ACK: 01363 LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n")); 01364 break; 01365 case TIME_WAIT: 01366 LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n")); 01367 break; 01368 } 01369 } 01370 01371 /** 01372 * Print tcp flags for debugging purposes. 01373 * 01374 * @param flags tcp flags, all active flags are printed 01375 */ 01376 void 01377 tcp_debug_print_flags(u8_t flags) 01378 { 01379 if (flags & TCP_FIN) { 01380 LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); 01381 } 01382 if (flags & TCP_SYN) { 01383 LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); 01384 } 01385 if (flags & TCP_RST) { 01386 LWIP_DEBUGF(TCP_DEBUG, ("RST ")); 01387 } 01388 if (flags & TCP_PSH) { 01389 LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); 01390 } 01391 if (flags & TCP_ACK) { 01392 LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); 01393 } 01394 if (flags & TCP_URG) { 01395 LWIP_DEBUGF(TCP_DEBUG, ("URG ")); 01396 } 01397 if (flags & TCP_ECE) { 01398 LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); 01399 } 01400 if (flags & TCP_CWR) { 01401 LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); 01402 } 01403 } 01404 01405 /** 01406 * Print all tcp_pcbs in every list for debugging purposes. 01407 */ 01408 void 01409 tcp_debug_print_pcbs(void) 01410 { 01411 struct tcp_pcb *pcb; 01412 LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); 01413 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 01414 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01415 pcb->local_port, pcb->remote_port, 01416 pcb->snd_nxt, pcb->rcv_nxt)); 01417 tcp_debug_print_state(pcb->state); 01418 } 01419 LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); 01420 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { 01421 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01422 pcb->local_port, pcb->remote_port, 01423 pcb->snd_nxt, pcb->rcv_nxt)); 01424 tcp_debug_print_state(pcb->state); 01425 } 01426 LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); 01427 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 01428 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01429 pcb->local_port, pcb->remote_port, 01430 pcb->snd_nxt, pcb->rcv_nxt)); 01431 tcp_debug_print_state(pcb->state); 01432 } 01433 } 01434 01435 /** 01436 * Check state consistency of the tcp_pcb lists. 01437 */ 01438 s16_t 01439 tcp_pcbs_sane(void) 01440 { 01441 struct tcp_pcb *pcb; 01442 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 01443 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); 01444 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); 01445 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); 01446 } 01447 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 01448 LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 01449 } 01450 return 1; 01451 } 01452 #endif /* TCP_DEBUG */ 01453 01454 #endif /* LWIP_TCP */
Generated on Tue Jul 12 2022 16:06:25 by 1.7.2