Microchip® Advanced Software Framework

tcp_impl.h File Reference
#include "lwip/opt.h"
#include "lwip/tcp.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/ip.h"
#include "lwip/icmp.h"
#include "lwip/err.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"

Data Structures

struct  tcp_hdr
 
union  tcp_listen_pcbs_t
 
struct  tcp_seg
 

Macros

#define LWIP_TCP_OPT_EOL   0
 
#define LWIP_TCP_OPT_LEN_MSS   4
 
#define LWIP_TCP_OPT_LEN_TS_OUT   0
 
#define LWIP_TCP_OPT_LEN_WS_OUT   0
 
#define LWIP_TCP_OPT_LENGTH(flags)
 
#define LWIP_TCP_OPT_MSS   2
 
#define LWIP_TCP_OPT_NOP   1
 
#define LWIP_TCP_OPT_TS   8
 
#define LWIP_TCP_OPT_WS   3
 
#define TCP_ACK   0x10U
 
#define tcp_ack(pcb)
 
#define tcp_ack_now(pcb)
 
#define TCP_BUILD_MSS_OPTION(mss)   htonl(0x02040000 | ((mss) & 0xFFFF))
 This returns a TCP header option for MSS in an u32_t. More...
 
#define TCP_CHECKSUM_ON_COPY   (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)
 Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled. More...
 
#define TCP_CWR   0x80U
 
#define TCP_DEBUG_PCB_LISTS   0
 
#define tcp_debug_print(tcphdr)
 
#define tcp_debug_print_flags(flags)
 
#define tcp_debug_print_pcbs()
 
#define tcp_debug_print_state(s)
 
#define tcp_do_output_nagle(tpcb)
 This is the Nagle algorithm: try to combine user data to send as few TCP segments as possible. More...
 
#define TCP_ECE   0x40U
 
#define tcp_eff_send_mss(sendmss, src, dest, isipv6)   tcp_eff_send_mss_impl(sendmss, dest, src, isipv6)
 
#define TCP_EVENT_ACCEPT(pcb, err, ret)
 
#define TCP_EVENT_CLOSED(pcb, ret)
 
#define TCP_EVENT_CONNECTED(pcb, err, ret)
 
#define TCP_EVENT_ERR(errf, arg, err)
 
#define TCP_EVENT_POLL(pcb, ret)
 
#define TCP_EVENT_RECV(pcb, p, err, ret)
 
#define TCP_EVENT_SENT(pcb, space, ret)
 
#define TCP_FAST_INTERVAL   TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */
 
#define TCP_FIN   0x01U
 
#define TCP_FIN_WAIT_TIMEOUT   20000 /* milliseconds */
 
#define TCP_FLAGS   0x3fU
 
#define TCP_HLEN   20
 
#define TCP_KEEPCNT_DEFAULT   9U /* Default Counter for KEEPALIVE probes */
 
#define TCP_KEEPIDLE_DEFAULT   7200000UL /* Default KEEPALIVE timer in milliseconds */
 
#define TCP_KEEPINTVL_DEFAULT   75000UL /* Default Time between KEEPALIVE probes in milliseconds */
 
#define TCP_MAXIDLE   TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */
 
#define TCP_MSL   60000UL /* The maximum segment lifetime in milliseconds */
 
#define TCP_OOSEQ_TIMEOUT   6U /* x RTO */
 
#define tcp_output_nagle(tpcb)   (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
 
#define TCP_OVERSIZE_DBGCHECK   0
 Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled. More...
 
#define TCP_PCB_REMOVE_ACTIVE(pcb)
 
#define tcp_pcbs_sane()   1
 
#define TCP_PSH   0x08U
 
#define TCP_REG(pcbs, npcb)
 
#define TCP_REG_ACTIVE(npcb)
 
#define TCP_RMV(pcbs, npcb)
 
#define TCP_RMV_ACTIVE(npcb)
 
#define TCP_RST   0x04U
 
#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6)   tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6)
 
#define TCP_SEQ_BETWEEN(a, b, c)   (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
 
#define TCP_SEQ_GEQ(a, b)   ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0)
 
#define TCP_SEQ_GT(a, b)   ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0)
 
#define TCP_SEQ_LEQ(a, b)   ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0)
 
#define TCP_SEQ_LT(a, b)   ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0)
 
#define TCP_SLOW_INTERVAL   (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */
 
#define TCP_SYN   0x02U
 
#define TCP_SYN_RCVD_TIMEOUT   20000 /* milliseconds */
 
#define TCP_TCPLEN(seg)   ((seg)->len + (((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0) ? 1U : 0U))
 
#define TCP_TMR_INTERVAL   250 /* The TCP timer interval in milliseconds. */
 
#define TCP_URG   0x20U
 
#define TCPH_FLAGS(phdr)   (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
 
#define TCPH_FLAGS_SET(phdr, flags)   (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags))
 
#define TCPH_HDRLEN(phdr)   (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
 
#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags)   (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags))
 
#define TCPH_HDRLEN_SET(phdr, len)   (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
 
#define TCPH_SET_FLAG(phdr, flags)   (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags))
 
#define TCPH_UNSET_FLAG(phdr, flags)   (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
 
#define TCPWND_MAX   0xFFFFU
 
#define TCPWNDSIZE_F   U16_F
 
