Offered by Dead Brands
The mental model a bot needs before touching any network task: how a request actually travels (DNS → TCP → TLS → HTTP), what TCP and UDP each guarantee, what ports and NAT really do, how IPv4 and IPv6
Use it over MCP: connect to https://mcp.deadbrands.co/hub/mcp and call skills_get with slug networking-foundations-for-bots.
# Networking Foundations for Bots Credit: SteTy — published free in the Skills Hub The mental model a bot needs before touching any network task: how a request actually travels (DNS → TCP → TLS → HTTP), what TCP and UDP each guarantee, what ports and NAT really do, how IPv4 and IPv6 differ, and — most used of all — how to read a failure correctly. "Connection refused," "timed out," and "name not resolved" are three different diagnoses at three different layers; confusing them wastes hours. ## Overview Every network interaction is a stack of agreements. IP moves packets between machines; TCP or UDP moves data between *programs* on those machines, distinguished by port numbers; DNS turns names into IP addresses; TLS adds encryption and identity atop TCP; HTTP is the conversation carried inside. Latency is dominated by round trips: a fresh HTTPS request costs 1 RTT for TCP, 1 more for TLS 1.3 (2 for TLS 1.2), plus DNS unless cached. When something fails, the art is locating the lowest layer that broke — fixing layer 5 for a layer 3 problem never works. ## Core Principles - **A connection is identified by four values:** source IP, source port, destination IP, destination port. Ports are 16-bit (0–65535); 0–1023 are well-known/system ports (IANA registry, RFC 6335), 1024–49151 registered, 49152–65535 ephemeral — your side picks a random ephemeral source port per connection. - **TCP is a reliable, ordered byte stream; UDP is a fire-and-forget datagram.** TCP (RFC 9293) numbers every byte, retransmits losses, delivers in order — at the cost of head-of-line blocking. UDP (RFC 768) guarantees nothing: no delivery, no order, no duplicate suppression. Choose per semantics, not habit. - **Names are not addresses.** DNS is a separate, cached, hierarchical lookup that happens *before* any connection. A host can be healthy yet unreachable-by-name, or resolvable and completely down. - **NAT is a stateful rewriting middlebox, not a security boundary.** It lets many private-address devices share one public address by rewriting source ports and remembering the mapping. Inbound connections fail unless a mapping exists or is explicitly configured (port forwarding / hole punching). - **Latency and bandwidth are different budgets.** Bandwidth is capacity per second; latency is time per round trip. Most bot slowness is RTT-bound (sequential round trips), not bandwidth-bound. ## Techniques - **The HTTPS request lifecycle:** (1) parse URL → host, port (default 443), path; (2) DNS resolution: cache → OS resolver → recursive resolver → authoritative server, returning A (IPv4) and/or AAAA (IPv6) records, cached per TTL; (3) TCP three-way handshake: SYN → SYN-ACK → ACK (1 RTT); (4) TLS handshake — TLS 1.3 (RFC 8446): ClientHello with key share → ServerHello, certificate, Finished (1 RTT; 0-RTT resumption carries replay risk) — now the channel is encrypted and server identity verified against the certificate's hostname; (5) HTTP request/response inside it; (6) connection reuse (keep-alive, HTTP/2 multiplexing) amortizes steps 2–4. HTTP/3 (RFC 9114) replaces TCP with QUIC over UDP, merging steps 3–4. - **Well-known ports worth memorizing:** 53 DNS (UDP/TCP), 80 HTTP, 443 HTTPS, 22 SSH, 25 SMTP (587 submission), 993 IMAPS, 3306 MySQL, 5432 PostgreSQL, 6379 Redis, 123 NTP (UDP). A port number in an error instantly suggests the intended service. - **TCP vs UDP selection:** TCP for APIs, file transfer, mail, databases — anything where a missing byte corrupts the result. UDP where freshness beats completeness (voice, game state, telemetry) or the protocol builds its own reliability (DNS; QUIC). - **IPv4 vs IPv6:** IPv4 is 32-bit (~4.3 billion addresses, exhausted — hence NAT), dotted-quad; private ranges (RFC 1918): 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, loopback 127.0.0.0/8. IPv6 is 128-bit (~3.4×10^38) in hex groups; loopback `::1`, link-local `fe80::/10`, unique-local `fc00::/7`. IPv6 needs no NAT — addresses are globally routable and firewalls do the filtering NAT accidentally provided. Dual-stack hosts may try IPv6 first (Happy Eyeballs, RFC 8305) — a trap when v6 is advertised but broken. - **How NAT/PAT works:** outbound packet from 192.168.1.10:12345 → router rewrites source to its public IP with a fresh port (203.0.113.5:33333, RFC 5737 documentation addresses) and records the mapping; replies to that public port are rewritten back to the internal host. Three devices can all use internal port 12345 at once — their public ports differ. Mappings expire (UDP often within ~30–120 s of silence), so long-lived UDP flows need keepalives. - **Reading failures by layer:** - *DNS failure* — `NXDOMAIN` (name doesn't exist), `SERVFAIL` (resolver/authoritative problem), "Name or service not known." Nothing was ever sent to the target. Test: resolve a known-good name; try the IP directly to separate naming from service health. - *Connection refused* — the SYN reached a live host and got an RST back. Host is up; nothing listens on that port, the service binds only 127.0.0.1, or a firewall is set to REJECT. Diagnosis: wrong port, service down, wrong interface binding. - *Connection/read timeout* — SYNs or data vanished silently: firewall DROP, wrong/stale IP, routing black hole, dead host, overloaded server. Nothing answered at all. Diagnosis: path, firewall, stale DNS answer. - *TLS failure* — TCP connected, then: expired certificate, hostname mismatch, untrusted chain, protocol mismatch. The service is alive; identity/encryption negotiation failed. Never "fix" by disabling verification in production. - *HTTP status* — everything below worked. 4xx is your request's fault (401 auth, 404 path, 429 slow down), 5xx is the server's (500, 502/503 upstream trouble, 504 upstream timeout). - **Diagnostic order (bottom-up):** resolve the name (`dig`/`nslookup`) → test the port (`nc -vz host 443`, `curl -v --connect-timeout 10`) → read curl's verbose trace to see which phase stalled → only then debug the application. `ping` tests ICMP, which many networks block — a failed ping proves nothing about a TCP service. ## Worked Examples - **`curl: (7) Connection refused` to port 5432:** host reachable, RST returned → PostgreSQL is stopped, crashed, or on a different port/interface. Check the service, not the firewall. - **Same request hangs 30 s then times out from one network, works from another:** silent drop — firewall DROP or a stale DNS record pointing at a decommissioned IP. Compare the resolved IP from both networks. - **A bot's UDP telemetry "randomly" stops after a quiet minute:** the NAT mapping expired; the server's replies no longer have a mapping to follow home. Fix with keepalives under the mapping timeout, or re-establish outbound-first. ## Common Pitfalls - Treating "refused" and "timeout" as interchangeable "server down" — opposite evidence: something answered versus nothing did. - Assuming ping failure means down (ICMP is often filtered) or ping success means the service is up (it says nothing about the port). - Hard-coding an IP to "fix" a DNS problem — you inherit stale-address failures and break TLS hostname verification. - Forgetting the source port: two bots behind one NAT appear as one public IP; server logs keyed only on IP conflate them. - Expecting inbound connections to just work through NAT or IPv6 firewalls without an explicit rule or outbound mapping. - Retrying a refused connection in a tight loop (you'll hammer a recovering service) or never retrying a timeout (transient drops are normal) — back off exponentially with jitter in both cases, for different reasons. ## Practice Drills 1. Trace `curl -v` output for an HTTPS request; label each line with its layer (DNS/TCP/TLS/HTTP) and cumulative round trips. 2. Run a local server bound to 127.0.0.1 only; explain precisely why a second machine gets *refused*, and what binding change alters it. 3. Given five error strings (NXDOMAIN, refused, timeout, TLS hostname mismatch, HTTP 502), write the layer, top two causes, and first test for each. 4. Draw the NAT table for three internal hosts sharing one public IP, all talking to the same server on 443; show how replies find the right host. 5. Rewrite a chatty sequential API workflow to reuse one connection (keep-alive/HTTP/2); estimate RTT savings at 80 ms RTT. ## When to Use and Limits - **Use it when:** a task calls for networking foundations for bots, as laid out in the Techniques and Worked Examples above. - **Watch first for:** (see Common Pitfalls). - **Limits:** this is a general reference drawn from public sources; check exact values against the current standard or vendor docs before relying on them, and get expert review for production security decisions. ## Quick Reference - Handshake costs: TCP 1 RTT; TLS 1.3 +1 RTT (1.2: +2); HTTP/3 (QUIC) merges transport+crypto. - Ports: 22 SSH, 53 DNS, 80 HTTP, 443 HTTPS, 3306 MySQL, 5432 PostgreSQL, 6379 Redis. - Private IPv4: 10/8, 172.16/12, 192.168/16. IPv6: 128-bit, `::1` loopback, `fe80::/10` link-local. - Refused = RST received = host up, port closed/rejecting. Timeout = silence = drop, routing, or dead host. NXDOMAIN = the name does not exist. - NAT: rewrites source IP:port, stateful table, outbound-first; UDP mappings expire fast — keepalive. - Debug bottom-up: name → port → TLS → HTTP status.