lwIP  2.1.0
Lightweight IP stack
tcp_priv.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"
#include "lwip/prot/tcp.h"

Macros

#define tcp_do_output_nagle(tpcb)
 
#define TF_RESET   (u8_t)0x08U /* Connection was reset. */
 
#define TCP_OVERSIZE_DBGCHECK   0
 
#define TCP_CHECKSUM_ON_COPY   (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)
 
#define TCP_BUILD_MSS_OPTION(mss)   lwip_htonl(0x02040000 | ((mss) & 0xFFFF))
 

Functions

void tcp_init (void)
 
void tcp_tmr (void)
 
void tcp_slowtmr (void)
 
void tcp_fasttmr (void)
 
void tcp_txnow (void)
 
void tcp_input (struct pbuf *p, struct netif *inp)
 
struct tcp_pcbtcp_alloc (u8_t prio)
 
void tcp_free (struct tcp_pcb *pcb)
 
void tcp_abandon (struct tcp_pcb *pcb, int reset)
 
err_t tcp_send_empty_ack (struct tcp_pcb *pcb)
 
err_t tcp_rexmit (struct tcp_pcb *pcb)
 
err_t tcp_rexmit_rto_prepare (struct tcp_pcb *pcb)
 
void tcp_rexmit_rto_commit (struct tcp_pcb *pcb)
 
void tcp_rexmit_rto (struct tcp_pcb *pcb)
 
void tcp_rexmit_fast (struct tcp_pcb *pcb)
 
u32_t tcp_update_rcv_ann_wnd (struct tcp_pcb *pcb)
 
err_t tcp_process_refused_data (struct tcp_pcb *pcb)
 
void tcp_pcb_purge (struct tcp_pcb *pcb)
 
