lwIP  2.1.0
Lightweight IP stack
tcp_out.c File Reference
#include "lwip/opt.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/inet_chksum.h"
#include "lwip/stats.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include <string.h>
#include "path/to/my/lwip_hooks.h"

Macros

#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK   0
 
#define TCP_OVERSIZE_CALC_LENGTH(length)   ((length) + TCP_OVERSIZE)
 

Functions

err_t tcp_write (struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
 
err_t tcp_split_unsent_seg (struct tcp_pcb *pcb, u16_t split)
 
err_t tcp_send_fin (struct tcp_pcb *pcb)
 
err_t tcp_enqueue_flags (struct tcp_pcb *pcb, u8_t flags)
 
err_t tcp_output (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)
 
err_t tcp_rexmit (struct tcp_pcb *pcb)
 
void tcp_rexmit_fast (struct tcp_pcb *pcb)
 
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)
 
err_t tcp_send_empty_ack (struct tcp_pcb *pcb)
 
err_t tcp_keepalive (struct tcp_pcb *pcb)
 
err_t tcp_zero_window_probe (struct tcp_pcb *pcb)
 

Detailed Description

Transmission Control Protocol, outgoing traffic

The output functions of TCP.

There are two distinct ways for TCP segments to get sent:

  • queued data: these are segments transferring data or segments containing SYN or FIN (which both count as one sequence number). They are created as struct Packet buffers (PBUF) together with a struct tcp_seg and enqueue to the unsent list of the pcb. They are sent by tcp_output:
    • tcp_write : creates data segments
    • tcp_split_unsent_seg : splits a data segment
    • tcp_enqueue_flags : creates SYN-only or FIN-only segments
    • tcp_output / tcp_output_segment : finalize the tcp header (e.g. sequence numbers, options, checksum) and output to IP
    • the various tcp_rexmit functions shuffle around segments between the unsent an unacked lists to retransmit them
    • tcp_create_segment and tcp_pbuf_prealloc allocate pbuf and segment for these functions
  • direct send: these segments don't contain data but control the connection behaviour. They are created as pbuf only and sent directly without enqueueing them:

Macro Definition Documentation

◆ TCP_CHECKSUM_ON_COPY_SANITY_CHECK

#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK   0

Define this to 1 for an extra check that the output checksum is valid (usefule when the checksum is generated by the application, not the stack)

◆ TCP_OVERSIZE_CALC_LENGTH

#define TCP_OVERSIZE_CALC_LENGTH (   length)    ((length) + TCP_OVERSIZE)

The size of segment pbufs created when TCP_OVERSIZE is enabled

Function Documentation

◆ 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_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_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_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_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_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