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