fix: support SDK TLS edges and client-facing node origins - #194
Merged
Merged
Conversation
The TLS edge support parsed and validated every address on every control request and every relay dial: sdk/go went from 28 ns/1 alloc to 246 ns/4 allocs per request, and Python built a default SSL context per Client (+5.5 ms) and a fresh urllib opener per request (+0.26 ms). Addresses are now validated once at Connect; requests concatenate the scheme, relay dials split the authority without url.Parse, and Python builds its TLS context and HTTPS opener lazily on the first https use. Measured on loopback: Go 39 ns/1 alloc per request and 19 ns/0 allocs per dial; Python Client() 5.5 ms -> 3.5 us, info() 540 -> 279 us. Connect keeps a bare entry address bare, http being the default scheme, so Owner() and the origin fallback read as before on plain HTTP. Both Go validators now reject a bare trailing '#' like the Python one (sandboxd accepted https://node#, which every Python client refused). Relay TLS failures raise ProtocolError like the plaintext dial. push()'s docstring states the real contract: a truncated stream leaves dest untouched. The Caddy test holds both edge ports until Caddy binds them. silkdtest's duplicate PortForward case and endpointURL's unreachable control-character clause are gone.
Connect's own http.Client used http.DefaultTransport, which keeps two idle connections per host: a client issuing 100 concurrent claims re-dialed about 98 of them on every burst (24.5 ms and 98 TCP dials per burst on loopback, and the ephemeral port range ran out under sustained load). Connect now clones the default transport with 100 idle connections per host: 1.4 ms and one dial per burst. A caller's own transport from WithHTTPClient keeps its settings. The relay dial cloned a tls.Config with no ClientSessionCache, so every RPC behind an HTTPS edge paid a full handshake. The client now owns one LRU session cache shared by the control-plane transport and the relay dials: 1.6 ms -> 0.6 ms per relay dial on loopback, 99% resumed. The config is materialized once in configureTLS, so dialAgent no longer special-cases a missing one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #192.
Upgrade: silkdrelays. Go acceptsWithTLSConfig; Python accepts a standardssl_context. Bare owner/peer addresses inherit the entry scheme; explicit schemes win.client_advertise, gossiped separately from internaladvertise_addr. Owners, all claim/template/checkpoint redirects, and peer discovery return client origins. Preview forwarding and checkpoint peer traffic retain internal HTTP addresses.data_endframe, without shutting down the Python TLS socket underneath the response stream.Verification
0 issuesresults). ASL hard gates pass on both targets.true, lookup, real guest HTTP via port relay and local proxy, half-close and release; Go fork passes. Repeated both SDK sequences directly over plaintext HTTP on the node withclient_advertiseunset.ghcr.io/cocoonstack/sandbox/rt@sha256:72eac39c87af2060ba82ac0eb15e1165ac54d513f197cf6611037324379dd456; tested sandboxd binary SHA-256:6b141f4e0211191754259aaea214b9dec9bf9d91c286f9183a6b7484178cad67. Isolated VMs, daemons and scratch data removed after verification.Local review is closed: no unresolved correctness findings. Existing ASL advisory predicate helpers are retained. Relative to main: production source -30 lines, tests/fixtures +583 lines, docs/config +159 lines (physical lines, including comment normalization).
Deployment contract
Each node needs its own stable client-facing origin; one randomly balanced owner hostname is insufficient. All external-client nodes must publish these origins.
client_advertiseis not an SDK argument, and sandboxd itself remains a plain-HTTP upstream.