Loading...
Searching...
No Matches
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)

## 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)
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)
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:
  - tcp_send_empty_ack sends an ACK-only segment
  - tcp_rst sends a RST segment
  - tcp_keepalive sends a keepalive segment
  - tcp_zero_window_probe sends a window probe segment
  - tcp_output_alloc_header allocates a header-only pbuf for these functions

## 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 (useful when the checksum is generated by the application, not the stack)

## TCP_OVERSIZE_CALC_LENGTH

#define TCP_OVERSIZE_CALC_LENGTH | ( |  | length | ) |

Value:
((length) + TCP_OVERSIZE)
TCP_OVERSIZE
#define TCP_OVERSIZE
Definition opt.h:1489

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

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

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

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