#define TF_CLOSED   (u8_t)0x10U /* Connection was successfully closed. */
 
#define TF_GOT_FIN   (u8_t)0x20U /* Connection was closed by the remote end. */
 
#define TF_RESET   (u8_t)0x08U /* Connection was reset. */
 Flags used on input processing, not on pcb->flags. More...
 
#define TF_SEG_DATA_CHECKSUMMED
 
#define TF_SEG_OPTS_MSS   (u8_t)0x01U /* Include MSS option. */
 
#define TF_SEG_OPTS_TS   (u8_t)0x02U /* Include timestamp option. */
 
#define TF_SEG_OPTS_WND_SCALE   (u8_t)0x08U /* Include WND SCALE option */
 

Functions

void tcp_abandon (struct tcp_pcb *pcb, int reset)
 Abandons a connection and optionally sends a RST to the remote host. More...
 
struct tcp_pcbtcp_alloc (u8_t prio)
 Allocate a new tcp_pcb structure. More...
 
u16_t tcp_eff_send_mss_impl (u16_t sendmss, ipX_addr_t *dest, ipX_addr_t *src, u8_t isipv6)
 Calculates the effective send mss that can be used for a specific IP address by using ip_route to determine the netif used to send to the address and calculating the minimum of TCP_MSS and that netif's mtu (if set). More...
 
err_t tcp_enqueue_flags (struct tcp_pcb *pcb, u8_t flags)
 Enqueue TCP options for transmission. More...
 
void tcp_fasttmr (void)
 Is called every TCP_FAST_INTERVAL (250 ms) and process data previously "refused" by upper layer (application) and sends delayed ACKs. More...
 
void tcp_init (void)
 Initialize this module. More...
 
void tcp_input (struct pbuf *p, struct netif *inp)
 The initial input processing of TCP. More...
 
void tcp_keepalive (struct tcp_pcb *pcb)
 Send keepalive packets to keep a connection active although no data is sent over it. More...
 
u32_t tcp_next_iss (void)
 Calculates a new initial sequence number for new connections. More...
 
struct tcp_pcbtcp_pcb_copy (struct tcp_pcb *pcb)
 
void tcp_pcb_purge (struct tcp_pcb *pcb)
 Purges a TCP PCB. More...
 