void tcp_pcb_remove (struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
 
void tcp_segs_free (struct tcp_seg *seg)
 
void tcp_seg_free (struct tcp_seg *seg)
 
struct tcp_seg * tcp_seg_copy (struct tcp_seg *seg)
 
err_t tcp_send_fin (struct tcp_pcb *pcb)
 
err_t tcp_enqueue_flags (struct tcp_pcb *pcb, u8_t flags)
 
void tcp_rst (const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno, const ip_addr_t *local_ip, const ip_addr_t *remote_ip, u16_t local_port, u16_t remote_port)
 
u32_t tcp_next_iss (struct tcp_pcb *pcb)
 
err_t tcp_keepalive (struct tcp_pcb *pcb)
 
err_t tcp_split_unsent_seg (struct tcp_pcb *pcb, u16_t split)
 
err_t tcp_zero_window_probe (struct tcp_pcb *pcb)
 
u16_t tcp_eff_send_mss_netif (u16_t sendmss, struct netif *outif, const ip_addr_t *dest)
 
err_t tcp_recv_null (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
 
void tcp_timer_needed (void)
 
void tcp_netif_ip_addr_changed (const ip_addr_t *old_addr, const ip_addr_t *new_addr)
 
err_t tcp_ext_arg_invoke_callbacks_passive_open (struct tcp_pcb_listen *lpcb, struct tcp_pcb *cpcb)
 

Variables

struct tcp_pcbtcp_bound_pcbs
 
union tcp_listen_pcbs_t tcp_listen_pcbs
 
struct tcp_pcbtcp_active_pcbs
 
struct tcp_pcbtcp_tw_pcbs
 
struct tcp_pcb **const tcp_pcb_lists [4]
 

Detailed Description

TCP internal implementations (do not use in application code)

Macro Definition Documentation

◆ TCP_BUILD_MSS_OPTION

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

This returns a TCP header option for MSS in an u32_t

◆ TCP_CHECKSUM_ON_COPY

#define TCP_CHECKSUM_ON_COPY   (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP)

Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled

◆ tcp_do_output_nagle

#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 tcp_sndbuf(pcb)
Definition: tcp.h:434
#define tcp_sndqueuelen(pcb)
Definition: tcp.h:436
#define TCP_SND_QUEUELEN
Definition: opt.h:1322

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)

◆ TCP_OVERSIZE_DBGCHECK

#define TCP_OVERSIZE_DBGCHECK   0

Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled

◆ TF_RESET

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

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

Function Documentation

◆ tcp_abandon()

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

◆ tcp_alloc()

struct tcp_pcb* tcp_alloc ( u8_t  prio)

Allocate a new tcp_pcb structure.

Parameters
priopriority for the new pcb
Returns
a new tcp_pcb that initially is in state CLOSED

◆ tcp_eff_send_mss_netif()

u16_t tcp_eff_send_mss_netif ( u16_t  sendmss,
struct netif outif,
const ip_addr_t dest 
)

Calculates the effective send mss that can be used for a specific IP address by calculating the minimum of TCP_MSS and the mtu (if set) of the target netif (if not NULL).

◆ tcp_enqueue_flags()

err_t tcp_enqueue_flags ( struct tcp_pcb pcb,
u8_t  flags 
)

Enqueue SYN or FIN for transmission.

Called by tcp_connect, tcp_listen_input, and tcp_close (via tcp_send_fin)

Parameters
pcbProtocol control block for the TCP connection.
flagsTCP header flags to set in the outgoing segment.

◆ tcp_ext_arg_invoke_callbacks_passive_open()

err_t tcp_ext_arg_invoke_callbacks_passive_open ( struct tcp_pcb_listen lpcb,
struct tcp_pcb cpcb 
)

This function calls the "passive_open" callback for all ext_args if a connection is in the process of being accepted. This is called just after the SYN is received and before a SYN/ACK is sent, to allow to modify the very first segment sent even on passive open. Naturally, the "accepted" callback of the pcb has not been called yet!

◆ tcp_fasttmr()

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 or pending FINs.

Automatically called from tcp_tmr().

◆ tcp_free()

void tcp_free ( struct tcp_pcb pcb)

Free a tcp pcb

◆ tcp_init()

void tcp_init ( void  )

Initialize this module.

◆ tcp_input()

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

◆ tcp_keepalive()

err_t 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

◆ tcp_netif_ip_addr_changed()

void tcp_netif_ip_addr_changed ( const ip_addr_t old_addr,
const ip_addr_t new_addr 
)

This function is called from netif.c when address is changed or netif is removed

Parameters
old_addrIP address of the netif before change
new_addrIP address of the netif after change or NULL if netif has been removed

◆ tcp_next_iss()

u32_t tcp_next_iss ( struct tcp_pcb pcb)

Calculates a new initial sequence number for new connections.

Returns
u32_t pseudo random sequence number

◆ tcp_pcb_purge()

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!

◆ tcp_pcb_remove()

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!

◆ tcp_process_refused_data()

err_t tcp_process_refused_data ( struct tcp_pcb pcb)

Pass pcb->refused_data to the recv callback

◆ tcp_recv_null()

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.

◆ tcp_rexmit()

err_t tcp_rexmit ( struct tcp_pcb pcb)

Requeue the first unacked segment for retransmission

Called by tcp_receive() for fast retransmit.

Parameters
pcbthe tcp_pcb for which to retransmit the first unacked segment

◆ 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

◆ tcp_rexmit_rto()

void tcp_rexmit_rto ( struct tcp_pcb pcb)

Requeue all unacked segments for retransmission

Called by tcp_process() only, tcp_slowtmr() needs to do some things between "prepare" and "commit".

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

◆ tcp_rexmit_rto_commit()

void tcp_rexmit_rto_commit ( 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

◆ tcp_rexmit_rto_prepare()

err_t tcp_rexmit_rto_prepare ( 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

◆ tcp_rst()

void tcp_rst ( const struct tcp_pcb pcb,
u32_t  seqno,
u32_t  ackno,
const ip_addr_t local_ip,
const 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
pcbTCP pcb (may be NULL if no pcb is available)
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

◆ tcp_seg_copy()

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

◆ tcp_seg_free()

void tcp_seg_free ( struct tcp_seg *  seg)

Frees a TCP segment (tcp_seg structure).

Parameters
segsingle tcp_seg to free

◆ 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

◆ tcp_send_empty_ack()

err_t tcp_send_empty_ack ( struct tcp_pcb pcb)

Send an ACK without data.

Parameters
pcbProtocol control block for the TCP connection to send the ACK

◆ tcp_send_fin()

err_t tcp_send_fin ( struct tcp_pcb pcb)

Called by tcp_close() to send a segment including FIN flag but not data. This FIN may be added to an existing segment or a new, otherwise empty segment is enqueued.

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

◆ tcp_slowtmr()

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. It also increments various timers such as the inactivity timer in each PCB.

Automatically called from tcp_tmr().

◆ tcp_split_unsent_seg()

err_t tcp_split_unsent_seg ( struct tcp_pcb pcb,
u16_t  split 
)

Split segment on the head of the unsent queue. If return is not ERR_OK, existing head remains intact

The split is accomplished by creating a new TCP segment and pbuf which holds the remainder payload after the split. The original pbuf is trimmed to new length. This allows splitting of read-only pbufs

Parameters
pcbthe tcp_pcb for which to split the unsent head
splitthe amount of payload to remain in the head

◆ tcp_timer_needed()

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).

Called from TCP_REG when registering a new PCB: the reason is to have the TCP timer only running when there are active (or time-wait) PCBs.

◆ tcp_tmr()

void tcp_tmr ( void  )

Called periodically to dispatch TCP timers.

◆ tcp_txnow()

void tcp_txnow ( void  )

Call tcp_output for all active pcbs that have TF_NAGLEMEMERR set

◆ tcp_update_rcv_ann_wnd()

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.

◆ tcp_zero_window_probe()

err_t 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.

Called by tcp_slowtmr()

Parameters
pcbthe tcp_pcb for which to send a zero-window probe packet

Variable Documentation

◆ tcp_active_pcbs

struct tcp_pcb* tcp_active_pcbs

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

◆ tcp_bound_pcbs

struct tcp_pcb* tcp_bound_pcbs

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

◆ tcp_listen_pcbs

union tcp_listen_pcbs_t tcp_listen_pcbs

List of all TCP PCBs in LISTEN state

◆ tcp_pcb_lists

struct tcp_pcb** const tcp_pcb_lists[4]

An array with all (non-temporary) PCB lists, mainly used for smaller code size

◆ tcp_tw_pcbs

struct tcp_pcb* tcp_tw_pcbs

List of all TCP PCBs in TIME-WAIT state