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"

Data Structures

struct  tcp_hdr
 
union  tcp_listen_pcbs_t
 
struct  tcp_seg
 

Macros

#define LWIP_TCP_OPT_LENGTH(flags)
 
#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_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_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))
 
#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 TF_CLOSED   (u8_t)0x10U /* Connection was sucessfully 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. */
 

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 (u16_t sendmss, ip_addr_t *addr)
 Calcluates the effective send mss that can be used for a specific IP address by using ip_route to determin 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 (u32_t seqno, u32_t ackno, ip_addr_t *local_ip, ip_addr_t *remote_ip, u16_t local_port, u16_t remote_port)
 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_LENGTH (   flags)
Value:
(flags & TF_SEG_OPTS_MSS ? 4 : 0) + \
(flags & TF_SEG_OPTS_TS ? 12 : 0)
#define TF_SEG_OPTS_MSS
Definition: tcp_impl.h:291
#define TF_SEG_OPTS_TS
Definition: tcp_impl.h:292
static u8_t flags
Definition: tcp_in.c:66

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

#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:178
#define TF_ACK_NOW
Definition: tcp.h:179
if(timeout==NULL)
Definition: lwip_timers_141.c:274
else
Definition: memp.c:418
static u8_t flags
Definition: tcp_in.c:66

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:179
static u8_t flags
Definition: tcp_in.c:66

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 NULL
Definition: def.h:47
#define TF_INFR
Definition: tcp.h:180
#define tcp_sndqueuelen(pcb)
Definition: tcp.h:327
#define TF_NODELAY
Definition: tcp.h:184
#define tcp_sndbuf(pcb)
Definition: tcp.h:326
static u8_t flags
Definition: tcp_in.c:66

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_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 NULL
Definition: def.h:47
if(timeout==NULL)
Definition: lwip_timers_141.c:274
#define ERR_ARG
Definition: err.h:70
else
Definition: memp.c:418

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 NULL
Definition: def.h:47
#define ERR_OK
Definition: err.h:52
if(timeout==NULL)
Definition: lwip_timers_141.c:274

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 NULL
Definition: def.h:47
#define ERR_OK
Definition: err.h:52
if(timeout==NULL)
Definition: lwip_timers_141.c:274
else
Definition: memp.c:418

Referenced by tcp_process().

#define TCP_EVENT_ERR (   errf,
  arg,
  err 
)
Value:
do { \
if((errf) != NULL) \
(errf)((arg),(err)); \
} while (0)
#define NULL
Definition: def.h:47
if(timeout==NULL)
Definition: lwip_timers_141.c:274
timeout arg
Definition: lwip_timers_141.c:280

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 NULL
Definition: def.h:47
#define ERR_OK
Definition: err.h:52
if(timeout==NULL)
Definition: lwip_timers_141.c:274
else
Definition: memp.c:418

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)
#define NULL
Definition: def.h:47
if(timeout==NULL)
Definition: lwip_timers_141.c:274
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:1197

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 NULL
Definition: def.h:47
#define ERR_OK
Definition: err.h:52
if(timeout==NULL)
Definition: lwip_timers_141.c:274
else
Definition: memp.c:418

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:1538
u8_t tcp_active_pcbs_changed
Definition: tcp.c:119
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:106

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_timers_141.c:103
timeout next
Definition: lwip_timers_141.c:278

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:119
#define TCP_REG(pcbs, npcb)
Definition: tcp_impl.h:368
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:106

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)
#define NULL
Definition: def.h:47
struct tcp_pcb * tcp_tmp_pcb
Only used for temporary storage.
Definition: tcp.c:117
if(timeout==NULL)
Definition: lwip_timers_141.c:274
timeout next
Definition: lwip_timers_141.c:278
else
Definition: memp.c:418

Referenced by 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:375
u8_t tcp_active_pcbs_changed
Definition: tcp.c:119
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:106

Referenced by tcp_close_shutdown(), and tcp_process().

#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))
#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 TF_CLOSED   (u8_t)0x10U /* Connection was sucessfully 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' */
uint8_t u8_t
Definition: cc.h:44

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. */

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, ERR_ABRT, tcp_pcb::errf, LISTEN, LWIP_ASSERT, LWIP_DEBUGF, memp_free(), NULL, tcp_pcb::ooseq, tcp_pcb::rcv_nxt, tcp_pcb::remote_port, seqno, tcp_pcb::snd_nxt, TCP_EVENT_ERR, tcp_pcb_remove(), TCP_PCB_REMOVE_ACTIVE, 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 ( u16_t  sendmss,
ip_addr_t addr 
)

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

