AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
tcp_socket.c File Reference

TCP connections (struct tcp_pcb) and their sockets (SOCK_STREAM). More...

#include <core/system.h>
#include <core/arch.h>
#include <core/string.h>
#include <dev/random.h>
#include <ds/hashmap.h>
#include <fs/vfs.h>
#include <net/byteorder.h>
#include <net/inet.h>
#include <net/netif.h>
#include <net/socket.h>
#include <net/tcp.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/uaccess.h>
#include <aquila/errno.h>
#include <aquila/fcntl.h>
#include <aquila/in.h>
#include <aquila/ioctl.h>
#include <aquila/tcp.h>

Go to the source code of this file.

Data Structures

struct  tcp_key
 What identifies a connection: both ends' addresses and ports. More...

Macros

#define PORT_FIRST   49152
#define PORT_LAST   65535
#define MSL   30000000000ULL
#define FIN_WAIT_2_TIME   60000000000ULL
#define RTO_INITIAL   1000000000ULL
#define KEEP_IDLE   7200000000000ULL
#define KEEP_INTERVAL   75000000000ULL
#define KEEP_PROBES   9
#define COPY_CHUNK   512

Functions

static hash_t key_hash (const struct tcp_key *key)
 Returns a connection key's hash.
static int key_eq (void *entry, void *k)
 Returns whether a connection has the key k.
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.
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.
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.
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.
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_wakeup (struct tcp_pcb *pcb)
 Wakes up the threads waiting on a connection (in accept(), connect(), recv() or send()).
static void unlink_parent (struct tcp_pcb *pcb)
 Takes a connection off its listener's queue, when it is done or accept() took it.
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_drop (struct tcp_pcb *pcb, int err)
 Drops a connection that is lost, giving its socket an error.
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().
static void timer2_closed (void *arg)
 Closes a connection when its TIME_WAIT or FIN_WAIT_2 time is over.
void tcp_time_wait (struct tcp_pcb *pcb)
 Moves a connection to TIME_WAIT, which it leaves after 2 MSL.
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.
static void keepalive_timeout (void *arg)
 Sends a keepalive probe after a silence, or drops the connection (ETIMEDOUT) once too many probes went unanswered.
void tcp_keepalive_reset (struct tcp_pcb *pcb)
 Restarts the keepalive timer, when the peer was heard from.
static int port_used (uint32_t addr, uint16_t port, int reuseaddr)
 Returns whether a local address and port are taken: by a listener, or by any connection unless reuseaddr is set.
static int bind_port (struct tcp_pcb *pcb, uint32_t addr, uint16_t port)
 Binds a connection to a local address and port; port 0 picks a free ephemeral port.
int socket_tcp_create (struct file *file, int domain, int type, int protocol)
 Makes a TCP socket, with its connection, CLOSED.
static int nonblock (struct file *file, int flags)
 Returns whether a call shouldn't wait: the socket doesn't block, or the call has MSG_DONTWAIT.
static uint64_t deadline (uint64_t timeo)
 Returns the deadline for a timeout of timeo ns from now, or 0 for none.
static int socket_tcp_bind (struct file *file, const struct sockaddr *addr, socklen_t len)
 Binds the socket to a local address (ours, or any) and port; ports below 1024 are root's.
static int socket_tcp_listen (struct file *file, int backlog)
 Makes the socket listen, binding it to an ephemeral port if it isn't bound.
static int socket_tcp_accept (struct file *file, struct file *conn, const struct sockaddr *addr, socklen_t *len)
 Accepts an established connection, waiting for one unless the socket doesn't block or the receive timeout passes.
static int socket_tcp_connect (struct file *file, const struct sockaddr *addr, socklen_t len)
 Connects to a peer: sends the SYN, and waits for the connection to be established, unless the socket doesn't block (-EINPROGRESS).
static int can_send (struct tcp_pcb *pcb)
 Returns whether data may be sent in the connection's state.
static ssize_t socket_tcp_send (struct file *file, struct iobuf *io, int flags, const struct sockaddr *to, socklen_t tolen)
 Sends data: it goes into the send buffer, waiting for room unless the socket doesn't block, and out as the windows allow.
static void window_update (struct tcp_pcb *pcb)
 Tells the peer that reading made room in the receive window, if it opened enough (tcp_rcv_window()).
static ssize_t socket_tcp_recv (struct file *file, struct iobuf *io, int flags, struct sockaddr *from, socklen_t *fromlen)
 Receives data, waiting for some unless the socket doesn't block or the receive timeout passes (with MSG_WAITALL, until the buffer is full).
static int socket_tcp_can_read (struct file *file, size_t len)
 Says whether a read (or an accept) wouldn't wait: there is data, a connection to accept, the end, or an error.
static struct waitq * socket_tcp_wait_queue (struct file *file, int write)
 Returns the connection's wait queue, which accept(), connect(), recv() and send() all wait on.
static int socket_tcp_can_write (struct file *file, size_t len)
 Says whether a write wouldn't wait: there is room in the send buffer, or an error or the end of sending to report.
static int socket_tcp_getname (struct file *file, struct sockaddr *addr, socklen_t *len, int peer)
 Gets the socket's local address, or its peer's (-ENOTCONN before the peer is known).
static int int_get (void *val, socklen_t *len, int v)
 Sets an option's value to the int v.
static int timeo_get (void *val, socklen_t *len, uint64_t ns)
 Sets an option's value to a timeout, as a struct timeval.
static int timeo_set (const void *val, socklen_t len, uint64_t *ns)
 Reads a timeout from an option's value, a struct timeval, into *ns.
static int socket_tcp_getsockopt (struct file *file, int level, int name, void *val, socklen_t *len)
 Reads a TCP or socket option.
static int socket_tcp_setsockopt (struct file *file, int level, int name, const void *val, socklen_t len)
 Sets a TCP or socket option.
static int socket_tcp_ioctl (struct file *file, int request, void *argp)
 Handles FIONREAD (how much data can be read) and the interface requests.
static void send_fin (struct tcp_pcb *pcb)
 Queues our FIN, to go after what is in the send buffer.
static int socket_tcp_shut (struct file *file, int how)
 Shuts down reading (readers see the end), writing (the FIN is sent), or both, for shutdown().
static int socket_tcp_shutdown (struct file *file, int how)
 Detaches the connection when the socket's last descriptor is closed: the connection is closed, and freed once it is done.

Variables

struct tcp_pcb * tcp_pcbs
static struct hashmap * conns
static uint8_t iss_secret [16]
static struct sock_ops socket_tcp_ops

Detailed Description

TCP connections (struct tcp_pcb) and their sockets (SOCK_STREAM).

Every connection is on one list, where the ports in use and the listeners are found. Once it has both ends' addresses and ports, it is also in a hashmap by them, where received segments find their connection. A socket has its connection. When the socket is closed, the connection stays (detached) until it is done: its data and FIN sent, and TIME_WAIT over. A connection that a listener made has no socket until accept() takes it.

Received segments and the timers are handled in the network's thread, and sending in the callers' system calls. Copying data to and from user memory may fault and sleep, while the network's thread changes the rings, so the code is careful about which end of a ring it touches.

Definition in file tcp_socket.c.

Macro Definition Documentation

◆ COPY_CHUNK

#define COPY_CHUNK   512

Definition at line 53 of file tcp_socket.c.

Referenced by socket_tcp_recv().

◆ FIN_WAIT_2_TIME

#define FIN_WAIT_2_TIME   60000000000ULL

Definition at line 46 of file tcp_socket.c.

Referenced by tcp_fin_wait_2().

◆ KEEP_IDLE

#define KEEP_IDLE   7200000000000ULL

Definition at line 49 of file tcp_socket.c.

Referenced by tcp_keepalive_reset().

◆ KEEP_INTERVAL

#define KEEP_INTERVAL   75000000000ULL

Definition at line 50 of file tcp_socket.c.

Referenced by keepalive_timeout().

◆ KEEP_PROBES

#define KEEP_PROBES   9

Definition at line 51 of file tcp_socket.c.

Referenced by keepalive_timeout().

◆ MSL

#define MSL   30000000000ULL

Definition at line 45 of file tcp_socket.c.

Referenced by tcp_time_wait().

◆ PORT_FIRST

#define PORT_FIRST   49152

Definition at line 42 of file tcp_socket.c.

◆ PORT_LAST

#define PORT_LAST   65535

Definition at line 43 of file tcp_socket.c.

◆ RTO_INITIAL

#define RTO_INITIAL   1000000000ULL

