lwip-1.4.1 (partial)
Embed:
(wiki syntax)
Show/hide line numbers
tcp.c
Go to the documentation of this file.
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 #include "lwip/tcp_impl.h" 00053 #include "lwip/debug.h" 00054 #include "lwip/stats.h" 00055 00056 #include <string.h> 00057 00058 #ifndef TCP_LOCAL_PORT_RANGE_START 00059 /* From http://www.iana.org/assignments/port-numbers: 00060 "The Dynamic and/or Private Ports are those from 49152 through 65535" */ 00061 #define TCP_LOCAL_PORT_RANGE_START 0xc000 00062 #define TCP_LOCAL_PORT_RANGE_END 0xffff 00063 #define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START) 00064 #endif 00065 00066 #if LWIP_TCP_KEEPALIVE 00067 #define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) 00068 #define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) 00069 #else /* LWIP_TCP_KEEPALIVE */ 00070 #define TCP_KEEP_DUR(pcb) TCP_MAXIDLE 00071 #define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT 00072 #endif /* LWIP_TCP_KEEPALIVE */ 00073 00074 const char * const tcp_state_str[] = { 00075 "CLOSED", 00076 "LISTEN", 00077 "SYN_SENT", 00078 "SYN_RCVD", 00079 "ESTABLISHED", 00080 "FIN_WAIT_1", 00081 "FIN_WAIT_2", 00082 "CLOSE_WAIT", 00083 "CLOSING", 00084 "LAST_ACK", 00085 "TIME_WAIT" 00086 }; 00087 00088 /* last local TCP port */ 00089 static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; 00090 00091 /* Incremented every coarse grained timer shot (typically every 500 ms). */ 00092 u32_t tcp_ticks; 00093 const u8_t tcp_backoff[13] = 00094 { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; 00095 /* Times per slowtmr hits */ 00096 const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; 00097 00098 /* The TCP PCB lists. */ 00099 00100 /** List of all TCP PCBs bound but not yet (connected || listening) */ 00101 struct tcp_pcb *tcp_bound_pcbs; 00102 /** List of all TCP PCBs in LISTEN state */ 00103 union tcp_listen_pcbs_t tcp_listen_pcbs; 00104 /** List of all TCP PCBs that are in a state in which 00105 * they accept or send data. */ 00106 struct tcp_pcb *tcp_active_pcbs; 00107 /** List of all TCP PCBs in TIME-WAIT state */ 00108 struct tcp_pcb *tcp_tw_pcbs; 00109 00110 #define NUM_TCP_PCB_LISTS 4 00111 #define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 00112 /** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ 00113 struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, 00114 &tcp_active_pcbs, &tcp_tw_pcbs}; 00115 00116 /** Only used for temporary storage. */ 00117 struct tcp_pcb *tcp_tmp_pcb; 00118 00119 u8_t tcp_active_pcbs_changed; 00120 00121 /** Timer counter to handle calling slow-timer from tcp_tmr() */ 00122 static u8_t tcp_timer; 00123 static u8_t tcp_timer_ctr; 00124 static u16_t tcp_new_port(void); 00125 00126 /** 00127 * Initialize this module. 00128 */ 00129 void 00130 tcp_init(void) 00131 { 00132 #if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) 00133 tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); 00134 #endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ 00135 } 00136 00137 /** 00138 * Called periodically to dispatch TCP timers. 00139 */ 00140 void 00141 tcp_tmr(void) 00142 { 00143 /* Call tcp_fasttmr() every 250 ms */ 00144 tcp_fasttmr(); 00145 00146 if (++tcp_timer & 1) { 00147 /* Call tcp_tmr() every 500 ms, i.e., every other timer 00148 tcp_tmr() is called. */ 00149 tcp_slowtmr(); 00150 } 00151 } 00152 00153 /** 00154 * Closes the TX side of a connection held by the PCB. 00155 * For tcp_close(), a RST is sent if the application didn't receive all data 00156 * (tcp_recved() not called for all data passed to recv callback). 00157 * 00158 * Listening pcbs are freed and may not be referenced any more. 00159 * Connection pcbs are freed if not yet connected and may not be referenced 00160 * any more. If a connection is established (at least SYN received or in 00161 * a closing state), the connection is closed, and put in a closing state. 00162 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore 00163 * unsafe to reference it. 00164 * 00165 * @param pcb the tcp_pcb to close 00166 * @return ERR_OK if connection has been closed 00167 * another err_t if closing failed and pcb is not freed 00168 */ 00169 static err_t 00170 tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) 00171 { 00172 err_t err; 00173 00174 if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { 00175 if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { 00176 /* Not all data received by application, send RST to tell the remote 00177 side about this. */ 00178 LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); 00179 00180 /* don't call tcp_abort here: we must not deallocate the pcb since 00181 that might not be expected when calling tcp_close */ 00182 tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, 00183 pcb->local_port, pcb->remote_port); 00184 00185 tcp_pcb_purge(pcb); 00186 TCP_RMV_ACTIVE(pcb); 00187 if (pcb->state == ESTABLISHED) { 00188 /* move to TIME_WAIT since we close actively */ 00189 pcb->state = TIME_WAIT; 00190 TCP_REG(&tcp_tw_pcbs, pcb); 00191 } else { 00192 /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ 00193 memp_free(MEMP_TCP_PCB, pcb); 00194 } 00195 return ERR_OK; 00196 } 00197 } 00198 00199 switch (pcb->state) { 00200 case CLOSED: 00201 /* Closing a pcb in the CLOSED state might seem erroneous, 00202 * however, it is in this state once allocated and as yet unused 00203 * and the user needs some way to free it should the need arise. 00204 * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) 00205 * or for a pcb that has been used and then entered the CLOSED state 00206 * is erroneous, but this should never happen as the pcb has in those cases 00207 * been freed, and so any remaining handles are bogus. */ 00208 err = ERR_OK; 00209 if (pcb->local_port != 0) { 00210 TCP_RMV(&tcp_bound_pcbs, pcb); 00211 } 00212 memp_free(MEMP_TCP_PCB, pcb); 00213 pcb = NULL; 00214 break; 00215 case LISTEN: 00216 err = ERR_OK; 00217 tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); 00218 memp_free(MEMP_TCP_PCB_LISTEN, pcb); 00219 pcb = NULL; 00220 break; 00221 case SYN_SENT: 00222 err = ERR_OK; 00223 TCP_PCB_REMOVE_ACTIVE(pcb); 00224 memp_free(MEMP_TCP_PCB, pcb); 00225 pcb = NULL; 00226 snmp_inc_tcpattemptfails(); 00227 break; 00228 case SYN_RCVD: 00229 err = tcp_send_fin(pcb); 00230 if (err == ERR_OK) { 00231 snmp_inc_tcpattemptfails(); 00232 pcb->state = FIN_WAIT_1; 00233 } 00234 break; 00235 case ESTABLISHED: 00236 err = tcp_send_fin(pcb); 00237 if (err == ERR_OK) { 00238 snmp_inc_tcpestabresets(); 00239 pcb->state = FIN_WAIT_1; 00240 } 00241 break; 00242 case CLOSE_WAIT: 00243 err = tcp_send_fin(pcb); 00244 if (err == ERR_OK) { 00245 snmp_inc_tcpestabresets(); 00246 pcb->state = LAST_ACK; 00247 } 00248 break; 00249 default: 00250 /* Has already been closed, do nothing. */ 00251 err = ERR_OK; 00252 pcb = NULL; 00253 break; 00254 } 00255 00256 if (pcb != NULL && err == ERR_OK) { 00257 /* To ensure all data has been sent when tcp_close returns, we have 00258 to make sure tcp_output doesn't fail. 00259 Since we don't really have to ensure all data has been sent when tcp_close 00260 returns (unsent data is sent from tcp timer functions, also), we don't care 00261 for the return value of tcp_output for now. */ 00262 /* @todo: When implementing SO_LINGER, this must be changed somehow: 00263 If SOF_LINGER is set, the data should be sent and acked before close returns. 00264 This can only be valid for sequential APIs, not for the raw API. */ 00265 tcp_output(pcb); 00266 } 00267 return err; 00268 } 00269 00270 /** 00271 * Closes the connection held by the PCB. 00272 * 00273 * Listening pcbs are freed and may not be referenced any more. 00274 * Connection pcbs are freed if not yet connected and may not be referenced 00275 * any more. If a connection is established (at least SYN received or in 00276 * a closing state), the connection is closed, and put in a closing state. 00277 * The pcb is then automatically freed in tcp_slowtmr(). It is therefore 00278 * unsafe to reference it (unless an error is returned). 00279 * 00280 * @param pcb the tcp_pcb to close 00281 * @return ERR_OK if connection has been closed 00282 * another err_t if closing failed and pcb is not freed 00283 */ 00284 err_t 00285 tcp_close(struct tcp_pcb *pcb) 00286 { 00287 #if TCP_DEBUG 00288 LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); 00289 tcp_debug_print_state(pcb->state); 00290 #endif /* TCP_DEBUG */ 00291 00292 if (pcb->state != LISTEN) { 00293 /* Set a flag not to receive any more data... */ 00294 pcb->flags |= TF_RXCLOSED; 00295 } 00296 /* ... and close */ 00297 return tcp_close_shutdown(pcb, 1); 00298 } 00299 00300 /** 00301 * Causes all or part of a full-duplex connection of this PCB to be shut down. 00302 * This doesn't deallocate the PCB unless shutting down both sides! 00303 * Shutting down both sides is the same as calling tcp_close, so if it succeds, 00304 * the PCB should not be referenced any more. 00305 * 00306 * @param pcb PCB to shutdown 00307 * @param shut_rx shut down receive side if this is != 0 00308 * @param shut_tx shut down send side if this is != 0 00309 * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down) 00310 * another err_t on error. 00311 */ 00312 err_t 00313 tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) 00314 { 00315 if (pcb->state == LISTEN) { 00316 return ERR_CONN; 00317 } 00318 if (shut_rx) { 00319 /* shut down the receive side: set a flag not to receive any more data... */ 00320 pcb->flags |= TF_RXCLOSED; 00321 if (shut_tx) { 00322 /* shutting down the tx AND rx side is the same as closing for the raw API */ 00323 return tcp_close_shutdown(pcb, 1); 00324 } 00325 /* ... and free buffered data */ 00326 if (pcb->refused_data != NULL) { 00327 pbuf_free(pcb->refused_data); 00328 pcb->refused_data = NULL; 00329 } 00330 } 00331 if (shut_tx) { 00332 /* This can't happen twice since if it succeeds, the pcb's state is changed. 00333 Only close in these states as the others directly deallocate the PCB */ 00334 switch (pcb->state) { 00335 case SYN_RCVD: 00336 case ESTABLISHED: 00337 case CLOSE_WAIT: 00338 return tcp_close_shutdown(pcb, shut_rx); 00339 default: 00340 /* Not (yet?) connected, cannot shutdown the TX side as that would bring us 00341 into CLOSED state, where the PCB is deallocated. */ 00342 return ERR_CONN; 00343 } 00344 } 00345 return ERR_OK; 00346 } 00347 00348 /** 00349 * Abandons a connection and optionally sends a RST to the remote 00350 * host. Deletes the local protocol control block. This is done when 00351 * a connection is killed because of shortage of memory. 00352 * 00353 * @param pcb the tcp_pcb to abort 00354 * @param reset boolean to indicate whether a reset should be sent 00355 */ 00356 void 00357 tcp_abandon(struct tcp_pcb *pcb, int reset) 00358 { 00359 u32_t seqno, ackno; 00360 #if LWIP_CALLBACK_API 00361 tcp_err_fn errf; 00362 #endif /* LWIP_CALLBACK_API */ 00363 void *errf_arg; 00364 00365 /* pcb->state LISTEN not allowed here */ 00366 LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", 00367 pcb->state != LISTEN); 00368 /* Figure out on which TCP PCB list we are, and remove us. If we 00369 are in an active state, call the receive function associated with 00370 the PCB with a NULL argument, and send an RST to the remote end. */ 00371 if (pcb->state == TIME_WAIT) { 00372 tcp_pcb_remove(&tcp_tw_pcbs, pcb); 00373 memp_free(MEMP_TCP_PCB, pcb); 00374 } else { 00375 seqno = pcb->snd_nxt; 00376 ackno = pcb->rcv_nxt; 00377 #if LWIP_CALLBACK_API 00378 errf = pcb->errf; 00379 #endif /* LWIP_CALLBACK_API */ 00380 errf_arg = pcb->callback_arg; 00381 TCP_PCB_REMOVE_ACTIVE(pcb); 00382 if (pcb->unacked != NULL) { 00383 tcp_segs_free(pcb->unacked); 00384 } 00385 if (pcb->unsent != NULL) { 00386 tcp_segs_free(pcb->unsent); 00387 } 00388 #if TCP_QUEUE_OOSEQ 00389 if (pcb->ooseq != NULL) { 00390 tcp_segs_free(pcb->ooseq); 00391 } 00392 #endif /* TCP_QUEUE_OOSEQ */ 00393 if (reset) { 00394 LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); 00395 tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); 00396 } 00397 memp_free(MEMP_TCP_PCB, pcb); 00398 TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); 00399 } 00400 } 00401 00402 /** 00403 * Aborts the connection by sending a RST (reset) segment to the remote 00404 * host. The pcb is deallocated. This function never fails. 00405 * 00406 * ATTENTION: When calling this from one of the TCP callbacks, make 00407 * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise 00408 * or you will risk accessing deallocated memory or memory leaks! 00409 * 00410 * @param pcb the tcp pcb to abort 00411 */ 00412 void 00413 tcp_abort(struct tcp_pcb *pcb) 00414 { 00415 tcp_abandon(pcb, 1); 00416 } 00417 00418 /** 00419 * Binds the connection to a local portnumber and IP address. If the 00420 * IP address is not given (i.e., ipaddr == NULL), the IP address of 00421 * the outgoing network interface is used instead. 00422 * 00423 * @param pcb the tcp_pcb to bind (no check is done whether this pcb is 00424 * already bound!) 00425 * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind 00426 * to any local address 00427 * @param port the local port to bind to 00428 * @return ERR_USE if the port is already in use 00429 * ERR_VAL if bind failed because the PCB is not in a valid state 00430 * ERR_OK if bound 00431 */ 00432 err_t 00433 tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) 00434 { 00435 int i; 00436 int max_pcb_list = NUM_TCP_PCB_LISTS; 00437 struct tcp_pcb *cpcb; 00438 00439 LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); 00440 00441 #if SO_REUSE 00442 /* Unless the REUSEADDR flag is set, 00443 we have to check the pcbs in TIME-WAIT state, also. 00444 We do not dump TIME_WAIT pcb's; they can still be matched by incoming 00445 packets using both local and remote IP addresses and ports to distinguish. 00446 */ 00447 if (ip_get_option(pcb, SOF_REUSEADDR)) { 00448 max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; 00449 } 00450 #endif /* SO_REUSE */ 00451 00452 if (port == 0) { 00453 port = tcp_new_port(); 00454 if (port == 0) { 00455 return ERR_BUF; 00456 } 00457 } 00458 00459 /* Check if the address already is in use (on all lists) */ 00460 for (i = 0; i < max_pcb_list; i++) { 00461 for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { 00462 if (cpcb->local_port == port) { 00463 #if SO_REUSE 00464 /* Omit checking for the same port if both pcbs have REUSEADDR set. 00465 For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in 00466 tcp_connect. */ 00467 if (!ip_get_option(pcb, SOF_REUSEADDR) || 00468 !ip_get_option(cpcb, SOF_REUSEADDR)) 00469 #endif /* SO_REUSE */ 00470 { 00471 if (ip_addr_isany(&(cpcb->local_ip)) || 00472 ip_addr_isany(ipaddr) || 00473 ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { 00474 return ERR_USE; 00475 } 00476 } 00477 } 00478 } 00479 } 00480 00481 if (!ip_addr_isany(ipaddr)) { 00482 pcb->local_ip = *ipaddr; 00483 } 00484 pcb->local_port = port; 00485 TCP_REG(&tcp_bound_pcbs, pcb); 00486 LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); 00487 return ERR_OK; 00488 } 00489 #if LWIP_CALLBACK_API 00490 /** 00491 * Default accept callback if no accept callback is specified by the user. 00492 */ 00493 static err_t 00494 tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) 00495 { 00496 LWIP_UNUSED_ARG(arg); 00497 LWIP_UNUSED_ARG(pcb); 00498 LWIP_UNUSED_ARG(err); 00499 00500 return ERR_ABRT; 00501 } 00502 #endif /* LWIP_CALLBACK_API */ 00503 00504 /** 00505 * Set the state of the connection to be LISTEN, which means that it 00506 * is able to accept incoming connections. The protocol control block 00507 * is reallocated in order to consume less memory. Setting the 00508 * connection to LISTEN is an irreversible process. 00509 * 00510 * @param pcb the original tcp_pcb 00511 * @param backlog the incoming connections queue limit 00512 * @return tcp_pcb used for listening, consumes less memory. 00513 * 00514 * @note The original tcp_pcb is freed. This function therefore has to be 00515 * called like this: 00516 * tpcb = tcp_listen(tpcb); 00517 */ 00518 struct tcp_pcb * 00519 tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) 00520 { 00521 struct tcp_pcb_listen *lpcb; 00522 00523 LWIP_UNUSED_ARG(backlog); 00524 LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); 00525 00526 /* already listening? */ 00527 if (pcb->state == LISTEN) { 00528 return pcb; 00529 } 00530 #if SO_REUSE 00531 if (ip_get_option(pcb, SOF_REUSEADDR)) { 00532 /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage 00533 is declared (listen-/connection-pcb), we have to make sure now that 00534 this port is only used once for every local IP. */ 00535 for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 00536 if (lpcb->local_port == pcb->local_port) { 00537 if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) { 00538 /* this address/port is already used */ 00539 return NULL; 00540 } 00541 } 00542 } 00543 } 00544 #endif /* SO_REUSE */ 00545 lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); 00546 if (lpcb == NULL) { 00547 return NULL; 00548 } 00549 lpcb->callback_arg = pcb->callback_arg; 00550 lpcb->local_port = pcb->local_port; 00551 lpcb->state = LISTEN; 00552 lpcb->prio = pcb->prio; 00553 lpcb->so_options = pcb->so_options; 00554 ip_set_option(lpcb, SOF_ACCEPTCONN); 00555 lpcb->ttl = pcb->ttl; 00556 lpcb->tos = pcb->tos; 00557 ip_addr_copy(lpcb->local_ip, pcb->local_ip); 00558 if (pcb->local_port != 0) { 00559 TCP_RMV(&tcp_bound_pcbs, pcb); 00560 } 00561 memp_free(MEMP_TCP_PCB, pcb); 00562 #if LWIP_CALLBACK_API 00563 lpcb->accept = tcp_accept_null; 00564 #endif /* LWIP_CALLBACK_API */ 00565 #if TCP_LISTEN_BACKLOG 00566 lpcb->accepts_pending = 0; 00567 lpcb->backlog = (backlog ? backlog : 1); 00568 #endif /* TCP_LISTEN_BACKLOG */ 00569 TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb); 00570 return (struct tcp_pcb *)lpcb; 00571 } 00572 00573 /** 00574 * Update the state that tracks the available window space to advertise. 00575 * 00576 * Returns how much extra window would be advertised if we sent an 00577 * update now. 00578 */ 00579 u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) 00580 { 00581 u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; 00582 00583 if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { 00584 /* we can advertise more window */ 00585 pcb->rcv_ann_wnd = pcb->rcv_wnd; 00586 return new_right_edge - pcb->rcv_ann_right_edge; 00587 } else { 00588 if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { 00589 /* Can happen due to other end sending out of advertised window, 00590 * but within actual available (but not yet advertised) window */ 00591 pcb->rcv_ann_wnd = 0; 00592 } else { 00593 /* keep the right edge of window constant */ 00594 u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; 00595 LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); 00596 pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd; 00597 } 00598 return 0; 00599 } 00600 } 00601 00602 /** 00603 * This function should be called by the application when it has 00604 * processed the data. The purpose is to advertise a larger window 00605 * when the data has been processed. 00606 * 00607 * @param pcb the tcp_pcb for which data is read 00608 * @param len the amount of bytes that have been read by the application 00609 */ 00610 void 00611 tcp_recved(struct tcp_pcb *pcb, u16_t len) 00612 { 00613 int wnd_inflation; 00614 00615 /* pcb->state LISTEN not allowed here */ 00616 LWIP_ASSERT("don't call tcp_recved for listen-pcbs", 00617 pcb->state != LISTEN); 00618 LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", 00619 len <= 0xffff - pcb->rcv_wnd ); 00620 00621 pcb->rcv_wnd += len; 00622 if (pcb->rcv_wnd > TCP_WND) { 00623 pcb->rcv_wnd = TCP_WND; 00624 } 00625 00626 wnd_inflation = tcp_update_rcv_ann_wnd(pcb); 00627 00628 /* If the change in the right edge of window is significant (default 00629 * watermark is TCP_WND/4), then send an explicit update now. 00630 * Otherwise wait for a packet to be sent in the normal course of 00631 * events (or more window to be available later) */ 00632 if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { 00633 tcp_ack_now(pcb); 00634 tcp_output(pcb); 00635 } 00636 00637 LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", 00638 len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); 00639 } 00640 00641 /** 00642 * Allocate a new local TCP port. 00643 * 00644 * @return a new (free) local TCP port number 00645 */ 00646 static u16_t 00647 tcp_new_port(void) 00648 { 00649 u8_t i; 00650 u16_t n = 0; 00651 struct tcp_pcb *pcb; 00652 00653 again: 00654 if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) { 00655 tcp_port = TCP_LOCAL_PORT_RANGE_START; 00656 } 00657 /* Check all PCB lists. */ 00658 for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { 00659 for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { 00660 if (pcb->local_port == tcp_port) { 00661 if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { 00662 return 0; 00663 } 00664 goto again; 00665 } 00666 } 00667 } 00668 return tcp_port; 00669 } 00670 00671 /** 00672 * Connects to another host. The function given as the "connected" 00673 * argument will be called when the connection has been established. 00674 * 00675 * @param pcb the tcp_pcb used to establish the connection 00676 * @param ipaddr the remote ip address to connect to 00677 * @param port the remote tcp port to connect to 00678 * @param connected callback function to call when connected (or on error) 00679 * @return ERR_VAL if invalid arguments are given 00680 * ERR_OK if connect request has been sent 00681 * other err_t values if connect request couldn't be sent 00682 */ 00683 err_t 00684 tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, 00685 tcp_connected_fn connected) 00686 { 00687 err_t ret; 00688 u32_t iss; 00689 u16_t old_local_port; 00690 00691 LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); 00692 00693 LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); 00694 if (ipaddr != NULL) { 00695 pcb->remote_ip = *ipaddr; 00696 } else { 00697 return ERR_VAL; 00698 } 00699 pcb->remote_port = port; 00700 00701 /* check if we have a route to the remote host */ 00702 if (ip_addr_isany(&(pcb->local_ip))) { 00703 /* no local IP address set, yet. */ 00704 struct netif *netif = ip_route(&(pcb->remote_ip)); 00705 if (netif == NULL) { 00706 /* Don't even try to send a SYN packet if we have no route 00707 since that will fail. */ 00708 return ERR_RTE; 00709 } 00710 /* Use the netif's IP address as local address. */ 00711 ip_addr_copy(pcb->local_ip, netif->ip_addr); 00712 } 00713 00714 old_local_port = pcb->local_port; 00715 if (pcb->local_port == 0) { 00716 pcb->local_port = tcp_new_port(); 00717 if (pcb->local_port == 0) { 00718 return ERR_BUF; 00719 } 00720 } 00721 #if SO_REUSE 00722 if (ip_get_option(pcb, SOF_REUSEADDR)) { 00723 /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure 00724 now that the 5-tuple is unique. */ 00725 struct tcp_pcb *cpcb; 00726 int i; 00727 /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ 00728 for (i = 2; i < NUM_TCP_PCB_LISTS; i++) { 00729 for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { 00730 if ((cpcb->local_port == pcb->local_port) && 00731 (cpcb->remote_port == port) && 00732 ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) && 00733 ip_addr_cmp(&cpcb->remote_ip, ipaddr)) { 00734 /* linux returns EISCONN here, but ERR_USE should be OK for us */ 00735 return ERR_USE; 00736 } 00737 } 00738 } 00739 } 00740 #endif /* SO_REUSE */ 00741 iss = tcp_next_iss(); 00742 pcb->rcv_nxt = 0; 00743 pcb->snd_nxt = iss; 00744 pcb->lastack = iss - 1; 00745 pcb->snd_lbb = iss - 1; 00746 pcb->rcv_wnd = TCP_WND; 00747 pcb->rcv_ann_wnd = TCP_WND; 00748 pcb->rcv_ann_right_edge = pcb->rcv_nxt; 00749 pcb->snd_wnd = TCP_WND; 00750 /* As initial send MSS, we use TCP_MSS but limit it to 536. 00751 The send MSS is updated when an MSS option is received. */ 00752 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 00753 #if TCP_CALCULATE_EFF_SEND_MSS 00754 pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); 00755 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 00756 pcb->cwnd = 1; 00757 pcb->ssthresh = pcb->mss * 10; 00758 #if LWIP_CALLBACK_API 00759 pcb->connected = connected; 00760 #else /* LWIP_CALLBACK_API */ 00761 LWIP_UNUSED_ARG(connected); 00762 #endif /* LWIP_CALLBACK_API */ 00763 00764 /* Send a SYN together with the MSS option. */ 00765 ret = tcp_enqueue_flags(pcb, TCP_SYN); 00766 if (ret == ERR_OK) { 00767 /* SYN segment was enqueued, changed the pcbs state now */ 00768 pcb->state = SYN_SENT; 00769 if (old_local_port != 0) { 00770 TCP_RMV(&tcp_bound_pcbs, pcb); 00771 } 00772 TCP_REG_ACTIVE(pcb); 00773 snmp_inc_tcpactiveopens(); 00774 00775 tcp_output(pcb); 00776 } 00777 return ret; 00778 } 00779 00780 /** 00781 * Called every 500 ms and implements the retransmission timer and the timer that 00782 * removes PCBs that have been in TIME-WAIT for enough time. It also increments 00783 * various timers such as the inactivity timer in each PCB. 00784 * 00785 * Automatically called from tcp_tmr(). 00786 */ 00787 void 00788 tcp_slowtmr(void) 00789 { 00790 struct tcp_pcb *pcb, *prev; 00791 u16_t eff_wnd; 00792 u8_t pcb_remove; /* flag if a PCB should be removed */ 00793 u8_t pcb_reset; /* flag if a RST should be sent when removing */ 00794 err_t err; 00795 00796 err = ERR_OK; 00797 00798 ++tcp_ticks; 00799 ++tcp_timer_ctr; 00800 00801 tcp_slowtmr_start: 00802 /* Steps through all of the active PCBs. */ 00803 prev = NULL; 00804 pcb = tcp_active_pcbs; 00805 if (pcb == NULL) { 00806 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); 00807 } 00808 while (pcb != NULL) { 00809 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); 00810 LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); 00811 LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); 00812 LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); 00813 if (pcb->last_timer == tcp_timer_ctr) { 00814 /* skip this pcb, we have already processed it */ 00815 pcb = pcb->next; 00816 continue; 00817 } 00818 pcb->last_timer = tcp_timer_ctr; 00819 00820 pcb_remove = 0; 00821 pcb_reset = 0; 00822 00823 if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { 00824 ++pcb_remove; 00825 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); 00826 } 00827 else if (pcb->nrtx == TCP_MAXRTX) { 00828 ++pcb_remove; 00829 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); 00830 } else { 00831 if (pcb->persist_backoff > 0) { 00832 /* If snd_wnd is zero, use persist timer to send 1 byte probes 00833 * instead of using the standard retransmission mechanism. */ 00834 pcb->persist_cnt++; 00835 if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { 00836 pcb->persist_cnt = 0; 00837 if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { 00838 pcb->persist_backoff++; 00839 } 00840 tcp_zero_window_probe(pcb); 00841 } 00842 } else { 00843 /* Increase the retransmission timer if it is running */ 00844 if(pcb->rtime >= 0) { 00845 ++pcb->rtime; 00846 } 00847 00848 if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { 00849 /* Time for a retransmission. */ 00850 LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F 00851 " pcb->rto %"S16_F"\n", 00852 pcb->rtime, pcb->rto)); 00853 00854 /* Double retransmission time-out unless we are trying to 00855 * connect to somebody (i.e., we are in SYN_SENT). */ 00856 if (pcb->state != SYN_SENT) { 00857 pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; 00858 } 00859 00860 /* Reset the retransmission timer. */ 00861 pcb->rtime = 0; 00862 00863 /* Reduce congestion window and ssthresh. */ 00864 eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); 00865 pcb->ssthresh = eff_wnd >> 1; 00866 if (pcb->ssthresh < (pcb->mss << 1)) { 00867 pcb->ssthresh = (pcb->mss << 1); 00868 } 00869 pcb->cwnd = pcb->mss; 00870 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F 00871 " ssthresh %"U16_F"\n", 00872 pcb->cwnd, pcb->ssthresh)); 00873 00874 /* The following needs to be called AFTER cwnd is set to one 00875 mss - STJ */ 00876 tcp_rexmit_rto(pcb); 00877 } 00878 } 00879 } 00880 /* Check if this PCB has stayed too long in FIN-WAIT-2 */ 00881 if (pcb->state == FIN_WAIT_2) { 00882 /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ 00883 if (pcb->flags & TF_RXCLOSED) { 00884 /* PCB was fully closed (either through close() or SHUT_RDWR): 00885 normal FIN-WAIT timeout handling. */ 00886 if ((u32_t)(tcp_ticks - pcb->tmr) > 00887 TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { 00888 ++pcb_remove; 00889 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); 00890 } 00891 } 00892 } 00893 00894 /* Check if KEEPALIVE should be sent */ 00895 if(ip_get_option(pcb, SOF_KEEPALIVE) && 00896 ((pcb->state == ESTABLISHED) || 00897 (pcb->state == CLOSE_WAIT))) { 00898 if((u32_t)(tcp_ticks - pcb->tmr) > 00899 (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) 00900 { 00901 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", 00902 ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), 00903 ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); 00904 00905 ++pcb_remove; 00906 ++pcb_reset; 00907 } 00908 else if((u32_t)(tcp_ticks - pcb->tmr) > 00909 (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) 00910 / TCP_SLOW_INTERVAL) 00911 { 00912 tcp_keepalive(pcb); 00913 pcb->keep_cnt_sent++; 00914 } 00915 } 00916 00917 /* If this PCB has queued out of sequence data, but has been 00918 inactive for too long, will drop the data (it will eventually 00919 be retransmitted). */ 00920 #if TCP_QUEUE_OOSEQ 00921 if (pcb->ooseq != NULL && 00922 (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { 00923 tcp_segs_free(pcb->ooseq); 00924 pcb->ooseq = NULL; 00925 LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); 00926 } 00927 #endif /* TCP_QUEUE_OOSEQ */ 00928 00929 /* Check if this PCB has stayed too long in SYN-RCVD */ 00930 if (pcb->state == SYN_RCVD) { 00931 if ((u32_t)(tcp_ticks - pcb->tmr) > 00932 TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { 00933 ++pcb_remove; 00934 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); 00935 } 00936 } 00937 00938 /* Check if this PCB has stayed too long in LAST-ACK */ 00939 if (pcb->state == LAST_ACK) { 00940 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { 00941 ++pcb_remove; 00942 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); 00943 } 00944 } 00945 00946 /* If the PCB should be removed, do it. */ 00947 if (pcb_remove) { 00948 struct tcp_pcb *pcb2; 00949 tcp_err_fn err_fn; 00950 void *err_arg; 00951 tcp_pcb_purge(pcb); 00952 /* Remove PCB from tcp_active_pcbs list. */ 00953 if (prev != NULL) { 00954 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); 00955 prev->next = pcb->next; 00956 } else { 00957 /* This PCB was the first. */ 00958 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); 00959 tcp_active_pcbs = pcb->next; 00960 } 00961 00962 if (pcb_reset) { 00963 tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, 00964 pcb->local_port, pcb->remote_port); 00965 } 00966 00967 err_fn = pcb->errf; 00968 err_arg = pcb->callback_arg; 00969 pcb2 = pcb; 00970 pcb = pcb->next; 00971 memp_free(MEMP_TCP_PCB, pcb2); 00972 00973 tcp_active_pcbs_changed = 0; 00974 TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); 00975 if (tcp_active_pcbs_changed) { 00976 goto tcp_slowtmr_start; 00977 } 00978 } else { 00979 /* get the 'next' element now and work with 'prev' below (in case of abort) */ 00980 prev = pcb; 00981 pcb = pcb->next; 00982 00983 /* We check if we should poll the connection. */ 00984 ++prev->polltmr; 00985 if (prev->polltmr >= prev->pollinterval) { 00986 prev->polltmr = 0; 00987 LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); 00988 tcp_active_pcbs_changed = 0; 00989 TCP_EVENT_POLL(prev, err); 00990 if (tcp_active_pcbs_changed) { 00991 goto tcp_slowtmr_start; 00992 } 00993 /* if err == ERR_ABRT, 'prev' is already deallocated */ 00994 if (err == ERR_OK) { 00995 tcp_output(prev); 00996 } 00997 } 00998 } 00999 } 01000 01001 01002 /* Steps through all of the TIME-WAIT PCBs. */ 01003 prev = NULL; 01004 pcb = tcp_tw_pcbs; 01005 while (pcb != NULL) { 01006 LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 01007 pcb_remove = 0; 01008 01009 /* Check if this PCB has stayed long enough in TIME-WAIT */ 01010 if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { 01011 ++pcb_remove; 01012 } 01013 01014 01015 01016 /* If the PCB should be removed, do it. */ 01017 if (pcb_remove) { 01018 struct tcp_pcb *pcb2; 01019 tcp_pcb_purge(pcb); 01020 /* Remove PCB from tcp_tw_pcbs list. */ 01021 if (prev != NULL) { 01022 LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); 01023 prev->next = pcb->next; 01024 } else { 01025 /* This PCB was the first. */ 01026 LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); 01027 tcp_tw_pcbs = pcb->next; 01028 } 01029 pcb2 = pcb; 01030 pcb = pcb->next; 01031 memp_free(MEMP_TCP_PCB, pcb2); 01032 } else { 01033 prev = pcb; 01034 pcb = pcb->next; 01035 } 01036 } 01037 } 01038 01039 /** 01040 * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously 01041 * "refused" by upper layer (application) and sends delayed ACKs. 01042 * 01043 * Automatically called from tcp_tmr(). 01044 */ 01045 void 01046 tcp_fasttmr(void) 01047 { 01048 struct tcp_pcb *pcb; 01049 01050 ++tcp_timer_ctr; 01051 01052 tcp_fasttmr_start: 01053 pcb = tcp_active_pcbs; 01054 01055 while(pcb != NULL) { 01056 if (pcb->last_timer != tcp_timer_ctr) { 01057 struct tcp_pcb *next; 01058 pcb->last_timer = tcp_timer_ctr; 01059 /* send delayed ACKs */ 01060 if (pcb->flags & TF_ACK_DELAY) { 01061 LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); 01062 tcp_ack_now(pcb); 01063 tcp_output(pcb); 01064 pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); 01065 } 01066 01067 next = pcb->next; 01068 01069 /* If there is data which was previously "refused" by upper layer */ 01070 if (pcb->refused_data != NULL) { 01071 tcp_active_pcbs_changed = 0; 01072 tcp_process_refused_data(pcb); 01073 if (tcp_active_pcbs_changed) { 01074 /* application callback has changed the pcb list: restart the loop */ 01075 goto tcp_fasttmr_start; 01076 } 01077 } 01078 pcb = next; 01079 } 01080 } 01081 } 01082 01083 /** Pass pcb->refused_data to the recv callback */ 01084 err_t 01085 tcp_process_refused_data(struct tcp_pcb *pcb) 01086 { 01087 err_t err; 01088 u8_t refused_flags = pcb->refused_data->flags; 01089 /* set pcb->refused_data to NULL in case the callback frees it and then 01090 closes the pcb */ 01091 struct pbuf *refused_data = pcb->refused_data; 01092 pcb->refused_data = NULL; 01093 /* Notify again application with data previously received. */ 01094 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); 01095 TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); 01096 if (err == ERR_OK) { 01097 /* did refused_data include a FIN? */ 01098 if (refused_flags & PBUF_FLAG_TCP_FIN) { 01099 /* correct rcv_wnd as the application won't call tcp_recved() 01100 for the FIN's seqno */ 01101 if (pcb->rcv_wnd != TCP_WND) { 01102 pcb->rcv_wnd++; 01103 } 01104 TCP_EVENT_CLOSED(pcb, err); 01105 if (err == ERR_ABRT) { 01106 return ERR_ABRT; 01107 } 01108 } 01109 } else if (err == ERR_ABRT) { 01110 /* if err == ERR_ABRT, 'pcb' is already deallocated */ 01111 /* Drop incoming packets because pcb is "full" (only if the incoming 01112 segment contains data). */ 01113 LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); 01114 return ERR_ABRT; 01115 } else { 01116 /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ 01117 pcb->refused_data = refused_data; 01118 } 01119 return ERR_OK; 01120 } 01121 01122 /** 01123 * Deallocates a list of TCP segments (tcp_seg structures). 01124 * 01125 * @param seg tcp_seg list of TCP segments to free 01126 */ 01127 void 01128 tcp_segs_free(struct tcp_seg *seg) 01129 { 01130 while (seg != NULL) { 01131 struct tcp_seg *next = seg->next; 01132 tcp_seg_free(seg); 01133 seg = next; 01134 } 01135 } 01136 01137 /** 01138 * Frees a TCP segment (tcp_seg structure). 01139 * 01140 * @param seg single tcp_seg to free 01141 */ 01142 void 01143 tcp_seg_free(struct tcp_seg *seg) 01144 { 01145 if (seg != NULL) { 01146 if (seg->p != NULL) { 01147 pbuf_free(seg->p); 01148 #if TCP_DEBUG 01149 seg->p = NULL; 01150 #endif /* TCP_DEBUG */ 01151 } 01152 memp_free(MEMP_TCP_SEG, seg); 01153 } 01154 } 01155 01156 /** 01157 * Sets the priority of a connection. 01158 * 01159 * @param pcb the tcp_pcb to manipulate 01160 * @param prio new priority 01161 */ 01162 void 01163 tcp_setprio(struct tcp_pcb *pcb, u8_t prio) 01164 { 01165 pcb->prio = prio; 01166 } 01167 01168 #if TCP_QUEUE_OOSEQ 01169 /** 01170 * Returns a copy of the given TCP segment. 01171 * The pbuf and data are not copied, only the pointers 01172 * 01173 * @param seg the old tcp_seg 01174 * @return a copy of seg 01175 */ 01176 struct tcp_seg * 01177 tcp_seg_copy(struct tcp_seg *seg) 01178 { 01179 struct tcp_seg *cseg; 01180 01181 cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); 01182 if (cseg == NULL) { 01183 return NULL; 01184 } 01185 SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); 01186 pbuf_ref(cseg->p); 01187 return cseg; 01188 } 01189 #endif /* TCP_QUEUE_OOSEQ */ 01190 01191 #if LWIP_CALLBACK_API 01192 /** 01193 * Default receive callback that is called if the user didn't register 01194 * a recv callback for the pcb. 01195 */ 01196 err_t 01197 tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) 01198 { 01199 LWIP_UNUSED_ARG(arg); 01200 if (p != NULL) { 01201 tcp_recved(pcb, p->tot_len); 01202 pbuf_free(p); 01203 } else if (err == ERR_OK) { 01204 return tcp_close(pcb); 01205 } 01206 return ERR_OK; 01207 } 01208 #endif /* LWIP_CALLBACK_API */ 01209 01210 /** 01211 * Kills the oldest active connection that has the same or lower priority than 01212 * 'prio'. 01213 * 01214 * @param prio minimum priority 01215 */ 01216 static void 01217 tcp_kill_prio(u8_t prio) 01218 { 01219 struct tcp_pcb *pcb, *inactive; 01220 u32_t inactivity; 01221 u8_t mprio; 01222 01223 01224 mprio = TCP_PRIO_MAX; 01225 01226 /* We kill the oldest active connection that has lower priority than prio. */ 01227 inactivity = 0; 01228 inactive = NULL; 01229 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 01230 if (pcb->prio <= prio && 01231 pcb->prio <= mprio && 01232 (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { 01233 inactivity = tcp_ticks - pcb->tmr; 01234 inactive = pcb; 01235 mprio = pcb->prio; 01236 } 01237 } 01238 if (inactive != NULL) { 01239 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", 01240 (void *)inactive, inactivity)); 01241 tcp_abort(inactive); 01242 } 01243 } 01244 01245 /** 01246 * Kills the oldest connection that is in TIME_WAIT state. 01247 * Called from tcp_alloc() if no more connections are available. 01248 */ 01249 static void 01250 tcp_kill_timewait(void) 01251 { 01252 struct tcp_pcb *pcb, *inactive; 01253 u32_t inactivity; 01254 01255 inactivity = 0; 01256 inactive = NULL; 01257 /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ 01258 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 01259 if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { 01260 inactivity = tcp_ticks - pcb->tmr; 01261 inactive = pcb; 01262 } 01263 } 01264 if (inactive != NULL) { 01265 LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", 01266 (void *)inactive, inactivity)); 01267 tcp_abort(inactive); 01268 } 01269 } 01270 01271 /** 01272 * Allocate a new tcp_pcb structure. 01273 * 01274 * @param prio priority for the new pcb 01275 * @return a new tcp_pcb that initially is in state CLOSED 01276 */ 01277 struct tcp_pcb * 01278 tcp_alloc(u8_t prio) 01279 { 01280 struct tcp_pcb *pcb; 01281 u32_t iss; 01282 01283 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); 01284 if (pcb == NULL) { 01285 /* Try killing oldest connection in TIME-WAIT. */ 01286 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); 01287 tcp_kill_timewait(); 01288 /* Try to allocate a tcp_pcb again. */ 01289 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); 01290 if (pcb == NULL) { 01291 /* Try killing active connections with lower priority than the new one. */ 01292 LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); 01293 tcp_kill_prio(prio); 01294 /* Try to allocate a tcp_pcb again. */ 01295 pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); 01296 if (pcb != NULL) { 01297 /* adjust err stats: memp_malloc failed twice before */ 01298 MEMP_STATS_DEC(err, MEMP_TCP_PCB); 01299 } 01300 } 01301 if (pcb != NULL) { 01302 /* adjust err stats: timewait PCB was freed above */ 01303 MEMP_STATS_DEC(err, MEMP_TCP_PCB); 01304 } 01305 } 01306 if (pcb != NULL) { 01307 memset(pcb, 0, sizeof(struct tcp_pcb)); 01308 pcb->prio = prio; 01309 pcb->snd_buf = TCP_SND_BUF; 01310 pcb->snd_queuelen = 0; 01311 pcb->rcv_wnd = TCP_WND; 01312 pcb->rcv_ann_wnd = TCP_WND; 01313 pcb->tos = 0; 01314 pcb->ttl = TCP_TTL; 01315 /* As initial send MSS, we use TCP_MSS but limit it to 536. 01316 The send MSS is updated when an MSS option is received. */ 01317 pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; 01318 pcb->rto = 3000 / TCP_SLOW_INTERVAL; 01319 pcb->sa = 0; 01320 pcb->sv = 3000 / TCP_SLOW_INTERVAL; 01321 pcb->rtime = -1; 01322 pcb->cwnd = 1; 01323 iss = tcp_next_iss(); 01324 pcb->snd_wl2 = iss; 01325 pcb->snd_nxt = iss; 01326 pcb->lastack = iss; 01327 pcb->snd_lbb = iss; 01328 pcb->tmr = tcp_ticks; 01329 pcb->last_timer = tcp_timer_ctr; 01330 01331 pcb->polltmr = 0; 01332 01333 #if LWIP_CALLBACK_API 01334 pcb->recv = tcp_recv_null; 01335 #endif /* LWIP_CALLBACK_API */ 01336 01337 /* Init KEEPALIVE timer */ 01338 pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; 01339 01340 #if LWIP_TCP_KEEPALIVE 01341 pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; 01342 pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; 01343 #endif /* LWIP_TCP_KEEPALIVE */ 01344 01345 pcb->keep_cnt_sent = 0; 01346 } 01347 return pcb; 01348 } 01349 01350 /** 01351 * Creates a new TCP protocol control block but doesn't place it on 01352 * any of the TCP PCB lists. 01353 * The pcb is not put on any list until binding using tcp_bind(). 01354 * 01355 * @internal: Maybe there should be a idle TCP PCB list where these 01356 * PCBs are put on. Port reservation using tcp_bind() is implemented but 01357 * allocated pcbs that are not bound can't be killed automatically if wanting 01358 * to allocate a pcb with higher prio (@see tcp_kill_prio()) 01359 * 01360 * @return a new tcp_pcb that initially is in state CLOSED 01361 */ 01362 struct tcp_pcb * 01363 tcp_new(void) 01364 { 01365 return tcp_alloc(TCP_PRIO_NORMAL); 01366 } 01367 01368 /** 01369 * Used to specify the argument that should be passed callback 01370 * functions. 01371 * 01372 * @param pcb tcp_pcb to set the callback argument 01373 * @param arg void pointer argument to pass to callback functions 01374 */ 01375 void 01376 tcp_arg(struct tcp_pcb *pcb, void *arg) 01377 { 01378 /* This function is allowed to be called for both listen pcbs and 01379 connection pcbs. */ 01380 pcb->callback_arg = arg; 01381 } 01382 #if LWIP_CALLBACK_API 01383 01384 /** 01385 * Used to specify the function that should be called when a TCP 01386 * connection receives data. 01387 * 01388 * @param pcb tcp_pcb to set the recv callback 01389 * @param recv callback function to call for this pcb when data is received 01390 */ 01391 void 01392 tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) 01393 { 01394 LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); 01395 pcb->recv = recv; 01396 } 01397 01398 /** 01399 * Used to specify the function that should be called when TCP data 01400 * has been successfully delivered to the remote host. 01401 * 01402 * @param pcb tcp_pcb to set the sent callback 01403 * @param sent callback function to call for this pcb when data is successfully sent 01404 */ 01405 void 01406 tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) 01407 { 01408 LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); 01409 pcb->sent = sent; 01410 } 01411 01412 /** 01413 * Used to specify the function that should be called when a fatal error 01414 * has occured on the connection. 01415 * 01416 * @param pcb tcp_pcb to set the err callback 01417 * @param err callback function to call for this pcb when a fatal error 01418 * has occured on the connection 01419 */ 01420 void 01421 tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) 01422 { 01423 LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); 01424 pcb->errf = err; 01425 } 01426 01427 /** 01428 * Used for specifying the function that should be called when a 01429 * LISTENing connection has been connected to another host. 01430 * 01431 * @param pcb tcp_pcb to set the accept callback 01432 * @param accept callback function to call for this pcb when LISTENing 01433 * connection has been connected to another host 01434 */ 01435 void 01436 tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) 01437 { 01438 /* This function is allowed to be called for both listen pcbs and 01439 connection pcbs. */ 01440 pcb->accept = accept; 01441 } 01442 #endif /* LWIP_CALLBACK_API */ 01443 01444 01445 /** 01446 * Used to specify the function that should be called periodically 01447 * from TCP. The interval is specified in terms of the TCP coarse 01448 * timer interval, which is called twice a second. 01449 * 01450 */ 01451 void 01452 tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) 01453 { 01454 LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); 01455 #if LWIP_CALLBACK_API 01456 pcb->poll = poll; 01457 #else /* LWIP_CALLBACK_API */ 01458 LWIP_UNUSED_ARG(poll); 01459 #endif /* LWIP_CALLBACK_API */ 01460 pcb->pollinterval = interval; 01461 } 01462 01463 /** 01464 * Purges a TCP PCB. Removes any buffered data and frees the buffer memory 01465 * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). 01466 * 01467 * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! 01468 */ 01469 void 01470 tcp_pcb_purge(struct tcp_pcb *pcb) 01471 { 01472 if (pcb->state != CLOSED && 01473 pcb->state != TIME_WAIT && 01474 pcb->state != LISTEN) { 01475 01476 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); 01477 01478 #if TCP_LISTEN_BACKLOG 01479 if (pcb->state == SYN_RCVD) { 01480 /* Need to find the corresponding listen_pcb and decrease its accepts_pending */ 01481 struct tcp_pcb_listen *lpcb; 01482 LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", 01483 tcp_listen_pcbs.listen_pcbs != NULL); 01484 for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { 01485 if ((lpcb->local_port == pcb->local_port) && 01486 (ip_addr_isany(&lpcb->local_ip) || 01487 ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) { 01488 /* port and address of the listen pcb match the timed-out pcb */ 01489 LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", 01490 lpcb->accepts_pending > 0); 01491 lpcb->accepts_pending--; 01492 break; 01493 } 01494 } 01495 } 01496 #endif /* TCP_LISTEN_BACKLOG */ 01497 01498 01499 if (pcb->refused_data != NULL) { 01500 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); 01501 pbuf_free(pcb->refused_data); 01502 pcb->refused_data = NULL; 01503 } 01504 if (pcb->unsent != NULL) { 01505 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); 01506 } 01507 if (pcb->unacked != NULL) { 01508 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); 01509 } 01510 #if TCP_QUEUE_OOSEQ 01511 if (pcb->ooseq != NULL) { 01512 LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); 01513 } 01514 tcp_segs_free(pcb->ooseq); 01515 pcb->ooseq = NULL; 01516 #endif /* TCP_QUEUE_OOSEQ */ 01517 01518 /* Stop the retransmission timer as it will expect data on unacked 01519 queue if it fires */ 01520 pcb->rtime = -1; 01521 01522 tcp_segs_free(pcb->unsent); 01523 tcp_segs_free(pcb->unacked); 01524 pcb->unacked = pcb->unsent = NULL; 01525 #if TCP_OVERSIZE 01526 pcb->unsent_oversize = 0; 01527 #endif /* TCP_OVERSIZE */ 01528 } 01529 } 01530 01531 /** 01532 * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. 01533 * 01534 * @param pcblist PCB list to purge. 01535 * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! 01536 */ 01537 void 01538 tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) 01539 { 01540 TCP_RMV(pcblist, pcb); 01541 01542 tcp_pcb_purge(pcb); 01543 01544 /* if there is an outstanding delayed ACKs, send it */ 01545 if (pcb->state != TIME_WAIT && 01546 pcb->state != LISTEN && 01547 pcb->flags & TF_ACK_DELAY) { 01548 pcb->flags |= TF_ACK_NOW; 01549 tcp_output(pcb); 01550 } 01551 01552 if (pcb->state != LISTEN) { 01553 LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); 01554 LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); 01555 #if TCP_QUEUE_OOSEQ 01556 LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); 01557 #endif /* TCP_QUEUE_OOSEQ */ 01558 } 01559 01560 pcb->state = CLOSED; 01561 01562 LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); 01563 } 01564 01565 /** 01566 * Calculates a new initial sequence number for new connections. 01567 * 01568 * @return u32_t pseudo random sequence number 01569 */ 01570 u32_t 01571 tcp_next_iss(void) 01572 { 01573 static u32_t iss = 6510; 01574 01575 iss += tcp_ticks; /* XXX */ 01576 return iss; 01577 } 01578 01579 #if TCP_CALCULATE_EFF_SEND_MSS 01580 /** 01581 * Calcluates the effective send mss that can be used for a specific IP address 01582 * by using ip_route to determin the netif used to send to the address and 01583 * calculating the minimum of TCP_MSS and that netif's mtu (if set). 01584 */ 01585 u16_t 01586 tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr) 01587 { 01588 u16_t mss_s; 01589 struct netif *outif; 01590 01591 outif = ip_route(addr); 01592 if ((outif != NULL) && (outif->mtu != 0)) { 01593 mss_s = outif->mtu - IP_HLEN - TCP_HLEN; 01594 /* RFC 1122, chap 4.2.2.6: 01595 * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize 01596 * We correct for TCP options in tcp_write(), and don't support IP options. 01597 */ 01598 sendmss = LWIP_MIN(sendmss, mss_s); 01599 } 01600 return sendmss; 01601 } 01602 #endif /* TCP_CALCULATE_EFF_SEND_MSS */ 01603 01604 const char* 01605 tcp_debug_state_str(enum tcp_state s) 01606 { 01607 return tcp_state_str[s]; 01608 } 01609 01610 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG 01611 /** 01612 * Print a tcp header for debugging purposes. 01613 * 01614 * @param tcphdr pointer to a struct tcp_hdr 01615 */ 01616 void 01617 tcp_debug_print(struct tcp_hdr *tcphdr) 01618 { 01619 LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); 01620 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01621 LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", 01622 ntohs(tcphdr->src), ntohs(tcphdr->dest))); 01623 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01624 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", 01625 ntohl(tcphdr->seqno))); 01626 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01627 LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", 01628 ntohl(tcphdr->ackno))); 01629 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01630 LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", 01631 TCPH_HDRLEN(tcphdr), 01632 TCPH_FLAGS(tcphdr) >> 5 & 1, 01633 TCPH_FLAGS(tcphdr) >> 4 & 1, 01634 TCPH_FLAGS(tcphdr) >> 3 & 1, 01635 TCPH_FLAGS(tcphdr) >> 2 & 1, 01636 TCPH_FLAGS(tcphdr) >> 1 & 1, 01637 TCPH_FLAGS(tcphdr) & 1, 01638 ntohs(tcphdr->wnd))); 01639 tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); 01640 LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); 01641 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01642 LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", 01643 ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); 01644 LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); 01645 } 01646 01647 /** 01648 * Print a tcp state for debugging purposes. 01649 * 01650 * @param s enum tcp_state to print 01651 */ 01652 void 01653 tcp_debug_print_state(enum tcp_state s) 01654 { 01655 LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s])); 01656 } 01657 01658 /** 01659 * Print tcp flags for debugging purposes. 01660 * 01661 * @param flags tcp flags, all active flags are printed 01662 */ 01663 void 01664 tcp_debug_print_flags(u8_t flags) 01665 { 01666 if (flags & TCP_FIN) { 01667 LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); 01668 } 01669 if (flags & TCP_SYN) { 01670 LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); 01671 } 01672 if (flags & TCP_RST) { 01673 LWIP_DEBUGF(TCP_DEBUG, ("RST ")); 01674 } 01675 if (flags & TCP_PSH) { 01676 LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); 01677 } 01678 if (flags & TCP_ACK) { 01679 LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); 01680 } 01681 if (flags & TCP_URG) { 01682 LWIP_DEBUGF(TCP_DEBUG, ("URG ")); 01683 } 01684 if (flags & TCP_ECE) { 01685 LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); 01686 } 01687 if (flags & TCP_CWR) { 01688 LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); 01689 } 01690 LWIP_DEBUGF(TCP_DEBUG, ("\n")); 01691 } 01692 01693 /** 01694 * Print all tcp_pcbs in every list for debugging purposes. 01695 */ 01696 void 01697 tcp_debug_print_pcbs(void) 01698 { 01699 struct tcp_pcb *pcb; 01700 LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); 01701 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 01702 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01703 pcb->local_port, pcb->remote_port, 01704 pcb->snd_nxt, pcb->rcv_nxt)); 01705 tcp_debug_print_state(pcb->state); 01706 } 01707 LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); 01708 for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { 01709 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01710 pcb->local_port, pcb->remote_port, 01711 pcb->snd_nxt, pcb->rcv_nxt)); 01712 tcp_debug_print_state(pcb->state); 01713 } 01714 LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); 01715 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 01716 LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", 01717 pcb->local_port, pcb->remote_port, 01718 pcb->snd_nxt, pcb->rcv_nxt)); 01719 tcp_debug_print_state(pcb->state); 01720 } 01721 } 01722 01723 /** 01724 * Check state consistency of the tcp_pcb lists. 01725 */ 01726 s16_t 01727 tcp_pcbs_sane(void) 01728 { 01729 struct tcp_pcb *pcb; 01730 for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { 01731 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); 01732 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); 01733 LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); 01734 } 01735 for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { 01736 LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); 01737 } 01738 return 1; 01739 } 01740 #endif /* TCP_DEBUG */ 01741 01742 #endif /* LWIP_TCP */
Generated on Wed Jul 13 2022 09:48:38 by 1.7.2