UDP connect() Sends Nothing, and getsockname() Gives You Your Local IP

A machine with Wi-Fi, a VPN and a container bridge has several addresses, and a hostname lookup can return the wrong one. Connecting a UDP socket to a destination makes the kernel pick the source address it would use, and getsockname() reads it back without a single packet being sent. Checked on Linux with three interfaces: five destinations, five answers, no IPv4 or ARP frames on the wire.

October 5, 2026 | 10 min

Cancel the Stream, Not the Connection, When One HTTP/2 Request Times Out

A request deadline fired on a connection that carries many requests at once. Do you close the connection, or only the request? In a small Node lab, closing the HTTP/2 session failed two innocent requests, while cancelling only the stream let them finish on the same TCP connection. The same lab shows the one case where cancelling is not enough: a lost packet stalls every stream on a TCP connection, and a connection-level PING is the right way to tell.

September 8, 2026 | 19 min

Waiting for bufferedAmount Protects the Sender, Not a Slow Consumer

WebSocket send() never waits, and bufferedAmount only sees the part of the path that is in your own process. In a small lab, a sender that politely waited for bufferedAmount to drain still let a slow consumer queue nearly all 400 messages in its own memory, while a credit window of 8 kept the backlog at 8. This post goes through four common beliefs about send(), bufferedAmount, message size and backpressure, tests each one, and ends with a table for choosing between them.

September 6, 2026 | 14 min

Two write() Calls Can Stall a TCP Connection for 40 ms

Send a header and a body as two small write() calls, then wait for a reply, and every round trip can stall for about 40 ms on an idle machine with an idle network. Neither Nagle’s algorithm nor delayed ACK is a bug; together they deadlock until a timer fires. This post predicts the stall, reproduces it with a 50-line script, reads it off a packet trace, and compares the four ways out.

September 1, 2026 | 13 min

A Dead TCP Peer Goes Unnoticed for 15 Minutes on Writes, Forever on Reads

TCP never tells you that the peer is gone. A reader blocks forever, a writer keeps retransmitting for a quarter of an hour, and SO_KEEPALIVE does nothing while data is unacknowledged. This post builds a one-file Linux lab with no root, climbs a ladder of mechanisms (nothing, keepalive, TCP_USER_TIMEOUT, an application heartbeat), measures how long each takes to notice, and shows where NAT and the RFCs fit in.

August 23, 2026 | 19 min

When a WebSocket Outlives Its Token

After the 101 response, no request carries credentials: the server remembers a verdict, not the evidence. This article follows one token through a browser handshake, shows what a page can and cannot see, and compares three ways to renew it (reconnect, in-band, out-of-band) with a runnable server, tests, and a headless-Chrome check.

August 21, 2026 | 20 min

Keeping an Agent Resident Behind NAT

Designing a resident agent behind NAT with outbound connections, separate liveness checks, and on-demand SSH sessions for interactive access.

August 3, 2026 | 16 min