lwIP 2.2.0 Lightweight IP stack

Macros | Functions | Variables
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_pcb * | tcp_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)
void | tcp_rst_netif (struct netif *netif, 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_pcb * | tcp_bound_pcbs
union tcp_listen_pcbs_t | tcp_listen_pcbs
struct tcp_pcb * | tcp_active_pcbs
struct tcp_pcb * | tcp_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)
tcp_sndbuf
#define tcp_sndbuf(pcb)
Definition: tcp.h:434
tcp_sndqueuelen
#define tcp_sndqueuelen(pcb)
Definition: tcp.h:436
TCP_SND_QUEUELEN
#define TCP_SND_QUEUELEN
Definition: opt.h:1373

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

  pcb | the tcp_pcb to abort
  reset | boolean 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

  prio | priority 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

  pcb | Protocol control block for the TCP connection.
  flags | TCP 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

  p | received TCP segment to process (p->payload pointing to the TCP header)
  inp | network 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

  pcb | the 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_addr | IP address of the netif before change
  new_addr | IP 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

  pcb | tcp_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

  pcblist | PCB list to purge.
  pcb | tcp_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

  pcb | the 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

  pcb | the 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

  pcb | the 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

  pcb | the 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

  pcb | the 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) to abort a connection.

Called by tcp_abort() (to abort a local connection), tcp_closen() (if not all data has been received by the application), tcp_timewait_input() (if a SYN is received) 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

  pcb | TCP pcb (may be NULL if no pcb is available)
  seqno | the sequence number to use for the outgoing segment
  ackno | the acknowledge number to use for the outgoing segment
  local_ip | the local IP address to send the segment from
  remote_ip | the remote IP address to send the segment to
  local_port | the local TCP port to send the segment from
  remote_port | the remote TCP port to send the segment to

## ◆ tcp_rst_netif()

void tcp_rst_netif | ( | struct netif * | netif,
|  | 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) to show that there is no matching local connection for a received segment.

Called by tcp_input() (if no matching local pcb was found) and tcp_listen_input() (if incoming segment has ACK flag set).

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

  netif | the netif on which to send the RST (since we have no pcb)
  seqno | the sequence number to use for the outgoing segment
  ackno | the acknowledge number to use for the outgoing segment
  local_ip | the local IP address to send the segment from
  remote_ip | the remote IP address to send the segment to
  local_port | the local TCP port to send the segment from
  remote_port | the 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

  seg | the 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

  seg | single 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

  seg | tcp_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

  pcb | Protocol 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

  pcb | the 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

  pcb | the tcp_pcb for which to split the unsent head
  split | the 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

  pcb | the 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