Skip to content

Update L7 APIs to be transport agnostic#42

Merged
gregnr merged 8 commits into
mainfrom
feat/transport-agnostic-apis
May 28, 2026
Merged

Update L7 APIs to be transport agnostic#42
gregnr merged 8 commits into
mainfrom
feat/transport-agnostic-apis

Conversation

@gregnr

@gregnr gregnr commented May 22, 2026

Copy link
Copy Markdown
Member

Currently each L7 API (@tcpip/http, @tcpip/dns,@tcpip/dhcp) depends on a tcpip NetworkStack as the transport layer that their protocols operate on top of (@tcpip/http uses stack.connectTcp(), @tcpip/dns uses stack.openUdp(), etc).

This PR does a number of API changes to make these L7 APIs transport agnostic - meaning that a tcpip NetworkStack is only one implementation of TCP/UDP, but you can plug in your own transport if you want. In the future we'll add helpers that would allow you to use these L7 APIs on top of Node and Deno TCP/UDP APIs.

The core change is that each L7 factory function accepts transport interface instead of a NetworkStack. The stateful TCP-style transport is called StreamTransport with connect() and listen() methods, and the connectionless UDP-style transport is called DatagramTransport with an open() method. Anyone can implement these methods to provide the underlying stream or datagram style transport that the higher level protocol operates on top of. @tcpip/http uses StreamTransport, @tcpip/dns and @tcpip/dhcp use DatagramTransport.

To make tcpip match these transport interfaces, we changed NetworkStack to nest protocol methods within their own objects:

const stack = await createStack();

stack.tcp // TcpTransport, implements StreamTransport
stack.udp // UdpTransport, implements DatagramTransport
stack.ping // Ping API, includes createSession() method
stack.interfaces // Manages network interfaces, e.g. createTun(), createTap(), etc

It is arguably a better API anyway, because it groups methods within each protocol vs a flat list of methods between all protocols. Because stack.tcp implements StreamTransport, using it in @tcpip/http is as simple as:

import { createStack } from 'tcpip';
import { createHttp } from '@tcpip/http';

const stack = await createStack();
const { fetch, serve } = await createHttp(stack.tcp);

And the same applies to other L7 APIs (e.g. @tcpip/dns with stack.udp).

This is a breaking change for most packages.

@gregnr gregnr merged commit 28f64b1 into main May 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant