@@ -110,6 +110,9 @@ \subsection{Contributions}
110110\item A modular architecture following an ABI/FFI/API triple that enables
111111 polyglot participation without compromising type safety
112112 (Section~\ref {sec:polyglot }).
113+ \item A zero-copy, frame-level IPv4$ \rightarrow $ IPv6 proxy implemented in Zig
114+ that transparently translates legacy connections using \texttt {splice(2) },
115+ requiring no elevated privileges (Section~\ref {sec:transport }).
113116\item A reference implementation across four independent systems demonstrating
114117 the protocol's practical applicability (Section~\ref {sec:implementation }).
115118\end {enumerate }
@@ -376,21 +379,79 @@ \subsection{Browser Extension Harness}
376379constraints. This provides a type-safe bridge between the browser security
377380sandbox and native desktop services.
378381
379- \section {Transport Considerations }
382+ \section {Transport: IPv6-First with Frame-Level Translation }
383+ \label {sec:transport }
380384
381- Groove mandates dual-stack binding (\texttt {[::]:PORT }) to ensure
382- discovery works on IPv4-only, IPv6-only, and dual-stack systems. Discovery
383- probes IPv6 first (following RFC~8305 Happy Eyeballs), with IPv4 fallback.
385+ \subsection {IPv6 as Default Transport }
386+
387+ Groove specifies IPv6-only binding (\texttt {[::1]:PORT }) as the recommended
388+ configuration for localhost discovery. Every operating system capable of
389+ running the Groove toolchain (Idris2, Zig) has a functional IPv6 loopback
390+ interface. IPv4 is treated as a legacy transport with an explicit sunset
391+ path.
384392
385393For LAN discovery beyond localhost, Groove uses mDNS/DNS-SD over IPv6
386- multicast (\texttt {ff02::fb }), leveraging link-local addresses that require
387- no DHCP configuration. LAN discovery is explicitly opt-in; the default
388- scope is localhost-only.
394+ multicast (\texttt {ff02::fb }), leveraging link-local addresses (\texttt {fe80:: })
395+ that require no DHCP configuration. LAN discovery is explicitly opt-in; the
396+ default scope is localhost-only.
397+
398+ \subsection {Frame-Level IPv4$ \rightarrow $ IPv6 Proxy }
399+
400+ For systems that must accept IPv4 connections during a transition period,
401+ we introduce a frame-level proxy that operates at the TCP stream layer
402+ (Layer~4) rather than the HTTP application layer (Layer~7). This provides
403+ transparent, zero-copy IPv4$ \rightarrow $ IPv6 translation.
404+
405+ The proxy accepts IPv4 TCP connections and opens a corresponding IPv6 TCP
406+ connection to the Groove service on \texttt {[::1]:PORT }. Bytes are spliced
407+ bidirectionally using the kernel's \texttt {splice(2) } syscall, which
408+ transfers data between socket file descriptors without copying to userspace.
409+
410+ \ begin{lstlisting} [caption={Frame-level proxy data path}]
411+ Client (IPv4) --> [accept] --> Frame Proxy --> [splice] --> Service (IPv6)
412+ Client (IPv4) <-- [splice] <-- Frame Proxy <-- [splice] <-- Service (IPv6)
413+ \end {lstlisting }
414+
415+ This approach has several advantages over HTTP-level upgrade directives:
416+
417+ \begin {enumerate }
418+ \item \textbf {Zero-copy }: On Linux, \texttt {splice(2) } moves data between
419+ sockets via kernel pipe buffers. No bytes are copied to userspace.
420+ \item \textbf {Transparent }: The client is unaware of the translation. No
421+ reconnection, no upgrade headers, no protocol awareness needed.
422+ \item \textbf {Protocol-agnostic }: Works for any protocol inside the TCP
423+ stream --- HTTP, WebSocket, gRPC, binary frames, or raw bytes. The proxy
424+ does not parse content.
425+ \item \textbf {No elevated privileges }: Runs in userspace without kernel
426+ modules, \texttt {nftables } rules, or eBPF programs.
427+ \end {enumerate }
428+
429+ The proxy is implemented in approximately 60 lines of Zig, with
430+ \texttt {splice(2) } on Linux and a 4KB userspace buffer fallback on
431+ macOS and Windows.
432+
433+ \begin {property }[Transport Transparency]
434+ The frame-level proxy preserves all Groove protocol properties. From the
435+ perspective of the Groove service, all connections arrive on IPv6. From
436+ the perspective of the client, the connection succeeds on IPv4 with no
437+ visible translation.
438+ \end {property }
439+
440+ For browser extensions, which cannot perform raw TCP operations, the
441+ protocol falls back to HTTP-level upgrade headers:
442+ \texttt {Groove-IPv6-Preferred } and \texttt {Groove-Upgrade-To } directives
443+ instruct the extension to reconnect on \texttt {[::1] } for subsequent
444+ requests. This is analogous to HSTS (HTTP Strict Transport Security)
445+ applied to the network layer rather than the encryption layer.
446+
447+ \subsection {CORS and the Browser Boundary }
389448
390449All Groove HTTP endpoints include CORS headers to enable browser extension
391450access. Control-plane traffic uses HTTP/1.1; data-plane traffic may use
392451any transport (WebSocket, gRPC, WebRTC, Unix sockets) as declared in the
393- capability interface definition.
452+ capability interface definition. The Idris2 ABI layer provides type-safe
453+ proofs that cross the browser--native boundary, ensuring structural
454+ compatibility between the browser security sandbox and local services.
394455
395456\section {Evaluation }
396457
0 commit comments