Definition at line 47 of file tcp_socket.c.

Referenced by tcp_pcb_new().

Function Documentation

◆ bind_port()

int bind_port ( struct tcp_pcb * pcb,
uint32_t addr,
uint16_t port )
static

Binds a connection to a local address and port; port 0 picks a free ephemeral port.

Returns 0 or -EADDRINUSE.

Definition at line 446 of file tcp_socket.c.

References bind_port(), htons, tcp_pcb::laddr, tcp_pcb::lport, tcp_pcb::next, PORT_FIRST, PORT_LAST, port_used(), random_get(), and tcp_pcb::reuseaddr.

Referenced by bind_port(), socket_tcp_bind(), socket_tcp_connect(), and socket_tcp_listen().

◆ can_send()

int can_send ( struct tcp_pcb * pcb)
static

Returns whether data may be sent in the connection's state.

Definition at line 692 of file tcp_socket.c.

References can_send(), tcp_pcb::fin_queued, tcp_pcb::state, TCP_CLOSE_WAIT, and TCP_ESTABLISHED.

Referenced by can_send(), socket_tcp_can_write(), and socket_tcp_send().

◆ deadline()

uint64_t deadline ( uint64_t timeo)
static

Returns the deadline for a timeout of timeo ns from now, or 0 for none.

Definition at line 522 of file tcp_socket.c.

References arch_rtime_ns(), and deadline().

Referenced by deadline(), socket_tcp_accept(), socket_tcp_recv(), and socket_tcp_send().

◆ int_get()

int int_get ( void * val,
socklen_t * len,
int v )
static

Sets an option's value to the int v.

Definition at line 917 of file tcp_socket.c.

References int_get().

Referenced by int_get(), and socket_tcp_getsockopt().

◆ keepalive_timeout()

void keepalive_timeout ( void * arg)
static

Sends a keepalive probe after a silence, or drops the connection (ETIMEDOUT) once too many probes went unanswered.

Definition at line 395 of file tcp_socket.c.

References KEEP_INTERVAL, KEEP_PROBES, tcp_pcb::keep_probes, tcp_pcb::keepalive, keepalive_timeout(), net_callout_set(), tcp_pcb::state, tcp_drop(), TCP_ESTABLISHED, tcp_send_keepalive(), tcp_send_rst(), and tcp_pcb::timer2.

Referenced by keepalive_timeout(), and tcp_keepalive_reset().

◆ key_eq()

int key_eq ( void * entry,
void * k )
static

Returns whether a connection has the key k.

Definition at line 78 of file tcp_socket.c.

References key_eq(), tcp_key::laddr, tcp_pcb::laddr, tcp_key::lport, tcp_pcb::lport, tcp_key::raddr, tcp_pcb::raddr, tcp_key::rport, and tcp_pcb::rport.

Referenced by key_eq(), and tcp_insert().

◆ key_hash()

hash_t key_hash ( const struct tcp_key * key)
static

Returns a connection key's hash.

Definition at line 72 of file tcp_socket.c.

References key_hash().

Referenced by key_hash(), tcp_insert(), and tcp_lookup().

◆ nonblock()

int nonblock ( struct file * file,
int flags )
static

Returns whether a call shouldn't wait: the socket doesn't block, or the call has MSG_DONTWAIT.

Definition at line 515 of file tcp_socket.c.

References file::flags, and nonblock().

Referenced by nonblock(), socket_tcp_accept(), socket_tcp_connect(), socket_tcp_recv(), and socket_tcp_send().

◆ port_used()

int port_used ( uint32_t addr,
uint16_t port,
int reuseaddr )
static

Returns whether a local address and port are taken: by a listener, or by any connection unless reuseaddr is set.

Definition at line 431 of file tcp_socket.c.

References tcp_pcb::next, port_used(), tcp_pcb::reuseaddr, TCP_LISTEN, and tcp_pcbs.

◆ send_fin()

void send_fin ( struct tcp_pcb * pcb)
static

Queues our FIN, to go after what is in the send buffer.

Definition at line 1056 of file tcp_socket.c.

References tcp_pcb::fin_queued, send_fin(), tcp_pcb::state, TCP_CLOSE_WAIT, TCP_FIN_WAIT_1, TCP_LAST_ACK, and tcp_output().

Referenced by send_fin(), socket_tcp_shut(), and socket_tcp_shutdown().

◆ socket_tcp_accept()

int socket_tcp_accept ( struct file * file,
struct file * conn,
const struct sockaddr * addr,
socklen_t * len )
static

Accepts an established connection, waiting for one unless the socket doesn't block or the receive timeout passes.

conn becomes its socket.

Definition at line 572 of file tcp_socket.c.

References tcp_pcb::accept_head, deadline(), FILE_SOCKET, file::flags, inet_sockaddr_put(), kmalloc(), M_ZERO, memcpy(), nonblock(), file::offset, socket::p, tcp_pcb::raddr, tcp_pcb::rcvtimeo, tcp_pcb::rport, sched_wait(), socket_tcp_accept(), tcp_pcb::state, TCP_LISTEN, unlink_parent(), and tcp_pcb::wait.

Referenced by socket_tcp_accept().

◆ socket_tcp_bind()

int socket_tcp_bind ( struct file * file,
const struct sockaddr * addr,
socklen_t len )
static

Binds the socket to a local address (ours, or any) and port; ports below 1024 are root's.

Definition at line 529 of file tcp_socket.c.

References bind_port(), curproc, inet_sockaddr_get(), ipv4_is_local(), tcp_pcb::lport, ntohs, socket_tcp_bind(), tcp_pcb::state, and TCP_CLOSED.

Referenced by socket_tcp_bind().

◆ socket_tcp_can_read()

int socket_tcp_can_read ( struct file * file,
size_t len )
static

Says whether a read (or an accept) wouldn't wait: there is data, a connection to accept, the end, or an error.

Definition at line 867 of file tcp_socket.c.

References tcp_pcb::accept_head, tcp_pcb::connected, tcp_pcb::error, tcp_pcb::fin_received, NULL, tcp_pcb::rcvbuf, tcp_pcb::shut_rd, socket_tcp_can_read(), tcp_pcb::state, TCP_CLOSED, and TCP_LISTEN.

Referenced by socket_tcp_can_read().

◆ socket_tcp_can_write()

int socket_tcp_can_write ( struct file * file,
size_t len )
static

Says whether a write wouldn't wait: there is room in the send buffer, or an error or the end of sending to report.

Definition at line 888 of file tcp_socket.c.

References can_send(), tcp_pcb::connected, tcp_pcb::error, tcp_pcb::sndbuf, socket_tcp_can_write(), and TCP_BUFSIZE.

Referenced by socket_tcp_can_write().

◆ socket_tcp_connect()

int socket_tcp_connect ( struct file * file,
const struct sockaddr * addr,
socklen_t len )
static

◆ socket_tcp_create()

int socket_tcp_create ( struct file * file,
int domain,
int type,
int protocol )

Makes a TCP socket, with its connection, CLOSED.

Parameters
filethe open file that becomes the socket
domainAF_INET
typeSOCK_STREAM
protocol0 or IPPROTO_TCP
Returns
0, or -ENOMEM

Definition at line 490 of file tcp_socket.c.

References socket::domain, FILE_SOCKET, file::flags, kfree(), kmalloc(), M_ZERO, socket::ops, socket::p, socket::protocol, socket_tcp_create(), socket_tcp_ops, tcp_pcb_free(), tcp_pcb_new(), and socket::type.

Referenced by socket_inet_create(), and socket_tcp_create().

◆ socket_tcp_getname()

int socket_tcp_getname ( struct file * file,
struct sockaddr * addr,
socklen_t * len,
int peer )
static

Gets the socket's local address, or its peer's (-ENOTCONN before the peer is known).

Definition at line 900 of file tcp_socket.c.

References inet_sockaddr_put(), tcp_pcb::laddr, tcp_pcb::lport, tcp_pcb::raddr, tcp_pcb::rport, socket_tcp_getname(), tcp_pcb::state, and TCP_SYN_SENT.

Referenced by socket_tcp_getname().

◆ socket_tcp_getsockopt()

int socket_tcp_getsockopt ( struct file * file,
int level,
int name,
void * val,
socklen_t * len )
static

◆ socket_tcp_ioctl()

int socket_tcp_ioctl ( struct file * file,
int request,
void * argp )
static

Handles FIONREAD (how much data can be read) and the interface requests.