void tcp_pcb_remove (struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
 Purges the PCB and removes it from a PCB list. More...
 
err_t tcp_process_refused_data (struct tcp_pcb *pcb)
 Pass pcb->refused_data to the recv callback. More...
 
err_t tcp_recv_null (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
 Default receive callback that is called if the user didn't register a recv callback for the pcb. More...
 
void tcp_rexmit (struct tcp_pcb *pcb)
 Requeue the first unacked segment for retransmission. More...
 
void tcp_rexmit_fast (struct tcp_pcb *pcb)
 Handle retransmission after three dupacks received. More...
 
void tcp_rexmit_rto (struct tcp_pcb *pcb)
 Requeue all unacked segments for retransmission. More...
 
void tcp_rexmit_seg (struct tcp_pcb *pcb, struct tcp_seg *seg)
 
void tcp_rst_impl (u32_t seqno, u32_t ackno, ipX_addr_t *local_ip, ipX_addr_t *remote_ip, u16_t local_port, u16_t remote_port, u8_t isipv6)
 Send a TCP RESET packet (empty segment with RST flag set) either to abort a connection or to show that there is no matching local connection for a received segment. More...
 
struct tcp_segtcp_seg_copy (struct tcp_seg *seg)
 Returns a copy of the given TCP segment. More...
 
void tcp_seg_free (struct tcp_seg *seg)
 Frees a TCP segment (tcp_seg structure). More...
 
void tcp_segs_free (struct tcp_seg *seg)
 Deallocates a list of TCP segments (tcp_seg structures). More...
 
err_t tcp_send_empty_ack (struct tcp_pcb *pcb)
 Send an ACK without data. More...
 
err_t tcp_send_fin (struct tcp_pcb *pcb)
 Called by tcp_close() to send a segment including FIN flag but not data. More...
 
void tcp_slowtmr (void)
 Called every 500 ms and implements the retransmission timer and the timer that removes PCBs that have been in TIME-WAIT for enough time. More...
 
void tcp_timer_needed (void)
 External function (implemented in timers.c), called when TCP detects that a timer is needed (i.e. More...
 
void tcp_tmr (void)
 Called periodically to dispatch TCP timers. More...
 
u32_t tcp_update_rcv_ann_wnd (struct tcp_pcb *pcb)
 Update the state that tracks the available window space to advertise. More...
 
void tcp_zero_window_probe (struct tcp_pcb *pcb)
 Send persist timer zero-window probes to keep a connection active when a window update is lost. More...
 

Variables

PACK_STRUCT_BEGIN struct tcp_hdr PACK_STRUCT_STRUCT
 
struct tcp_pcbtcp_active_pcbs
 List of all TCP PCBs that are in a state in which they accept or send data. More...
 
u8_t tcp_active_pcbs_changed
 
struct tcp_pcbtcp_bound_pcbs
 List of all TCP PCBs bound but not yet (connected || listening) More...
 
struct tcp_pcbtcp_input_pcb
 
union tcp_listen_pcbs_t tcp_listen_pcbs
 List of all TCP PCBs in LISTEN state. More...
 
u32_t tcp_ticks
 
struct tcp_pcbtcp_tmp_pcb
 Only used for temporary storage. More...
 
struct tcp_pcbtcp_tw_pcbs
 List of all TCP PCBs in TIME-WAIT state. More...
 

#define LWIP_TCP_OPT_EOL   0

Referenced by tcp_parseopt().

#define LWIP_TCP_OPT_LEN_MSS   4

Referenced by tcp_parseopt().

#define LWIP_TCP_OPT_LEN_TS_OUT   0
#define LWIP_TCP_OPT_LEN_WS_OUT   0
#define LWIP_TCP_OPT_LENGTH (   flags)
Value:
#define LWIP_TCP_OPT_LEN_MSS
Definition: tcp_impl.h:307
#define TF_SEG_OPTS_WND_SCALE
Definition: tcp_impl.h:297
#define TF_SEG_OPTS_MSS
Definition: tcp_impl.h:293
#define LWIP_TCP_OPT_LEN_WS_OUT
Definition: tcp_impl.h:318
#define TF_SEG_OPTS_TS
Definition: tcp_impl.h:294
#define LWIP_TCP_OPT_LEN_TS_OUT
Definition: tcp_impl.h:312
static u8_t flags
Definition: tcp_in.c:76

Referenced by tcp_create_segment(), tcp_enqueue_flags(), tcp_send_empty_ack(), and tcp_write().

#define LWIP_TCP_OPT_MSS   2

Referenced by tcp_parseopt().

#define LWIP_TCP_OPT_NOP   1

Referenced by tcp_parseopt().

#define LWIP_TCP_OPT_TS   8

Referenced by tcp_parseopt().

#define LWIP_TCP_OPT_WS   3

Referenced by tcp_parseopt().

#define tcp_ack (   pcb)
Value:
do { \
if((pcb)->flags & TF_ACK_DELAY) { \
(pcb)->flags &= ~TF_ACK_DELAY; \
(pcb)->flags |= TF_ACK_NOW; \
} \
else { \
(pcb)->flags |= TF_ACK_DELAY; \
} \
} while (0)
#define TF_ACK_DELAY
Definition: tcp.h:192
#define TF_ACK_NOW
Definition: tcp.h:193
if(memp!=NULL)
Definition: memp.c:426
else
Definition: memp.c:437
static u8_t flags
Definition: tcp_in.c:76

Referenced by tcp_receive().

#define tcp_ack_now (   pcb)
Value:
do { \
(pcb)->flags |= TF_ACK_NOW; \
} while (0)
#define TF_ACK_NOW
Definition: tcp.h:193
static u8_t flags
Definition: tcp_in.c:76

Referenced by tcp_fasttmr(), tcp_process(), tcp_receive(), and tcp_recved().

#define TCP_BUILD_MSS_OPTION (   mss)    htonl(0x02040000 | ((mss) & 0xFFFF))

This returns a TCP header option for MSS in an u32_t.

Referenced by tcp_output_segment().

#define TCP_CHECKSUM_ON_COPY   (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)

Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled.

#define TCP_CWR   0x80U
#define TCP_DEBUG_PCB_LISTS   0
#define tcp_debug_print (   tcphdr)

Referenced by tcp_input().

#define tcp_debug_print_flags (   flags)

Referenced by tcp_input().

#define tcp_debug_print_pcbs ( )
#define tcp_debug_print_state (   s)

Referenced by tcp_close(), and tcp_input().

#define tcp_do_output_nagle (   tpcb)
Value:
((((tpcb)->unacked == NULL) || \
((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \
(((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \
((tpcb)->unsent->len >= (tpcb)->mss))) || \
((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \
) ? 1 : 0)
#define TF_INFR
Definition: tcp.h:194
#define TCP_SND_QUEUELEN
TCP_SND_QUEUELEN: TCP sender buffer space (pbufs).
Definition: lwipopts.h:209
#define tcp_sndqueuelen(pcb)
Definition: tcp.h:352
#define TF_NODELAY
Definition: tcp.h:198
#define NULL
Definition: nm_bsp.h:70
#define tcp_sndbuf(pcb)
Definition: tcp.h:351
static u8_t flags
Definition: tcp_in.c:76

This is the Nagle algorithm: try to combine user data to send as few TCP segments as possible.

Only send if

  • no previously transmitted data on the connection remains unacknowledged or
  • the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or
  • the only unsent segment is at least pcb->mss bytes long (or there is more than one unsent segment - with lwIP, this can happen although unsent->len < mss)
  • or if we are in fast-retransmit (TF_INFR)

Referenced by tcp_output().

#define TCP_ECE   0x40U
#define tcp_eff_send_mss (   sendmss,
  src,
  dest,
  isipv6 
)    tcp_eff_send_mss_impl(sendmss, dest, src, isipv6)
#define TCP_EVENT_ACCEPT (   pcb,
  err,
  ret 
)
Value:
do { \
if((pcb)->accept != NULL) \
(ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \
else (ret) = ERR_ARG; \
} while (0)
#define ERR_ARG
Definition: err.h:72
if(memp!=NULL)
Definition: memp.c:426
#define NULL
Definition: nm_bsp.h:70
else
Definition: memp.c:437

Referenced by tcp_process().

#define TCP_EVENT_CLOSED (   pcb,
  ret 
)
Value:
do { \
if(((pcb)->recv != NULL)) { \
(ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\
} else { \
(ret) = ERR_OK; \
} \
} while (0)
#define ERR_OK
Definition: err.h:52
if(memp!=NULL)
Definition: memp.c:426
#define NULL
Definition: nm_bsp.h:70

Referenced by tcp_input(), and tcp_process_refused_data().

#define TCP_EVENT_CONNECTED (   pcb,
  err,
  ret 
)
Value:
do { \
if((pcb)->connected != NULL) \
(ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \
else (ret) = ERR_OK; \
} while (0)
#define ERR_OK
Definition: err.h:52
if(memp!=NULL)
Definition: memp.c:426
#define NULL
Definition: nm_bsp.h:70
else
Definition: memp.c:437

Referenced by tcp_process().

#define TCP_EVENT_ERR (   errf,
  arg,
  err 
)
Value:
do { \
if((errf) != NULL) \
(errf)((arg),(err)); \
} while (0)
if(memp!=NULL)
Definition: memp.c:426
timeout arg
Definition: lwip/lwip-1.4.1-dev/src/core/timers.c:351
#define NULL
Definition: nm_bsp.h:70

Referenced by tcp_abandon(), tcp_input(), and tcp_slowtmr().

#define TCP_EVENT_POLL (   pcb,
  ret 
)
Value:
do { \
if((pcb)->poll != NULL) \
(ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \
else (ret) = ERR_OK; \
} while (0)
#define ERR_OK
Definition: err.h:52
if(memp!=NULL)
Definition: memp.c:426
#define NULL
Definition: nm_bsp.h:70
else
Definition: memp.c:437

Referenced by tcp_slowtmr().

#define TCP_EVENT_RECV (   pcb,
  p,
  err,
  ret 
)
Value:
do { \
if((pcb)->recv != NULL) { \
(ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\
} else { \
(ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \
} \
} while (0)
err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
Default receive callback that is called if the user didn&#39;t register a recv callback for the pcb...
Definition: tcp.c:1268
if(memp!=NULL)
Definition: memp.c:426
#define NULL
Definition: nm_bsp.h:70

Referenced by tcp_input(), and tcp_process_refused_data().

#define TCP_EVENT_SENT (   pcb,
  space,
  ret 
)
Value:
do { \
if((pcb)->sent != NULL) \
(ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \
else (ret) = ERR_OK; \
} while (0)
#define ERR_OK
Definition: err.h:52
if(memp!=NULL)
Definition: memp.c:426
#define NULL
Definition: nm_bsp.h:70
else
Definition: memp.c:437

Referenced by tcp_input().

#define TCP_FAST_INTERVAL   TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */
#define TCP_FIN_WAIT_TIMEOUT   20000 /* milliseconds */

Referenced by tcp_slowtmr().

#define TCP_FLAGS   0x3fU
#define TCP_KEEPCNT_DEFAULT   9U /* Default Counter for KEEPALIVE probes */

Referenced by tcp_alloc().

#define TCP_KEEPIDLE_DEFAULT   7200000UL /* Default KEEPALIVE timer in milliseconds */

Referenced by tcp_alloc().

#define TCP_KEEPINTVL_DEFAULT   75000UL /* Default Time between KEEPALIVE probes in milliseconds */

Referenced by tcp_alloc().

#define TCP_MAXIDLE   TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */
#define TCP_MSL   60000UL /* The maximum segment lifetime in milliseconds */

Referenced by tcp_slowtmr().

#define TCP_OOSEQ_TIMEOUT   6U /* x RTO */

Referenced by tcp_slowtmr().

#define tcp_output_nagle (   tpcb)    (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK)
#define TCP_OVERSIZE_DBGCHECK   0

Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled.

#define TCP_PCB_REMOVE_ACTIVE (   pcb)
Value:
do { \
} while (0)
void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
Purges the PCB and removes it from a PCB list.
Definition: tcp.c:1650
u8_t tcp_active_pcbs_changed
Definition: tcp.c:122
struct tcp_pcb * tcp_active_pcbs
List of all TCP PCBs that are in a state in which they accept or send data.
Definition: tcp.c:109

Referenced by tcp_abandon(), and tcp_close_shutdown().

#define tcp_pcbs_sane ( )    1

Referenced by tcp_input(), and tcp_pcb_remove().

#define TCP_PSH   0x08U

Referenced by tcp_input(), and tcp_write().

#define TCP_REG (   pcbs,
  npcb 
)
Value:
do { \
(npcb)->next = *pcbs; \
*(pcbs) = (npcb); \
} while (0)
void tcp_timer_needed(void)
Called from TCP_REG when registering a new PCB: the reason is to have the TCP timer only running when...
Definition: lwip/lwip-1.4.1-dev/src/core/timers.c:103
timeout next
Definition: lwip/lwip-1.4.1-dev/src/core/timers.c:349

Referenced by tcp_bind(), tcp_close_shutdown(), tcp_listen_with_backlog(), and tcp_process().

#define TCP_REG_ACTIVE (   npcb)
Value:
do { \
} while (0)
u8_t tcp_active_pcbs_changed
Definition: tcp.c:122
#define TCP_REG(pcbs, npcb)
Definition: tcp_impl.h:400
struct tcp_pcb * tcp_active_pcbs
List of all TCP PCBs that are in a state in which they accept or send data.
Definition: tcp.c:109

Referenced by tcp_connect(), and tcp_listen_input().

#define TCP_RMV (   pcbs,
  npcb 
)
Value:
do { \
if(*(pcbs) == (npcb)) { \
(*(pcbs)) = (*pcbs)->next; \
} \
else { \
for(tcp_tmp_pcb = *pcbs; \
if(tcp_tmp_pcb->next == (npcb)) { \
tcp_tmp_pcb->next = (npcb)->next; \
break; \
} \
} \
} \
(npcb)->next = NULL; \
} while(0)
struct tcp_pcb * tcp_tmp_pcb
Only used for temporary storage.
Definition: tcp.c:120
timeout next
Definition: lwip/lwip-1.4.1-dev/src/core/timers.c:349
if(memp!=NULL)
Definition: memp.c:426
#define NULL
Definition: nm_bsp.h:70
else
Definition: memp.c:437

Referenced by tcp_abandon(), tcp_close_shutdown(), tcp_connect(), tcp_listen_with_backlog(), and tcp_pcb_remove().

#define TCP_RMV_ACTIVE (   npcb)
Value:
do { \
} while (0)
#define TCP_RMV(pcbs, npcb)
Definition: tcp_impl.h:407
u8_t tcp_active_pcbs_changed
Definition: tcp.c:122
struct tcp_pcb * tcp_active_pcbs
List of all TCP PCBs that are in a state in which they accept or send data.
Definition: tcp.c:109

Referenced by tcp_close_shutdown(), and tcp_process().

#define tcp_rst (   seqno,
  ackno,
  local_ip,
  remote_ip,
  local_port,
  remote_port,
  isipv6 
)    tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6)
#define TCP_SEQ_BETWEEN (   a,
  b,
 
)    (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c))
#define TCP_SEQ_GEQ (   a,
 
)    ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0)
#define TCP_SEQ_GT (   a,
 
)    ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0)
#define TCP_SEQ_LEQ (   a,
 
)    ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0)

