Skip to content

Add fd injection and in-process pipe connect for vws server#11

Open
vrtql wants to merge 3 commits into
mainfrom
claude/add-socketpair-pipe-example-29KnU
Open

Add fd injection and in-process pipe connect for vws server#11
vrtql wants to merge 3 commits into
mainfrom
claude/add-socketpair-pipe-example-29KnU

Conversation

@vrtql
Copy link
Copy Markdown
Owner

@vrtql vrtql commented Apr 25, 2026

Adds three new APIs that together allow an in-process WebSocket
connection over a uv_socketpair():

  • vws_tcp_svr_inject_fd(server, fd): thread-safe injection of an
    already-connected stream fd into a running server's libuv loop.
    Pushes onto a per-server queue and signals a uv_async_t; the loop
    thread drains the queue and adopts each fd as a uv_pipe_t.

  • vws_cnx_from_fd(cnx, fd): bypass DNS/TCP and adopt an existing fd
    as a vws client, switching it to non-blocking and running the
    standard handshake.

  • vws_pipe_connect(server): one-shot helper that creates a
    socketpair, hands one end to the server, wraps the other as a
    fully-handshaken vws_cnx and returns it.

The server must be running on a different thread than the caller of
vws_pipe_connect(), since the client handshake blocks waiting for
the server's HTTP upgrade response.

Includes test/test_pipe_server demonstrating the round trip.

claude added 3 commits April 25, 2026 05:29
Adds three new APIs that together allow an in-process WebSocket
connection over a uv_socketpair():

- vws_tcp_svr_inject_fd(server, fd): thread-safe injection of an
  already-connected stream fd into a running server's libuv loop.
  Pushes onto a per-server queue and signals a uv_async_t; the loop
  thread drains the queue and adopts each fd as a uv_pipe_t.

- vws_cnx_from_fd(cnx, fd): bypass DNS/TCP and adopt an existing fd
  as a vws client, switching it to non-blocking and running the
  standard handshake.

- vws_pipe_connect(server): one-shot helper that creates a
  socketpair, hands one end to the server, wraps the other as a
  fully-handshaken vws_cnx and returns it.

The server must be running on a different thread than the caller of
vws_pipe_connect(), since the client handshake blocks waiting for
the server's HTTP upgrade response.

Includes test/test_pipe_server demonstrating the round trip.
The previous docstring said the function "switches the fd to non-blocking"
which was misleading -- the client API is intentionally blocking-with-
timeout. The fd is placed in O_NONBLOCK only so the internal poll()-driven
read/write loops can drive it (same as vws_connect() does after a TCP
connect). Caller-facing send/recv semantics are unchanged.
Frame masking exists to defeat cache-poisoning attacks on intermediate
proxies. A socketpair has no proxies, so masking is pure overhead -- it
adds a 4-byte mask key per frame, an RAND_bytes() call, and a per-byte
XOR over the payload. Calling vws_cnx_set_server_mode() inside
vws_pipe_connect() skips all of that. The server's frame parser already
accepts both masked and unmasked frames so no server-side change is
needed.
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.

2 participants