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

AF_INET datagram sockets: UDP (SOCK_DGRAM), and ping sockets (SOCK_DGRAM with IPPROTO_ICMP), which send echo requests and receive the replies, without needing root. More...

#include <core/system.h>
#include <dev/random.h>
#include <core/string.h>
#include <core/arch.h>
#include <ds/queue.h>
#include <fs/vfs.h>
#include <net/byteorder.h>
#include <net/inet.h>
#include <net/socket.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>

Go to the source code of this file.

Data Structures

struct  inet_sock
 A UDP or ping socket. More...

Macros

#define RECV_MAX   (128 * NETBUF_SIZE)
#define PORT_FIRST   49152
#define PORT_LAST   65535

Functions

static int port_used (uint8_t proto, uint32_t addr, uint16_t port)
 Returns whether a socket of proto is bound to port on addr (or on any address, or addr is any).
static int sock_bind (struct inet_sock *sock, uint32_t addr, uint16_t port)
 Binds a socket to an address and port, and puts it on the list of bound sockets.
static void sock_unbind (struct inet_sock *sock)
 Takes a socket off the list of bound sockets.
struct inet_sock * inet_sock_find (struct netif *netif, uint8_t proto, uint32_t local, uint16_t port, uint32_t remote, uint16_t remote_port)
 Finds the socket that a received datagram is for: a socket connected to its sender first, or else one that isn't connected.
void inet_sock_deliver (struct inet_sock *sock, struct netbuf *nb)
 Queues a received datagram on its socket, and wakes up its readers.
void inet_sock_error (struct inet_sock *sock, int err)
 Gives a socket an error (from ICMP), which its next call reports.
int socket_inet_create (struct file *file, int domain, int type, int protocol)
 Makes an AF_INET socket: a TCP, UDP or ping socket.
int inet_sockaddr_get (const struct sockaddr *addr, socklen_t len, uint32_t *ip, uint16_t *port)
 Reads an AF_INET address.
void inet_sockaddr_put (struct sockaddr *addr, socklen_t *len, uint32_t ip, uint16_t port)
 Writes an AF_INET address, cut to *len bytes if it doesn't fit.
static int socket_inet_bind (struct file *file, const struct sockaddr *addr, socklen_t len)
 Binds a socket to an address that is ours, any address, or the broadcast address.
static int socket_inet_connect (struct file *file, const struct sockaddr *addr, socklen_t len)
 Connects a datagram socket: its default destination, and the only sender it receives from.
static ssize_t socket_inet_send (struct file *file, struct iobuf *io, int flags, const struct sockaddr *to, socklen_t tolen)
 Sends a datagram, whole: to to, or to the connected peer.
static ssize_t socket_inet_recv (struct file *file, struct iobuf *io, int flags, struct sockaddr *from, socklen_t *fromlen)
 Receives a datagram, waiting for one unless the socket doesn't block or the receive timeout passes.
static int socket_inet_can_read (struct file *file, size_t len)
 Says whether a read wouldn't wait: a datagram is queued, or there is an error to report, or reading is shut down.
static int socket_inet_can_write (struct file *file, size_t len)
 Says that a write never waits.
static struct waitq * socket_inet_wait_queue (struct file *file, int write)
 Returns the wait queue that the socket's readers sleep on; writers never wait.