Referenced by tcp_receive().

#define TCP_SEQ_LT (   a,
 
)    ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0)

Referenced by tcp_output(), tcp_receive(), and tcp_rexmit().

#define TCP_SLOW_INTERVAL   (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */

Referenced by tcp_alloc(), tcp_receive(), and tcp_slowtmr().

#define TCP_SYN_RCVD_TIMEOUT   20000 /* milliseconds */

Referenced by tcp_slowtmr().

#define TCP_TCPLEN (   seg)    ((seg)->len + (((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0) ? 1U : 0U))
#define TCP_TMR_INTERVAL   250 /* The TCP timer interval in milliseconds. */
#define TCP_URG   0x20U
#define TCPH_FLAGS (   phdr)    (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)
#define TCPH_FLAGS_SET (   phdr,
  flags 
)    (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags))
#define TCPH_HDRLEN (   phdr)    (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)
#define TCPH_HDRLEN_FLAGS_SET (   phdr,
  len,
  flags 
)    (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags))
#define TCPH_HDRLEN_SET (   phdr,
  len 
)    (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr))
#define TCPH_SET_FLAG (   phdr,
  flags 
)    (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags))
#define TCPH_UNSET_FLAG (   phdr,
  flags 
)    (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) )
#define TCPWND_MAX   0xFFFFU
#define TCPWNDSIZE_F   U16_F
#define TF_CLOSED   (u8_t)0x10U /* Connection was successfully closed. */

