Part 6 of 10

Networking

How machines find and talk to each other, from packets and protocols to TCP/IP, TLS, and the modern web.

Ch. 24

How Computers Talk: Networking Fundamentals

Every time you load a page, a message travels across the planet, through a dozen machines you'll never see, and back — usually in under a tenth of a second. That this works at all, reliably, between devices built by different vendors running different software, is one of computing's quiet miracles. The trick behind it is layering: instead of one impossibly complex system, networking is a stack of small, independent problems, each solved once and reused everywhere.

The Layered Model

The classic teaching tool is the OSI model — seven conceptual layers describing how data flows down the stack on the sender, across the wire, and back up on the receiver.

The OSI model is useful for vocabulary ("that's a layer-7 load balancer," "this is a layer-2 switch"), but real networks run the leaner TCP/IP model, which collapses those seven into four practical layers:

The point of layering is independence: each layer talks only to the one above and below it through a fixed interface. TCP doesn't care whether your packets travel over fiber or WiFi; HTTP doesn't care whether TCP retransmitted a lost segment. You can swap Ethernet for WiFi, or IPv4 for IPv6, without rewriting a single web server. This is the same modularity principle that governs good software design — narrow interfaces, hidden implementations.

Grand Analogy: Sending a letter through a corporate mail system. You write the letter (Application). You seal it in a tracked envelope (Transport). You write the destination address (Internet). The mail carrier drives it to the next post office (Link). Nobody at any step needs to understand the others' jobs — the address-writer doesn't drive the truck, and the driver doesn't read your letter.

Encapsulation

How does one layer hand data to the next without the layers getting tangled? Each layer wraps the data from the layer above in its own header — like nesting dolls. The receiver unwraps them in reverse.

A useful vocabulary note that trips up beginners: the same bundle of bytes has a different name at each layer. At the Transport layer it's a segment (TCP) or datagram (UDP); at the Internet layer it's a packet; at the Link layer it's a frame. Same data, different wrapper.

IP Addresses

An IP address is the globally meaningful "where" of networking — it identifies a host anywhere on the internet.

IPv4 is a 32-bit address written as four octets, like 192.168.1.100. That's about 4.3 billion addresses — which sounded infinite in 1981 and ran out years ago. IPv6 uses 128 bits (2001:0db8:85a3::8a2e:0370:7334), enough to give every grain of sand on Earth billions of addresses. We've spent two decades slowly migrating, propped up by workarounds like NAT (below).

Certain IPv4 ranges are private — reserved for use inside local networks and never routed on the public internet: 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. Your home devices almost certainly have addresses in one of these.

An address has two parts: a network portion (which network you're on) and a host portion (which device on that network). The dividing line is set by the subnet mask, written in CIDR shorthand as a slash and a bit count.

Analogy: The network portion is the street name; the host portion is the house number. Every house on the same street shares the street name. Routers care about getting your letter to the right street; only the final local delivery cares about the house number.

The Local Hop — MAC Addresses and ARP

IP addresses get a packet to the right network, but the actual hardware on a local network (your WiFi, an office Ethernet) delivers frames using MAC addresses — a permanent 48-bit identifier burned into each network card. IP is logical and routable; MAC is physical and local.

So when your laptop wants to send a packet to 192.168.1.1 (your router), it needs that router's MAC address. It finds it with ARP (Address Resolution Protocol): it shouts to the whole local network, "Who has 192.168.1.1?" and the owner replies with its MAC. This is why the link layer exists as a separate concern — IP is a global abstraction layered on top of whatever local delivery mechanism is actually present.

One more link-layer detail every engineer eventually meets: the MTU (Maximum Transmission Unit), the largest frame a link can carry — typically 1500 bytes on Ethernet. Packets larger than the MTU must be fragmented, which hurts performance, so TCP negotiates a segment size that fits.

Routing — Finding the Way

A packet rarely reaches its destination in one hop. Routers forward it toward its destination one step at a time, each consulting a routing table that maps destination networks to the next router along the way:

Destination Next Hop Interface
10.0.0.0/8 192.168.1.1 eth0
172.16.0.0/16 10.0.0.1 eth1
0.0.0.0/0 (default route) 10.0.0.254 eth1

The last entry, 0.0.0.0/0, is the default route — "if nothing else matches, send it here." It's how your home router handles every address it doesn't specifically know about: it just forwards to your ISP.

Analogy: Routing is like asking for directions in an unfamiliar country. You don't need the whole route — you ask a local, who says "head to the highway." At the highway, a sign says "city center, exit 5." Each step gets you closer, and no single person knows the entire path.

TCP vs UDP — Two Philosophies of Delivery

The Internet layer (IP) makes no promises: packets can be lost, duplicated, or arrive out of order. The Transport layer decides what to do about that, and offers two opposite answers.

Analogy: TCP is registered mail with tracking — you know it arrived, in what order, and lost items are resent. UDP is shouting across a room — fast, but some words may be lost. For a live video call you'd rather drop a frame than pause to recover it, so UDP wins; for a bank transfer, correctness is everything, so TCP wins.

Inside TCP

TCP turns IP's unreliable packet delivery into a reliable, ordered byte stream. It's worth understanding the three mechanisms that make this work — they show up constantly in performance debugging.

The three-way handshake establishes a connection before any data flows, so both sides agree on starting sequence numbers and that the other is reachable.

Sequence numbers and acknowledgements provide reliability. Every byte is numbered; the receiver acknowledges what it has received. If the sender doesn't get an ACK in time, it retransmits:

Sender:   "Here are bytes 1–100"        (SEQ=1)
Receiver: "Got it, send from 101"        (ACK=101)
Sender:   "Here are bytes 101–200"       (SEQ=101)
          ... (packet lost, no ACK) ...
Sender:   (timeout) "Here are 101–200 again"

The sliding window is what makes TCP fast. Rather than waiting for an ACK after every packet (which would waste a full round-trip each time), the sender keeps multiple packets "in flight" up to the window size. As ACKs return, the window slides forward.

Congestion control is the final piece — and a genuinely beautiful piece of distributed cooperation. TCP starts slow ("slow start"), ramps up its sending rate, and backs off sharply the moment it detects packet loss (a signal of congestion). Because every TCP connection on Earth follows this discipline, the internet shares its capacity gracefully instead of collapsing under load.

Analogy: Congestion control is highway driving. You start gently, speed up as the road stays clear, and slam the brakes when you see tail lights ahead (loss) — then cautiously accelerate again. Millions of drivers doing this independently keep traffic flowing without a central controller.

DNS — The Phone Book of the Internet

Humans remember names; machines route to numbers. DNS (Domain Name System) translates www.google.com into an IP address. It's a globally distributed, cached, hierarchical database — and the lookup walks down that hierarchy:

Analogy: DNS is like directory assistance. You ask the operator for "Google," they don't know offhand, so they ask whoever manages .com, who points to Google's own records. Once anyone learns the answer, they remember it (cache it) for a while.

Caching is what keeps DNS fast: your browser, your OS, and your resolver all cache results for the duration of each record's TTL (time-to-live). The vast majority of lookups are answered from cache and never touch the root servers.

Ports and Sockets

An IP address gets you to a machine. But a machine runs many services at once — a web server, a database, an SSH daemon. A port number identifies which service.

The combination of IP address, port, and protocol is a socket — the endpoint of a connection. A full connection is a pair of sockets, and it's this four-tuple (source IP/port + destination IP/port) that uniquely identifies every conversation your machine is having, which is how one server handles thousands of simultaneous clients on a single port.

Analogy: If an IP address is a building's street address, the port is the apartment number. Mail to "123 Main St, Apt 443" reaches the HTTPS tenant specifically.

NAT — One Public IP, Many Devices

Your home has a dozen devices but typically one public IP from your ISP. NAT (Network Address Translation), running in your router, lets them all share it by rewriting addresses and ports as traffic passes through, then reversing the translation on the way back.

NAT was invented as a stopgap for IPv4 exhaustion, but it has a lasting side effect: devices behind NAT aren't directly reachable from the internet, which acts as an accidental firewall — and also why peer-to-peer apps (video calls, games) need clever "hole-punching" tricks to connect two devices that are both behind NAT.

HTTP — The Language of the Web

Atop TCP sits HTTP, the request/response protocol that powers the web. A client sends a request; the server returns a response. Both are plain, structured text (in HTTP/1.1):

HTTP methods describe the intent of a request. The key property to understand is idempotency — whether repeating a request has the same effect as making it once. This matters enormously for retries: a client can safely retry an idempotent request after a network hiccup, but retrying a POST might create a duplicate order.

Method Purpose Idempotent?
GET Retrieve data Yes
POST Create / submit data No
PUT Replace a resource Yes
PATCH Partially update No
DELETE Remove a resource Yes

Status codes tell the client what happened, grouped by their first digit:

Range Meaning Examples
1xx Informational 101 Switching Protocols
2xx Success 200 OK, 201 Created, 204 No Content
3xx Redirection 301 Moved Permanently, 304 Not Modified
4xx Client error 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found
5xx Server error 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable

A reliable mnemonic: 4xx is your fault (the client sent something wrong), 5xx is the server's fault (it failed to handle a valid request).

HTTP Versions — The Quest to Kill Latency

HTTP has evolved to fight one enemy: head-of-line blocking, where one slow item holds up everything behind it.

Analogy: HTTP/1.1 is a one-lane road — one car at a time. HTTP/2 is a multi-lane highway — many cars, one road, but one accident still blocks every lane. HTTP/3 is several independent roads — if one is blocked, the others keep flowing.

HTTPS is simply HTTP carried over an encrypted TLS channel. The next chapter unpacks exactly how that encryption is established without ever sending a secret key in the clear.

The Life of a Web Request

It's worth stitching every layer together with one concrete story — typing example.com and pressing Enter:

  1. DNS resolves example.com to an IP address (cache → resolver → root → TLD → authoritative).
  2. Your OS finds the route; ARP discovers the router's MAC for the local hop.
  3. TCP performs its three-way handshake with the server on port 443.
  4. TLS negotiates an encrypted channel (Chapter 18).
  5. HTTP sends GET / HTTP/1.1; the request is encapsulated down the stack, routed hop by hop across the internet, and reassembled on the server.
  6. The server responds; TCP guarantees the bytes arrive complete and in order; your browser renders the page.

Every concept in this chapter participated in that one tenth of a second. That's the payoff of layering: each piece does one job, and together they make the impossible routine.

Ch. 25

TLS/SSL and Cryptography Basics

When you send a credit card number to a website, it crosses dozens of machines run by strangers. Yet you trust that none of them can read it, tamper with it, or impersonate the site you meant to reach. That trust rests on cryptography — and specifically on TLS (Transport Layer Security, the protocol formerly called SSL), the layer that turns HTTP into HTTPS. This chapter builds up the ideas behind it from the ground.

Cryptography provides three guarantees, and it's worth naming them precisely because they're distinct:

  • Confidentiality — nobody but the intended recipient can read the data.
  • Integrity — any tampering is detectable.
  • Authenticity — you're really talking to who you think you are.

TLS delivers all three. The pieces that make it work are symmetric encryption, asymmetric encryption, hashing, and digital signatures.

Symmetric vs Asymmetric Encryption

Symmetric encryption uses one shared key for both encrypting and decrypting. It's extremely fast — modern CPUs have dedicated instructions for AES — but it has a bootstrapping problem: how do two strangers agree on a secret key over a channel that's being eavesdropped?

Asymmetric (public-key) encryption solves exactly that. Each party has a key pair: a public key anyone may know, and a private key kept secret. Anything encrypted with the public key can only be decrypted with the private key. The catch is that it's far slower than symmetric encryption.

The elegant resolution, used by TLS: use slow asymmetric crypto once, just to agree on a shared secret, then switch to fast symmetric crypto for the actual data. Best of both worlds.

The TLS Handshake

The handshake is where the magic happens — establishing an encrypted, authenticated channel over a wire anyone can read.

Analogy: You and a friend want to pass secret notes in a room full of eavesdroppers. First you verify each other's identity (the certificate). Then, using a clever trick (a key exchange like Diffie–Hellman), you both independently arrive at the same secret number — even though everything you said aloud was overheard. From then on you use that shared secret for fast symmetric encryption.

The "clever trick" is Diffie–Hellman key exchange, and it's worth appreciating why it works: it relies on a mathematical operation that's easy to perform but practically impossible to reverse. Both sides mix their private value with a shared public value; the results can be exchanged in the open, yet only the two participants can combine them into the final shared secret. An eavesdropper sees the public exchanges but cannot derive the secret.

Modern TLS (1.3) insists on forward secrecy: a fresh, ephemeral key is generated for every session and discarded afterward. So even if an attacker records your encrypted traffic today and steals the server's private key years later, they still can't decrypt the old sessions — the keys that protected them no longer exist anywhere.

Certificates and the Chain of Trust

Key exchange protects against eavesdropping, but not against impersonation. What stops an attacker from intercepting your connection and presenting their public key, pretending to be your bank? This is the authenticity problem, and certificates solve it.

A TLS certificate binds a public key to an identity (a domain name) and is digitally signed by a Certificate Authority (CA) — a trusted third party like Let's Encrypt or DigiCert. Your operating system and browser ship with a built-in list of trusted root CAs. When a server presents its certificate, your browser verifies the CA's signature against that trusted list.

Analogy: A certificate is a passport. You don't personally know every traveler, but you trust passports because they're issued by a government you recognize and are very hard to forge. The CA is the passport office; your browser's root store is the list of governments you've decided to trust.

In practice trust forms a chain: a root CA signs an intermediate CA, which signs the server's certificate. Your browser walks the chain up to a root it trusts. If any link is broken, expired, or untrusted, you get the dreaded "Your connection is not private" warning. This whole system — CAs, certificates, chains, and the rules around them — is called PKI (Public Key Infrastructure).

Hashing

A hash function maps input of any size to a fixed-size output (a digest), and it's a one-way street — you cannot reverse a digest back to its input.

A cryptographic hash function (like SHA-256) has three essential properties:

  • Deterministic and one-way — the same input always yields the same digest, but the digest reveals nothing about the input.
  • Avalanche effect — flipping a single input bit changes roughly half the output bits, so similar inputs produce wildly different digests.
  • Collision-resistant — it's computationally infeasible to find two different inputs with the same digest.

Analogy: A hash is a fingerprint. Each input has a unique fingerprint, you can't reconstruct the person from it, but you can instantly verify whether two things match.

These properties make hashing the workhorse of security: verifying that a download wasn't corrupted or tampered with, indexing data, powering blockchains, and — critically — storing passwords.

Digital Signatures and MACs

Hashing plus asymmetric crypto gives us digital signatures, which prove both integrity and authenticity. To sign a message, you hash it and encrypt the hash with your private key. Anyone can decrypt that signature with your public key and compare it to their own hash of the message. If they match, the message is provably unaltered and provably from you (only you hold the private key). This is exactly how a CA signs certificates.

When two parties already share a symmetric key, a lighter-weight tool called a MAC (Message Authentication Code, e.g. HMAC) provides the same integrity-and-authenticity guarantee without the cost of asymmetric crypto — which is why TLS uses MACs to protect each record after the handshake.

Storing Passwords Safely

A common interview question and a real-world minefield: never store passwords as plaintext, and never store them as a plain hash either. Plain hashes are vulnerable to rainbow tables (precomputed hash lookups) and to attackers brute-forcing fast hash functions on stolen databases.

The correct approach:

  • Salt — add a unique random value to each password before hashing, so identical passwords produce different digests and precomputed tables are useless.
  • Use a slow, deliberately expensive hash — algorithms like bcrypt, scrypt, or Argon2 are designed to be slow and memory-hard, so each guess costs an attacker real time and hardware, even though a single legitimate login is unaffected.
stored = argon2( password + unique_salt )   ✓  slow, salted, memory-hard
stored = sha256( password )                  ✗  fast, unsalted — crackable
stored = password                            ✗✗ never

Principal-Level Notes

A few hard-won lessons worth carrying:

  • Don't roll your own crypto. The algorithms are public and well-studied; the bugs live in the implementation — timing side-channels, weak randomness, nonce reuse. Use vetted libraries (libsodium, your platform's TLS stack) and keep them updated.
  • The endpoints are the weak link. TLS protects data in transit, not on the machines at either end. Most breaches happen at rest, in logs, or through compromised credentials — not by breaking the encryption.
  • Encryption is not authentication is not authorization. Confidentiality (can't read it), authenticity (know who sent it), and authorization (allowed to do it) are three separate problems. Conflating them is a classic source of security holes.

Together, these primitives — symmetric speed, asymmetric key agreement, hashing for integrity, and certificates for identity — compose into the small green lock in your address bar, and into the trust that makes commerce on an open, hostile network possible at all.

Ch. 26

Networking Deep Dive: What Happens When You Type a URL

This is the question that ties the whole book together — and a famous interview prompt. Let's trace, end to end, what happens when you type https://www.example.com/page and press Enter. Every layer from earlier parts makes an appearance.

1. URL parsing. The browser splits the URL into scheme (https), host (www.example.com), and path (/page).

2. DNS resolution. The name must become an IP address. The browser checks its cache, then the OS, then asks a resolver, which walks the hierarchy if needed:

browser cache → OS cache → resolver → root → .com TLD → example.com authoritative
→ 93.184.216.34

3. TCP connection. A three-way handshake establishes a reliable channel:

Client → Server:  SYN
Server → Client:  SYN-ACK
Client → Server:  ACK          connection established

4. TLS handshake. Since it's HTTPS, an encrypted channel is negotiated — ClientHello, ServerHello plus certificate, a Diffie–Hellman key exchange, and a derived symmetric key. This costs one or two extra round trips (which HTTP/3 and TLS 1.3 work hard to cut).

5. HTTP request. Finally the actual ask:

GET /page HTTP/2
Host: www.example.com
Accept: text/html
Cookie: session=abc123

6. Server processing. The request hits a load balancer, routes to an app server, matches a route, runs business logic, queries databases, and renders HTML.

7. HTTP response. The server replies with a status, headers, and body:

HTTP/2 200 OK
Content-Type: text/html
Content-Encoding: gzip
Cache-Control: max-age=3600

8. Browser rendering. The browser turns bytes into pixels through a pipeline: parse HTML into the DOM tree, parse CSS into the CSSOM, combine them into a render tree, compute layout (positions and sizes), paint pixels, and composite layers (often on the GPU). Meanwhile it downloads and executes JavaScript, which can mutate the DOM and trigger re-layout and re-paint.

9–10. Subsequent requests and connection reuse. The HTML references CSS, JS, and images, fetched in parallel (HTTP/2 multiplexes them over one connection). The connection is kept alive for reuse, then eventually closed with a TCP FIN handshake.

Putting timings to it reveals where the time actually goes:

Analogy: The whole process is ordering something online. You type the address (URL parsing), look up the store's number (DNS), call and they answer (TCP), verify it's really them (TLS), place your order (HTTP request), they prepare it (server), they ship it (response), and you unbox and assemble it (rendering).

Ch. 27

The Complete Network Stack in Practice

The networking chapters so far traced a request across the internet. This one zooms into the two places where production networking actually lives: the physical data center, and the software layer that now sits between every microservice.

Inside a Data Center

A cloud region is, physically, a building full of racks wired in a hierarchy designed so no single link becomes a chokepoint:

Traffic enters through a border router and firewall, hits a load balancer, and is steered down through aggregation and top-of-rack switches to the actual servers — with a separate high-speed storage network behind it all. Understanding this hierarchy explains real performance facts: two servers in the same rack talk faster than servers in different rows, which is why schedulers care about locality.

Service Mesh

Inside a microservices deployment, every service-to-service call needs the same cross-cutting machinery: encryption, authentication, retries, timeouts, circuit breaking, and observability. Building all of that into every service, in every language, is wasteful and inconsistent. A service mesh extracts it into a sidecar proxy deployed alongside each service:

The application code shrinks to pure business logic; the proxy (Envoy, in meshes like Istio and Linkerd) intercepts all traffic and applies policy uniformly, configured centrally by a control plane. The cost is real — an extra network hop and operational complexity — so a mesh earns its keep only once you have enough services that managing this by hand becomes the bottleneck.

Analogy: A service mesh is a postal system built into an office building. Instead of each office handling its own deliveries, every office has a mailroom (sidecar) that does routing, tracking, and security. The offices just write letters and drop them in the outbox.

Ch. 28

Networking: Advanced Protocols

The earlier networking chapters covered the protocols you use every day. This one goes a level deeper into the mechanisms that keep the internet from collapsing under its own load, the protocol replacing TCP for the web, and the long-overdue securing of DNS.

TCP Congestion Control

If every connection sent as fast as it could, the internet would melt into congestion collapse. Congestion control is the distributed traffic-management system that prevents it — and remarkably, it works with no central coordinator, just every TCP connection following the same rules:

The algorithm has evolved over decades:

Algorithm Approach Used by
TCP Reno Classic — halve the window on loss legacy
TCP CUBIC Cubic recovery curve, scales to fast links Linux default
BBR (Google) Model bandwidth + RTT instead of reacting to loss Google, YouTube

BBR's insight is important: packet loss doesn't always mean congestion (on wireless it's often just interference), so instead of treating every loss as a signal to slow down, BBR measures the actual bottleneck bandwidth and minimum RTT and paces itself to match.

QUIC and HTTP/3

TCP carries deep problems for the modern web: head-of-line blocking (one lost packet stalls every stream sharing the connection), handshake overhead (TCP + TLS costs 2–3 round trips before any data), and ossification (middleboxes inspect TCP headers, making the protocol nearly impossible to evolve). QUIC — which HTTP/3 runs on — rebuilds transport on top of UDP to fix all three:

By folding TLS, multiplexed streams, and congestion control into one layer, QUIC eliminates cross-stream head-of-line blocking, cuts setup to 0–1 round trips, and — because connections are identified by an ID rather than an IP/port pair — lets a connection survive switching from Wi-Fi to cellular without reconnecting.

Analogy: TCP is a single-lane road with traffic lights — one broken-down car blocks everyone. QUIC is a multi-lane highway with a fast-pass: a problem in one lane doesn't stop the others, and you can switch highways without coming to a halt.

Securing DNS

DNS was designed in a more trusting era, with no authentication — which makes cache poisoning possible: an attacker races the real server with a forged reply, redirecting bank.com to their own IP and harvesting credentials. Two complementary defenses address different gaps:

  • DNSSEC cryptographically signs DNS records, so a resolver can verify a response is authentic and untampered — defeating spoofing.
  • DNS over HTTPS / TLS (DoH / DoT) encrypts the DNS query itself, so your ISP (or anyone on the path) can no longer see — or tamper with — which domains you look up.

DNSSEC protects integrity; DoH/DoT protect privacy. Modern systems increasingly use both.