I Β· One Machine Β· Chapter 7

Which Program?

The frame arrives at Mira’s machine. Her card checks the destination identity, finds that it is hers, and verifies the check, which passes. It strips the header and the trailer and hands the content up to her operating system. The operating system opens the letter inside, reads the location name on it, confirms that this is the machine meant, and strips that header too. What is left is your message, meet at 7, and the operating system is now holding nine bytes with nowhere to put them.

Mira’s machine is running, at this moment, a chat window, a music player, a browser with nine tabs open, a file-syncing tool, a calendar that checks for updates every few minutes, and a handful of things she has never heard of that came with the operating system. Every one of them is a program, and any one of them might be expecting bytes from the network. The operating system’s job is to give these nine bytes to the right one, and it has nothing to go on. Consider what it knows. The frame said: for card a4:83:e7:2b:91:0c. The letter inside said: for location 203.0.113.7. Both of those name the machine, and neither says a word about which program on the machine. Every agreement you have made so far has been about getting bytes to a computer, and you have done that, and it turns out a computer is not the thing you were talking to.

Let’s watch it fail. Suppose the operating system, knowing no better, hands the bytes to every program that is listening for network input. The chat window gets meet at 7 and displays it, which is what you wanted. The music player also gets meet at 7, tries to interpret it as part of a stream it was downloading, and skips. The file-syncing tool gets it too, and writes nine bytes of garbage into the middle of a document. Everything that listens to the network has received a message that was meant for one of them, and only one of them was right.

Or suppose the operating system hands the bytes to whichever program most recently asked for network input. That is the calendar, which polled for updates two seconds ago. The calendar receives meet at 7, fails to parse it, and discards it. The chat window never sees your message at all.

The problem is the one from Chapter 4, one level up. There, a frame reached every machine on the wire and none of them could tell whether it was theirs, and you fixed it by naming the machine. Here the bytes reach the machine and none of the programs can tell whether they are theirs. You are going to fix it the same way.

Put a number in the message that says which program it is for. The operating system reads the number, looks up which program has that number, and delivers the bytes to that program alone. That much is obvious. What is not obvious is where the numbers come from, and you have been in this position twice before.

The first thing to try is the program’s name. Send to β€œchat”. But two different chat programs could be installed on one machine, so program names are not unique, and besides that they are long, they change between versions, and they mean nothing to an operating system, which thinks in numbers.

The second thing to try is the number the operating system already gave the program. Every running program has one, assigned when it starts and unique on that machine. Send to program 4471. But you are on a different machine. You have no idea that Mira’s chat program is number 4471 today. It was 3902 yesterday, before she restarted, and it will be something else tomorrow. The number is assigned when the program launches and it is private to her machine. To find out what it is you would have to ask, and to ask you would have to send a message to some program on her machine, and you do not know that one’s number either.

That is the circularity from Chapters 4 and 6. Both times it was broken by having a name that existed before the conversation: the factory identity in one case, and in the other, that same identity used to bootstrap the location. The pattern is that you cannot discover a name by asking, if asking requires the name. Something has to be known in advance.

So know it in advance. Do not number the process; number the role. Agree, you and Mira and everyone who will ever write a chat program, that chat lives at number 5222. When Mira’s chat program starts, it tells her operating system that it is the program for 5222, and the operating system writes that down. When bytes arrive marked 5222, the operating system looks in its table and delivers them to whichever program claimed that number. You did not have to ask. You knew, because it was agreed beforehand, in the same way you knew that 01001000 was H. The number is a convention.

This is a new kind of thing in the tower, and it is worth a moment. Every agreement so far has been enforced by machinery. The frame’s start marker is recognised by the card. The check is computed by the card. The identity is burned into the card. The location is assigned by a machine on the network and checked by routers. Get any one of these wrong and something physical fails: the card ignores your frame, or the router drops your letter.

This one is different. Nothing in the hardware knows that 5222 means chat. Nothing stops Mira’s music player from claiming 5222 instead, and nothing stops you from sending your chat message to 80. The agreement between numbers and roles is enforced by documentation, by a published list that says this number means this thing, and by everyone choosing to follow it. It is an agreement among people that machines merely carry out.

The list exists. Jon Postel began keeping it in 1972, as a memo listing which numbers meant what on the network of the day, and he went on keeping it for twenty-five years. Today it is kept by a small organisation that also hands out the top-level chunks of IP address space, and it says that 80 is the web, 443 is the web with encryption, 22 is remote login, 25 is mail, 53 is name lookup, and several thousand other things. A program that wants to be found claims its number from that list, a program that wants to reach it uses the same number, and they meet.

