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