Referenced by tcp_input(), and tcp_process().

#define TF_GOT_FIN   (u8_t)0x20U /* Connection was closed by the remote end. */

Referenced by tcp_input(), tcp_process(), and tcp_receive().

#define TF_RESET   (u8_t)0x08U /* Connection was reset. */

Flags used on input processing, not on pcb->flags.

Referenced by tcp_input(), and tcp_process().

#define TF_SEG_DATA_CHECKSUMMED
Value:
(u8_t)0x04U /* ALL data (not the header) is
checksummed into 'chksum' */
unsigned char u8_t
Definition: cc.h:47

Referenced by tcp_create_segment(), tcp_output_segment(), and tcp_write().

#define TF_SEG_OPTS_MSS   (u8_t)0x01U /* Include MSS option. */
#define TF_SEG_OPTS_TS   (u8_t)0x02U /* Include timestamp option. */
#define TF_SEG_OPTS_WND_SCALE   (u8_t)0x08U /* Include WND SCALE option */

void tcp_abandon ( struct tcp_pcb pcb,
int  reset 
)

Abandons a connection and optionally sends a RST to the remote host.

Deletes the local protocol control block. This is done when a connection is killed because of shortage of memory.

Parameters
pcbthe tcp_pcb to abort
resetboolean to indicate whether a reset should be sent

References ackno, CLOSED, ERR_ABRT, tcp_pcb::errf, LISTEN, LWIP_ASSERT, LWIP_DEBUGF, memp_free(), NULL, tcp_pcb::ooseq, PCB_ISIPV6, tcp_pcb::rcv_nxt, tcp_pcb::remote_port, seqno, tcp_pcb::snd_nxt, TCP_EVENT_ERR, tcp_pcb_remove(), TCP_PCB_REMOVE_ACTIVE, TCP_RMV, tcp_rst, TCP_RST_DEBUG, tcp_segs_free(), TIME_WAIT, tcp_pcb::unacked, and tcp_pcb::unsent.

