Skip to content
Kavachकवच

Standard Library: std.net

● Intermediate5 min

Every type, method and function of std.net: what the spec lists, then each declaration in its source, with its examples and the line that declares it.

Spec 14.10 · learn it in Sockets.

A declaration below shows what a program writes against: a type's fields, a function's parameters, what it gives, its contracts (require, ensure) and its examples. kavach test runs every example, so each one is true of the code.

What the spec lists

Function or methodGives
net.listen(address) -> Listener ! NetErrorListens for connections at address
listener.address() -> StringThe address it listens at, with the port the system picked
listener.accept() -> Connection ! NetErrorWaits for the next connection
net.connect(address) -> Connection ! NetErrorA connection to address
net.connect_tls(address, protocols: [String] = [], roots: String = "", cert: String = "", key: String = "") -> Connection ! NetErrorA connection encrypted with TLS (1.3, or 1.2 for servers without 1.3). The server's certificate must be valid for the host name in address, checked against root certificates built into Kavach (decision 0021) and the PEM certificates in roots, if any (a company's own certificate authority); there is no way to skip the check. protocols are offered to the server (ALPN), such as ["h2", "http/1.1"]. With cert and key (PEM), the client proves who it is to a server that asks (mutual TLS)
net.listen_tls(address, cert, key, protocols: [String] = [], clients: String = "") -> Listener ! NetErrorListens for TLS connections, proving the server's identity with the certificate chain cert and private key key (PEM text, read with fs.read_text where they are files). key takes a secret (8.7), here and in connect_tls, so a key read with env or kept in a secret field needs no reveal. It chooses the first of protocols a client offers. With clients (PEM certificates), every client must present a certificate signed by one of them (mutual TLS); a client without one is refused while connecting
conn.read() -> Bytes? ! NetErrorWaits for data: the bytes that came (at most 64 KB at a time), or none once the other side has closed
conn.write(data) ! NetErrorSends all of data (Bytes)
conn.protocol() -> String?The protocol the two sides agreed on, from those connect_tls offered and listen_tls takes, or none
conn.peer() -> StringThe other side's address: for a connection a listener accepted, whoever opened it (203.0.113.7:51234)
conn.start_tls(host, protocols: [String] = [], roots: String = "", cert: String = "", key: String = "") -> Connection ! NetErrorTLS begun as a client on a connection that has spoken plain TCP so far, the way PostgreSQL's SSLRequest and SMTP's STARTTLS do it. The server's certificate is checked against host, and the other settings are those of connect_tls. It gives the encrypted connection; conn itself is closed from then on, so nothing is sent in the clear by mistake. key takes a secret, as in connect_tls
conn.accept_tls(cert, key, protocols: [String] = [], clients: String = "") -> Connection ! NetErrorThe server's side of the same: TLS begun on a connection the server accepted, with the settings of listen_tls; key takes a secret
conn.peer_certificate() -> Bytes?The other side's TLS certificate as DER: the server's on a client connection, a client's (mutual TLS) on a server one; none without TLS. For channel binding, such as SCRAM's tls-server-end-point, which hashes it
conn.client_cert() -> ClientCert?With mutual TLS (clients: on listen_tls), the names on the certificate the client showed: ClientCert(common_name:, dns:, uris:), from its subject and its subject-alternative names (a SPIFFE id such as spiffe://shop/orders is a URI); none otherwise (decision 0099)
conn.close()Closes the connection (or stops listening). A connection or listener is also closed when its last holder lets it go (6.1), so one a function opens and doesn't return is closed when the function ends
net.bind(address) -> UdpSocket ! NetErrorA UDP socket at address
sock.send(data, to) ! NetErrorSends data (Bytes) as one datagram to the address to
sock.receive() -> Datagram ! NetErrorWaits for the next datagram: Datagram(data: Bytes, from: String), with the sender's address
sock.address(), sock.close()As for a listener
Function or methodGives
net.connect_quic(address, protocols: [String]) -> Connection ! NetErrorA QUIC connection to address, offering protocols (ALPN, such as ["h3"]); conn.protocol() tells which one the server chose
conn.open_stream(two_way: Bool) -> Int ! NetErrorOpens a stream, two-way or only for sending, and gives its number; waits while the server allows no more
conn.write_stream(stream, data, done: Bool) ! NetErrorSends all of data on the stream; done ends the stream's sending side
conn.read_stream(stream) -> Bytes? ! NetErrorWaits for data on a two-way stream: the bytes that came, or none once the server has ended its side

std.net · net.kav

use std.net: 3 types and 0 functions. stdlib/net/net.kav

NetError type

Why a network operation failed.

pub type NetError = Refused(address: String) |
    TimedOut(address: String) |
    Failed(address: String, reason: String)

ClientCert type

The names of the certificate a client showed a server, with mutual TLS (spec 14.10): its common name, and its DNS and URI subject-alternative names (a SPIFFE id such as spiffe://shop/orders is a URI).

pub type ClientCert {
    pub common_name: String
    pub dns: [String]
    pub uris: [String]
}

Datagram type

A UDP datagram that came in, with the address it came from.

pub type Datagram {
    pub data: Bytes
    pub from: String
}