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 * Aborts a connection by sending a RST to the remote host and deletes 00190 * the local protocol control block. This is done when a connection is 00191 * killed because of shortage of memory. 00192 * 00193 * @param pcb the tcp_pcb to abort 00194 */ 00195 void 00196 tcp_abort(struct tcp_pcb *pcb) 00197 { 00198 u32_t seqno, ackno; 00199 u16_t remote_port, local_port; 00200 struct ip_addr remote_ip, local_ip; 00201 #if LWIP_CALLBACK_API 00202 void (* errf)(void *arg, err_t err); 00203 #endif /* LWIP_CALLBACK_API */ 00204 void *errf_arg; 00205 00206 00207 /* Figure out on which TCP PCB list we are, and remove us. If we 00208 are in an active state, call the receive function associated with 00209 the PCB with a NULL argument, and send an RST to the remote end. */ 00210 if (pcb->state == TIME_WAIT) { 00211 tcp_pcb_remove(&tcp_tw_pcbs, pcb); 00212 memp_free(MEMP_TCP_PCB, pcb); 00213 } else { 00214 seqno = pcb->snd_nxt; 00215 ackno = pcb->rcv_nxt; 00216 ip_addr_set(&local_ip, &(pcb->local_ip)); 00217 ip_addr_set(&remote_ip, &(pcb->remote_ip)); 00218 local_port = pcb->local_port; 00219 remote_port = pcb->remote_port; 00220 #if LWIP_CALLBACK_API 00221 errf = pcb->errf; 00222 #endif /* LWIP_CALLBACK_API */ 00223 errf_arg = pcb->callback_arg; 00224 tcp_pcb_remove(&tcp_active_pcbs, pcb); 00225 if (pcb->unacked != NULL) { 00226 tcp_segs_free(pcb->unacked); 00227 } 00228 if (pcb->unsent != NULL) { 00229 tcp_segs_free(pcb->unsent); 00230 } 00231 #if TCP_QUEUE_OOSEQ 00232 if (pcb->ooseq != NULL) { 00233 tcp_segs_free(pcb->ooseq); 00234 } 00235 #endif /* TCP_QUEUE_OOSEQ */ 00236 memp_free(MEMP_TCP_PCB, pcb); 00237 TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); 00238 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abort: sending RST\n")); 00239 tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port); 00240 } 00241 } 00242 00243 /** 00244 * Binds the connection to a local portnumber and IP address. If the 00245 * IP address is not given (i.e., ipaddr == NULL), the IP address of 00246 * the outgoing network interface is used instead. 00247 * 00248 * @param pcb the tcp_pcb to bind (no check is done whether this pcb is 00249 * already bound!) 00250 * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind 00251 * to any local address 00252 * @param port the local port to bind to 00253 * @return ERR_USE if the port is already in use 00254 * ERR_OK if bound 00255 */ 00256 err_t 00257 tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) 00258 { 00259 struct tcp_pcb *cpcb; 00260 00261 LWIP_ERROR("tcp_connect: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); 00262 00263 if (port == 0) { 00264 port = tcp_new_port(); 00265 } 00266 /* Check if the address already is in use. */ 00267 /* Check the listen pcbs. */ 00268 for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; 00269 cpcb != NULL; cpcb = cpcb->next) { 00270 if (cpcb->local_port == port) { 00271 if (ip_addr_isany(&(cpcb->local_ip)) || 00272 ip_addr_isany(ipaddr) || 00273 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00274 return ERR_USE; 00275 } 00276 } 00277 } 00278 /* Check the connected pcbs. */ 00279 for(cpcb = tcp_active_pcbs; 00280 cpcb != NULL; cpcb = cpcb->next) { 00281 if (cpcb->local_port == port) { 00282 if (ip_addr_isany(&(cpcb->local_ip)) || 00283 ip_addr_isany(ipaddr) || 00284 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00285 return ERR_USE; 00286 } 00287 } 00288 } 00289 /* Check the bound, not yet connected pcbs. */ 00290 for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) { 00291 if (cpcb->local_port == port) { 00292 if (ip_addr_isany(&(cpcb->local_ip)) || 00293 ip_addr_isany(ipaddr) || 00294 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00295 return ERR_USE; 00296 } 00297 } 00298 } 00299 /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah), 00300 * we have to check the pcbs in TIME-WAIT state, also: */ 00301 for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) { 00302 if (cpcb->local_port == port) { 00303 if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00304 return ERR_USE; 00305 } 00306 } 00307 } 00308 00309 if (!ip_addr_isany(ipaddr)) { 00310 pcb->local_ip = *ipaddr; 00311 } 00312 pcb->local_port = port; 00313 TCP_REG(&tcp_bound_pcbs, pcb); 00314 LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); 00315 return ERR_OK; 00316 } 00317 #if LWIP_CALLBACK_API 00318 /** 00319 * Default accept callback if no accept callback is specified by the user. 00320 */ 00321 static err_t 00322 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) 00323 { 00324 LWIP_UNUSED_ARG(arg); 00325 LWIP_UNUSED_ARG(pcb); 00326 LWIP_UNUSED_ARG(err); 00327 00328 return ERR_ABRT; 00329 } 00330 #endif /* LWIP_CALLBACK_API */ 00331 00332 /** 00333 * Set the state of the connection to be LISTEN, which means that it 00334 * is able to accept incoming connections. The protocol control block 00335 * is reallocated in order to consume less memory. Setting the 00336 * connection to LISTEN is an irreversible process. 00337 * 00338 * @param pcb the original tcp_pcb 00339 * @param backlog the incoming connections queue limit 00340 * @return tcp_pcb used for listening, consumes less memory. 00341 * 00342 * @note The original tcp_pcb is freed. This function therefore has to be 00343 * called like this: 00344 * tpcb = tcp_listen(tpcb); 00345 */ 00346 struct tcp_pcb * 00347 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) 00348 { 00349 struct tcp_pcb_listen *lpcb; 00350 00351 LWIP_UNUSED_ARG(backlog); 00352 LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); 00353 00354 /* already listening? */ 00355 if (pcb->state == LISTEN) { 00356 return pcb; 00357 } 00358 lpcb = static_cast<struct tcp_pcb_listen *>(memp_malloc(MEMP_TCP_PCB_LISTEN)); 00359 if (lpcb == NULL) { 00360 return NULL; 00361 } 00362 lpcb->callback_arg = pcb->callback_arg; 00363 lpcb->local_port = pcb->local_port; 00364 lpcb->state = LISTEN; 00365 lpcb->so_options = pcb->so_options; 00366 lpcb->so_options |= SOF_ACCEPTCONN; 00367 lpcb->ttl = pcb->ttl; 00368 lpcb->tos = pcb->tos; 00369 ip_addr_set(&lpcb->local_ip, &pcb->local_ip); 00370 TCP_RMV(&tcp_bound_pcbs, pcb); 00371 memp_free(MEMP_TCP_PCB, pcb); 00372 #if LWIP_CALLBACK_API 00373 lpcb->accept = tcp_accept_null; 00374 #endif /* LWIP_CALLBACK_API */ 00375 #if TCP_LISTEN_BACKLOG 00376 lpcb->accepts_pending = 0; 00377 lpcb->backlog = (backlog ? backlog : 1); 00378 #endif /* TCP_LISTEN_BACKLOG */ 00379 TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb); 00380 return (struct tcp_pcb *)lpcb; 00381 } 00382 00383 /** 00384 * This function should be called by the application when it has 00385 * processed the data. The purpose is to advertise a larger window 00386 * when the data has been processed. 00387 * 00388 * @param pcb the tcp_pcb for which data is read 00389 * @param len the amount of bytes that have been read by the application 00390 */ 00391 void 00392 tcp_recved(struct tcp_pcb *pcb, u16_t len) 00393 { 00394 if ((u32_t)pcb->rcv_wnd + len > TCP_WND) { 00395 pcb->rcv_wnd = TCP_WND; 00396 pcb->rcv_ann_wnd = TCP_WND; 00397 } else { 00398 pcb->rcv_wnd += len; 00399 if (pcb->rcv_wnd >= pcb->mss) { 00400 pcb->rcv_ann_wnd = pcb->rcv_wnd; 00401 } 00402 } 00403 00404 if (!(pcb->flags & TF_ACK_DELAY) && 00405 !(pcb->flags & TF_ACK_NOW)) { 00406 /* 00407 * We send an ACK here (if one is not already pending, hence 00408 * the above tests) as tcp_recved() implies that the application 00409 * has processed some data, and so we can open the receiver's 00410 * window to allow more to be transmitted. This could result in 00411 * two ACKs being sent for each received packet in some limited cases 00412 * (where the application is only receiving data, and is slow to 00413 * process it) but it is necessary to guarantee that the sender can 00414 * continue to transmit. 00415 */ 00416 tcp_ack(pcb); 00417 } 00418 else if (pcb->flags & TF_ACK_DELAY && pcb->rcv_wnd >= TCP_WND/2) { 00419 /* If we can send a window update such that there is a full 00420 * segment available in the window, do so now. This is sort of 00421 * nagle-like in its goals, and tries to hit a compromise between 00422 * sending acks each time the window is updated, and only sending 00423 * window updates when a timer expires. The "threshold" used 00424 * above (currently TCP_WND/2) can be tuned to be more or less 00425 * aggressive */ 00426 tcp_ack_now(pcb); 00427 } 00428 00429 LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", 00430 len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); 00431 } 00432 00433 /** 00434 * A nastly hack featuring 'goto' statements that allocates a 00435 * new TCP local port. 00436 * 00437 * @return a new (free) local TCP port number 00438 */ 00439 static u16_t 00440 tcp_new_port(void) 00441 { 00442 struct tcp_pcb *pcb; 00443 #ifndef TCP_LOCAL_PORT_RANGE_START 00444 #define TCP_LOCAL_PORT_RANGE_START 4096 00445 #define TCP_LOCAL_PORT_RANGE_END 0x7fff 00446 #endif 00447 static u16_t port = TCP_LOCAL_PORT_RANGE_START; 00448 00449 again: 00450 if (++port > TCP_LOCAL_PORT_RANGE_END) { 00451 port = TCP_LOCAL_PORT_RANGE_START; 00452 } 00453 00454 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00455 if (pcb->local_port == port) { 00456 goto again; 00457 } 00458 } 00459 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 00460 if (pcb->local_port == port) { 00461 goto again; 00462 } 00463 } 00464 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { 00465 if (pcb->local_port == port) { 00466 goto again; 00467 } 00468 } 00469 return port; 00470 } 00471 00472 /** 00473 * Connects to another host. The function given as the "connected" 00474 * argument will be called when the connection has been established. 00475 * 00476 * @param pcb the tcp_pcb used to establish the connection 00477 * @param ipaddr the remote ip address to connect to 00478 * @param port the remote tcp port to connect to 00479 * @param connected callback function to call when connected (or on error) 00480 * @return ERR_VAL if invalid arguments are given 00481 * ERR_OK if connect request has been sent 00482 * other err_t values if connect request couldn't be sent 00483 */ 00484 err_t 00485 tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port, 00486 err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err)) 00487 { 00488 u32_t optdata; 00489 err_t ret; 00490 u32_t iss; 00491 00492 LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); 00493 00494 LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); 00495 if (ipaddr != NULL) { 00496 pcb->remote_ip = *ipaddr; 00497 } else { 00498 return ERR_VAL; 00499 } 00500 pcb->remote_port = port; 00501 if (pcb->local_port == 0) { 00502 pcb->local_port = tcp_new_port(); 00503 } 00504 iss = tcp_next_iss(); 00505 pcb->rcv_nxt = 0; 00506 pcb->snd_nxt = iss; 00507 pcb->lastack = iss - 1; 00508 pcb->snd_lbb = iss - 1; 00509 pcb->rcv_wnd = TCP_WND; 00510 pcb->rcv_ann_wnd = TCP_WND; 00511 pcb->snd_wnd = TCP_WND; 00512 /* The send MSS is updated when an MSS option is received. */ 00513 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 00514 #if TCP_CALCULATE_EFF_SEND_MSS 00515 pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); 00516 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00517 pcb->cwnd = 1; 00518 pcb->ssthresh = pcb->mss * 10; 00519 pcb->state = SYN_SENT; 00520 #if LWIP_CALLBACK_API 00521 pcb->connected = connected; 00522 #endif /* LWIP_CALLBACK_API */ 00523 TCP_RMV(&tcp_bound_pcbs, pcb); 00524 TCP_REG(&tcp_active_pcbs, pcb); 00525 00526 snmp_inc_tcpactiveopens(); 00527 00528 /* Build an MSS option */ 00529 optdata = TCP_BUILD_MSS_OPTION(); 00530 00531 ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, (u8_t *)&optdata, 4); 00532 if (ret == ERR_OK) { 00533 tcp_output(pcb); 00534 } 00535 return ret; 00536 } 00537 00538 /** 00539 * Called every 500 ms and implements the retransmission timer and the timer that 00540 * removes PCBs that have been in TIME-WAIT for enough time. It also increments 00541 * various timers such as the inactivity timer in each PCB. 00542 * 00543 * Automatically called from tcp_tmr(). 00544 */ 00545 void 00546 tcp_slowtmr(void) 00547 { 00548 struct tcp_pcb *pcb, *pcb2, *prev; 00549 u16_t eff_wnd; 00550 u8_t pcb_remove; /* flag if a PCB should be removed */ 00551 err_t err; 00552 00553 err = ERR_OK; 00554 00555 ++tcp_ticks; 00556 00557 /* Steps through all of the active PCBs. */ 00558 prev = NULL; 00559 pcb = tcp_active_pcbs; 00560 if (pcb == NULL) { 00561 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); 00562 } 00563 while (pcb != NULL) { 00564 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); 00565 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); 00566 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); 00567 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); 00568 00569 pcb_remove = 0; 00570 00571 if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { 00572 ++pcb_remove; 00573 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); 00574 } 00575 else if (pcb->nrtx == TCP_MAXRTX) { 00576 ++pcb_remove; 00577 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); 00578 } else { 00579 if (pcb->persist_backoff > 0) { 00580 /* If snd_wnd is zero, use persist timer to send 1 byte probes 00581 * instead of using the standard retransmission mechanism. */ 00582 pcb->persist_cnt++; 00583 if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { 00584 pcb->persist_cnt = 0; 00585 if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { 00586 pcb->persist_backoff++; 00587 } 00588 tcp_zero_window_probe(pcb); 00589 } 00590 } else { 00591 /* Increase the retransmission timer if it is running */ 00592 if(pcb->rtime >= 0) 00593 ++pcb->rtime; 00594 00595 if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { 00596 /* Time for a retransmission. */ 00597 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F 00598 " pcb->rto %"S16_F"\n", 00599 pcb->rtime, pcb->rto)); 00600 00601 /* Double retransmission time-out unless we are trying to 00602 * connect to somebody (i.e., we are in SYN_SENT). */ 00603 if (pcb->state != SYN_SENT) { 00604 pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; 00605 } 00606 00607 /* Reset the retransmission timer. */ 00608 pcb->rtime = 0; 00609 00610 /* Reduce congestion window and ssthresh. */ 00611 eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); 00612 pcb->ssthresh = eff_wnd >> 1; 00613 if (pcb->ssthresh < pcb->mss) { 00614 pcb->ssthresh = pcb->mss * 2; 00615 } 00616 pcb->cwnd = pcb->mss; 00617 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F 00618 " ssthresh %"U16_F"\n", 00619 pcb->cwnd, pcb->ssthresh)); 00620 00621 /* The following needs to be called AFTER cwnd is set to one 00622 mss - STJ */ 00623 tcp_rexmit_rto(pcb); 00624 } 00625 } 00626 } 00627 /* Check if this PCB has stayed too long in FIN-WAIT-2 */ 00628 if (pcb->state == FIN_WAIT_2) { 00629 if ((u32_t)(tcp_ticks - pcb->tmr) > 00630 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { 00631 ++pcb_remove; 00632 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); 00633 } 00634 } 00635 00636 /* Check if KEEPALIVE should be sent */ 00637 if((pcb->so_options & SOF_KEEPALIVE) && 00638 ((pcb->state == ESTABLISHED) || 00639 (pcb->state == CLOSE_WAIT))) { 00640 #if LWIP_TCP_KEEPALIVE 00641 if((u32_t)(tcp_ticks - pcb->tmr) > 00642 (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl)) 00643 / TCP_SLOW_INTERVAL) 00644 #else 00645 if((u32_t)(tcp_ticks - pcb->tmr) > 00646 (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL) 00647 #endif /* LWIP_TCP_KEEPALIVE */ 00648 { 00649 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", 00650 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip), 00651 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip))); 00652 00653 tcp_abort(pcb); 00654 } 00655 #if LWIP_TCP_KEEPALIVE 00656 else if((u32_t)(tcp_ticks - pcb->tmr) > 00657 (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl) 00658 / TCP_SLOW_INTERVAL) 00659 #else 00660 else if((u32_t)(tcp_ticks - pcb->tmr) > 00661 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) 00662 / TCP_SLOW_INTERVAL) 00663 #endif /* LWIP_TCP_KEEPALIVE */ 00664 { 00665 tcp_keepalive(pcb); 00666 pcb->keep_cnt_sent++; 00667 } 00668 } 00669 00670 /* If this PCB has queued out of sequence data, but has been 00671 inactive for too long, will drop the data (it will eventually 00672 be retransmitted). */ 00673 #if TCP_QUEUE_OOSEQ 00674 if (pcb->ooseq != NULL && 00675 (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { 00676 tcp_segs_free(pcb->ooseq); 00677 pcb->ooseq = NULL; 00678 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); 00679 } 00680 #endif /* TCP_QUEUE_OOSEQ */ 00681 00682 /* Check if this PCB has stayed too long in SYN-RCVD */ 00683 if (pcb->state == SYN_RCVD) { 00684 if ((u32_t)(tcp_ticks - pcb->tmr) > 00685 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { 00686 ++pcb_remove; 00687 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); 00688 } 00689 } 00690 00691 /* Check if this PCB has stayed too long in LAST-ACK */ 00692 if (pcb->state == LAST_ACK) { 00693 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { 00694 ++pcb_remove; 00695 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); 00696 } 00697 } 00698 00699 /* If the PCB should be removed, do it. */ 00700 if (pcb_remove) { 00701 tcp_pcb_purge(pcb); 00702 /* Remove PCB from tcp_active_pcbs list. */ 00703 if (prev != NULL) { 00704 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); 00705 prev->next = pcb->next; 00706 } else { 00707 /* This PCB was the first. */ 00708 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); 00709 tcp_active_pcbs = pcb->next; 00710 } 00711 00712 TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT); 00713 00714 pcb2 = pcb->next; 00715 memp_free(MEMP_TCP_PCB, pcb); 00716 pcb = pcb2; 00717 } else { 00718 00719 /* We check if we should poll the connection. */ 00720 ++pcb->polltmr; 00721 if (pcb->polltmr >= pcb->pollinterval) { 00722 pcb->polltmr = 0; 00723 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); 00724 TCP_EVENT_POLL(pcb, err); 00725 if (err == ERR_OK) { 00726 tcp_output(pcb); 00727 } 00728 } 00729 00730 prev = pcb; 00731 pcb = pcb->next; 00732 } 00733 } 00734 00735 00736 /* Steps through all of the TIME-WAIT PCBs. */ 00737 prev = NULL; 00738 pcb = tcp_tw_pcbs; 00739 while (pcb != NULL) { 00740 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 00741 pcb_remove = 0; 00742 00743 /* Check if this PCB has stayed long enough in TIME-WAIT */ 00744 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { 00745 ++pcb_remove; 00746 } 00747 00748 00749 00750 /* If the PCB should be removed, do it. */ 00751 if (pcb_remove) { 00752 tcp_pcb_purge(pcb); 00753 /* Remove PCB from tcp_tw_pcbs list. */ 00754 if (prev != NULL) { 00755 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); 00756 prev->next = pcb->next; 00757 } else { 00758 /* This PCB was the first. */ 00759 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); 00760 tcp_tw_pcbs = pcb->next; 00761 } 00762 pcb2 = pcb->next; 00763 memp_free(MEMP_TCP_PCB, pcb); 00764 pcb = pcb2; 00765 } else { 00766 prev = pcb; 00767 pcb = pcb->next; 00768 } 00769 } 00770 } 00771 00772 /** 00773 * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously 00774 * "refused" by upper layer (application) and sends delayed ACKs. 00775 * 00776 * Automatically called from tcp_tmr(). 00777 */ 00778 void 00779 tcp_fasttmr(void) 00780 { 00781 struct tcp_pcb *pcb; 00782 00783 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00784 /* If there is data which was previously "refused" by upper layer */ 00785 if (pcb->refused_data != NULL) { 00786 /* Notify again application with data previously received. */ 00787 err_t err; 00788 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n")); 00789 TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); 00790 if (err == ERR_OK) { 00791 pcb->refused_data = NULL; 00792 } 00793 } 00794 00795 /* send delayed ACKs */ 00796 if (pcb->flags & TF_ACK_DELAY) { 00797 LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); 00798 tcp_ack_now(pcb); 00799 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); 00800 } 00801 } 00802 } 00803 00804 /** 00805 * Deallocates a list of TCP segments (tcp_seg structures). 00806 * 00807 * @param seg tcp_seg list of TCP segments to free 00808 * @return the number of pbufs that were deallocated 00809 */ 00810 u8_t 00811 tcp_segs_free(struct tcp_seg *seg) 00812 { 00813 u8_t count = 0; 00814 struct tcp_seg *next; 00815 while (seg != NULL) { 00816 next = seg->next; 00817 count += tcp_seg_free(seg); 00818 seg = next; 00819 } 00820 return count; 00821 } 00822 00823 /** 00824 * Frees a TCP segment (tcp_seg structure). 00825 * 00826 * @param seg single tcp_seg to free 00827 * @return the number of pbufs that were deallocated 00828 */ 00829 u8_t 00830 tcp_seg_free(struct tcp_seg *seg) 00831 { 00832 u8_t count = 0; 00833 00834 if (seg != NULL) { 00835 if (seg->p != NULL) { 00836 count = pbuf_free(seg->p); 00837 #if TCP_DEBUG 00838 seg->p = NULL; 00839 #endif /* TCP_DEBUG */ 00840 } 00841 memp_free(MEMP_TCP_SEG, seg); 00842 } 00843 return count; 00844 } 00845 00846 /** 00847 * Sets the priority of a connection. 00848 * 00849 * @param pcb the tcp_pcb to manipulate 00850 * @param prio new priority 00851 */ 00852 void 00853 tcp_setprio(struct tcp_pcb *pcb, u8_t prio) 00854 { 00855 pcb->prio = prio; 00856 } 00857 #if TCP_QUEUE_OOSEQ 00858 00859 /** 00860 * Returns a copy of the given TCP segment. 00861 * The pbuf and data are not copied, only the pointers 00862 * 00863 * @param seg the old tcp_seg 00864 * @return a copy of seg 00865 */ 00866 struct tcp_seg * 00867 tcp_seg_copy(struct tcp_seg *seg) 00868 { 00869 struct tcp_seg *cseg; 00870 00871 cseg = static_cast<struct tcp_seg *>(memp_malloc(MEMP_TCP_SEG)); 00872 if (cseg == NULL) { 00873 return NULL; 00874 } 00875 SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 00876 pbuf_ref(cseg->p); 00877 return cseg; 00878 } 00879 #endif 00880 00881 #if LWIP_CALLBACK_API 00882 /** 00883 * Default receive callback that is called if the user didn't register 00884 * a recv callback for the pcb. 00885 */ 00886 static err_t 00887 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) 00888 { 00889 arg = arg; 00890 if (p != NULL) { 00891 pbuf_free(p); 00892 } else if (err == ERR_OK) { 00893 return tcp_close(pcb); 00894 } 00895 return ERR_OK; 00896 } 00897 #endif /* LWIP_CALLBACK_API */ 00898 00899 /** 00900 * Kills the oldest active connection that has lower priority than prio. 00901 * 00902 * @param prio minimum priority 00903 */ 00904 static void 00905 tcp_kill_prio(u8_t prio) 00906 { 00907 struct tcp_pcb *pcb, *inactive; 00908 u32_t inactivity; 00909 u8_t mprio; 00910 00911 00912 mprio = TCP_PRIO_MAX; 00913 00914 /* We kill the oldest active connection that has lower priority than prio. */ 00915 inactivity = 0; 00916 inactive = NULL; 00917 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 00918 if (pcb->prio <= prio && 00919 pcb->prio <= mprio && 00920 (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { 00921 inactivity = tcp_ticks - pcb->tmr; 00922 inactive = pcb; 00923 mprio = pcb->prio; 00924 } 00925 } 00926 if (inactive != NULL) { 00927 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", 00928 (void *)inactive, inactivity)); 00929 tcp_abort(inactive); 00930 } 00931 } 00932 00933 /** 00934 * Kills the oldest connection that is in TIME_WAIT state. 00935 * Called from tcp_alloc() if no more connections are available. 00936 */ 00937 static void 00938 tcp_kill_timewait(void) 00939 { 00940 struct tcp_pcb *pcb, *inactive; 00941 u32_t inactivity; 00942 00943 inactivity = 0; 00944 inactive = NULL; 00945 /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ 00946 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 00947 if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { 00948 inactivity = tcp_ticks - pcb->tmr; 00949 inactive = pcb; 00950 } 00951 } 00952 if (inactive != NULL) { 00953 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", 00954 (void *)inactive, inactivity)); 00955 tcp_abort(inactive); 00956 } 00957 } 00958 00959 /** 00960 * Allocate a new tcp_pcb structure. 00961 * 00962 * @param prio priority for the new pcb 00963 * @return a new tcp_pcb that initially is in state CLOSED 00964 */ 00965 struct tcp_pcb * 00966 tcp_alloc(u8_t prio) 00967 { 00968 struct tcp_pcb *pcb; 00969 u32_t iss; 00970 00971 pcb = static_cast<struct tcp_pcb *>(memp_malloc(MEMP_TCP_PCB)); 00972 if (pcb == NULL) { 00973 /* Try killing oldest connection in TIME-WAIT. */ 00974 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); 00975 tcp_kill_timewait(); 00976 /* Try to allocate a tcp_pcb again. */ 00977 pcb = static_cast<struct tcp_pcb *>(memp_malloc(MEMP_TCP_PCB)); 00978 if (pcb == NULL) { 00979 /* Try killing active connections with lower priority than the new one. */ 00980 tcp_kill_prio(prio); 00981 /* Try to allocate a tcp_pcb again. */ 00982 pcb = static_cast<struct tcp_pcb *>(memp_malloc(MEMP_TCP_PCB)); 00983 } 00984 } 00985 if (pcb != NULL) { 00986 memset(pcb, 0, sizeof(struct tcp_pcb)); 00987 pcb->prio = TCP_PRIO_NORMAL; 00988 pcb->snd_buf = TCP_SND_BUF; 00989 pcb->snd_queuelen = 0; 00990 pcb->rcv_wnd = TCP_WND; 00991 pcb->rcv_ann_wnd = TCP_WND; 00992 pcb->tos = 0; 00993 pcb->ttl = TCP_TTL; 00994 /* The send MSS is updated when an MSS option is received. */ 00995 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 00996 pcb->rto = 3000 / TCP_SLOW_INTERVAL; 00997 pcb->sa = 0; 00998 pcb->sv = 3000 / TCP_SLOW_INTERVAL; 00999 pcb->rtime = -1; 01000 pcb->cwnd = 1; 01001 iss = tcp_next_iss(); 01002 pcb->snd_wl2 = iss; 01003 pcb->snd_nxt = iss; 01004 pcb->snd_max = iss; 01005 pcb->lastack = iss; 01006 pcb->snd_lbb = iss; 01007 pcb->tmr = tcp_ticks; 01008 01009 pcb->polltmr = 0; 01010 01011 #if LWIP_CALLBACK_API 01012 pcb->recv = tcp_recv_null; 01013 #endif /* LWIP_CALLBACK_API */ 01014 01015 /* Init KEEPALIVE timer */ 01016 pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; 01017 01018 #if LWIP_TCP_KEEPALIVE 01019 pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; 01020 pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; 01021 #endif /* LWIP_TCP_KEEPALIVE */ 01022 01023 pcb->keep_cnt_sent = 0; 01024 } 01025 return pcb; 01026 } 01027 01028 /** 01029 * Creates a new TCP protocol control block but doesn't place it on 01030 * any of the TCP PCB lists. 01031 * The pcb is not put on any list until binding using tcp_bind(). 01032 * 01033 * @internal: Maybe there should be a idle TCP PCB list where these 01034 * PCBs are put on. Port reservation using tcp_bind() is implemented but 01035 * allocated pcbs that are not bound can't be killed automatically if wanting 01036 * to allocate a pcb with higher prio (@see tcp_kill_prio()) 01037 * 01038 * @return a new tcp_pcb that initially is in state CLOSED 01039 */ 01040 struct tcp_pcb * 01041 tcp_new(void) 01042 { 01043 return tcp_alloc(TCP_PRIO_NORMAL); 01044 } 01045 01046 /** 01047 * Used to specify the argument that should be passed callback 01048 * functions. 01049 * 01050 * @param pcb tcp_pcb to set the callback argument 01051 * @param arg void pointer argument to pass to callback functions 01052 */ 01053 void 01054 tcp_arg(struct tcp_pcb *pcb, void *arg) 01055 { 01056 pcb->callback_arg = arg; 01057 } 01058 #if LWIP_CALLBACK_API 01059 01060 /** 01061 * Used to specify the function that should be called when a TCP 01062 * connection receives data. 01063 * 01064 * @param pcb tcp_pcb to set the recv callback 01065 * @param recv callback function to call for this pcb when data is received 01066 */ 01067 void 01068 tcp_recv(struct tcp_pcb *pcb, 01069 err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)) 01070 { 01071 pcb->recv = recv; 01072 } 01073 01074 /** 01075 * Used to specify the function that should be called when TCP data 01076 * has been successfully delivered to the remote host. 01077 * 01078 * @param pcb tcp_pcb to set the sent callback 01079 * @param sent callback function to call for this pcb when data is successfully sent 01080 */ 01081 void 01082 tcp_sent(struct tcp_pcb *pcb, 01083 err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len)) 01084 { 01085 pcb->sent = sent; 01086 } 01087 01088 /** 01089 * Used to specify the function that should be called when a fatal error 01090 * has occured on the connection. 01091 * 01092 * @param pcb tcp_pcb to set the err callback 01093 * @param errf callback function to call for this pcb when a fatal error 01094 * has occured on the connection 01095 */ 01096 void 01097 tcp_err(struct tcp_pcb *pcb, 01098 void (* errf)(void *arg, err_t err)) 01099 { 01100 pcb->errf = errf; 01101 } 01102 01103 /** 01104 * Used for specifying the function that should be called when a 01105 * LISTENing connection has been connected to another host. 01106 * 01107 * @param pcb tcp_pcb to set the accept callback 01108 * @param accept callback function to call for this pcb when LISTENing 01109 * connection has been connected to another host 01110 */ 01111 void 01112 tcp_accept(struct tcp_pcb *pcb, 01113 err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err)) 01114 { 01115 ((struct tcp_pcb_listen *)pcb)->accept = accept; 01116 } 01117 #endif /* LWIP_CALLBACK_API */ 01118 01119 01120 /** 01121 * Used to specify the function that should be called periodically 01122 * from TCP. The interval is specified in terms of the TCP coarse 01123 * timer interval, which is called twice a second. 01124 * 01125 */ 01126 void 01127 tcp_poll(struct tcp_pcb *pcb, 01128 err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval) 01129 { 01130 #if LWIP_CALLBACK_API 01131 pcb->poll = poll; 01132 #endif /* LWIP_CALLBACK_API */ 01133 pcb->pollinterval = interval; 01134 } 01135 01136 /** 01137 * Purges a TCP PCB. Removes any buffered data and frees the buffer memory 01138 * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). 01139 * 01140 * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! 01141 */ 01142 void 01143 tcp_pcb_purge(struct tcp_pcb *pcb) 01144 { 01145 if (pcb->state != CLOSED && 01146 pcb->state != TIME_WAIT && 01147 pcb->state != LISTEN) { 01148 01149 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); 01150 01151 if (pcb->refused_data != NULL) { 01152 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); 01153 pbuf_free(pcb->refused_data); 01154 pcb->refused_data = NULL; 01155 } 01156 if (pcb->unsent != NULL) { 01157 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); 01158 } 01159 if (pcb->unacked != NULL) { 01160 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); 01161 } 01162 #if TCP_QUEUE_OOSEQ /* LW */ 01163 if (pcb->ooseq != NULL) { 01164 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); 01165 } 01166 01167 /* Stop the retransmission timer as it will expect data on unacked 01168 queue if it fires */ 01169 pcb->rtime = -1; 01170 01171 tcp_segs_free(pcb->ooseq); 01172 pcb->ooseq = NULL; 01173 #endif /* TCP_QUEUE_OOSEQ */ 01174 tcp_segs_free(pcb->unsent); 01175 tcp_segs_free(pcb->unacked); 01176 pcb->unacked = pcb->unsent = NULL; 01177 } 01178 } 01179 01180 /** 01181 * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. 01182 * 01183 * @param pcblist PCB list to purge. 01184 * @param pcb tcp_pcb to purge. The pcb itself is also deallocated! 01185 */ 01186 void 01187 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) 01188 { 01189 TCP_RMV(pcblist, pcb); 01190 01191 tcp_pcb_purge(pcb); 01192 01193 /* if there is an outstanding delayed ACKs, send it */ 01194 if (pcb->state != TIME_WAIT && 01195 pcb->state != LISTEN && 01196 pcb->flags & TF_ACK_DELAY) { 01197 pcb->flags |= TF_ACK_NOW; 01198 tcp_output(pcb); 01199 } 01200 01201 if (pcb->state != LISTEN) { 01202 LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); 01203 LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); 01204 #if TCP_QUEUE_OOSEQ 01205 LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); 01206 #endif /* TCP_QUEUE_OOSEQ */ 01207 } 01208 01209 pcb->state = CLOSED; 01210 01211 LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); 01212 } 01213 01214 /** 01215 * Calculates a new initial sequence number for new connections. 01216 * 01217 * @return u32_t pseudo random sequence number 01218 */ 01219 u32_t 01220 tcp_next_iss(void) 01221 { 01222 static u32_t iss = 6510; 01223 01224 iss += tcp_ticks; /* XXX */ 01225 return iss; 01226 } 01227 01228 #if TCP_CALCULATE_EFF_SEND_MSS 01229 /** 01230 * Calcluates the effective send mss that can be used for a specific IP address 01231 * by using ip_route to determin the netif used to send to the address and 01232 * calculating the minimum of TCP_MSS and that netif's mtu (if set). 01233 */ 01234 u16_t 01235 tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr) 01236 { 01237 u16_t mss_s; 01238 struct netif *outif; 01239 01240 outif = ip_route(addr); 01241 if ((outif != NULL) && (outif->mtu != 0)) { 01242 mss_s = outif->mtu - IP_HLEN - TCP_HLEN; 01243 /* RFC 1122, chap 4.2.2.6: 01244 * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize 01245 * but we only send options with SYN and that is never filled with data! */ 01246 sendmss = LWIP_MIN(sendmss, mss_s); 01247 } 01248 return sendmss; 01249 } 01250 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 01251 01252 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG 01253 /** 01254 * Print a tcp header for debugging purposes. 01255 * 01256 * @param tcphdr pointer to a struct tcp_hdr 01257 */ 01258 void 01259 tcp_debug_print(struct tcp_hdr *tcphdr) 01260 { 01261 LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); 01262 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01263 LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", 01264 ntohs(tcphdr->src), ntohs(tcphdr->dest))); 01265 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01266 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", 01267 ntohl(tcphdr->seqno))); 01268 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01269 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", 01270 ntohl(tcphdr->ackno))); 01271 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01272 LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", 01273 TCPH_HDRLEN(tcphdr), 01274 TCPH_FLAGS(tcphdr) >> 5 & 1, 01275 TCPH_FLAGS(tcphdr) >> 4 & 1, 01276 TCPH_FLAGS(tcphdr) >> 3 & 1, 01277 TCPH_FLAGS(tcphdr) >> 2 & 1, 01278 TCPH_FLAGS(tcphdr) >> 1 & 1, 01279 TCPH_FLAGS(tcphdr) & 1, 01280 ntohs(tcphdr->wnd))); 01281 tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); 01282 LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); 01283 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01284 LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", 01285 ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); 01286 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01287 } 01288 01289 /** 01290 * Print a tcp state for debugging purposes. 01291 * 01292 * @param s enum tcp_state to print 01293 */ 01294 void 01295 tcp_debug_print_state(enum tcp_state s) 01296 { 01297 LWIP_DEBUGF(TCP_DEBUG, ("State: ")); 01298 switch (s) { 01299 case CLOSED: 01300 LWIP_DEBUGF(TCP_DEBUG, ("CLOSED\n")); 01301 break; 01302 case LISTEN: 01303 LWIP_DEBUGF(TCP_DEBUG, ("LISTEN\n")); 01304 break; 01305 case SYN_SENT: 01306 LWIP_DEBUGF(TCP_DEBUG, ("SYN_SENT\n")); 01307 break; 01308 case SYN_RCVD: 01309 LWIP_DEBUGF(TCP_DEBUG, ("SYN_RCVD\n")); 01310 break; 01311 case ESTABLISHED: 01312 LWIP_DEBUGF(TCP_DEBUG, ("ESTABLISHED\n")); 01313 break; 01314 case FIN_WAIT_1: 01315 LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_1\n")); 01316 break; 01317 case FIN_WAIT_2: 01318 LWIP_DEBUGF(TCP_DEBUG, ("FIN_WAIT_2\n")); 01319 break; 01320 case CLOSE_WAIT: 01321 LWIP_DEBUGF(TCP_DEBUG, ("CLOSE_WAIT\n")); 01322 break; 01323 case CLOSING: 01324 LWIP_DEBUGF(TCP_DEBUG, ("CLOSING\n")); 01325 break; 01326 case LAST_ACK: 01327 LWIP_DEBUGF(TCP_DEBUG, ("LAST_ACK\n")); 01328 break; 01329 case TIME_WAIT: 01330 LWIP_DEBUGF(TCP_DEBUG, ("TIME_WAIT\n")); 01331 break; 01332 } 01333 } 01334 01335 /** 01336 * Print tcp flags for debugging purposes. 01337 * 01338 * @param flags tcp flags, all active flags are printed 01339 */ 01340 void 01341 tcp_debug_print_flags(u8_t flags) 01342 { 01343 if (flags & TCP_FIN) { 01344 LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); 01345 } 01346 if (flags & TCP_SYN) { 01347 LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); 01348 } 01349 if (flags & TCP_RST) { 01350 LWIP_DEBUGF(TCP_DEBUG, ("RST ")); 01351 } 01352 if (flags & TCP_PSH) { 01353 LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); 01354 } 01355 if (flags & TCP_ACK) { 01356 LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); 01357 } 01358 if (flags & TCP_URG) { 01359 LWIP_DEBUGF(TCP_DEBUG, ("URG ")); 01360 } 01361 if (flags & TCP_ECE) { 01362 LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); 01363 } 01364 if (flags & TCP_CWR) { 01365 LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); 01366 } 01367 } 01368 01369 /** 01370 * Print all tcp_pcbs in every list for debugging purposes. 01371 */ 01372 void 01373 tcp_debug_print_pcbs(void) 01374 { 01375 struct tcp_pcb *pcb; 01376 LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); 01377 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 01378 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01379 pcb->local_port, pcb->remote_port, 01380 pcb->snd_nxt, pcb->rcv_nxt)); 01381 tcp_debug_print_state(pcb->state); 01382 } 01383 LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); 01384 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { 01385 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01386 pcb->local_port, pcb->remote_port, 01387 pcb->snd_nxt, pcb->rcv_nxt)); 01388 tcp_debug_print_state(pcb->state); 01389 } 01390 LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); 01391 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 01392 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01393 pcb->local_port, pcb->remote_port, 01394 pcb->snd_nxt, pcb->rcv_nxt)); 01395 tcp_debug_print_state(pcb->state); 01396 } 01397 } 01398 01399 /** 01400 * Check state consistency of the tcp_pcb lists. 01401 */ 01402 s16_t 01403 tcp_pcbs_sane(void) 01404 { 01405 struct tcp_pcb *pcb; 01406 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 01407 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); 01408 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); 01409 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); 01410 } 01411 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 01412 LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 01413 } 01414 return 1; 01415 } 01416 #endif /* TCP_DEBUG */ 01417 01418 #endif /* LWIP_TCP */
Generated on Tue Jul 12 2022 16:06:25 by 1.7.2