|
AquilaOS documentation
How it works, and its code
|
TCP input (RFC 9293 3.10.7, "SEGMENT ARRIVES"). More...
#include <core/system.h>#include <core/arch.h>#include <core/string.h>#include <net/byteorder.h>#include <net/inet.h>#include <net/netif.h>#include <net/tcp.h>#include <aquila/errno.h>Go to the source code of this file.
Data Structures | |
| struct | seg |
| A received segment, with its header in host byte order. More... | |
Macros | |
| #define | IN_WINDOW(x) |
Functions | |
| static void | options (const struct tcp_hdr *th, size_t hlen, struct seg *s) |
| Reads a segment's options; the only one used is the MSS. | |
| static void | set_mss (struct tcp_pcb *pcb, uint16_t peer) |
| Sets the connection's segment size: the peer's MSS (536 if it didn't send one), but no more than ours. | |
| static void | rtt_sample (struct tcp_pcb *pcb, uint32_t ack) |
| Takes a round trip measurement, if ack acknowledges the segment that is being timed. | |
| static void | listen_input (struct tcp_pcb *l, const struct ipv4_hdr *ih, const struct tcp_hdr *th, struct seg *s, struct netif *netif) |
| Handles a segment for a listening socket. | |
| static void | syn_sent_input (struct tcp_pcb *pcb, const struct ipv4_hdr *ih, const struct tcp_hdr *th, struct seg *s, struct netif *netif) |
| Handles a segment for a connection in SYN_SENT (RFC 9293 3.10.7.3): the peer's SYN and ACK establish it, a reset refuses it. | |
| static int | acceptable (struct tcp_pcb *pcb, struct seg *s, uint32_t wnd) |
| Returns whether a segment is acceptable (RFC 9293 3.10.7.4): it falls within the window we advertised. | |
| static void | retransmit_first (struct tcp_pcb *pcb) |
| Retransmits the first unacknowledged segment, for a fast retransmit or a partial ACK. | |
| static int | ack_input (struct tcp_pcb *pcb, struct seg *s) |
| Handles a segment's acknowledgment of what we sent: the send buffer, the congestion window, the timers and the peer's window. | |
| static void | ooo_insert (struct tcp_pcb *pcb, struct netbuf *nb, struct seg *s, int fin) |
| Queues a segment that came ahead of rcv_nxt, sorted by sequence number; its netbuf now holds just its data. | |
| static void | ooo_purge (struct tcp_pcb *pcb) |
| Drops the segments that still wait, once the FIN is in: nothing follows the FIN, so they are only copies of what came before it, cut differently. | |
| static int | ooo_drain (struct tcp_pcb *pcb) |
| Takes the waiting segments that now follow rcv_nxt into the receive buffer. | |
| static void | fin_input (struct tcp_pcb *pcb) |
| Handles the peer's FIN, once all the data before it is in: the end of its data, and a change of state. | |
| static void | segment_input (struct tcp_pcb *pcb, struct netbuf *nb, struct seg *s, const struct ipv4_hdr *ih, const struct tcp_hdr *th, struct netif *netif) |
| Handles a segment for a connection in a synchronized state (RFC 9293 3.10.7.4). | |
| void | tcp_input (struct netif *netif, struct netbuf *nb, const struct ipv4_hdr *ih) |
| Takes in a TCP segment that IPv4 received, and passes it to its connection or listener. | |
TCP input (RFC 9293 3.10.7, "SEGMENT ARRIVES").
A segment goes to its connection's state machine, or to a listener, which makes a new connection for a SYN. A segment for no connection is answered with a reset.
Acknowledgments drive the congestion window (RFC 5681): slow start, then congestion avoidance; three duplicate ACKs mean a lost segment, which is retransmitted at once, with NewReno's recovery (RFC 6582). Data that arrives out of order waits in a sorted list until what is missing comes, and a duplicate ACK tells the peer what is missing.
Definition in file tcp_input.c.
| #define IN_WINDOW | ( | x | ) |
Returns whether a segment is acceptable (RFC 9293 3.10.7.4): it falls within the window we advertised.
Definition at line 186 of file tcp_input.c.
References acceptable(), seg::flags, IN_WINDOW, seg::len, tcp_pcb::rcv_nxt, seg::seq, TH_FIN, and TH_SYN.
Referenced by acceptable(), and segment_input().
Handles a segment's acknowledgment of what we sent: the send buffer, the congestion window, the timers and the peer's window.
Returns 0 if the segment should be processed further, or -1 if not.
Definition at line 227 of file tcp_input.c.
References seg::ack, ack_input(), callout_stop(), tcp_pcb::cwnd, tcp_pcb::dupacks, tcp_pcb::fin_queued, seg::flags, tcp_pcb::in_recovery, seg::len, MAX, MIN, tcp_pcb::mss, tcp_pcb::persist, tcp_pcb::recover, retransmit_first(), tcp_pcb::retries, tcp_pcb::rexmt, ringbuf_discard(), rtt_sample(), seg::seq, SEQ_GEQ, SEQ_GT, SEQ_LEQ, SEQ_LT, tcp_pcb::snd_max, tcp_pcb::snd_nxt, tcp_pcb::snd_una, tcp_pcb::snd_wl1, tcp_pcb::snd_wl2, tcp_pcb::snd_wnd, tcp_pcb::sndbuf, tcp_pcb::ssthresh, tcp_pcb::state, tcp_closed(), TCP_CLOSING, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, tcp_fin_wait_2(), TCP_LAST_ACK, tcp_output(), tcp_rexmt_start(), tcp_send_ack(), tcp_time_wait(), tcp_wakeup(), TH_FIN, and seg::win.
Referenced by ack_input(), and segment_input().
|
static |
Handles the peer's FIN, once all the data before it is in: the end of its data, and a change of state.
Definition at line 404 of file tcp_input.c.
References fin_input(), tcp_pcb::fin_received, tcp_pcb::rcv_nxt, tcp_pcb::state, TCP_CLOSE_WAIT, TCP_CLOSING, TCP_ESTABLISHED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, tcp_send_ack(), TCP_SYN_RECEIVED, TCP_TIME_WAIT, tcp_time_wait(), and tcp_wakeup().
Referenced by fin_input(), and segment_input().
|
static |
Handles a segment for a listening socket.
A SYN makes a new connection in SYN_RECEIVED, which belongs to the listener until accept() takes it; an ACK is answered with a reset.
Definition at line 84 of file tcp_input.c.
References tcp_pcb::backlog, ipv4_hdr::dst, tcp_hdr::dst, seg::flags, tcp_pcb::irs, tcp_pcb::iss, tcp_pcb::keepalive, tcp_pcb::laddr, seg::len, listen_input(), tcp_pcb::lport, seg::mss, tcp_pcb::nodelay, tcp_pcb::parent, tcp_pcb::qlen, tcp_pcb::raddr, tcp_pcb::rcv_nxt, tcp_pcb::rport, seg::seq, set_mss(), tcp_pcb::snd_una, tcp_pcb::snd_wl1, tcp_pcb::snd_wnd, ipv4_hdr::src, tcp_hdr::src, tcp_pcb::state, tcp_insert(), tcp_iss(), tcp_pcb_free(), tcp_pcb_new(), tcp_reply_rst(), tcp_send_syn(), TCP_SYN_RECEIVED, TH_ACK, TH_RST, TH_SYN, and seg::win.
Referenced by listen_input(), and tcp_input().
|
static |
Takes the waiting segments that now follow rcv_nxt into the receive buffer.
Returns 1 if the FIN came with them, or 0.
Definition at line 369 of file tcp_input.c.
References netbuf::data, netbuf::fin, netbuf::len, netbuf_free(), netbuf::next, tcp_pcb::ooo, ooo_drain(), ooo_purge(), tcp_pcb::rcv_nxt, tcp_pcb::rcvbuf, netbuf::seq, SEQ_LEQ, and skip.
Referenced by ooo_drain(), and segment_input().
Queues a segment that came ahead of rcv_nxt, sorted by sequence number; its netbuf now holds just its data.
Definition at line 332 of file tcp_input.c.
References netbuf::data, seg::data, netbuf::fin, netbuf::len, seg::len, netbuf_free(), netbuf::next, tcp_pcb::ooo, ooo_insert(), netbuf::seq, seg::seq, and SEQ_LT.
Referenced by ooo_insert(), and segment_input().
|
static |
Drops the segments that still wait, once the FIN is in: nothing follows the FIN, so they are only copies of what came before it, cut differently.
(They aren't data no one read, which socket_tcp_shutdown() deals with.)
Definition at line 358 of file tcp_input.c.
References netbuf_free(), netbuf::next, tcp_pcb::ooo, and ooo_purge().
Referenced by ooo_drain(), ooo_purge(), and segment_input().
Reads a segment's options; the only one used is the MSS.
Definition at line 36 of file tcp_input.c.
References seg::mss, and options().
Referenced by options(), sys_waitpid(), and tcp_input().
|
static |
Retransmits the first unacknowledged segment, for a fast retransmit or a partial ACK.
Definition at line 203 of file tcp_input.c.
References tcp_pcb::cwnd, tcp_pcb::mss, tcp_pcb::nodelay, retransmit_first(), tcp_pcb::rtt_timing, SEQ_GT, tcp_pcb::snd_nxt, tcp_pcb::snd_una, and tcp_output().
Referenced by ack_input(), and retransmit_first().
Takes a round trip measurement, if ack acknowledges the segment that is being timed.
Definition at line 73 of file tcp_input.c.
References rtt_sample(), tcp_pcb::rtt_seq, tcp_pcb::rtt_timing, and SEQ_GT.
Referenced by ack_input(), rtt_sample(), segment_input(), and syn_sent_input().
|
static |
Handles a segment for a connection in a synchronized state (RFC 9293 3.10.7.4).
The netbuf is freed, or kept if the segment waits out of order.
Definition at line 430 of file tcp_input.c.
References acceptable(), seg::ack, ack_input(), callout_stop(), seg::data, tcp_pcb::detached, netbuf::fin, fin_input(), seg::flags, seg::len, netbuf_free(), NULL, tcp_pcb::ooo, ooo_drain(), ooo_insert(), ooo_purge(), tcp_pcb::rcv_adv, tcp_pcb::rcv_nxt, tcp_pcb::rcvbuf, tcp_pcb::retries, tcp_pcb::rexmt, rtt_sample(), segment_input(), seg::seq, SEQ_GT, SEQ_LEQ, SEQ_LT, skip, tcp_pcb::snd_max, tcp_pcb::snd_una, tcp_pcb::snd_wl1, tcp_pcb::snd_wl2, tcp_pcb::snd_wnd, tcp_pcb::state, TCP_CLOSED, tcp_closed(), TCP_CLOSING, tcp_dack(), tcp_drop(), TCP_ESTABLISHED, tcp_established(), TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, tcp_keepalive_reset(), TCP_LAST_ACK, tcp_output(), tcp_reply_rst(), tcp_send_ack(), tcp_send_rst(), TCP_SYN_RECEIVED, TCP_TIME_WAIT, tcp_wakeup(), TH_ACK, TH_FIN, TH_RST, TH_SYN, and seg::win.
Referenced by segment_input(), and tcp_input().
Sets the connection's segment size: the peer's MSS (536 if it didn't send one), but no more than ours.
Definition at line 62 of file tcp_input.c.
References ipv4_route(), MIN, netif::mtu, tcp_pcb::raddr, set_mss(), and TCP_MSS_DEFAULT.
Referenced by listen_input(), set_mss(), and syn_sent_input().
|
static |
Handles a segment for a connection in SYN_SENT (RFC 9293 3.10.7.3): the peer's SYN and ACK establish it, a reset refuses it.
Definition at line 136 of file tcp_input.c.
References seg::ack, callout_stop(), seg::flags, tcp_pcb::irs, tcp_pcb::iss, seg::len, seg::mss, tcp_pcb::rcv_nxt, tcp_pcb::retries, tcp_pcb::rexmt, rtt_sample(), seg::seq, SEQ_GT, SEQ_LEQ, set_mss(), tcp_pcb::snd_max, tcp_pcb::snd_una, tcp_pcb::snd_wl1, tcp_pcb::snd_wl2, tcp_pcb::snd_wnd, tcp_pcb::state, syn_sent_input(), tcp_drop(), tcp_established(), tcp_reply_rst(), tcp_send_ack(), tcp_send_syn(), TCP_SYN_RECEIVED, TH_ACK, TH_RST, TH_SYN, and seg::win.
Referenced by syn_sent_input(), and tcp_input().
Takes in a TCP segment that IPv4 received, and passes it to its connection or listener.
A segment with a bad checksum or header, or not sent to one of our addresses, is dropped.
| netif | the interface it came in on |
| nb | the segment, from its TCP header; it is freed or kept |
| ih | its IPv4 header |
Definition at line 585 of file tcp_input.c.
References tcp_hdr::ack, netbuf::data, ipv4_hdr::dst, tcp_hdr::dst, tcp_hdr::flags, inet_checksum_pseudo(), IP_PROTO_TCP, ipv4_is_local(), netbuf::len, seg::len, listen_input(), netbuf_free(), ntohl, ntohs, tcp_hdr::off, options(), segment_input(), tcp_hdr::seq, ipv4_hdr::src, tcp_hdr::src, tcp_pcb::state, netif::stats, syn_sent_input(), tcp_input(), tcp_listener(), tcp_lookup(), tcp_reply_rst(), TCP_SYN_SENT, and tcp_hdr::win.
Referenced by ipv4_input(), and tcp_input().