Referenced by tcp_abort(), and tcp_listen_input().

u16_t tcp_eff_send_mss_impl ( u16_t  sendmss,
ipX_addr_t dest,
ipX_addr_t src,
u8_t  isipv6 
)

Calculates the effective send mss that can be used for a specific IP address by using ip_route to determine the netif used to send to the address and calculating the minimum of TCP_MSS and that netif's mtu (if set).

References IP6_HLEN, IP_HLEN, ipX_2_ip6, ipX_route, LWIP_MIN, netif::mtu, nd6_get_destination_mtu(), NULL, and TCP_HLEN.

err_t tcp_enqueue_flags ( struct tcp_pcb pcb,
u8_t  flags 
)
void tcp_fasttmr ( void  )

Is called every TCP_FAST_INTERVAL (250 ms) and process data previously "refused" by upper layer (application) and sends delayed ACKs.

Automatically called from tcp_tmr().

References tcp_pcb::flags, tcp_pcb::last_timer, LWIP_DEBUGF, next, NULL, tcp_pcb::refused_data, tcp_ack_now, tcp_active_pcbs, tcp_active_pcbs_changed, TCP_DEBUG, tcp_output(), tcp_process_refused_data(), tcp_timer_ctr, TF_ACK_DELAY, and TF_ACK_NOW.

Referenced by tcp_tmr().

void tcp_init ( void  )

Initialize this module.

References LWIP_RAND, TCP_ENSURE_LOCAL_PORT_RANGE, and tcp_port.

Referenced by lwip_init().

void tcp_input ( struct pbuf p,
struct netif inp 
)

The initial input processing of TCP.

It verifies the TCP header, demultiplexes the segment between the PCBs and passes it on to tcp_process(), which implements the TCP finite state machine. This function is called by the IP layer (in ip_input()).

Parameters
preceived TCP segment to process (p->payload pointing to the TCP header)
inpnetwork interface on which this segment was received

References tcp_pcb_listen::accept_any_ip_version, tcp_pcb::acked, ackno, CLOSED, ERR_ABRT, ERR_CLSD, ERR_OK, ERR_RST, tcp_pcb::errf, flags, pbuf::flags, tcp_pcb::flags, inseg, ip_addr_isbroadcast, ip_current_dest_addr, ip_current_is_v6, IP_PCB_IPVER_INPUT_MATCH, IP_PROTO_TCP, ipX_addr_cmp, ipX_addr_isany, ipX_addr_ismulticast, ipX_chksum_pseudo, ipX_current_dest_addr, ipX_current_src_addr, pbuf::len, tcp_seg::len, LISTEN, tcp_listen_pcbs_t::listen_pcbs, LWIP_ASSERT, LWIP_DEBUGF, LWIP_MIN, memp_free(), pbuf::next, tcp_seg::next, ntohl, ntohs, NULL, tcp_seg::p, pbuf::payload, pbuf_cat(), PBUF_FLAG_PUSH, PBUF_FLAG_TCP_FIN, pbuf_free(), pbuf_header(), PERF_START, PERF_STOP, tcp_pcb::rcv_wnd, recv_data, recv_flags, tcp_pcb::refused_data, tcp_pcb::remote_port, seqno, snmp_inc_tcpinerrs, snmp_inc_tcpinsegs, tcp_abort(), tcp_active_pcbs, tcp_debug_print, tcp_debug_print_flags, tcp_debug_print_state, TCP_EVENT_CLOSED, TCP_EVENT_ERR, TCP_EVENT_RECV, TCP_EVENT_SENT, TCP_FIN, TCP_HLEN, TCP_INPUT_DEBUG, tcp_listen_input(), tcp_listen_pcbs, tcp_output(), tcp_pcb_remove(), tcp_pcbs_sane, tcp_process(), tcp_process_refused_data(), TCP_PSH, TCP_RST, tcp_rst, TCP_RST_DEBUG, TCP_STATS_INC, TCP_SYN, tcp_timewait_input(), tcp_tw_pcbs, TCP_WND, TCPH_FLAGS, TCPH_HDRLEN, tcphdr, tcp_seg::tcphdr, tcphdr_opt1len, tcphdr_opt2, tcplen, TF_CLOSED, TF_GOT_FIN, TF_RESET, TF_RXCLOSED, TIME_WAIT, pbuf::tot_len, U16_F, and X16_F.

Referenced by ip6_input(), and ip_input().

void tcp_keepalive ( struct tcp_pcb pcb)

Send keepalive packets to keep a connection active although no data is sent over it.

Called by tcp_slowtmr()

Parameters
pcbthe tcp_pcb for which to send a keepalive packet

References htonl, IP_PROTO_TCP, ipX_addr_debug_print, ipX_chksum_pseudo, ipX_output, ipX_output_hinted, tcp_pcb::keep_cnt_sent, LWIP_DEBUGF, NULL, pbuf::payload, pbuf_free(), PCB_ISIPV6, tcp_pcb::rcv_nxt, tcp_pcb::snd_nxt, TCP_DEBUG, tcp_output_alloc_header(), TCP_STATS_INC, tcp_ticks, tcphdr, tcp_pcb::tmr, pbuf::tot_len, U16_F, and U32_F.