static int socket_inet_getname (struct file *file, struct sockaddr *addr, socklen_t *len, int peer)
 Gets the socket's local address, or its peer's (-ENOTCONN if it isn't connected).
static int socket_inet_getsockopt (struct file *file, int level, int name, void *val, socklen_t *len)
 Reads a socket option: SO_ERROR, SO_BROADCAST, SO_BINDTODEVICE or SO_RCVTIMEO.
static int socket_inet_setsockopt (struct file *file, int level, int name, const void *val, socklen_t len)
 Sets a socket option: SO_BROADCAST, SO_BINDTODEVICE or SO_RCVTIMEO.
static int socket_inet_ioctl (struct file *file, int request, void *argp)
 Handles FIONREAD (the size of the next datagram) and the interface requests.
static int socket_inet_shut (struct file *file, int how)
 Shuts down reading: the readers wake up and see the end.
static int socket_inet_shutdown (struct file *file, int how)
 Frees the socket when its last descriptor is closed: it is unbound, and its queued datagrams are freed.

Variables

static struct inet_sock * bound
static struct sock_ops socket_inet_ops

Detailed Description

AF_INET datagram sockets: UDP (SOCK_DGRAM), and ping sockets (SOCK_DGRAM with IPPROTO_ICMP), which send echo requests and receive the replies, without needing root.

TCP sockets are in tcp_socket.c.

A socket bound to a port (for a ping socket, the identifier of its echoes) is on the list of bound sockets, where the protocols look up the socket a datagram is for. Received datagrams wait in the socket's queue, with where they came from, up to RECV_MAX bytes of buffers; more are dropped.

Definition in file socket.c.

Macro Definition Documentation

◆ PORT_FIRST

#define PORT_FIRST   49152

Definition at line 41 of file socket.c.

Referenced by bind_port(), and sock_bind().

◆ PORT_LAST

#define PORT_LAST   65535

Definition at line 42 of file socket.c.

Referenced by bind_port(), and sock_bind().

◆ RECV_MAX

#define RECV_MAX   (128 * NETBUF_SIZE)

Definition at line 39 of file socket.c.

Referenced by inet_sock_deliver().

Function Documentation

◆ inet_sock_deliver()

void inet_sock_deliver ( struct inet_sock * sock,
struct netbuf * nb )

Queues a received datagram on its socket, and wakes up its readers.

The datagram is dropped if the socket's queue is full or reading is shut down. The netbuf is the socket's from now on.

Parameters
sockthe socket
nbthe datagram's data, with src_ip and src_port set

Definition at line 185 of file socket.c.

References inet_sock_deliver(), netbuf_free(), NETBUF_SIZE, netbuf::next, NULL, inet_sock::recv_bytes, inet_sock::recv_head, RECV_MAX, inet_sock::recv_tail, inet_sock::recv_wait, inet_sock::shut_rd, and waitq_wakeup().

Referenced by icmp_input(), inet_sock_deliver(), and udp_input().

◆ inet_sock_error()

void inet_sock_error ( struct inet_sock * sock,
int err )

Gives a socket an error (from ICMP), which its next call reports.

Parameters
sockthe socket
errthe error (a positive errno)

Definition at line 211 of file socket.c.

References inet_sock::error, inet_sock_error(), inet_sock::recv_wait, and waitq_wakeup().

Referenced by icmp_unreachable_input(), and inet_sock_error().

◆ inet_sock_find()

struct inet_sock * inet_sock_find ( struct netif * netif,
uint8_t proto,
uint32_t local,
uint16_t port,
uint32_t remote,
uint16_t remote_port )

Finds the socket that a received datagram is for: a socket connected to its sender first, or else one that isn't connected.

A socket bound to another interface doesn't count. For ping sockets, the remote port doesn't count.

Parameters
netifthe interface it came in on
protoIP_PROTO_UDP or IP_PROTO_ICMP
localthe address it was sent to
portthe port it was sent to (a ping's identifier)
remotethe sender's address
remote_portthe sender's port
Returns
the socket, or NULL

Definition at line 154 of file socket.c.

References bound, inet_sock_find(), IP_PROTO_ICMP, inet_sock::next, NULL, and inet_sock::proto.

Referenced by icmp_input(), icmp_unreachable_input(), inet_sock_find(), and udp_input().

◆ inet_sockaddr_get()

int inet_sockaddr_get ( const struct sockaddr * addr,
socklen_t len,
uint32_t * ip,
uint16_t * port )

Reads an AF_INET address.

Parameters
addrthe address, in the kernel's memory
lenits size
ipset to its IPv4 address
portset to its port
Returns
0, -EINVAL if it's too short, or -EAFNOSUPPORT

Definition at line 283 of file socket.c.

References inet_sockaddr_get().

Referenced by inet_sockaddr_get(), socket_inet_bind(), socket_inet_connect(), socket_inet_send(), socket_tcp_bind(), and socket_tcp_connect().

◆ inet_sockaddr_put()

void inet_sockaddr_put ( struct sockaddr * addr,
socklen_t * len,
uint32_t ip,
uint16_t port )

Writes an AF_INET address, cut to *len bytes if it doesn't fit.

Parameters
addrwhere to write it
lenits room, set to the address's full size
ipthe IPv4 address
portthe port

Definition at line 306 of file socket.c.

References inet_sockaddr_put(), memcpy(), and MIN.

Referenced by inet_sockaddr_put(), socket_inet_getname(), socket_inet_recv(), socket_tcp_accept(), socket_tcp_getname(), and socket_tcp_recv().

◆ port_used()

int port_used ( uint8_t proto,
uint32_t addr,
uint16_t port )
static

Returns whether a socket of proto is bound to port on addr (or on any address, or addr is any).

Definition at line 80 of file socket.c.

References bound, inet_sock::next, and port_used().

Referenced by bind_port(), port_used(), port_used(), and sock_bind().

◆ sock_bind()

int sock_bind ( struct inet_sock * sock,
uint32_t addr,
uint16_t port )
static

Binds a socket to an address and port, and puts it on the list of bound sockets.

Port 0 picks a free ephemeral port. Returns 0, or -EADDRINUSE.

Definition at line 93 of file socket.c.

References bound, htons, inet_sock::laddr, inet_sock::lport, inet_sock::next, PORT_FIRST, PORT_LAST, port_used(), inet_sock::proto, random_get(), and sock_bind().

Referenced by sock_bind(), socket_inet_bind(), and socket_inet_connect().

◆ sock_unbind()

void sock_unbind ( struct inet_sock * sock)
static

Takes a socket off the list of bound sockets.

Definition at line 128 of file socket.c.

References bound, inet_sock::lport, inet_sock::next, and sock_unbind().

Referenced by sock_unbind(), and socket_inet_shutdown().

◆ socket_inet_bind()

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

Binds a socket to an address that is ours, any address, or the broadcast address.

Ports below 1024 are root's.

Definition at line 320 of file socket.c.

References curproc, inet_sockaddr_get(), IP_PROTO_UDP, ipv4_is_local(), inet_sock::lport, ntohs, inet_sock::proto, sock_bind(), and socket_inet_bind().

Referenced by socket_inet_bind().

◆ socket_inet_can_read()

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

Says whether a read wouldn't wait: a datagram is queued, or there is an error to report, or reading is shut down.

Definition at line 533 of file socket.c.

References inet_sock::error, netbuf::len, inet_sock::recv_head, inet_sock::shut_rd, and socket_inet_can_read().

Referenced by socket_inet_can_read().

◆ socket_inet_can_write()

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

Says that a write never waits.

Definition at line 541 of file socket.c.

References socket_inet_can_write().

Referenced by socket_inet_can_write().

◆ socket_inet_connect()

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

Connects a datagram socket: its default destination, and the only sender it receives from.

AF_UNSPEC disconnects it.

Definition at line 347 of file socket.c.

References inet_sock::connected, inet_sock::error, inet_sockaddr_get(), IP_PROTO_UDP, inet_sock::lport, inet_sock::proto, inet_sock::raddr, inet_sock::rport, sock_bind(), and socket_inet_connect().

Referenced by socket_inet_connect().

◆ socket_inet_create()

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

Makes an AF_INET socket: a TCP, UDP or ping socket.

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

Definition at line 230 of file socket.c.

References socket::domain, FILE_SOCKET, file::flags, IP_PROTO_ICMP, IP_PROTO_UDP, kfree(), kmalloc(), M_ZERO, socket::ops, socket::p, inet_sock::proto, socket::protocol, socket_inet_create(), socket_inet_ops, socket_tcp_create(), and socket::type.

Referenced by socket_create(), and socket_inet_create().

◆ socket_inet_getname()

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

Gets the socket's local address, or its peer's (-ENOTCONN if it isn't connected).

Definition at line 556 of file socket.c.

References inet_sock::connected, inet_sockaddr_put(), inet_sock::laddr, inet_sock::lport, inet_sock::raddr, inet_sock::rport, and socket_inet_getname().

Referenced by socket_inet_getname().

◆ socket_inet_getsockopt()

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

Reads a socket option: SO_ERROR, SO_BROADCAST, SO_BINDTODEVICE or SO_RCVTIMEO.

Definition at line 574 of file socket.c.

References inet_sock::broadcast, inet_sock::error, memcpy(), netif::name, inet_sock::netif, inet_sock::rcvtimeo, socket_inet_getsockopt(), timeval::tv_sec, and timeval::tv_usec.

Referenced by socket_inet_getsockopt().

◆ socket_inet_ioctl()

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

Handles FIONREAD (the size of the next datagram) and the interface requests.

Definition at line 686 of file socket.c.

References inet_ifioctl(), netbuf::len, inet_sock::recv_head, and socket_inet_ioctl().

Referenced by socket_inet_ioctl().

◆ socket_inet_recv()

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

Receives a datagram, waiting for one unless the socket doesn't block or the receive timeout passes.

A datagram longer than the buffer is cut; the rest is lost. Returns its size, 0 once reading is shut down, or a negative errno.

Definition at line 481 of file socket.c.

References arch_rtime_ns(), netbuf::data, inet_sock::error, file::flags, inet_sockaddr_put(), iobuf_out(), netbuf::len, netbuf_free(), NETBUF_SIZE, netbuf::next, NULL, inet_sock::rcvtimeo, inet_sock::recv_bytes, inet_sock::recv_head, inet_sock::recv_tail, inet_sock::recv_wait, sched_wait(), inet_sock::shut_rd, socket_inet_recv(), netbuf::src_ip, and netbuf::src_port.

Referenced by socket_inet_recv().

◆ socket_inet_send()

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

◆ socket_inet_setsockopt()

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

Sets a socket option: SO_BROADCAST, SO_BINDTODEVICE or SO_RCVTIMEO.

Definition at line 627 of file socket.c.

References inet_sock::broadcast, curproc, memcpy(), MIN, netif::name, inet_sock::netif, netif_find(), NULL, inet_sock::rcvtimeo, socket_inet_setsockopt(), timeval::tv_sec, and timeval::tv_usec.

Referenced by socket_inet_setsockopt().

◆ socket_inet_shut()

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

Shuts down reading: the readers wake up and see the end.

Shutting down writing does nothing for a datagram socket.

Definition at line 700 of file socket.c.

References inet_sock::recv_wait, inet_sock::shut_rd, socket_inet_shut(), and waitq_wakeup().

Referenced by socket_inet_shut().

◆ socket_inet_shutdown()

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

Frees the socket when its last descriptor is closed: it is unbound, and its queued datagrams are freed.

Definition at line 714 of file socket.c.

References kfree(), inet_sock::lport, netbuf_free(), netbuf::next, NULL, inet_sock::recv_head, sock_unbind(), and socket_inet_shutdown().

Referenced by socket_inet_shutdown().

◆ socket_inet_wait_queue()

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

Returns the wait queue that the socket's readers sleep on; writers never wait.

Definition at line 548 of file socket.c.

References NULL, inet_sock::recv_wait, and socket_inet_wait_queue().

Referenced by socket_inet_wait_queue().

Variable Documentation

◆ bound

struct inet_sock* bound
static

Definition at line 70 of file socket.c.

Referenced by inet_sock_find(), port_used(), sock_bind(), and sock_unbind().

◆ socket_inet_ops

struct sock_ops socket_inet_ops
static
Initial value:
= {
.connect = socket_inet_connect,
.can_read = socket_inet_can_read,
.can_write = socket_inet_can_write,
.wait_queue = socket_inet_wait_queue,
.getname = socket_inet_getname,
.getsockopt = socket_inet_getsockopt,
.setsockopt = socket_inet_setsockopt,
.shutdown = socket_inet_shutdown,
}
static int socket_inet_bind(struct file *file, const struct sockaddr *addr, socklen_t len)
Binds a socket to an address that is ours, any address, or the broadcast address.
Definition socket.c:320
static ssize_t socket_inet_send(struct file *file, struct iobuf *io, int flags, const struct sockaddr *to, socklen_t tolen)
Sends a datagram, whole: to to, or to the connected peer.
Definition socket.c:381
static int socket_inet_can_write(struct file *file, size_t len)
Says that a write never waits.
Definition socket.c:541
static int socket_inet_setsockopt(struct file *file, int level, int name, const void *val, socklen_t len)
Sets a socket option: SO_BROADCAST, SO_BINDTODEVICE or SO_RCVTIMEO.
Definition socket.c:627
static int socket_inet_ioctl(struct file *file, int request, void *argp)
Handles FIONREAD (the size of the next datagram) and the interface requests.
Definition socket.c:686
static int socket_inet_shut(struct file *file, int how)
Shuts down reading: the readers wake up and see the end.
Definition socket.c:700
static ssize_t socket_inet_recv(struct file *file, struct iobuf *io, int flags, struct sockaddr *from, socklen_t *fromlen)
Receives a datagram, waiting for one unless the socket doesn't block or the receive timeout passes.
Definition socket.c:481
static int socket_inet_connect(struct file *file, const struct sockaddr *addr, socklen_t len)
Connects a datagram socket: its default destination, and the only sender it receives from.
Definition socket.c:347
static int socket_inet_getname(struct file *file, struct sockaddr *addr, socklen_t *len, int peer)
Gets the socket's local address, or its peer's (-ENOTCONN if it isn't connected).
Definition socket.c:556
static int socket_inet_shutdown(struct file *file, int how)
Frees the socket when its last descriptor is closed: it is unbound, and its queued datagrams are free...
Definition socket.c:714
static int socket_inet_can_read(struct file *file, size_t len)
Says whether a read wouldn't wait: a datagram is queued, or there is an error to report,...
Definition socket.c:533
static int socket_inet_getsockopt(struct file *file, int level, int name, void *val, socklen_t *len)
Reads a socket option: SO_ERROR, SO_BROADCAST, SO_BINDTODEVICE or SO_RCVTIMEO.
Definition socket.c:574
static struct waitq * socket_inet_wait_queue(struct file *file, int write)
Returns the wait queue that the socket's readers sleep on; writers never wait.
Definition socket.c:548

Definition at line 72 of file socket.c.

Referenced by socket_inet_create().