Definition at line 1043 of file tcp_socket.c.

References inet_ifioctl(), tcp_pcb::rcvbuf, and socket_tcp_ioctl().

Referenced by socket_tcp_ioctl().

◆ socket_tcp_listen()

int socket_tcp_listen ( struct file * file,
int backlog )
static

Makes the socket listen, binding it to an ephemeral port if it isn't bound.

Definition at line 554 of file tcp_socket.c.

References tcp_pcb::backlog, bind_port(), tcp_pcb::lport, MAX, MIN, socket_tcp_listen(), tcp_pcb::state, TCP_CLOSED, and TCP_LISTEN.

Referenced by socket_tcp_listen().

◆ socket_tcp_recv()

ssize_t socket_tcp_recv ( struct file * file,
struct iobuf * io,
int flags,
struct sockaddr * from,
socklen_t * fromlen )
static

Receives data, waiting for some unless the socket doesn't block or the receive timeout passes (with MSG_WAITALL, until the buffer is full).

Returns how much was read, 0 at the end, or a negative errno.

Definition at line 783 of file tcp_socket.c.

References tcp_pcb::connected, COPY_CHUNK, deadline(), tcp_pcb::error, iobuf::fault, tcp_pcb::fin_received, inet_sockaddr_put(), iobuf_out(), MIN, nonblock(), tcp_pcb::raddr, tcp_pcb::rcvbuf, tcp_pcb::rcvtimeo, iobuf::resid, tcp_pcb::rport, sched_wait(), tcp_pcb::shut_rd, socket_tcp_recv(), tcp_pcb::state, TCP_CLOSED, TCP_LISTEN, tcp_pcb::wait, and window_update().

Referenced by socket_tcp_recv().

◆ socket_tcp_send()

ssize_t socket_tcp_send ( struct file * file,
struct iobuf * io,
int flags,
const struct sockaddr * to,
socklen_t tolen )
static

Sends data: it goes into the send buffer, waiting for room unless the socket doesn't block, and out as the windows allow.

Returns how much was taken, or a negative errno (-EPIPE once sending is over).

Definition at line 700 of file tcp_socket.c.

References can_send(), tcp_pcb::connected, deadline(), tcp_pcb::error, iobuf::fault, MIN, nonblock(), iobuf::resid, sched_wait(), tcp_pcb::sndbuf, tcp_pcb::sndtimeo, socket_tcp_send(), tcp_pcb::state, TCP_BUFSIZE, tcp_output(), TCP_SYN_RECEIVED, TCP_SYN_SENT, and tcp_pcb::wait.

Referenced by socket_tcp_send().

◆ socket_tcp_setsockopt()

int socket_tcp_setsockopt ( struct file * file,
int level,
int name,
const void * val,
socklen_t len )
static

◆ socket_tcp_shut()

int socket_tcp_shut ( struct file * file,
int how )
static

Shuts down reading (readers see the end), writing (the FIN is sent), or both, for shutdown().

Definition at line 1073 of file tcp_socket.c.

References send_fin(), tcp_pcb::shut_rd, socket_tcp_shut(), tcp_pcb::state, TCP_CLOSE_WAIT, TCP_CLOSED, TCP_ESTABLISHED, TCP_LISTEN, TCP_SYN_RECEIVED, TCP_SYN_SENT, and tcp_wakeup().

Referenced by socket_tcp_shut().

◆ socket_tcp_shutdown()

int socket_tcp_shutdown ( struct file * file,
int how )
static

Detaches the connection when the socket's last descriptor is closed: the connection is closed, and freed once it is done.

A listener resets the connections not accepted yet.

Definition at line 1095 of file tcp_socket.c.

References tcp_pcb::accept_head, tcp_pcb::detached, kfree(), tcp_pcb::next, NULL, tcp_pcb::ooo, tcp_pcb::rcvbuf, send_fin(), socket_tcp_shutdown(), tcp_pcb::state, TCP_CLOSE_WAIT, TCP_CLOSED, tcp_drop(), TCP_ESTABLISHED, TCP_FIN_WAIT_2, tcp_fin_wait_2(), TCP_LISTEN, tcp_pcb_free(), tcp_pcbs, tcp_send_rst(), TCP_SYN_RECEIVED, and TCP_SYN_SENT.

Referenced by socket_tcp_shutdown().