Referenced by tcp_slowtmr().

u32_t tcp_next_iss ( void  )

Calculates a new initial sequence number for new connections.

Returns
u32_t pseudo random sequence number

References tcp_ticks.

Referenced by tcp_alloc(), and tcp_connect().

struct tcp_pcb* tcp_pcb_copy ( struct tcp_pcb pcb)
void tcp_pcb_purge ( struct tcp_pcb pcb)

Purges a TCP PCB.

Removes any buffered data and frees the buffer memory (pcb->ooseq, pcb->unsent and pcb->unacked are freed).

Parameters
pcbtcp_pcb to purge. The pcb itself is not deallocated!

References CLOSED, IP_PCB_IPVER_EQ, ipX_addr_cmp, ipX_addr_isany, LISTEN, tcp_listen_pcbs_t::listen_pcbs, LWIP_ASSERT, LWIP_DEBUGF, NULL, tcp_pcb::ooseq, pbuf_free(), PCB_ISIPV6, tcp_pcb::refused_data, tcp_pcb::rtime, SYN_RCVD, TCP_DEBUG, tcp_listen_pcbs, tcp_segs_free(), TIME_WAIT, tcp_pcb::unacked, tcp_pcb::unsent, and tcp_pcb::unsent_oversize.

Referenced by tcp_close_shutdown(), tcp_pcb_remove(), tcp_process(), and tcp_slowtmr().

void tcp_pcb_remove ( struct tcp_pcb **  pcblist,
struct tcp_pcb pcb 
)

Purges the PCB and removes it from a PCB list.

Any delayed ACKs are sent first.

Parameters
pcblistPCB list to purge.
pcbtcp_pcb to purge. The pcb itself is NOT deallocated!

References CLOSED, tcp_pcb::flags, LISTEN, LWIP_ASSERT, NULL, tcp_pcb::ooseq, tcp_output(), tcp_pcb_purge(), tcp_pcbs_sane, TCP_RMV, TF_ACK_DELAY, TF_ACK_NOW, TIME_WAIT, tcp_pcb::unacked, and tcp_pcb::unsent.

Referenced by tcp_abandon(), tcp_close_shutdown(), and tcp_input().

err_t tcp_process_refused_data ( struct tcp_pcb pcb)
err_t tcp_recv_null ( void arg,
struct tcp_pcb pcb,
struct pbuf p,
err_t  err 
)

Default receive callback that is called if the user didn't register a recv callback for the pcb.

References ERR_OK, NULL, pbuf_free(), tcp_close(), tcp_recved(), and pbuf::tot_len.

Referenced by tcp_alloc().

void tcp_rexmit ( struct tcp_pcb pcb)

Requeue the first unacked segment for retransmission.

Called by tcp_receive() for fast retramsmit.

Parameters
pcbthe tcp_pcb for which to retransmit the first unacked segment

References tcp_seg::next, tcp_pcb::nrtx, ntohl, NULL, tcp_pcb::rttest, snmp_inc_tcpretranssegs, TCP_SEQ_LT, tcp_seg::tcphdr, tcp_pcb::unacked, tcp_pcb::unsent, and tcp_pcb::unsent_oversize.

Referenced by tcp_process(), and tcp_rexmit_fast().

void tcp_rexmit_fast ( struct tcp_pcb pcb)

Handle retransmission after three dupacks received.

Parameters
pcbthe tcp_pcb for which to retransmit the first unacked segment

References tcp_pcb::cwnd, tcp_pcb::dupacks, tcp_pcb::flags, tcp_pcb::lastack, LWIP_DEBUGF, tcp_pcb::mss, ntohl, NULL, tcp_pcb::snd_wnd, tcp_pcb::ssthresh, TCP_FR_DEBUG, tcp_rexmit(), tcp_seg::tcphdr, TF_INFR, U16_F, U32_F, and tcp_pcb::unacked.

Referenced by tcp_receive().

void tcp_rexmit_rto ( struct tcp_pcb pcb)

Requeue all unacked segments for retransmission.

Called by tcp_slowtmr() for slow retransmission.

Parameters
pcbthe tcp_pcb for which to re-enqueue all unacked segments

References tcp_seg::next, tcp_pcb::nrtx, NULL, tcp_pcb::rttest, tcp_output(), tcp_pcb::unacked, tcp_pcb::unsent, and tcp_pcb::unsent_oversize.

Referenced by tcp_slowtmr().

void tcp_rexmit_seg ( struct tcp_pcb pcb,
struct tcp_seg seg 
)
void tcp_rst_impl ( u32_t  seqno,
u32_t  ackno,
ipX_addr_t local_ip,
ipX_addr_t remote_ip,
u16_t  local_port,
u16_t  remote_port,
u8_t  isipv6 
)

Send a TCP RESET packet (empty segment with RST flag set) either to abort a connection or to show that there is no matching local connection for a received segment.

Called by tcp_abort() (to abort a local connection), tcp_input() (if no matching local pcb was found), tcp_listen_input() (if incoming segment has ACK flag set) and tcp_process() (received segment in the wrong state)

Since a RST segment is in most cases not sent for an active connection, tcp_rst() has a number of arguments that are taken from a tcp_pcb for most other segment output functions.

