net.dtls
import net
netexposes this asnet.dtls, soimport netis enough and the names are called asnet.dtls.*.import net.dtlsreaches the same definitions directly.
Datagram Transport Layer Security over a UdpSocket - the same
certificate-based encryption and authentication tls provides, for
protocols built on UDP instead of TCP.
Unlike tls, DtlsSocket owns its own socket rather than wrapping one
you’ve already opened: a UDP port has no OS-level concept of a per-peer
connection, so a single bound DtlsSocket multiplexes every accepted
peer itself, by remote address.
A client:
import net.dtls
var config = dtls.DtlsConfig()
var socket = dtls.DtlsSocket()
socket.connect(config, '203.0.113.10:5684')
socket.write('hello')
echo socket.read(1024)
socket.close()
A server, accepting many clients on one bound port:
import net.dtls
var config = dtls.DtlsConfig()
config.set_cert_chain(cert_chain_pem, private_key_pem)
var server = dtls.DtlsSocket()
server.bind('0.0.0.0:5684')
while true {
var client = server.accept(config)
echo 'connection from ${client.peer_address()}'
client.write('hello over DTLS')
}
Classes
DtlsConfig
class net.dtls.DtlsConfig
The trust roots and optional certificate a DTLS handshake needs - the
same idea as tls.TlsConfig, minus the TLS-specific ALPN/version
options DTLS doesn’t have.
Constructor
net.dtls.DtlsConfig()
Returns a new DtlsConfig with sensible defaults: the bundled Mozilla
root certificate list and no client/server certificate.
DtlsConfig.native_ptr()
net.dtls.DtlsConfig.native_ptr() -> Ptr
Hands out this config’s underlying native handle - DtlsSocket needs it
and, like any _-prefixed field, _ptr isn’t otherwise reachable from
outside this class.
Returns Ptr
DtlsConfig.set_root_store()
net.dtls.DtlsConfig.set_root_store(mode)
Chooses where trusted root certificate authorities come from. Same
meaning as tls.TlsConfig.set_root_store().
Parameters
mode(string) —'bundled'or'native'
Raises Error if mode is neither, or (for 'native') if the OS
trust store can’t be read
DtlsConfig.add_ca_pem()
net.dtls.DtlsConfig.add_ca_pem(pem)
Adds one or more PEM-encoded certificates to this config’s trusted
roots. Same meaning as tls.TlsConfig.add_ca_pem().
Parameters
pem(string) — One or more PEM-encoded CA certificates
Raises Error if none of the certificates in pem could be parsed
DtlsConfig.set_cert_chain()
net.dtls.DtlsConfig.set_cert_chain(cert_chain_pem, key_pem)
Sets the certificate chain and private key this side presents. Required
before DtlsSocket.accept() can be used with this config.
Parameters
cert_chain_pem(string) — The end-entity certificate followed by any intermediate certificates, all PEM-encodedkey_pem(string) — The PEM-encoded private key matching the end-entity certificate
Raises Error if either PEM can’t be parsed, or if the key doesn’t
match the certificate
DtlsConfig.require_client_cert()
net.dtls.DtlsConfig.require_client_cert(required)
For a server config: whether to require the connecting peer to present a trusted certificate (mutual TLS).
Parameters
required(bool)
DtlsConfig.set_insecure()
net.dtls.DtlsConfig.set_insecure(insecure)
Disables certificate verification entirely. Same meaning, and same
“development and testing only” caveat, as
tls.TlsConfig.set_insecure().
Parameters
insecure(bool)
DtlsSocket
class net.dtls.DtlsSocket
A DTLS socket, in either its connected (client or accepted-server) role or its listening role.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
net.dtls.DtlsSocket(_ptr)
Returns a new, unbound DtlsSocket. Call bind() to listen for
incoming connections, or connect() to dial out to one.
DtlsSocket.bind()
net.dtls.DtlsSocket.bind(address)
Binds this socket to address and prepares it to accept incoming DTLS
associations via accept().
Parameters
address(string|SocketAddr) — The host:port to bind and listen on
Raises Error if binding fails (e.g. the address is already in use)
DtlsSocket.connect()
net.dtls.DtlsSocket.connect(config, address, server_name)
Opens a DTLS association with address, performing the full handshake
before returning. server_name is used to verify the peer’s
certificate, the same way tls.TlsStream.connect() uses it; omit it to
fall back to verifying against the resolved IP address instead of a
hostname.
Parameters
config(DtlsConfig) — The trust roots and options to handshake withaddress(string|SocketAddr) — The host:port to connect toserver_name(?string) — The hostname to verify the peer’s certificate against
Raises Error if resolution or the handshake fails, or the peer’s
certificate isn’t trusted or doesn’t match server_name
DtlsSocket.accept()
net.dtls.DtlsSocket.accept(config) -> DtlsSocket
Waits for the next peer to complete a handshake and returns a new
DtlsSocket representing that specific peer’s association. Only valid
on a bound socket. Blocks (subject to set_read_timeout()) until a new
peer finishes handshaking; existing peers’ traffic keeps flowing to
their own DtlsSocket instances in the meantime.
Parameters
config(DtlsConfig) — Must have a certificate chain set viaDtlsConfig.set_cert_chain()
Returns DtlsSocket — a socket for the newly accepted peer
Raises Error if this socket isn’t bound, config has no
certificate chain, or (with require_client_cert()) a peer’s handshake
didn’t present a trusted certificate
DtlsSocket.read()
net.dtls.DtlsSocket.read(length) -> bytes
Reads the next decrypted application-data message, up to length bytes
of it. DTLS preserves message boundaries the way UDP does: this always
returns one whole message (truncated to length if it was longer),
never a partial one glued to the next.
Parameters
length(number) — The maximum number of bytes to return
Returns bytes — the next message, up to length bytes
Raises Error on an underlying I/O or DTLS record error, or if the
configured read timeout elapses first
DtlsSocket.write()
net.dtls.DtlsSocket.write(data) -> number
Encrypts and sends data as a single application-data message to the
peer this socket is connected/accepted for.
Parameters
data(bytes|string) — The bytes (or UTF-8 text) to send
Returns number — the number of bytes sent
Raises Error on an underlying I/O or DTLS record error
DtlsSocket.local_address()
net.dtls.DtlsSocket.local_address() -> SocketAddr
The local socket address this instance is bound to.
Returns SocketAddr
Raises Error if this socket isn’t bound
DtlsSocket.peer_address()
net.dtls.DtlsSocket.peer_address() -> SocketAddr
The remote peer’s socket address.
Returns SocketAddr
Raises Error if this socket isn’t a connected/accepted association
DtlsSocket.set_read_timeout()
net.dtls.DtlsSocket.set_read_timeout(timeout)
Sets how long read() may block before raising a timeout error. Pass
0 (or any negative number) to block indefinitely, which is the
default.
Parameters
timeout(number) — Milliseconds, or a non-positive number to disable the timeout
DtlsSocket.close()
net.dtls.DtlsSocket.close()
Releases this socket. Safe to call more than once. Only closes this
particular peer association’s bookkeeping - if this is a listening
socket, other already-accepted DtlsSocket instances sharing its
underlying bound port are unaffected.
DtlsSocket.peer_certificate()
net.dtls.DtlsSocket.peer_certificate() -> ?PeerCertificate
The peer’s end-entity certificate, or nil if the peer didn’t present
one.
Returns ?PeerCertificate
DtlsSocket.to_string()
net.dtls.DtlsSocket.to_string()
2026, Richard Ore and Zuri contributors