Transmission Control Protocol, outgoing traffic.
The output functions of TCP.
#include "lwip/opt.h"
#include "lwip/tcp_impl.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/snmp.h"
#include <string.h>
Macros | |
#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) More... | |
#define | TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) |
#define | TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) |
Functions | |
static struct tcp_seg * | tcp_create_segment (struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) |
Create a TCP segment with prefilled header. More... | |
err_t | tcp_enqueue_flags (struct tcp_pcb *pcb, u8_t flags) |
Enqueue TCP options for transmission. More... | |
void | tcp_keepalive (struct tcp_pcb *pcb) |
Send keepalive packets to keep a connection active although no data is sent over it. More... | |
err_t | tcp_output (struct tcp_pcb *pcb) |
Find out what we can send and send it. More... | |
static struct pbuf * | tcp_output_alloc_header (struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, u32_t seqno_be) |
Allocate a pbuf and create a tcphdr at p->payload, used for output functions other than the default tcp_output -> tcp_output_segment (e.g. More... | |
static void | tcp_output_segment (struct tcp_seg *seg, struct tcp_pcb *pcb) |
Called by tcp_output() to actually send a TCP segment over IP. More... | |
static struct pbuf * | tcp_pbuf_prealloc (pbuf_layer layer, u16_t length, u16_t max_length, u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags, u8_t first_seg) |
Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. 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_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... | |
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... | |
err_t | tcp_write (struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) |
Write data for sending (but does not send it immediately). More... | |
static err_t | tcp_write_checks (struct tcp_pcb *pcb, u16_t len) |
Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). 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... | |
#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)
#define TCP_DATA_COPY | ( | dst, | |
src, | |||
len, | |||
seg | |||
) | MEMCPY(dst, src, len) |
Referenced by tcp_write().
#define TCP_DATA_COPY2 | ( | dst, | |
src, | |||
len, | |||
chksum, | |||
chksum_swapped | |||
) | MEMCPY(dst, src, len) |
Referenced by tcp_write().
|
static |
Create a TCP segment with prefilled header.
Called by tcp_write and tcp_enqueue_flags.
pcb | Protocol control block for the TCP connection. |
p | pbuf that is used to hold the TCP header. |
flags | TCP flags for header. |
seqno | TCP sequence number of this packet |
optflags | options to include in TCP header |
References tcp_seg::flags, htonl, htons, tcp_seg::len, LWIP_ASSERT, LWIP_DEBUGF, LWIP_TCP_OPT_LENGTH, memp_malloc(), tcp_seg::next, NULL, tcp_seg::p, pbuf::payload, pbuf_free(), pbuf_header(), tcp_pcb::remote_port, TCP_HLEN, TCP_OUTPUT_DEBUG, tcp_seg_free(), TCP_STATS_INC, TCPH_HDRLEN_FLAGS_SET, tcp_seg::tcphdr, TF_SEG_DATA_CHECKSUMMED, and pbuf::tot_len.
Referenced by tcp_enqueue_flags(), and tcp_write().
Enqueue TCP options for transmission.
Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl().
pcb | Protocol control block for the TCP connection. |
flags | TCP header flags to set in the outgoing segment. |
optdata | pointer to TCP options, or NULL. |
optlen | length 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().
Send keepalive packets to keep a connection active although no data is sent over it.
Called by tcp_slowtmr()
pcb | the 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().
Find out what we can send and send it.
pcb | Protocol control block for the TCP connection to send data |
References tcp_pcb::cwnd, ERR_OK, tcp_pcb::flags, tcp_pcb::lastack, tcp_seg::len, LISTEN, LWIP_ASSERT, LWIP_DEBUGF, LWIP_MIN, tcp_seg::next, ntohl, NULL, S16_F, tcp_pcb::snd_nxt, tcp_pcb::snd_wnd, SYN_SENT, TCP_ACK, TCP_CWND_DEBUG, tcp_do_output_nagle, tcp_input_pcb, TCP_OUTPUT_DEBUG, tcp_output_segment(), TCP_RST, tcp_seg_free(), tcp_send_empty_ack(), TCP_SEQ_LT, TCP_TCPLEN, TCPH_FLAGS, TCPH_SET_FLAG, tcp_seg::tcphdr, TF_ACK_DELAY, TF_ACK_NOW, TF_FIN, TF_NAGLEMEMERR, U16_F, U32_F, tcp_pcb::unacked, tcp_pcb::unsent, and tcp_pcb::unsent_oversize.
Referenced by tcp_close_shutdown(), tcp_connect(), tcp_fasttmr(), tcp_input(), tcp_listen_input(), tcp_pcb_remove(), tcp_recved(), tcp_rexmit_rto(), tcp_slowtmr(), and tcp_timewait_input().
|
static |
Allocate a pbuf and create a tcphdr at p->payload, used for output functions other than the default tcp_output -> tcp_output_segment (e.g.
tcp_send_empty_ack, etc.)
pcb | tcp pcb for which to send a packet (used to initialize tcp_hdr) |
optlen | length of header-options |
datalen | length of tcp data to reserve in pbuf |
seqno_be | seqno in network byte order (big-endian) |
References htonl, htons, pbuf::len, LWIP_ASSERT, NULL, pbuf::payload, pbuf_alloc(), PBUF_IP, PBUF_RAM, tcp_pcb::rcv_ann_right_edge, tcp_pcb::rcv_ann_wnd, tcp_pcb::rcv_nxt, tcp_pcb::remote_port, TCP_ACK, TCP_HLEN, TCPH_HDRLEN_FLAGS_SET, and tcphdr.
Referenced by tcp_keepalive(), tcp_send_empty_ack(), and tcp_zero_window_probe().
Called by tcp_output() to actually send a TCP segment over IP.
References tcp_seg::flags, FOLD_U32T, htonl, htons, inet_chksum_pseudo(), inet_chksum_pseudo_partial(), netif::ip_addr, ip_addr_copy, ip_addr_isany, ip_output(), IP_PROTO_TCP, ip_route(), pbuf::len, tcp_seg::len, LWIP_ASSERT, LWIP_DBG_LEVEL_WARNING, LWIP_DEBUGF, ntohl, NULL, tcp_seg::p, pbuf::payload, tcp_pcb::rcv_ann_right_edge, tcp_pcb::rcv_ann_wnd, tcp_pcb::rcv_nxt, tcp_pcb::rtime, tcp_pcb::rtseq, tcp_pcb::rttest, snmp_inc_tcpoutsegs, SWAP_BYTES_IN_WORD, TCP_BUILD_MSS_OPTION, TCP_DEBUG, tcp_eff_send_mss(), TCP_MSS, TCP_OUTPUT_DEBUG, TCP_RTO_DEBUG, TCP_STATS_INC, tcp_ticks, TCPH_HDRLEN, tcp_seg::tcphdr, TF_SEG_DATA_CHECKSUMMED, TF_SEG_OPTS_MSS, TF_SEG_OPTS_TS, pbuf::tot_len, U32_F, and X16_F.
Referenced by tcp_output().
|
static |
Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
This function is like pbuf_alloc(layer, length, PBUF_RAM) except there may be extra bytes available at the end.
layer | flag to define header size. |
length | size of the pbuf's payload. |
max_length | maximum usable size of payload+oversize. |
oversize | pointer to a u16_t that will receive the number of usable tail bytes. |
pcb | The TCP connection that willo enqueue the pbuf. |
apiflags | API flags given to tcp_write. |
first_seg | true when this pbuf will be used in the first enqueued segment. |
References tcp_pcb::flags, pbuf::len, LWIP_ASSERT, LWIP_MEM_ALIGN_SIZE, LWIP_MIN, LWIP_UNUSED_ARG, pbuf::next, NULL, pbuf_alloc(), PBUF_RAM, TCP_WRITE_FLAG_MORE, TF_NODELAY, pbuf::tot_len, tcp_pcb::unacked, and tcp_pcb::unsent.
Referenced by tcp_write().
Requeue the first unacked segment for retransmission.
Called by tcp_receive() for fast retramsmit.
pcb | the 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().
Handle retransmission after three dupacks received.
pcb | the 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().
Requeue all unacked segments for retransmission.
Called by tcp_slowtmr() for slow retransmission.
pcb | the 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_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.
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 |
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().
Send an ACK without data.
pcb | Protocol control block for the TCP connection to send the ACK |
References ERR_BUF, ERR_OK, tcp_pcb::flags, htonl, inet_chksum_pseudo(), ip_output(), IP_PROTO_TCP, LWIP_DEBUGF, LWIP_TCP_OPT_LENGTH, NULL, pbuf::payload, pbuf_free(), tcp_pcb::rcv_nxt, tcp_pcb::snd_nxt, tcp_output_alloc_header(), TCP_OUTPUT_DEBUG, tcphdr, TF_ACK_DELAY, TF_ACK_NOW, TF_SEG_OPTS_TS, TF_TIMESTAMP, pbuf::tot_len, and U32_F.
Referenced by tcp_output(), and tcp_receive().
Called by tcp_close() to send a segment including FIN flag but not data.
pcb | the tcp_pcb over which to send a segment |
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().
Write data for sending (but does not send it immediately).
It waits in the expectation of more data being sent soon (as it can send them more efficiently by combining them together). To prompt the system to send data now, call tcp_output() after calling tcp_write().
pcb | Protocol control block for the TCP connection to enqueue data for. |
arg | Pointer to the data to be enqueued for sending. |
len | Data length in bytes |
apiflags | combination of following flags :
|
References ERR_ARG, ERR_MEM, ERR_OK, tcp_pcb::flags, tcp_seg::flags, inet_chksum(), pbuf::len, tcp_seg::len, LWIP_ASSERT, LWIP_DBG_STATE, LWIP_DBG_TRACE, LWIP_DEBUGF, LWIP_ERROR(), LWIP_MIN, LWIP_TCP_OPT_LENGTH, tcp_pcb::mss, pbuf::next, tcp_seg::next, ntohl, NULL, tcp_seg::p, pbuf::payload, pbuf_alloc(), pbuf_cat(), pbuf_clen(), pbuf_free(), PBUF_RAM, PBUF_RAW, PBUF_ROM, PBUF_TRANSPORT, S16_F, tcp_pcb::snd_buf, tcp_pcb::snd_lbb, tcp_pcb::snd_queuelen, tcp_pcb::snd_wnd_max, tcp_create_segment(), TCP_DATA_COPY, TCP_DATA_COPY2, TCP_OUTPUT_DEBUG, tcp_pbuf_prealloc(), TCP_PSH, TCP_QLEN_DEBUG, tcp_segs_free(), TCP_SNDQUEUELEN_OVERFLOW, TCP_STATS_INC, TCP_TCPLEN, tcp_write_checks(), TCP_WRITE_FLAG_COPY, TCP_WRITE_FLAG_MORE, TCPH_SET_FLAG, TF_NAGLEMEMERR, TF_SEG_DATA_CHECKSUMMED, TF_SEG_OPTS_TS, TF_TIMESTAMP, pbuf::tot_len, U16_F, U32_F, tcp_pcb::unacked, tcp_pcb::unsent, and tcp_pcb::unsent_oversize.
Referenced by http_send_data().
Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen).
pcb | the tcp pcb to check for |
len | length of data to send (checked agains snd_buf) |
References CLOSE_WAIT, ERR_CONN, ERR_MEM, ERR_OK, ESTABLISHED, tcp_pcb::flags, LWIP_ASSERT, LWIP_DBG_LEVEL_SEVERE, LWIP_DBG_STATE, LWIP_DEBUGF, NULL, tcp_pcb::snd_buf, tcp_pcb::snd_queuelen, SYN_RCVD, SYN_SENT, TCP_OUTPUT_DEBUG, TCP_QLEN_DEBUG, TCP_SNDQUEUELEN_OVERFLOW, TCP_STATS_INC, TF_NAGLEMEMERR, U16_F, tcp_pcb::unacked, and tcp_pcb::unsent.
Referenced by tcp_write().
Send persist timer zero-window probes to keep a connection active when a window update is lost.
Called by tcp_slowtmr()
pcb | the tcp_pcb for which to send a zero-window probe packet |
References if(), 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, tcp_seg::len, LWIP_DEBUGF, NULL, tcp_seg::p, pbuf::payload, pbuf_copy_partial(), pbuf_free(), tcp_pcb::rcv_nxt, tcp_pcb::snd_nxt, TCP_ACK, TCP_DEBUG, TCP_FIN, TCP_HLEN, tcp_output_alloc_header(), TCP_STATS_INC, tcp_ticks, TCPH_FLAGS, TCPH_FLAGS_SET, tcphdr, tcp_seg::tcphdr, tcp_pcb::tmr, pbuf::tot_len, U16_F, U32_F, tcp_pcb::unacked, and tcp_pcb::unsent.
Referenced by tcp_slowtmr().