Parameters
seqnothe sequence number to use for the outgoing segment
acknothe acknowledge number to use for the outgoing segment
local_ipthe local IP address to send the segment from
remote_ipthe remote IP address to send the segment to
local_portthe local TCP port to send the segment from
remote_portthe remote TCP port to send the segment to

References htonl, htons, IP_PROTO_TCP, ipX_chksum_pseudo, ipX_output, pbuf::len, LWIP_ASSERT, LWIP_DEBUGF, NULL, pbuf::payload, pbuf_alloc(), pbuf_free(), PBUF_IP, PBUF_RAM, PP_HTONS, snmp_inc_tcpoutrsts, TCP_ACK, TCP_DEBUG, TCP_HLEN, TCP_RST, TCP_RST_DEBUG, TCP_STATS_INC, TCP_WND, TCPH_HDRLEN_FLAGS_SET, tcphdr, pbuf::tot_len, and U32_F.

struct tcp_seg* tcp_seg_copy ( struct tcp_seg seg)

Returns a copy of the given TCP segment.

The pbuf and data are not copied, only the pointers

Parameters
segthe old tcp_seg
Returns
a copy of seg

References memp_malloc(), NULL, tcp_seg::p, and pbuf_ref().

Referenced by tcp_receive().

void tcp_seg_free ( struct tcp_seg seg)

Frees a TCP segment (tcp_seg structure).

Parameters
segsingle tcp_seg to free

References memp_free(), NULL, tcp_seg::p, and pbuf_free().

Referenced by tcp_create_segment(), tcp_oos_insert_segment(), tcp_output(), tcp_process(), tcp_receive(), and tcp_segs_free().

void tcp_segs_free ( struct tcp_seg seg)

Deallocates a list of TCP segments (tcp_seg structures).

Parameters
segtcp_seg list of TCP segments to free

References tcp_seg::next, next, NULL, and tcp_seg_free().

Referenced by pbuf_free_ooseq(), tcp_abandon(), tcp_oos_insert_segment(), tcp_pcb_purge(), tcp_receive(), tcp_slowtmr(), and tcp_write().

err_t tcp_send_empty_ack ( struct tcp_pcb pcb)
err_t tcp_send_fin ( struct tcp_pcb pcb)

Called by tcp_close() to send a segment including FIN flag but not data.

Parameters
pcbthe tcp_pcb over which to send a segment
Returns
ERR_OK if sent, another err_t otherwise

References ERR_OK, tcp_pcb::flags, tcp_seg::next, NULL, tcp_enqueue_flags(), TCP_FIN, TCP_RST, TCP_SYN, TCPH_FLAGS, TCPH_SET_FLAG, tcp_seg::tcphdr, TF_FIN, and tcp_pcb::unsent.

Referenced by tcp_close_shutdown().

void tcp_timer_needed ( void  )

External function (implemented in timers.c), called when TCP detects that a timer is needed (i.e.

active- or time-wait-pcb found).

External function (implemented in timers.c), called when TCP detects that a timer is needed (i.e.

References NULL, sys_timeout(), tcp_active_pcbs, TCP_TMR_INTERVAL, tcp_tw_pcbs, tcpip_tcp_timer(), and tcpip_tcp_timer_active.

void tcp_tmr ( void  )

Called periodically to dispatch TCP timers.

References tcp_fasttmr(), tcp_slowtmr(), and tcp_timer.

Referenced by tcpip_tcp_timer().

u32_t tcp_update_rcv_ann_wnd ( struct tcp_pcb pcb)

Update the state that tracks the available window space to advertise.

Returns how much extra window would be advertised if we sent an update now.

References LWIP_ASSERT, LWIP_MIN, tcp_pcb::mss, tcp_pcb::rcv_ann_right_edge, tcp_pcb::rcv_ann_wnd, tcp_pcb::rcv_nxt, tcp_pcb::rcv_wnd, TCP_SEQ_GEQ, TCP_SEQ_GT, and TCP_WND.

Referenced by tcp_receive(), and tcp_recved().

void tcp_zero_window_probe ( struct tcp_pcb pcb)

PACK_STRUCT_BEGIN struct tcp_hdr PACK_STRUCT_STRUCT
struct tcp_pcb* tcp_active_pcbs

List of all TCP PCBs that are in a state in which they accept or send data.

Referenced by netif_set_ipaddr(), pbuf_free_ooseq(), tcp_fasttmr(), tcp_input(), tcp_slowtmr(), tcp_timer_needed(), and tcpip_tcp_timer().

u8_t tcp_active_pcbs_changed

Referenced by tcp_fasttmr(), and tcp_slowtmr().

struct tcp_pcb* tcp_bound_pcbs

List of all TCP PCBs bound but not yet (connected || listening)

struct tcp_pcb* tcp_input_pcb

Referenced by tcp_output().

union tcp_listen_pcbs_t tcp_listen_pcbs

List of all TCP PCBs in LISTEN state.

Referenced by netif_set_ipaddr(), tcp_close_shutdown(), tcp_input(), tcp_listen_with_backlog(), and tcp_pcb_purge().

struct tcp_pcb* tcp_tmp_pcb

Only used for temporary storage.

struct tcp_pcb* tcp_tw_pcbs

List of all TCP PCBs in TIME-WAIT state.

Referenced by tcp_input(), tcp_process(), tcp_slowtmr(), tcp_timer_needed(), and tcpip_tcp_timer().