📁 Sangam Dhakal - Portfolio v2.0 - Netscape Navigator 4.0
_
□
×

📚 Interview question

Walk me through what happens, at the network level, when a .NET client calls https://api.example.com/orders/42 and gets a response.

An end-to-end tour of one HTTPS request: DNS, IP routing, ports, TCP handshake, TLS, HTTP, load balancers and proxies, connection reuse, and where time goes.

Intermediate Theory Intermediate dns fundamentals http networking tcp tls

🎯 Key points

  • DNS resolves api.example.com to IPv4 (A) and IPv6 (AAAA) addresses with a TTL; .NET asks the OS resolver and keeps no DNS cache of its own, and SocketsHttpHandler tries the returned addresses in order.
  • Packets are routed hop by hop by destination IP, usually through NAT on the client side and often through a CDN or WAF at the edge.
  • TCP connects to port 443 with a three-way handshake (SYN, SYN-ACK, ACK), costing one round trip before any data flows.
  • TLS 1.3 adds one round trip: the client sends SNI and ALPN, the server proves its identity with a certificate, and the client validates the chain and hostname.
  • ALPN usually picks HTTP/2, which multiplexes many requests over one connection with HPACK header compression; HTTP/3 over QUIC (UDP) merges transport and TLS setup and avoids TCP head-of-line blocking.
  • A load balancer or ingress often terminates TLS and forwards to an app instance, adding X-Forwarded-For and X-Forwarded-Proto headers that ASP.NET Core must be configured to trust.
  • Connection reuse in HttpClient's pool skips DNS, TCP and TLS on later requests, so a cold call can be three or four times slower than a warm one.
  • Measure each phase separately with curl -w, the System.Net metrics in dotnet-counters, or OpenTelemetry and Application Insights dependency spans, to find whether time goes on DNS, connect, TLS or the server.

⏱ 30-second answer

  1. DNS: resolve api.example.com to an IP address (OS cache, then a resolver).
  2. IP routing: packets go from my machine through routers (and usually NAT) to that IP.
  3. TCP: connect to port 443 with a three-way handshake (SYN, SYN-ACK, ACK). One round trip.
  4. TLS: negotiate keys and verify the server's certificate for api.example.com (TLS 1.3: one more round trip).
  5. HTTP: send GET /orders/42 with headers; often a load balancer or reverse proxy terminates TLS and forwards to an app instance.
  6. Response comes back on the same connection, which HttpClient keeps alive and reuses for the next request, skipping steps 1–4.

On a cold connection, DNS + TCP + TLS can cost more than the request itself, which is why connection reuse matters.

🗣 Full answer (senior)

The journey

.NET HttpClient                                                   api.example.com
     │
 1   │── DNS query: api.example.com A/AAAA? ──► resolver ──► answer 203.0.113.10 (TTL 60)
     │
 2   │── SYN ────────────────────────────────────────────►  load balancer :443
     │◄── SYN-ACK ──────────────────────────────────────────  (1 RTT)
     │── ACK ────────────────────────────────────────────►
     │
 3   │── TLS ClientHello (SNI=api.example.com, ALPN=h2) ──────────────►
     │◄── ServerHello + certificate + Finished ─────────────────────  (TLS 1.3: 1 RTT)
     │   (client validates chain + hostname)
     │
 4   │── HTTP/2 HEADERS: GET /orders/42, Authorization, Accept ────────► LB ──► app pod :8080
     │◄── HEADERS 200 + DATA {json} ────────────────────────────────── LB ◄── app
     │
 5   │   connection stays open in HttpClient's pool for the next request

Where the time goes (example: client in Sydney, server in Melbourne, RTT 15 ms)

Step Cold connection Warm (reused) connection
DNS 1–50 ms (0 if cached) 0
TCP handshake 15 ms 0
TLS 1.3 handshake 15 ms (+ CPU) 0
Request + server work + response 15 ms + server time 15 ms + server time

A cold call can be three or four times slower than a warm one before the server does any work. Across regions (Sydney to US West, ~150 ms RTT) a cold call costs 450 ms+ in handshakes alone.

Production example

A Blazor Server app called an internal API through a new HttpClient per request. Application Insights showed 120 ms dependency calls for a 5 ms endpoint. Splitting the timing with HttpClient diagnostics events showed DNS + connect + TLS taking 100 ms each time because nothing was reused. Moving to IHttpClientFactory brought calls down to 15 ms.

🔍 What the interviewer is checking

A classic broad question that shows whether the candidate has a mental model of the network stack and where latency and failures come from.

Green flags

  • Covers DNS, TCP handshake, TLS (certificate and SNI), HTTP, and proxies/load balancers in order.
  • Mentions round trips and connection reuse.
  • Knows ports (443) and the role of TTLs.

Red flags

  • Skips DNS or TLS entirely.
  • Thinks HTTPS is "HTTP with a password".
  • No idea where time is spent.

📚 Learn in depth

1. The layers involved

Layer (TCP/IP model)   What it does here                   .NET / tooling
───────────────────────────────────────────────────────────────────────────
Application            HTTP request/response, DNS          HttpClient, Dns.GetHostAddressesAsync
Security               TLS encryption, certificate check   SslStream (inside SocketsHttpHandler)
Transport              TCP (or UDP for HTTP/3), ports      Socket
Internet               IP addresses, routing               IPAddress, ping, traceroute
Link                   Ethernet/Wi-Fi frames, MAC          (OS and NIC)

2. DNS

The OS resolver checks its cache and hosts file, then asks the configured DNS server, which may recurse through root, .com and example.com name servers. The answer has a TTL. .NET asks the OS (getaddrinfo); it does not keep its own DNS cache.

3. Routing and NAT

Your machine sends packets to its default gateway. Home and cloud networks usually NAT private addresses (e.g. 10.x) to a public IP. Each router hop forwards based on the destination IP. traceroute / tracert shows the hops.

4. TCP and ports

The client picks an ephemeral source port (e.g. 51544) and connects to 443. The connection is identified by the 4-tuple (client IP, client port, server IP, 443). TCP guarantees ordered, reliable delivery and controls the sending rate.

5. TLS

The client sends the hostname in SNI so a load balancer hosting many sites can pick the right certificate, and lists protocols in ALPN (h2, http/1.1). It validates the certificate chain to a trusted root and checks the name matches.

6. HTTP and the edge

Often the request passes through a CDN or WAF, then a load balancer or ingress controller that terminates TLS and forwards plain HTTP (or re-encrypted HTTPS) to a pod. Headers like X-Forwarded-For and X-Forwarded-Proto carry the original client details.

7. Seeing it from .NET

SocketsHttpHandler publishes metrics (System.Net.Http, System.Net.NameResolution, System.Net.Sockets) including DNS lookup duration, connection setup time and open connections. View with:

dotnet-counters monitor -n MyApp --counters System.Net.Http,System.Net.NameResolution

OpenTelemetry's HTTP client instrumentation also records these as spans and metrics.

8. Try it yourself

  1. curl -w "dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} total:%{time_total}\n" -o /dev/null -s https://example.com
  2. Run it twice with --http2 and compare.
  3. dig example.com and traceroute example.com (or tracert).
  4. In .NET, call the same URL 5 times with one HttpClient and print Stopwatch times; the first call is slowest.

💻 Code

// Measure where time goes for one request (cold vs warm) using HttpClient events
using System.Diagnostics;

var handler = new SocketsHttpHandler
{
    PooledConnectionLifetime = TimeSpan.FromMinutes(2),
    ConnectCallback = async (ctx, ct) =>
    {
        var sw = Stopwatch.StartNew();
        var addresses = await Dns.GetHostAddressesAsync(ctx.DnsEndPoint.Host, ct);
        Console.WriteLine($"DNS {ctx.DnsEndPoint.Host} → {addresses[0]} in {sw.ElapsedMilliseconds} ms");

        sw.Restart();
        var socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true };
        await socket.ConnectAsync(addresses, ctx.DnsEndPoint.Port, ct);
        Console.WriteLine($"TCP connect in {sw.ElapsedMilliseconds} ms");
        return new NetworkStream(socket, ownsSocket: true); // TLS happens after this
    }
};

using var client = new HttpClient(handler);
for (int i = 0; i < 3; i++)
{
    var sw = Stopwatch.StartNew();
    using var response = await client.GetAsync("https://example.com/");
    Console.WriteLine($"Request {i + 1}: {(int)response.StatusCode} HTTP/{response.Version} in {sw.ElapsedMilliseconds} ms");
}
// Request 1 prints DNS + TCP lines and is slowest; requests 2 and 3 reuse the connection.
# Same breakdown from the command line
curl -so /dev/null -w "dns %{time_namelookup}s  tcp %{time_connect}s  tls %{time_appconnect}s  ttfb %{time_starttransfer}s  total %{time_total}s\n" https://example.com

⚠ Common mistakes

Mistake: Describing only "the client sends a request and the server responds". Why it is wrong: It skips DNS, TCP and TLS, which are where most cold-call latency and many outages come from. Instead: Walk through each step and say what can fail or be slow at each one.

Mistake: Ignoring connection reuse. Why it is wrong: A new connection per call repeats DNS, TCP and TLS every time, adding several round trips and TLS CPU. Instead: Share HttpClient through IHttpClientFactory, or a static client with PooledConnectionLifetime.

Mistake: Assuming IPv4 only. Why it is wrong: Many networks return AAAA records first; if IPv6 is broken somewhere on the path, connects time out before falling back to IPv4. Instead: Check both A and AAAA answers with dig, and test connectivity on both families when you see slow or failing first connects.

Mistake: Assuming the app server sees the client directly. Why it is wrong: A CDN, WAF, load balancer or ingress usually terminates TLS, so RemoteIpAddress and the scheme reflect the proxy, not the caller. Instead: Configure ForwardedHeadersOptions with the known proxies and account for proxy timeouts.

Mistake: Blaming the server for slow calls without splitting the timing. Why it is wrong: "The API is slow" often turns out to be DNS, TLS or connection setup. Instead: Measure DNS, connect, TLS and time-to-first-byte separately with curl -w, HttpClient metrics or OpenTelemetry traces.

🏛 Senior insight: trade-offs

This question is a map of everything that can go wrong. A strong answer names each hop, its cost and its failure mode.

Step Typical cost (cold) Common failure How I see it
DNS 0 to 50 ms Stale records, resolver timeouts, broken AAAA dig, System.Net.NameResolution metrics
TCP connect 1 RTT Firewall timeouts, refused, port exhaustion ss, connect duration metric
TLS 1 RTT (TLS 1.3) plus CPU Expired or mismatched certificate, missing intermediate openssl s_client, TLS handshake metrics
Edge (CDN, LB, ingress) Small Header rewriting, idle timeouts, buffering LB logs, X-Forwarded-*
HTTP request 1 RTT plus server time Server errors, slow queries Server traces
Protocol Setup Multiplexing Head-of-line blocking
HTTP/1.1 TCP + TLS No (one request per connection at a time) Per connection
HTTP/2 TCP + TLS Yes, many streams At the TCP level on loss
HTTP/3 QUIC (transport and TLS combined) Yes Per stream only

The lessons are to reuse connections, measure each phase with OpenTelemetry or Application Insights dependency tracking, and know your edge, because proxies change what the app sees.

🔗 Follow-ups the interviewer may ask

  1. When: Candidate mentions DNS lookup Why: Probes DNS resolution, TTLs and caching
    How to answer

    DNS maps names to records: A (IPv4), AAAA (IPv6), CNAME (alias), plus MX, TXT, SRV, NS and PTR. A client asks a recursive resolver, which walks root → TLD → authoritative servers and caches the answer for its TTL. .NET uses the OS resolver (getaddrinfo) and does not cache itself.

    Typical incidents:

    • Stale endpoint after failover: DNS changed, but HttpClient kept pooled connections to the old IP. Fix with PooledConnectionLifetime.
    • Slow or failing lookups in Kubernetes: ndots:5 makes each external name try several search domains first, and UDP conntrack races cause occasional 5-second delays.
    • Split-horizon / private endpoints: the name resolves to a public IP from one network and a private IP from another.

    Diagnose with dig/nslookup from the same pod, check TTLs, and look at the DNS phase of the HTTP timing.

  2. When: Candidate mentions the TLS handshake or certificates Why: Checks TLS and certificate validation depth
    How to answer

    HTTPS is HTTP inside TLS. TLS gives confidentiality (encryption), integrity (tamper detection) and server authentication (certificates).

    TLS 1.3 handshake (one round trip): the client sends supported ciphers, a key share, SNI (hostname) and ALPN (h2); the server replies with its key share, certificate chain and a signature proving it owns the private key. Both derive session keys via ECDHE (forward secrecy).

    The client validates: chain to a trusted root, not expired, hostname matches the SAN, and optionally revocation.

    For "remote certificate is invalid": read the SslPolicyErrors / chain status, inspect with openssl s_client -showcerts, then fix the real cause (expired cert, missing intermediate, wrong hostname, or a private/corporate root CA not trusted in the container). Never return true from ServerCertificateCustomValidationCallback in production.

  3. When: Candidate mentions round trips Why: Moves to latency vs bandwidth and chattiness
    How to answer
    • Latency: how long one thing takes, such as one round trip or one request (ms). Bounded by distance (light in fibre travels roughly 200 km per ms) plus queuing and processing.
    • Bandwidth: the maximum data rate of a link (Mbit/s, Gbit/s). The width of the pipe.
    • Throughput: what you actually achieve (requests/s or MB/s). Limited by bandwidth, latency, windows, concurrency and the slowest component.

    For most APIs, latency × number of round trips dominates, not bandwidth. A request that makes 50 sequential database calls at 2 ms RTT spends 100 ms on the network; move the database to another region at 30 ms RTT and it spends 1.5 s. Fix it by reducing round trips (batching, joins, fewer chatty calls), moving compute near data, caching, and parallelising independent calls.

↩ Usually asked after

More in Networking Basics

Last updated 23 Oct 2026.

🌐 Sangam's Webring

⏪ Previous 🏠 Main Next ⏩
💬 Chat with me