◆ socket_tcp_wait_queue()

struct waitq * socket_tcp_wait_queue ( struct file * file,
int write )
static

Returns the connection's wait queue, which accept(), connect(), recv() and send() all wait on.

Definition at line 880 of file tcp_socket.c.

References socket_tcp_wait_queue(), and tcp_pcb::wait.

Referenced by socket_tcp_wait_queue().

◆ tcp_closed()

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.

Parameters
pcbthe 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().

◆ tcp_drop()

void tcp_drop ( struct tcp_pcb * pcb,
int err )

Drops a connection that is lost, giving its socket an error.

Parameters
pcbthe connection
errthe 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().

◆ tcp_established()

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().

Parameters
pcbthe 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().

◆ tcp_fin_wait_2()

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.

Parameters
pcbthe 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().

◆ tcp_insert()

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.

Parameters
pcbthe connection
Returns
0, -EADDRINUSE if another connection has the same ones, or -ENOMEM

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().

◆ tcp_iss()

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.

Parameters
pcbthe connection, with its addresses and ports
Returns
the initial sequence number

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().

◆ tcp_keepalive_reset()

void tcp_keepalive_reset ( struct tcp_pcb * pcb)

Restarts the keepalive timer, when the peer was heard from.

Parameters
pcbthe 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().

◆ tcp_listener()

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.

Parameters
laddrthe local address
lportthe local port
Returns
the listener, or NULL

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().

◆ tcp_lookup()

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.

Parameters
laddrthe local address
lportthe local port
raddrthe remote address
rportthe remote port
Returns
the connection, or NULL

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().

◆ tcp_pcb_free()

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.

Parameters
pcbthe 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().

◆ tcp_pcb_new()

struct tcp_pcb * tcp_pcb_new ( void )

Makes a connection, CLOSED, with its send and receive buffers, on the list of connections.

Returns
the connection, or NULL if there was no memory

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().

◆ tcp_time_wait()

void tcp_time_wait ( struct tcp_pcb * pcb)

Moves a connection to TIME_WAIT, which it leaves after 2 MSL.

Parameters
pcbthe 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().

◆ tcp_wakeup()

void tcp_wakeup ( struct tcp_pcb * pcb)

Wakes up the threads waiting on a connection (in accept(), connect(), recv() or send()).

Parameters
pcbthe 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().

◆ timeo_get()

int timeo_get ( void * val,
socklen_t * len,
uint64_t ns )
static

Sets an option's value to a timeout, as a struct timeval.

Definition at line 928 of file tcp_socket.c.

References timeo_get(), timeval::tv_sec, and timeval::tv_usec.

Referenced by socket_tcp_getsockopt(), and timeo_get().

◆ timeo_set()

int timeo_set ( const void * val,
socklen_t len,
uint64_t * ns )
static

Reads a timeout from an option's value, a struct timeval, into *ns.

Definition at line 942 of file tcp_socket.c.

References timeo_set(), timeval::tv_sec, and timeval::tv_usec.

Referenced by socket_tcp_setsockopt(), and timeo_set().

◆ timer2_closed()

void timer2_closed ( void * arg)
static

Closes a connection when its TIME_WAIT or FIN_WAIT_2 time is over.

Definition at line 363 of file tcp_socket.c.

References tcp_closed(), and timer2_closed().

Referenced by tcp_fin_wait_2(), tcp_time_wait(), and timer2_closed().

◆ unlink_parent()

void unlink_parent ( struct tcp_pcb * pcb)
static

Takes a connection off its listener's queue, when it is done or accept() took it.

Definition at line 264 of file tcp_socket.c.

References tcp_pcb::accept_head, tcp_pcb::accept_next, tcp_pcb::accept_tail, NULL, tcp_pcb::parent, tcp_pcb::qlen, and unlink_parent().

Referenced by socket_tcp_accept(), tcp_closed(), and unlink_parent().

◆ window_update()

void window_update ( struct tcp_pcb * pcb)
static

Tells the peer that reading made room in the receive window, if it opened enough (tcp_rcv_window()).

Definition at line 768 of file tcp_socket.c.

References tcp_pcb::rcv_adv, tcp_pcb::rcv_nxt, SEQ_GT, tcp_pcb::state, TCP_ESTABLISHED, TCP_FIN_WAIT_1, TCP_FIN_WAIT_2, tcp_rcv_window(), tcp_send_ack(), and window_update().

