Network Engineering, November 2020

Ports, the Communication Endpoint

A port is not an opening. It is a sixteen bit field the transport layer uses to decide which local socket a segment belongs to, and nothing about it grants or denies anything.

The address identifies the host. The port identifies which conversation on that host, which is the only reason a machine can hold thousands of simultaneous sessions over one address.

The tuple that identifies a connection

A TCP connection is identified by five values, the protocol, the source address, the source port, the destination address, and the destination port. Two connections are distinct if any one of the five differs.

This is why a server listening on one port serves many clients without confusion, and why one client can open many connections to the same server, since each uses a different source port and is therefore a different tuple.

The ranges

RangeNameAssigned byTypical use
0 to 1023Well knownRegistryStandard services, privileged to bind
1024 to 49151RegisteredRegistry on requestVendor and application services
49152 to 65535DynamicNobodySource ports chosen by the client

The privilege boundary at 1024 is a convention of unix like systems rather than a property of the protocol, and it exists so an unprivileged process cannot impersonate a standard service on a shared machine.

The dynamic range is where source ports come from, and the range actually used is a local setting rather than the registry definition. Several systems default to a wider range than the formal one, which matters when the number available becomes the constraint.

The two port spaces are separate

TCP port 53 and UDP port 53 are unrelated allocations that happen to be assigned to the same service. A firewall rule permitting one says nothing about the other.

This causes a specific and recurring fault with name resolution, where small responses over UDP succeed and larger ones requiring TCP fail, producing resolution that works for most queries and breaks for a few.

Ephemeral exhaustion is a real limit

A host initiating many connections to the same destination consumes a source port for each, and the number available is bounded by the configured range.

Closed connections do not release the port immediately. A connection remains in a waiting state for a period to ensure delayed segments are not delivered to a later connection reusing the same tuple, and under high connection rates the ports held in that state can outnumber the ones in use.

The symptom is a host that fails to open new connections to one destination while everything else works, and the remedies are connection reuse, widening the range, or adding source addresses, in that order of preference.

Translation depends on the port entirely

Address translation that maps many internal hosts to one external address cannot work on addresses alone, since the return traffic would be ambiguous. It rewrites the source port as well, and the mapping table is keyed on the resulting tuple.

Two consequences follow directly. Inbound connections are impossible without a pre-configured mapping, because no table entry exists, and any protocol carrying an address or port inside its payload breaks unless the translator inspects and rewrites that too.

What opening a port actually means

A firewall rule permitting a port does not create a service. If nothing is listening, the connection is refused whether the rule exists or not, and the rule has changed nothing.

Equally, a service is reachable only if something is listening, the host permits it, and every device on the path permits it. The common troubleshooting error is checking one of those three and concluding about the other two, which is why verifying from the client rather than from the configuration is the only reliable test.

Note: a connection refused and a connection timing out are different diagnoses. Refused means the packet reached a host that had nothing listening. Timed out means it was discarded somewhere on the path, and the distinction narrows the search considerably.