References IP_HLEN, ip_route(), LWIP_MIN, netif::mtu, NULL, and TCP_HLEN.

Referenced by tcp_connect(), tcp_listen_input(), tcp_output_segment(), and tcp_process().

err_t tcp_enqueue_flags ( struct tcp_pcb pcb,
u8_t  flags 
)

Enqueue TCP options for transmission.

Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().

Parameters
pcbProtocol control block for the TCP connection.
flagsTCP header flags to set in the outgoing segment.
optdatapointer to TCP options, or NULL.
optlenlength of TCP options in bytes.

References ERR_MEM, ERR_OK, tcp_pcb::flags, pbuf::len, tcp_seg::len, LWIP_ASSERT, LWIP_DBG_TRACE, LWIP_DEBUGF, LWIP_TCP_OPT_LENGTH, MEM_ALIGNMENT, tcp_seg::next, ntohl, NULL, tcp_seg::p, pbuf_alloc(), pbuf_clen(), PBUF_RAM, PBUF_TRANSPORT, S16_F, tcp_pcb::snd_buf, tcp_pcb::snd_lbb, tcp_pcb::snd_queuelen, tcp_create_segment(), TCP_FIN, TCP_OUTPUT_DEBUG, TCP_QLEN_DEBUG, TCP_SNDQUEUELEN_OVERFLOW, TCP_STATS_INC, TCP_SYN, TCP_TCPLEN, tcp_seg::tcphdr, TF_FIN, TF_NAGLEMEMERR, TF_SEG_OPTS_MSS, TF_SEG_OPTS_TS, TF_TIMESTAMP, U16_F, U32_F, tcp_pcb::unacked, tcp_pcb::unsent, tcp_pcb::unsent_oversize, and X16_F.

Referenced by tcp_connect(), tcp_listen_input(), and tcp_send_fin().

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 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 IP header)
inpnetwork interface on which this segment was received

References tcp_pcb::acked, ackno, CLOSED, current_iphdr_dest, current_iphdr_src, ERR_ABRT, ERR_CLSD, ERR_OK, ERR_RST, tcp_pcb::errf, flags, pbuf::flags, tcp_pcb::flags, inet_chksum_pseudo(), inseg, ip_addr_cmp, ip_addr_isany, ip_addr_isbroadcast, ip_addr_ismulticast, ip_current_dest_addr, ip_current_src_addr, IP_PROTO_TCP, IPH_HL, tcp_seg::len, LISTEN, tcp_listen_pcbs_t::listen_pcbs, LWIP_ASSERT, LWIP_DEBUGF, memp_free(), tcp_seg::next, ntohl, ntohs, NULL, tcp_seg::p, pbuf::payload, 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_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, tcplen, TF_CLOSED, TF_GOT_FIN, TF_RESET, TF_RXCLOSED, TIME_WAIT, pbuf::tot_len, U16_F, and X16_F.

Referenced by 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 CHECKSUM_GEN_TCP, htonl, inet_chksum_pseudo(), ip4_addr1_16, ip4_addr2_16, ip4_addr3_16, ip4_addr4_16, ip_output(), IP_PROTO_TCP, tcp_pcb::keep_cnt_sent, LWIP_DEBUGF, NULL, pbuf::payload, pbuf_free(), 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_addr_cmp, ip_addr_isany, LISTEN, tcp_listen_pcbs_t::listen_pcbs, LWIP_ASSERT, LWIP_DEBUGF, NULL, tcp_pcb::ooseq, pbuf_free(), 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, LWIP_UNUSED_ARG, 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, and tcp_pcb::unsent.

Referenced by tcp_slowtmr().

void tcp_rexmit_seg ( struct tcp_pcb pcb,
struct tcp_seg seg 
)
void tcp_rst ( u32_t  seqno,
u32_t  ackno,
ip_addr_t local_ip,
ip_addr_t remote_ip,
u16_t  local_port,
u16_t  remote_port 
)

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, inet_chksum_pseudo(), ip_output(), IP_PROTO_TCP, 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.

Referenced by tcp_abandon(), tcp_close_shutdown(), tcp_input(), tcp_listen_input(), tcp_process(), tcp_slowtmr(), and tcp_timewait_input().

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 next, tcp_seg::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().