The number is called a port. It is sixteen bits, so it runs from 0 through 65535, and the ones on the published list are called well-known ports. Your chat program will pick one, and anyone who wants to talk to it will need to know which.

loading…

The machine as a building with one street address and 65,536 numbered doors. The location name gets you to the building; the port gets you to the door. Behind most of the doors, nobody is home.

You need a second port, and it is the mirror of the first. When Mira’s chat program replies, its reply has to reach your chat window, and not your browser or your music player. So your message must also carry the number of the program it came from, so that the reply has somewhere to go. It is a source port, in the same way that there is a source identity and a source location.

But your chat window does not need a well-known number. Nobody is trying to find it in advance; it is the one starting the conversation. It needs only a number that is currently unused on your machine, so that when Mira’s reply arrives marked with it, your operating system knows which program to hand it to. So your operating system picks one for it from a range set aside for this purpose, say 51844, writes that into its table alongside 5222, and puts it in the message as the source.

Mira’s operating system receives a message to 5222, from 51844. It delivers to the program at 5222. That program replies, and the reply goes to 51844, from 5222. Your operating system delivers to the program at 51844, which is your chat window. The well-known port is for being found. The other one, assigned on the fly, is for being answered. Ports of that second kind are called ephemeral ports, and your machine burns through them constantly without your ever noticing.

Where do these two numbers go? Not in the frame header. The card reads that, and the card does not care which program the bytes are for, only whether they are for this machine. Not in the letter’s addressing header either. The router reads that, and the router cares even less about programs, since it is forwarding by building. They go in a third header, inside the letter, after the location addressing. Only the two operating systems at the ends read it. The card strips the frame, the routers read the location, and then, at the destination, the operating system reads the ports and makes the last delivery.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ frame header           ← read by cards and switches            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ location header    ← read by routers                     β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚  β”‚ port header      ← read by the two operating systemsβ”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β”‚ content        ← read by the program          β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
loading…

Three headers, three readers. Each layer of the tower reads its own header and passes the rest up untouched. The port header is the first that is read only at the two ends and by nothing in between.

This is the shape of the tower now, and the new layer is a different kind of thing from the two below it. The frame is one hop: card to card, replaced at every switch. The location is end to end, but read along the way, since every router looks at it. The port header is end to end and read only at the ends. Nothing between your machine and Mira’s cares about it or even needs to understand it. It is a private matter between two operating systems.

Now Mira installs a second chat program. It starts up and tells the operating system that it is the program for 5222, and the operating system has to decide what to do. It could let both programs claim the number and deliver incoming bytes to both, but that is the failure from the top of the chapter, brought back on purpose. It could let the most recent claim win, but then installing a program silently steals traffic from another, and the first program has no idea it has gone deaf. Neither of those is a system anyone could reason about.

So the operating system refuses. The second program is told that the number is taken, and it is up to the program, or the person running it, to pick another or to shut down the first. If you have ever started a server and been told the address was already in use, that was this refusal, and now you know why it is the right answer. A port is a name, and a name that two things answer to is not a name.

One more thing has changed in this chapter, and it is easy to miss. Until now the operating system was barely present. Frames were the card’s business, and the operating system merely received content. Now it holds a table, from port to program, and it reads a header and makes a delivery decision. It has become a participant.

What it does physically when bytes arrive, where it puts them, how it wakes the program, how many times it copies them along the way, is a story of its own, and not one you are ready for yet. It matters enormously for how fast things go and not at all for whether they work. So we set it aside until the tower is complete, and open the operating system up properly at the very end of Part I.

Coming up Β· IΒ·23 β€” It Works, and It's Too Slow

The operating system reads a header and delivers to a program. Chapter 23 is about what that costs, and how a busy machine survives it.

β†’

A message can now find its way from a program on your machine to a program on Mira’s. Card, location, port: three names, each narrowing the destination one step further, each read by a different part of the tower. The chat window gets chat, the music player gets music, and the file-syncing tool is left alone. There is a gap, though, and you will see it the moment more than one person tries to talk to the same program.

Coming up Β· IΒ·8 β€” Which Conversation?

Mira’s chat program is at 5222. You open two windows to it. Theo opens one. All three conversations arrive at the same door.

β†’