|
AquilaOS documentation
How it works, and its code
|
#include <core/system.h>#include <ds/hashmap.h>#include <ds/queue.h>#include <ds/ringbuf.h>#include <net/inet.h>#include <sys/callout.h>Go to the source code of this file.
Data Structures | |
| struct | tcp_hdr |
| A TCP segment's header. More... | |
| struct | tcp_pcb |
| A connection (its control block, or PCB). More... | |
Macros | |
| #define | TH_FIN 0x01 |
| #define | TH_SYN 0x02 |
| #define | TH_RST 0x04 |
| #define | TH_PSH 0x08 |
| #define | TH_ACK 0x10 |
| #define | TH_URG 0x20 |
| #define | SEQ_LT(a, b) |
| #define | SEQ_LEQ(a, b) |
| #define | SEQ_GT(a, b) |
| #define | SEQ_GEQ(a, b) |
| #define | TCP_BUFSIZE 65536 |
| #define | TCP_MSS_DEFAULT 536 |
Enumerations | |
| enum | tcp_state { TCP_CLOSED , TCP_LISTEN , TCP_SYN_SENT , TCP_SYN_RECEIVED , TCP_ESTABLISHED , TCP_FIN_WAIT_1 , TCP_FIN_WAIT_2 , TCP_CLOSE_WAIT , TCP_CLOSING , TCP_LAST_ACK , TCP_TIME_WAIT } |
Functions | |
| 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. | |
| void | tcp_send_keepalive (struct tcp_pcb *pcb) |
| Sends a keepalive probe: a segment one byte before what the peer has acknowledged (with no data), which the peer answers with an ACK. | |
| void | tcp_output (struct tcp_pcb *pcb) |
| Sends as much of the send buffer as the windows allow, in segments of at most mss bytes. | |
| void | tcp_send_ack (struct tcp_pcb *pcb) |
| Sends an ACK, now. | |
| void | tcp_send_syn (struct tcp_pcb *pcb) |
| Sends the SYN (or, in SYN_RECEIVED, the SYN and ACK), the first time or again, and starts the retransmission timer. | |
| void | tcp_send_rst (struct tcp_pcb *pcb) |
| Sends a reset on a connection. | |
| void | tcp_reply_rst (struct netif *netif, const struct ipv4_hdr *ih, const struct tcp_hdr *th, size_t len) |
| Answers a segment that is for no connection with a reset (RFC 9293 3.10.7.1). | |
| void | tcp_rexmt_start (struct tcp_pcb *pcb) |
| Starts the retransmission timer, if it isn't running. | |
| void | tcp_rtt_update (struct tcp_pcb *pcb, uint64_t rtt) |
| Updates the round trip estimates with a new measurement, and the retransmission timeout from them (RFC 6298). | |
| uint16_t | tcp_rcv_window (struct tcp_pcb *pcb) |
| Computes the window to advertise: the room in the receive buffer. | |
| void | tcp_dack (struct tcp_pcb *pcb) |
| Acknowledges a received segment: at once if it's the second one not acknowledged yet, or else after DACK_DELAY. | |
| struct tcp_pcb * | tcp_pcb_new (void) |
| Makes a connection, CLOSED, with its send and receive buffers, on the list of connections. | |
| void | tcp_pcb_free (struct tcp_pcb *pcb) |
| Frees a connection: its timers stop, it leaves the lists, and its buffers and waiting segments are freed. | |
| struct tcp_pcb * | tcp_lookup (uint32_t laddr, uint16_t lport, uint32_t raddr, uint16_t rport) |
| Finds a connection by both ends' addresses and ports. | |
| struct tcp_pcb * | tcp_listener (uint32_t laddr, uint16_t lport) |
| Finds the listener for a local address and port: one bound to that address, or else one bound to any address. | |
| int | tcp_insert (struct tcp_pcb *pcb) |
| Adds a connection to the hashmap of connections, by its addresses and ports, which it must have now. | |
| uint32_t | tcp_iss (struct tcp_pcb *pcb) |
| Chooses a connection's initial sequence number (RFC 6528): a clock that ticks every 4 us, plus a hash of the connection's addresses and ports with a secret, so that it can't be guessed. | |
| void | tcp_fin_wait_2 (struct tcp_pcb *pcb) |
| Handles our FIN being acknowledged (FIN_WAIT_2): if the socket is closed, the connection waits for the peer's FIN only for a while. | |
| void | tcp_keepalive_reset (struct tcp_pcb *pcb) |
| Restarts the keepalive timer, when the peer was heard from. | |
| void | tcp_established (struct tcp_pcb *pcb) |
| Moves a connection to ESTABLISHED: its congestion window starts, and a listener's connection is queued for accept(). | |
| void | tcp_drop (struct tcp_pcb *pcb, int err) |
| Drops a connection that is lost, giving its socket an error. | |
| void | tcp_closed (struct tcp_pcb *pcb) |
| Moves a connection to CLOSED: it leaves the hashmap, its timers stop, and its waiters wake up. | |
| void | tcp_time_wait (struct tcp_pcb *pcb) |
| Moves a connection to TIME_WAIT, which it leaves after 2 MSL. | |
| void | tcp_wakeup (struct tcp_pcb *pcb) |
| Wakes up the threads waiting on a connection (in accept(), connect(), recv() or send()). | |
Variables | |
| struct tcp_pcb * | tcp_pcbs |
| #define SEQ_GEQ | ( | a, | |
| b ) |
| #define SEQ_GT | ( | a, | |
| b ) |
Definition at line 52 of file tcp.h.
Referenced by ack_input(), retransmit_first(), rexmt_timeout(), rtt_sample(), segment_input(), syn_sent_input(), tcp_output(), tcp_rcv_window(), and window_update().
| #define SEQ_LEQ | ( | a, | |
| b ) |
Definition at line 51 of file tcp.h.
Referenced by ack_input(), ooo_drain(), segment_input(), and syn_sent_input().
| #define SEQ_LT | ( | a, | |
| b ) |
Definition at line 50 of file tcp.h.
Referenced by ack_input(), ooo_insert(), and segment_input().
| #define TCP_BUFSIZE 65536 |
Definition at line 56 of file tcp.h.
Referenced by socket_tcp_can_write(), socket_tcp_getsockopt(), socket_tcp_send(), tcp_pcb_new(), and tcp_rcv_window().
| #define TCP_MSS_DEFAULT 536 |
Definition at line 59 of file tcp.h.
Referenced by our_mss(), set_mss(), and tcp_pcb_new().
| #define TH_ACK 0x10 |
Definition at line 31 of file tcp.h.
Referenced by listen_input(), rexmt_timeout(), segment(), segment_input(), syn_sent_input(), tcp_output(), tcp_reply_rst(), tcp_send_ack(), tcp_send_keepalive(), tcp_send_rst(), and tcp_send_syn().
| #define TH_FIN 0x01 |
Definition at line 27 of file tcp.h.
Referenced by acceptable(), ack_input(), segment_input(), tcp_output(), and tcp_reply_rst().
| #define TH_PSH 0x08 |
Definition at line 30 of file tcp.h.
Referenced by tcp_output().
| #define TH_RST 0x04 |
Definition at line 29 of file tcp.h.
Referenced by listen_input(), segment_input(), syn_sent_input(), tcp_reply_rst(), and tcp_send_rst().
| #define TH_SYN 0x02 |
Definition at line 28 of file tcp.h.
Referenced by acceptable(), listen_input(), segment(), segment_input(), syn_sent_input(), tcp_reply_rst(), and tcp_send_syn().
| enum tcp_state |
| void tcp_closed | ( | struct tcp_pcb * | pcb | ) |
Moves a connection to CLOSED: it leaves the hashmap, its timers stop, and its waiters wake up.
It is freed if nothing holds it anymore; otherwise its socket keeps it.
| pcb | the connection |
Definition at line 295 of file tcp_socket.c.
References callout_stop(), conns, tcp_pcb::dack, tcp_pcb::detached, tcp_pcb::hnode, NULL, tcp_pcb::parent, tcp_pcb::rexmt, tcp_pcb::state, TCP_CLOSED, tcp_closed(), tcp_pcb_free(), tcp_wakeup(), tcp_pcb::timer2, and unlink_parent().
Referenced by ack_input(), segment_input(), tcp_closed(), tcp_drop(), and timer2_closed().
| void tcp_dack | ( | struct tcp_pcb * | pcb | ) |
Acknowledges a received segment: at once if it's the second one not acknowledged yet, or else after DACK_DELAY.
| pcb | the connection |
Definition at line 344 of file tcp_output.c.
References tcp_pcb::ack_pending, tcp_pcb::dack, DACK_DELAY, dack_timeout(), net_callout_set(), callout::pending, tcp_dack(), and tcp_send_ack().
Referenced by segment_input(), and tcp_dack().
| void tcp_drop | ( | struct tcp_pcb * | pcb, |
| int | err ) |
Drops a connection that is lost, giving its socket an error.
| pcb | the connection |
| err | the error for the socket (a positive errno), or 0 |
Definition at line 323 of file tcp_socket.c.
References tcp_pcb::error, tcp_closed(), and tcp_drop().
Referenced by keepalive_timeout(), rexmt_timeout(), segment_input(), socket_tcp_shutdown(), syn_sent_input(), and tcp_drop().
| void tcp_established | ( | struct tcp_pcb * | pcb | ) |
Moves a connection to ESTABLISHED: its congestion window starts, and a listener's connection is queued for accept().
| pcb | the connection |
Definition at line 335 of file tcp_socket.c.
References tcp_pcb::accept_head, tcp_pcb::accept_next, tcp_pcb::accept_tail, tcp_pcb::connected, tcp_pcb::cwnd, MAX, MIN, tcp_pcb::mss, tcp_pcb::parent, tcp_pcb::snd_max, tcp_pcb::snd_nxt, tcp_pcb::snd_una, tcp_pcb::state, TCP_ESTABLISHED, tcp_established(), tcp_keepalive_reset(), and tcp_wakeup().
Referenced by segment_input(), syn_sent_input(), and tcp_established().
| void tcp_fin_wait_2 | ( | struct tcp_pcb * | pcb | ) |
Handles our FIN being acknowledged (FIN_WAIT_2): if the socket is closed, the connection waits for the peer's FIN only for a while.
| pcb | the connection |
Definition at line 387 of file tcp_socket.c.
References tcp_pcb::detached, FIN_WAIT_2_TIME, net_callout_set(), tcp_fin_wait_2(), tcp_pcb::timer2, and timer2_closed().
Referenced by ack_input(), socket_tcp_shutdown(), and tcp_fin_wait_2().
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().
| int tcp_insert | ( | struct tcp_pcb * | pcb | ) |
Adds a connection to the hashmap of connections, by its addresses and ports, which it must have now.
| pcb | the connection |
Definition at line 112 of file tcp_socket.c.
References conns, tcp_pcb::hnode, key_eq(), key_hash(), tcp_pcb::laddr, tcp_pcb::lport, tcp_pcb::raddr, tcp_pcb::rport, and tcp_insert().
Referenced by listen_input(), socket_tcp_connect(), and tcp_insert().
Chooses a connection's initial sequence number (RFC 6528): a clock that ticks every 4 us, plus a hash of the connection's addresses and ports with a secret, so that it can't be guessed.
| pcb | the connection, with its addresses and ports |
Definition at line 231 of file tcp_socket.c.
References arch_rtime_ns(), iss_secret, tcp_pcb::laddr, tcp_pcb::lport, memcpy(), tcp_pcb::raddr, random_get(), tcp_pcb::rport, and tcp_iss().
Referenced by listen_input(), socket_tcp_connect(), and tcp_iss().
| void tcp_keepalive_reset | ( | struct tcp_pcb * | pcb | ) |
Restarts the keepalive timer, when the peer was heard from.
| pcb | the connection |
Definition at line 417 of file tcp_socket.c.
References KEEP_IDLE, tcp_pcb::keep_probes, tcp_pcb::keepalive, keepalive_timeout(), net_callout_set(), tcp_pcb::state, TCP_ESTABLISHED, tcp_keepalive_reset(), and tcp_pcb::timer2.
Referenced by segment_input(), socket_tcp_setsockopt(), tcp_established(), and tcp_keepalive_reset().
Finds the listener for a local address and port: one bound to that address, or else one bound to any address.
| laddr | the local address |
| lport | the local port |
Definition at line 138 of file tcp_socket.c.
References tcp_pcb::laddr, tcp_pcb::lport, tcp_pcb::next, NULL, TCP_LISTEN, tcp_listener(), and tcp_pcbs.
Referenced by tcp_input(), and tcp_listener().
Finds a connection by both ends' addresses and ports.
| laddr | the local address |
| lport | the local port |
| raddr | the remote address |
| rport | the remote port |
Definition at line 96 of file tcp_socket.c.
References conns, hashmap_node::entry, key_hash(), tcp_key::laddr, tcp_key::lport, NULL, tcp_key::raddr, tcp_key::rport, and tcp_lookup().
Referenced by tcp_input(), and tcp_lookup().
| void tcp_output | ( | struct tcp_pcb * | pcb | ) |
Sends as much of the send buffer as the windows allow, in segments of at most mss bytes.
A smaller segment goes only if it has the last of the data and nothing is unacknowledged (Nagle's algorithm, unless TCP_NODELAY), and never just because the peer's window is small (the sender's silly window avoidance). The FIN goes with the last of the data. If the peer's window is zero, the persist timer probes it.
| pcb | the connection |
Definition at line 249 of file tcp_output.c.
References arch_rtime_ns(), tcp_pcb::cwnd, tcp_pcb::fin_queued, tcp_hdr::flags, MIN, tcp_pcb::mss, net_callout_set(), tcp_pcb::nodelay, callout::pending, tcp_pcb::persist, tcp_pcb::rexmt, rexmt_timeout(), tcp_pcb::rto, tcp_pcb::rtt_seq, tcp_pcb::rtt_start, tcp_pcb::rtt_timing, segment(), sending(), tcp_hdr::seq, SEQ_GT, tcp_pcb::snd_max, tcp_pcb::snd_nxt, tcp_pcb::snd_una, tcp_pcb::snd_wnd, tcp_pcb::sndbuf, tcp_output(), tcp_rexmt_start(), TH_ACK, TH_FIN, and TH_PSH.
Referenced by ack_input(), retransmit_first(), rexmt_timeout(), segment_input(), send_fin(), socket_tcp_send(), socket_tcp_setsockopt(), and tcp_output().
| void tcp_pcb_free | ( | struct tcp_pcb * | pcb | ) |
Frees a connection: its timers stop, it leaves the lists, and its buffers and waiting segments are freed.
| pcb | the connection |
Definition at line 196 of file tcp_socket.c.
References callout_stop(), conns, tcp_pcb::dack, tcp_pcb::hnode, kfree(), netbuf_free(), netbuf::next, tcp_pcb::next, tcp_pcb::ooo, tcp_pcb::rcvbuf, tcp_pcb::rexmt, tcp_pcb::sndbuf, tcp_pcb_free(), tcp_pcbs, and tcp_pcb::timer2.
Referenced by listen_input(), socket_tcp_create(), socket_tcp_shutdown(), tcp_closed(), and tcp_pcb_free().
| struct tcp_pcb * tcp_pcb_new | ( | void | ) |
Makes a connection, CLOSED, with its send and receive buffers, on the list of connections.
Definition at line 162 of file tcp_socket.c.
References kfree(), kmalloc(), M_ZERO, tcp_pcb::mss, tcp_pcb::next, NULL, tcp_pcb::rcvbuf, tcp_pcb::rto, RTO_INITIAL, tcp_pcb::sndbuf, tcp_pcb::ssthresh, tcp_pcb::state, TCP_BUFSIZE, TCP_CLOSED, TCP_MSS_DEFAULT, tcp_pcb_new(), and tcp_pcbs.
Referenced by listen_input(), socket_tcp_create(), and tcp_pcb_new().
Computes the window to advertise: the room in the receive buffer.
Its right edge only moves forward by at least a segment (or half the buffer), so that the peer isn't offered small windows (RFC 9293 3.8.6.2.2, the receiver's silly window avoidance), and it never moves back.
| pcb | the connection |
Definition at line 49 of file tcp_output.c.
References MIN, tcp_pcb::mss, tcp_pcb::rcv_adv, tcp_pcb::rcv_nxt, tcp_pcb::rcvbuf, SEQ_GT, TCP_BUFSIZE, and tcp_rcv_window().
Referenced by segment(), tcp_rcv_window(), and window_update().
| void tcp_reply_rst | ( | struct netif * | netif, |
| const struct ipv4_hdr * | ih, | ||
| const struct tcp_hdr * | th, | ||
| size_t | len ) |
Answers a segment that is for no connection with a reset (RFC 9293 3.10.7.1).
A reset itself isn't answered.
| netif | the interface it came in on |
| ih | its IPv4 header |
| th | its TCP header |
| len | the length of its data |
Definition at line 192 of file tcp_output.c.
References tcp_hdr::ack, tcp_hdr::checksum, ipv4_hdr::dst, tcp_hdr::dst, tcp_hdr::flags, htonl, inet_checksum_pseudo(), IP_PROTO_TCP, ipv4_output(), netbuf::len, memset(), netbuf_alloc(), netbuf_push(), ntohl, tcp_hdr::off, tcp_hdr::seq, ipv4_hdr::src, tcp_hdr::src, tcp_reply_rst(), TH_ACK, TH_FIN, TH_RST, and TH_SYN.
Referenced by listen_input(), segment_input(), syn_sent_input(), tcp_input(), and tcp_reply_rst().
| void tcp_rexmt_start | ( | struct tcp_pcb * | pcb | ) |
Starts the retransmission timer, if it isn't running.
| pcb | the connection |
Definition at line 122 of file tcp_output.c.
References net_callout_set(), callout::pending, tcp_pcb::rexmt, rexmt_timeout(), tcp_pcb::rto, and tcp_rexmt_start().
Referenced by ack_input(), tcp_output(), tcp_rexmt_start(), and tcp_send_syn().
Updates the round trip estimates with a new measurement, and the retransmission timeout from them (RFC 6298).
| pcb | the connection |
| rtt | the round trip measured, in ns |
Definition at line 316 of file tcp_output.c.
References MAX, MIN, tcp_pcb::rto, RTO_MAX, RTO_MIN, RTT_GRANULARITY, tcp_pcb::rttvar, tcp_pcb::srtt, and tcp_rtt_update().
Referenced by tcp_rtt_update().
| void tcp_send_ack | ( | struct tcp_pcb * | pcb | ) |
Sends an ACK, now.
| pcb | the connection |
Definition at line 157 of file tcp_output.c.
References segment(), tcp_pcb::snd_nxt, tcp_send_ack(), and TH_ACK.
Referenced by ack_input(), dack_timeout(), fin_input(), segment_input(), syn_sent_input(), tcp_dack(), tcp_send_ack(), and window_update().
| void tcp_send_keepalive | ( | struct tcp_pcb * | pcb | ) |
Sends a keepalive probe: a segment one byte before what the peer has acknowledged (with no data), which the peer answers with an ACK.
| pcb | the connection |
Definition at line 168 of file tcp_output.c.
References segment(), tcp_pcb::snd_una, tcp_send_keepalive(), and TH_ACK.
Referenced by keepalive_timeout(), and tcp_send_keepalive().
| void tcp_send_rst | ( | struct tcp_pcb * | pcb | ) |
Sends a reset on a connection.
| pcb | the connection |
Definition at line 178 of file tcp_output.c.
References segment(), tcp_pcb::snd_nxt, tcp_send_rst(), TH_ACK, and TH_RST.
Referenced by keepalive_timeout(), segment_input(), socket_tcp_shutdown(), and tcp_send_rst().
| void tcp_send_syn | ( | struct tcp_pcb * | pcb | ) |
Sends the SYN (or, in SYN_RECEIVED, the SYN and ACK), the first time or again, and starts the retransmission timer.
The first one is timed, to measure the round trip.
| pcb | the connection |
Definition at line 135 of file tcp_output.c.
References arch_rtime_ns(), tcp_hdr::flags, tcp_pcb::iss, tcp_pcb::retries, tcp_pcb::rtt_seq, tcp_pcb::rtt_start, tcp_pcb::rtt_timing, segment(), tcp_pcb::snd_max, tcp_pcb::snd_nxt, tcp_pcb::state, tcp_rexmt_start(), tcp_send_syn(), TCP_SYN_RECEIVED, TH_ACK, and TH_SYN.
Referenced by listen_input(), rexmt_timeout(), socket_tcp_connect(), syn_sent_input(), and tcp_send_syn().
| void tcp_time_wait | ( | struct tcp_pcb * | pcb | ) |
Moves a connection to TIME_WAIT, which it leaves after 2 MSL.
| pcb | the connection |
Definition at line 373 of file tcp_socket.c.
References callout_stop(), MSL, net_callout_set(), tcp_pcb::rexmt, tcp_pcb::state, TCP_TIME_WAIT, tcp_time_wait(), tcp_wakeup(), tcp_pcb::timer2, and timer2_closed().
Referenced by ack_input(), fin_input(), and tcp_time_wait().
| void tcp_wakeup | ( | struct tcp_pcb * | pcb | ) |
Wakes up the threads waiting on a connection (in accept(), connect(), recv() or send()).
| pcb | the connection |
Definition at line 257 of file tcp_socket.c.
References tcp_wakeup(), tcp_pcb::wait, and waitq_wakeup().
Referenced by ack_input(), fin_input(), segment_input(), socket_tcp_shut(), tcp_closed(), tcp_established(), tcp_time_wait(), and tcp_wakeup().
|
extern |
Definition at line 55 of file tcp_socket.c.
Referenced by port_used(), socket_tcp_shutdown(), tcp_listener(), tcp_pcb_free(), and tcp_pcb_new().