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