Referenced by socket_tcp_recv(), and window_update().

Variable Documentation

◆ conns

struct hashmap* conns
static

Definition at line 56 of file tcp_socket.c.

Referenced by tcp_closed(), tcp_insert(), tcp_lookup(), and tcp_pcb_free().

◆ iss_secret

uint8_t iss_secret[16]
static

Definition at line 57 of file tcp_socket.c.

Referenced by tcp_iss().

◆ socket_tcp_ops

struct sock_ops socket_tcp_ops
static
Initial value:
= {
.accept = socket_tcp_accept,
.bind = socket_tcp_bind,
.connect = socket_tcp_connect,
.listen = socket_tcp_listen,
.recv = socket_tcp_recv,
.send = socket_tcp_send,
.can_read = socket_tcp_can_read,
.can_write = socket_tcp_can_write,
.wait_queue = socket_tcp_wait_queue,
.getname = socket_tcp_getname,
.getsockopt = socket_tcp_getsockopt,
.setsockopt = socket_tcp_setsockopt,
.ioctl = socket_tcp_ioctl,
.shut = socket_tcp_shut,
.shutdown = socket_tcp_shutdown,
}
static ssize_t socket_tcp_recv(struct file *file, struct iobuf *io, int flags, struct sockaddr *from, socklen_t *fromlen)
Receives data, waiting for some unless the socket doesn't block or the receive timeout passes (with M...
Definition tcp_socket.c:783
static int socket_tcp_shutdown(struct file *file, int how)
Detaches the connection when the socket's last descriptor is closed: the connection is closed,...
static int socket_tcp_can_read(struct file *file, size_t len)
Says whether a read (or an accept) wouldn't wait: there is data, a connection to accept,...
Definition tcp_socket.c:867
static int socket_tcp_setsockopt(struct file *file, int level, int name, const void *val, socklen_t len)
Sets a TCP or socket option.
Definition tcp_socket.c:992
static int socket_tcp_connect(struct file *file, const struct sockaddr *addr, socklen_t len)
Connects to a peer: sends the SYN, and waits for the connection to be established,...
Definition tcp_socket.c:616
static int socket_tcp_getsockopt(struct file *file, int level, int name, void *val, socklen_t *len)
Reads a TCP or socket option.
Definition tcp_socket.c:957
static int socket_tcp_can_write(struct file *file, size_t len)
Says whether a write wouldn't wait: there is room in the send buffer, or an error or the end of sendi...
Definition tcp_socket.c:888
static ssize_t socket_tcp_send(struct file *file, struct iobuf *io, int flags, const struct sockaddr *to, socklen_t tolen)
Sends data: it goes into the send buffer, waiting for room unless the socket doesn't block,...
Definition tcp_socket.c:700
static struct waitq * socket_tcp_wait_queue(struct file *file, int write)
Returns the connection's wait queue, which accept(), connect(), recv() and send() all wait on.
Definition tcp_socket.c:880
static int socket_tcp_ioctl(struct file *file, int request, void *argp)
Handles FIONREAD (how much data can be read) and the interface requests.
static int socket_tcp_accept(struct file *file, struct file *conn, const struct sockaddr *addr, socklen_t *len)
Accepts an established connection, waiting for one unless the socket doesn't block or the receive tim...
Definition tcp_socket.c:572
static int socket_tcp_shut(struct file *file, int how)
Shuts down reading (readers see the end), writing (the FIN is sent), or both, for shutdown().
static int socket_tcp_bind(struct file *file, const struct sockaddr *addr, socklen_t len)
Binds the socket to a local address (ours, or any) and port; ports below 1024 are root's.
Definition tcp_socket.c:529
static int socket_tcp_listen(struct file *file, int backlog)
Makes the socket listen, binding it to an ephemeral port if it isn't bound.
Definition tcp_socket.c:554
static int socket_tcp_getname(struct file *file, struct sockaddr *addr, socklen_t *len, int peer)
Gets the socket's local address, or its peer's (-ENOTCONN before the peer is known).
Definition tcp_socket.c:900

Definition at line 59 of file tcp_socket.c.

Referenced by socket_tcp_create().

◆ tcp_pcbs

struct tcp_pcb* tcp_pcbs

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().