RFC 814
Name, addresses, ports, and routes
NAME, ADDRESSES, PORTS, AND ROUTES π
okay bestie, this is RFC 814 π written by David D. Clark from the MIT Laboratory for Computer Science, in the Computer Systems and Communications Group, dated July, 1982 π . This copy doesn't list a category, a status, or anything it obsoletes or updates, so there's nothing to add there π
1. Introduction β¨
okay so someone once said the main job of an operating system is to give the same object a bunch of different names, and then spend its whole life keeping track of which name goes with which thing π network protocols are giving the exact same energy π«Ά in TCP/IP there are several ways of referring to things π¦
at the human-visible level, you've got character string "names" for networks, hosts, and services πΈ host names get translated into network "addresses", which are 32-bit values that tell you which network a host is attached to, and where the host sits on that net π service names get translated into a "port identifier", which in TCP is a 16-bit value π§ and finally, addresses get translated into "routes", meaning the sequence of steps a packet must take to reach the specified addresses π routes show up explicitly in the form of the internet routing options, and also implicitly in the address-to-route translation tables that all hosts and gateways maintain π
this RFC gives suggestions and guidance for designing the tables and algorithms needed to keep track of all these different sorts of identifiers inside a host implementation of TCP/IP β¨ main character energy for sure π
2. The Scope of the Problem π
okay, first question you should ask about any naming mechanism: how many names are we even going to run into? π€ to answer that, you need to know roughly how big the internet is going to get π
right now the internet is pretty small, ngl π it has no more than 25 active networks, and no more than a few hundred hosts. that means you can totally install tables that list every single element π₯° BUT any implementation you build now should be based on the assumption of a much larger internet π₯ the guidelines currently recommended are an upper limit of about 1,000 networks. if you imagine an average of 25 hosts per net, that suggests a maximum of 25,000 hosts π
is that host estimate high or low? honestly, nobody really knows π€·ββοΈ but even if it's off by several factors of two, the number is still big enough that current table management strategies are unacceptable π some fresh techniques will be required to deal with the internet of the future π¦
3. Names π
so, as the last section hinted, the internet will eventually have so many names that a host can't keep a static table translating every name to its address π΅βπ« and there are reasons beyond raw size that make a full table a bad vibe π ββοΈ
first, with that many names, they'll get added and deleted so fast that an installer could spend their whole life just updating the table π© second, most of those names point to machines you'll never talk to. like, there might be entire networks your host will never have any traffic with π« literally why store all that π
to handle this big, kinda chaotic environment, the internet is moving away from a setup where the NIC maintains one single name table and sends it out to every host π¦ instead, each network (or group of networks) is responsible for maintaining its own names and running a "name server" that translates between names and addresses on that network π§ββοΈ each host only stores a cache of recently used names, not the whole list πΈ when a user gives a name that needs translating, the host checks its local cache first π if it's not there, the host asks an appropriate name server, then can stash the answer in its cache for next time π
BUT the name server mechanism isn't fully in place yet π€ so for now, you still have to keep the old strategy going: a complete table of all names in every host π implementors, though, should set this table up so it's easy to convert to a name server approach later π«Ά a reasonable strategy would be to make the name table accessible only through a subroutine interface, instead of scattering direct references to the table all over the code π that way, later on, you can swap that subroutine out for one that makes calls to remote name servers π¦ it's giving future-proof π₯
a problem that pops up sometimes on the ARPANET today: the info in a local host table is out of date, because a host has moved and the table revision hasn't been installed from the NIC yet π so you try to connect to a host and find some unexpected machine sitting at the address your local table gave you π if a human is watching the connection attempt, they usually notice right away π but for unattended stuff like sending queued mail, this can cause a total mess π
the nameserver scheme will only make this worse π¬ if hosts cache the address associated with each looked-up name locally, they have no way of knowing when that address changes and the cache entry should be removed π₯² to fix this, plans are under way to define a simple facility where a host can query a foreign address to find out what name is actually associated with it π SMTP already has a verification technique based on this same approach β¨ iykyk π
4. Addresses πΈ
the IP layer needs to know some stuff about addresses π§ specifically, when a datagram is sent out from a host, IP has to decide where it goes on the immediately connected network, based on the internet address π mechanically, IP first checks whether the recipient's network number matches the sender's network number π―ββοΈ if it does, the packet can go directly to the final recipient π if not, the datagram has to go to a gateway for further forwarding π and in that case, a second decision is needed, since there may be more than one gateway available on the immediately attached network π«
when the internet address format was first specified, 8 bits were reserved to identify the network π so early implementations used a table with 256 entries, one for each possible net, that stored the gateway of choice for that net π there was also a special case entry for the nets the host was immediately connected to π§ these tables were sometimes filled in statically, which caused confusion and malfunctions whenever gateways and networks moved (or crashed) π the static vibes were NOT it π
the current internet address definition gives three different options for network numbering, so a very large number of networks can be part of the internet π that means it's no longer possible to have an exhaustive table for selecting a gateway for any foreign net π΅ current implementations have to use a strategy based on a local cache of routing information for the addresses being used right now π
here's the recommended strategy for turning addresses into routes π when IP gets an outbound datagram for transmission, it pulls the network number out of the destination address and checks its local table for a suitable gateway to send the datagram to π if it finds one, the job is done β¨ (but see RFC 816 on Fault Isolation and Recovery for recommendations on handling the possible failure of the gateway π οΈ) if there's no such entry, then pick any accessible gateway at random, add it to the table as an entry, and use it to send the packet π² either the guess is right or it's wrong π if it's wrong, the gateway the packet was sent to will return an ICMP redirect message, reporting that there's a better gateway to reach that net πββοΈ when that redirect arrives, it should cause an update of the local table π¦
the number of entries in the local table should match the maximum number of active connections this particular host can support at any one time π for a big time-sharing system, you might picture a table with 100 or more entries π’ for a personal computer supporting a single user telnet connection, only one address-to-gateway association needs to be kept at once π» tiny but mighty πΈ
okay but here's the plot twist π€ the strategy above doesn't fully solve the problem, it just pushes it down one level π« now the question becomes: how does a brand-new host, freshly arriving on the internet, find all of its accessible gateways? π€― this is intentionally NOT solved inside the internetwork architecture π ββοΈ why? because different networks have wildly different ways of letting a host find out about other hosts on its immediate network π some nets allow broadcast: the host sends out a message and expects answers back from all the attached gateways π’ other networks are richly equipped with tools for supporting the internet, so there may be a special network mechanism a host can invoke to find out where the gateways are π§ and in other cases, an installer may have to manually provide the name of at least one accessible gateway π οΈ once a host has discovered one gateway, it can build up a table of all the other available gateways by keeping track of every gateway reported back to it in an ICMP message π
5. Advanced Topics in Addressing and Routing π
everything we've talked about so far is the mechanism needed in a minimal implementation π± that's an implementation meant only to provide operational service access today to the various networks that make up the internet β¨ but if a host is going to take part in future research (as opposed to just providing service), it needs some extra features π¬ these features will also help service hosts that want access to some of the more exotic networks coming to the internet over the next few years π all implementors are urged to at least provide a structure where these features could be integrated later π«Ά future-proofing is the whole vibe π
there are several features, either already part of the architecture or still under development, that modify or expand the relationships between addresses and routes π¦ the IP source route options let a host explicitly direct a datagram through a series of gateways to its foreign host πΊοΈ there's also an alternative form of the ICMP redirect packet that's been proposed, which would return information specific to a particular destination host instead of a destination net π― and finally, additional IP options have been proposed to identify particular routes within the internet that are unacceptable π« the difficulty with implementing these new features is that the mechanisms do not lie
okay so picking up right where we left off, the whole point is that this stuff all has to stay entirely within the bounds of IP π π Every one of these mechanisms is built to apply to one particular connection, which means their use must be specified at the TCP level. So the interface between IP and the layers above it must include ways to pass this info back and forth, and TCP (or any other protocol at this level, like UDP) must be prepared to store it π§
It gets messier because some of the info, especially ICMP packets, can show up at any time π The normal vibe between TCP and IP is one where packets get sent or received, full stop. But asynchronous ICMP messages mean there has to be an extra channel between the two, totally separate from the actual sending and receiving of data π¦ And honestly there are tons of other ICMP messages that also arrive asynchronously and have to get passed from IP up to the higher layers. (See RFC 816, Fault Isolation and Recovery, for the full story πβ¨)
Source routes are already being used on the internet, so lots of implementations are going to want to take advantage of them π The following kinds of usage should be permitted. First, a user starting a TCP connection should be able to hand a source route into TCP, and TCP in turn must hand that source route to IP with every outgoing datagram π The user could get the source route by asking a different kind of name server, one that returns a source route instead of an address. Or they could just fabricate the source route by hand, which is giving DIY energy π Now a TCP that's listening for a connection, instead of trying to open one, must be prepared to receive a datagram that contains a IP return route. When that happens it must remember this return route and use it as a source route on all returning datagrams. Main character behavior, honestly π
6. Ports and Service Identifiers β¨
Okay this section is where it gets really good π₯ The IP layer holds the address info that says which destination host the datagram is headed to. But datagrams aren't just meant for hosts. They're meant for particular agents inside a host, like processes or other entities that are the actual source and sink of the data π IP only does a super simple dispatch once the datagram reaches the target host: it sends it to a particular protocol. After that, it's the job of that protocol handler, like TCP, to finish dispatching the datagram to the specific connection it's meant for π«Ά This next layer of dispatching uses "port identifiers," which live in the header of the higher level protocol, not in the IP layer π
This two-layer dispatch setup has caused a problem for certain implementations π¬ Some people wanted to put the IP layer inside the operating system kernel and run TCP as a user domain application program. But if you strictly stick to that split, you can end up with grave performance problems π The datagram has to get dispatched from the kernel to a TCP process, and then that process dispatches it again to its final destination process. The overhead of scheduling that extra dispatch step can seriously limit the throughput you can actually achieve π
As RFC 817, Modularity and Efficiency in Protocol Implementations, discusses, this kernel-and-user split causes other performance problems too, even if you ignore port level dispatching π Still, there's an acceptable shortcut: you can move the higher level dispatching function into the IP layer, if that makes the implementation substantially easier β¨
Now in principle, every higher level protocol could have its own dispatching algorithm. The reason for that is discussed below. But for the protocols in the service offering being implemented today, TCP and UDP, the dispatching algorithm is exactly the same, and the port field sits in precisely the same spot in the header π So unless you're into participating in further protocol research, there's only one higher level dispatch algorithm. It takes into account the internet level foreign address, the protocol number, and the local port and foreign port from the higher level protocol header. This algorithm can be built as a sort of adjunct to the IP layer implementation, as long as no other higher level protocols are going to be implemented π§
(Okay, technically the above is only partially true π€ The UDP dispatch function is a subset of the TCP dispatch function. UDP dispatch depends only on the protocol number and the local port. But there's one moment inside TCP when this exact same subset comes into play: when a process wants to listen for a connection from any foreign host. So the range of mechanisms needed to support TCP dispatch is also enough to support precisely the UDP requirement π¦)
Some implementors have questioned the decision to take port level dispatching out of IP and push it up to the higher level protocol π€ The argument was that if all of the address structure lived in the IP layer, then IP could do all of the packet dispatching within the host, and that would give you a simpler modularity πΈ But three problems were identified with that. First, not all protocol implementors could agree on the size of the port identifier. TCP picked a fairly short one, 16 bits, to keep the header size down. Other protocols being designed wanted a larger port identifier, perhaps 32 bits, so that the port identifier, if properly selected, could be considered probabilistically unique. So constraining the port id to one particular IP level mechanism would block certain fruitful lines of research π€ Second, ports do a special job on top of datagram delivery: certain port numbers are reserved to identify particular services. For example, TCP port 23 is the remote login service π If ports were implemented at the IP level, then assigning well known ports couldn't be done on a protocol basis. It would have to be done in a centralized manner for the entire IP architecture, which is a mess π Third, IP was designed with a very simple layering role: IP contains exactly the functions that the gateways must understand. If the port idea had been made part of the IP layer, it would have suggested that gateways needed to know about ports, and that's not the case π ββοΈ
There are, of course, other ways to dodge these problems π In particular, the "well-known port" problem can be solved by devising a second mechanism, separate from port dispatching, that names well-known ports. Several protocols have settled on the idea of putting a more general service descriptor, like a character string field, into the packet that sets up a connection to a particular service π These special packets, which request a connection to a particular service, get routed on arrival to a special server, sometimes called a "rendezvous server." That server examines the service request, picks a random port to use for this instance of the service, and then passes the packet along to the service itself to kick off the interaction β¨
For the internet architecture, though, this strategy had a serious flaw π© It assumed that all protocols would fit the same service paradigm: an initial setup phase, which might have a certain overhead like indirect routing through a rendezvous server, followed by the packets of the interaction itself, which flow directly to the process providing the service. Unfortunately, not all high level protocols on the internet were expected to fit this model. The best example is isolated datagram exchange using UDP π¦ The simplest UDP exchange is one process sending a single datagram to another. Especially on a local net, where the net related overhead is very low, this kind of simple single datagram interchange can be extremely efficient, with very low overhead in the hosts π«Ά But these individual packets aren't part of an established connection. So if IP supported a strategy based on a rendezvous server and service descriptors, every isolated datagram would have to be routed indirectly in the receiving host through the rendezvous server. That would substantially increase processing overhead, and every datagram would have to carry the full service request field, which would bloat the size of the packet header π
In general, if a network is meant for "virtual circuit service," or things like that, then using a special high overhead mechanism for circuit setup makes sense π§ But current research is heading away from this class of protocol, so once again the architecture was designed not to preclude alternative protocol structures πΈ The only rational position was that the particular dispatching strategy used should be part of the higher level protocol design, not the IP layer π
The same argument about circuit setup mechanisms also applies to the design of the IP address structure π Lots of protocols don't send a full address field as part of every packet. Instead they send a short identifier that gets created as part of a circuit setup from source to destination β¨ If the full address only needs to be carried in the first packet of a long exchange, then the overhead of a very long address field can easily be justified. Under those circumstances you can create truly extravagant address fields, capable of extending to address almost any conceivable entity π However, that strategy is only usable in a virtual circuit net, where the packets being transmitted are part of an established sequence. Otherwise this large extravagant address must be transported on every packet π¬ Since the Internet explicitly rejected this restriction on the architecture, it was necessary to come up with an address field that was compact enough to be sent in every datagram, but general enough to correctly route the datagram through the catanet without a previous setup phase π The IP address of 32 bits is the compromise that results. Honestly, it takes a substantial amount of shoehorning to address all of the interesting places in the universe with only 32 bits π But on the other hand, if the address field had become much bigger, IP would have been open to another criticism: that the header had grown unworkably large π Again, the fundamental design decision was that the protocol be designed to support research into new and different sorts of protocol architectures π¦
There are some limited restrictions the IP design puts on the port mechanism the higher level process selects π When a packet goes awry somewhere on the internet, the offending packet is returned along with an error indication, as part of an ICMP packet. An ICMP packet returns only the IP layer and the next 64 bits of the original datagram. So any higher level protocol that wants to sort out which port a particular offending datagram came from must make sure that the port information is contained within the first 64 bits of the next level header. This also means, in most cases, that it is possible
It's giving "port dispatch mechanism" energy π§ Picture this: as part of the IP layer, you could have a port dispatch mechanism π
that works by masking and matching on the first 64 bits of the incoming higher level header. So the IP layer just peeks at those first 64 bits and sorts the traffic based on what it finds there β¨ The whole thing is lowkey genius, bestie π«Ά
π¦ where this page comes from
- ietf: rfc814 1982-07
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms