When application code starts an HTTP request, or a device reports one MQTT message to the cloud, it looks like “the application is talking to a service”. The real path is longer: the host first needs its address and gateway, then it resolves the name to an address, finds the local next hop, wraps the data in a link-layer frame, lets routers forward it hop by hop, crosses NAT, firewalls, and the public Internet, and only then do TCP, TLS, HTTP, and the other layers visible to application developers come into play.
The TCP/IP stack is easy to misread as a static layering diagram. Layer diagrams are useful, but they do not answer a lot of field questions: why DNS can be fine while the connection times out, why ping works but HTTPS fails, why small packets work but large ones stall, and why the same domain resolves to different addresses on different networks.
The useful map is not “which protocols live in each layer”. It is “what each layer is filling in for the layer before it during one real access”.
Main path of a network access:
Get network parameters
-> Resolve the name
-> Find the local next hop
-> Forward the IP packet hop by hop
-> Establish a transport session or send datagrams
-> Negotiate a secure channel
-> Send application requests and responses
Each layer in that path solves only part of the problem, and each layer also leaves some work to the upper layer or to a neighboring mechanism.
First Get an Identity That Can Go Online
When a host first joins the network, it usually does not have enough information to start cross-subnet communication. It needs at least:
- Its own IP address
- The subnet mask or prefix length
- The default gateway
- A DNS resolver
- Sometimes extra parameters such as NTP, search domains, or proxy settings
In IPv4 networks, this information often comes from DHCP. Without that step, the later HTTP, TLS, and TCP layers do not have a place to stand, because the host does not even know what source address to use or which device to hand non-local traffic to.
The judgment here is straightforward: if the address, gateway, or DNS configuration is wrong, the failure will disguise itself as many upper-layer symptoms. The application sees “cannot reach the service”, but the root cause may simply be that the host got the wrong gateway or an unusable resolver.
IPv6’s default model is different. It can combine router advertisements, stateless address autoconfiguration, DHCPv6, and NDP to complete attachment. However the mechanism changes, the core still stays the same: the host first has to get the basic facts of “who am I, which network am I on, and who should handle non-local destinations”.
The Name Has to Land on an Address First
Users and applications usually remember names, not addresses. Names such as www.example.com, api.example.com, and mqtt.example.com must pass through DNS before they become one or more IP addresses.
DNS is not a data transport channel. It only answers “where should this name go right now?” Getting the address does not mean the connection has started yet.
This is also one of the easiest places to get confused during troubleshooting:
- If DNS succeeds, that only means the name was resolved to an address
- If DNS fails, the later TCP, TLS, and HTTP layers will not start
- If DNS returns an old address, the application may connect to an old datacenter, an old CDN node, or an already retired entry point
- If the same name returns different addresses on different networks, that is not necessarily an error. It may be scheduling, CDN behavior, or split-horizon resolution
So “the domain name is fine” needs to be broken apart. Is the authoritative record fine, is the recursive resolver fine, is the local cache fine, or is the address the application actually received fine? DNS only turns names into addresses. It does not guarantee that the address is reachable afterward.
The Local Link Only Handles the Next Hop
Once the target IP is known, the host still cannot throw the packet directly into the Internet. It first has to decide whether the target is inside the local network.
If the target is on the local subnet, the host resolves the target IP into the peer’s link-layer address. IPv4 usually relies on ARP, and IPv6 relies on NDP.
If the target is not on the local subnet, the host does not look for the final server at Layer 2. It looks for the default gateway’s link-layer address. The first hop of every cross-subnet packet is handed to that gateway.
Target is on the local subnet:
Host -> target host MAC
Target is not on the local subnet:
Host -> default gateway MAC -> later routing path
That explains a common false assumption: when you access a public service, the thing your local ARP is usually looking for is not the public server. It is the local gateway. The public server’s MAC address never crosses routers and arrives at your NIC.
Ethernet and similar link-layer protocols solve delivery on the same local link or broadcast domain. They do not solve cross-network path selection, and they do not understand HTTP requests, TLS certificates, or business domains.
IP Moves the Packet Hop by Hop
IP is the main trunk of this map. It handles cross-network addressing and forwarding: every packet carries a source address and a destination address, and routers in the middle look up the destination in their routing table and hand the packet to the next hop.
The boundary of IP is best effort. It does not guarantee:
- That the packet will arrive
- That the packet will arrive in order
- That the packet will arrive only once
- That the packet size will fit the whole path
- That the return path will match the forward path
These limits are not defects. They are the result of keeping IP focused on unified addressing and hop-by-hop forwarding. Reliability, ordering, retransmission, and application semantics are not IP’s job.
When debugging at the IP layer, the first things worth checking are:
- Whether the source and destination addresses are what you expected
- Whether the default route and next hop are correct
- Whether the path contains ICMP unreachable or TTL-expired signals
- Whether large packets hit MTU or fragmentation problems
- Whether the return path may be different from the outbound path
If a packet cannot reach its destination at IP, no upper-layer protocol can save it. Conversely, IP reachability only means “the packet roughly can move across”. It does not mean the transport, security, and application layers all succeeded.
Routing Decides Which Next Hop Gets Each Packet
Every time an IP packet reaches a router, the same question appears again: which next hop should this destination address go to?
In a small network, that decision may come from static routes or a default route. In a larger network, it depends on routing mechanisms such as Routing, OSPF, or BGP, which tell devices which prefixes are reachable from where.
Routing solves path selection and reachability propagation, not service health. A route existing only means a prefix is considered reachable. Whether the target machine is listening, whether the certificate is valid, or whether HTTP returns 500 are all higher-layer questions.
That is why CDN, Anycast, and multi-exit networks are easy to misunderstand. Behind the same address or the same domain, the real path may depend on carriers, autonomous systems, regions, policies, and routing convergence. The application sees one access. The network is making a chain of hop-by-hop choices.
NAT and Firewalls Change the Path Assumptions
Many real networks are not end-to-end transparent. Packets often go through NAT and Firewall.
NAT rewrites addresses or ports so that many internal hosts can share one public exit, or so that external access can be mapped to an internal service. Firewalls decide whether to allow traffic based on address, port, protocol, direction, and connection state.
The key change they introduce is that communication is no longer decided only by the two endpoints. Middle devices also maintain state and policy.
That leads to several common problems:
- Outbound works, but inbound may not
- A TCP connection can be reclaimed if it stays idle too long
- UDP has no connection state, so mapping timeout is more visible
- Once the five-tuple changes, a middlebox may think it is a different flow
- Some ICMP, fragmentation, or unusual ports may be dropped by policy
So “public IP reachable” does not mean “every protocol is reachable”, and “port open” does not mean “a full application session is guaranteed to complete”.
The Transport Layer Delivers the Packet to a Process
IP only gets the packet to the destination host. That host may run many processes, so the transport layer has to answer the next question: which communication endpoint should get it?
Port and the five-tuple become important here:
protocol + source IP + source port + destination IP + destination port
That combination is what hosts, middleboxes, and packet-capture tools often use to identify one communication flow.
TCP and UDP are the two most common transport choices.
TCP provides connection semantics, ordered delivery, acknowledgments, retransmission, flow control, and congestion control. The application gets a byte stream, at the cost of more state, handshake latency, and head-of-line blocking.
UDP keeps a thinner datagram model. It does not establish a connection, and it does not guarantee reliability or ordering. The application or an upper-layer protocol has to handle loss, retries, timeouts, and deduplication itself. DNS, NTP, QUIC, many real-time audio/video systems, and many IoT protocols use that lightness.
The usual debugging order for this layer is:
- Whether the TCP three-way handshake completed
- Whether the target port is actually listening
- Whether there are retransmissions, duplicate ACKs, zero windows, or connection resets
- Whether the UDP request got a reply and whether NAT or firewall dropped it
- Whether the same flow’s five-tuple changed in the middle
Once the transport layer succeeds, the application finally gets a chance to speak its own protocol.
The Security Layer Protects the Session, Not the Path
HTTPS, MQTTS, DoT, and many modern protocols place TLS above the transport layer. TLS solves identity verification, key negotiation, encryption, and integrity protection.
It does not solve:
- Whether DNS resolved correctly
- Whether IP routing is reachable
- Whether TCP can establish
- Whether the firewall allows the traffic
- Whether the server application returns the correct business result
TLS failures are often read by users as “the site does not open”, but debugging needs to distinguish the failure point:
- If TCP never connects, TLS has not even started
- If TLS fails after starting, the cause may be certificate, SNI, protocol version, cipher suite, or middlebox issues
- If TLS succeeds and HTTP errors appear afterward, the issue has already moved into the application layer
HTTPS is not “HTTP automatically becoming reliable”. It is the combination of HTTP + TLS + TCP or HTTP + QUIC. Failures at each layer all show up while trying to do the same access, but they are not caused by the same boundary.
The Application Layer Is Where Business Semantics Appear
At the application layer, the protocol finally starts expressing “which resource do I want”, “which message should I publish”, “which topic should I subscribe to”, or “which status code should I return”.
HTTP cares about methods, paths, headers, status codes, caching, and intermediary semantics. MQTT cares about connections, topics, publish/subscribe, and QoS. CoAP is built for constrained environments and often runs lightweight interactions over UDP. WebSocket upgrades HTTP into long-lived bidirectional communication.
The application layer is the easiest place to misread as the root cause because it is what users and logs see first. But many application symptoms come from below:
- An HTTP timeout may be TCP retransmission or an IP routing black hole
- A 502 / 504 may be a connection problem between a proxy and upstream
- An MQTT disconnect may be NAT idle timeout
- A WebSocket disconnect may be an intermediate timeout policy
- Small requests succeeding while large ones fail may be MTU, fragmentation, or proxy limits
So application-layer debugging cannot stop at the status code. The code only explains the result after the application or intermediary was already able to speak. If the path before the connection never worked, there will not even be a status code.
You Can Slice One Access in This Order
Putting the layers together, a typical HTTPS access can be broken down like this:
1. Does the host have a usable IP, gateway, and DNS?
2. Which address did the name resolve to?
3. Is the target local, or does it use the default gateway?
4. Can the next-hop link-layer address be resolved?
5. Can the IP packet reach the target along the route?
6. Do NAT, firewalls, and security policy allow the flow?
7. Did the TCP three-way handshake complete?
8. Did the TLS handshake complete, and do the certificate and SNI match?
9. Was the HTTP request sent, and is the response what we expected?
If the protocol changes to UDP or QUIC, the transport-layer checks will change, but the address, link, routing, and policy checks are still there.
The value of this map is not in memorizing it. It is in avoiding layer jumps when something breaks. Once DNS succeeds, look at TCP. Once TCP succeeds, look at TLS. Once TLS succeeds, look at HTTP. If a lower layer has not yet been established, do not rush to explain higher-layer symptoms.
A Few Commonly Misused Judgments
ping working does not mean the business works. ping mainly validates some ICMP echo path. Many networks restrict ICMP, and many services are not automatically usable just because ICMP is reachable.
DNS working does not mean the target service works. DNS only gives an address, not port state, route quality, TLS certificates, or application health.
TCP working does not mean HTTPS works. TCP only says the transport connection was established; TLS and HTTP are still ahead.
If HTTP returns an error, that does not mean the network layer failed. If you got an explicit HTTP status code, then at least DNS, routing, transport, and the necessary security layer likely reached the point where an application response could travel.
The same problem may look different on different networks, and that does not mean the application code is randomly broken. DNS scheduling, BGP path selection, NAT behavior, firewall policy, MTU, and carrier path differences can all change the result.
Further Reading
- DHCP - how a host first gets its address, gateway, and DNS parameters
- Ethernet - how the local link delivers frames to the next hop inside the same broadcast domain
- ARP - how the IPv4 next hop maps from IP address to MAC address
- IP - why cross-network forwarding only promises best effort
- Routing - how destination prefixes become next-hop decisions at each hop
- TCP - how reliable byte streams are built on top of unreliable IP
- UDP - why connectionless datagrams are useful for lightweight, real-time, and custom-reliability scenarios
- TLS - how secure channels are built on top of transport
- HTTP - how application request/response semantics run on top of all these lower layers