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/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 19:21:01 by
