sigil-apps 3f47417 closes the Apps-layer network dark lane. dns_resolve.sg constructs a real UDP DNS A-record query packet and parses the A-record response — the resolver that http_fetch.sg and tls_handshake.sg call to turn hostnames into Cap<NetConn> addresses. tls_handshake.sg constructs a complete TLS 1.3 ClientHello (record header + handshake header + cipher suites + all required extensions) and parses a synthetic ServerHello to verify TLS 1.3 negotiation. Both run arm-el0 (real hardware cap ABI), today using loopback stubs for the final wire step; live ECDH, HKDF, and cert verify on the OS crypto lane when the Kernel grants CAP_NET.
dns_resolve.sg — UDP DNS A-record query
dns_resolve.sg (arm-el0, links net.sg) is the DNS resolver that feeds http_fetch.sg. It constructs a real DNS query packet — the packet that would go on the wire to a real DNS server — and parses the A-record response. Today the wire step uses a loopback stub from net.sg (a canned DNS response bytes); when Cap<NetConn> UDP syscall 109-112 lands, the same code path sends to :53 unchanged.
hostname. Wire format: 12-byte header (ID=id, FLAGS=0x0100 QR/RD, QDCOUNT=1) + QNAME (length-prefixed labels: "sigil"→\x05sigil, "os"→\x02os, terminator \x00) + QTYPE=0x0001 (A) + QCLASS=0x0001 (IN). Output length returned; out receives raw bytes.Cap<NetConn> send.sys-109 UDP recv replaces.out_ip[0..3]. Returns 0 on success, -1 on bad format.Resolves sigil.os / sigil-pi.local / github.com in the test path, printing the resolved IPv4 for http_fetch (tcp://<ip>:80) and tls_handshake (:443).
Live wire-in: Cap<NetConn> sys-109 UDP send/recv replaces the dns_response loopback stub. No other code changes — the packet construction and parse path are wire-compatible today.
tls_handshake.sg — TLS 1.3 ClientHello
tls_handshake.sg (arm-el0, standalone, 249 lines) constructs a complete TLS 1.3 ClientHello and parses a synthetic ServerHello to verify TLS 1.3 negotiation. This is the "dark TLS lane" — the Apps-layer exercise of the protocol that the OS tls_client.sg (0ecc2f6) implements kernel-side. The two paths converge when the Kernel grants CAP_NET and ECDH + HKDF + cert verify run on OS crypto.
ClientHello construction
0x16 (handshake), legacy version 0x0301 (TLS 1.0 compatibility), length (2 bytes, filled after body). All TLS 1.3 records use 0x0301 in the record layer; the actual version is negotiated in the supported_versions extension.0x01 (ClientHello), length (3 bytes). Followed by legacy version 0x0303 (TLS 1.2 compatibility, required by RFC 8446 §4.1.2).sys_random when available).TLS_AES_128_GCM_SHA256 (0x1301) + TLS_AES_256_GCM_SHA384 (0x1302). Both are TLS 1.3-only; no TLS 1.2 suites offered (sigilOS browser does not support TLS 1.2).[0x0304] (TLS 1.3 only). This is the extension that actually negotiates TLS 1.3; the record/handshake legacy versions are ignored by TLS 1.3 servers.host_name (0), length-prefixed. Required for virtual hosting on shared IPs. Value set from the hostname passed to tls_handshake_build.[x25519] (0x001d). ECDH key exchange curve. Matches the OS tls_client.sg curve preference.[ecdsa_secp256r1_sha256, rsa_pss_rsae_sha256] (0x0403, 0x0804). Covers the cert types expected from modern CAs.ServerHello parse
0x16, handshake type=0x02, cipher suite matches one of the offered suites, supported_versions extension present with value 0x0304. Returns 0 on success (TLS 1.3 confirmed), -1 on mismatch.Live path and convergence with OS tls_client.sg
The tls_handshake.sg arm-el0 path validates the packet construction and parse logic independently of the OS crypto layer. When the Kernel grants CAP_NET, the live path activates: ECDH key agreement (x25519 scalar multiply), HKDF key derivation (HKDF-Extract + HKDF-Expand-Label for HS/MS/key material), and cert chain verify all run via OS tls_client.sg sys 117–119. The Apps-layer tls_handshake.sg and the OS tls_client.sg (0ecc2f6) share the same wire format and curve preference — they converge on the same crypto substrate.
dns_resolve.sg
→ dns_query() # construct UDP DNS A-record packet (wire-compatible)
→ dns_response() # loopback stub (→ sys-109 UDP recv when CAP_NET lands)
→ dns_parse_a() # extract IPv4 from A-record RDATA
→ ip passed to http_fetch / tls_handshake
tls_handshake.sg
→ tls_handshake_build(hostname)
record hdr (0x16 / 0x0301)
handshake hdr (0x01 / 0x0303)
client_random [32B]
cipher_suites [0x1301, 0x1302]
ext: supported_versions [0x0304]
ext: server_name (SNI)
ext: supported_groups [x25519]
ext: signature_algorithms [0x0403, 0x0804]
ext: key_share x25519 [32B stub]
→ tls_parse_server_hello() # verify TLS 1.3 negotiated
→ live: ECDH + HKDF + cert verify via tls_client.sg sys 117-119