RFC 46

ARPA Network protocol notes

πŸ“… published April 1970, from ietf

RFC 46: ARPA Network Protocol Notes πŸŽ€

Okay bestie, this is RFC 46, called ARPA Network Protocol Notes ✨ It was written by Edwin E. Meyer, Jr. from the Massachusetts Institute of Technology and dated 17 April 1970. Network Working Group is the group behind it. The header doesn't list a category, and it doesn't say what it obsoletes or updates, so there's nothing to report on that front πŸ’…

The opening is basically the group saying "here's our draft, tell us what you think" 🫢

Here's the preamble. The attached document has comments and suggestions from the Network Working Group at Project MAC. It's built on the protocol from NWG/RFC 33, 36, and later documents. It's meant as a contribution to a conversation that ends with a protocol specification the whole Network Working Group accepts. They're asking for your comments, so send them πŸ’–


I - INTRODUCTION ✨

Okay so in this doc, the Network Working Group at MIT Project MAC suggests changes and add-ons to the protocol from Carr, Crocker, and Cerf (a preprint of their 1970 SJCC paper), which Crocker extended in NWG/RFC 36. It's not trying to be a full spec. It's more of a vibe check on the type and size of protocol they think should get implemented first πŸ¦‹

They're on board with simplex communication between sockets that have unique identifiers. Their plan is to implement a slightly modified subset of the network commands from NWG/RFC36, plus the ERR command from Harslem and Heafner in NWG/RFC 40 πŸ”₯

The big goal is getting every ARPA contractor onto the network and talking to each other as early as possible. So the first protocol needs to be simple enough to be easy to implement everywhere with minimal extra software, but still extendable and able to handle the main early uses πŸ“

The protocol will evolve, but the core stuff that everyone adopts is going to be super hard to change later. So the first version has to be open-ended and flexible, and simple is more likely to survive that than complicated. Extra protocol layers between installations are still fine, as long as the basic protocol keeps being supported πŸ’…

They think three things have to be in the initial protocol:

  1. Multi-path communication between two existing processes that already know how to connect to each other.
  2. A standard way for a process to connect to the logger (the logging process at a foreign HOST) and ask for a user process to be created. (Whether the login ritual gets standardized is up in the air.)
  3. A standard way for a newly created process to start pseudo-typewriter communication with the foreign process that asked for it to be created 🧚

Here's how their proposal differs from Carr, Crocker, and Cerf's protocol:

  1. The dynamic reconnection strategy from Crocker's NWG/RFC 36 is saved for later. They think including it would make the first implementation way too complicated. They lay out a foreign process creation strategy that doesn't need dynamic reconnection. Nothing here blocks adding dynamic reconnection later 🌸
  2. They want an "instance tag" added to the socket identifier, so sockets from different processes belonging to the same user, all running on one HOST, stay separate πŸŽ€
  3. These NCP commands were added:
    • a. The ERR command from NWG/RFC 40 is included.
    • b. BLK and RSM are offered as options instead of the "cease on link" IMP command and the SPD and RSM commands from NWG/RFC 36. Since these work on socket connections instead of link numbers, they don't get in the way of multiplexing socket connections over one link number, if that ever turns out to be useful πŸ¦‹
    • c. An INT command that interrupts a process is specified. Being able to interrupt a process doing unwanted computation or output is super important. Making the interrupt a special format inside a normal message is a nightmare, because the connection could be blocked right when you need the interrupt, and the NCP would have to scan every incoming message for an interrupt signal 😭
    • d. An ECO echoing command is included for testing communication between NCPs πŸ’œ
  4. Sockets are treated as having several states, and those states decide when network requests can get queued. This is different from unlimited queuing, which causes some implementation headaches πŸ‘‘
  5. Creating a foreign process and communicating with it gets moved into a separate User Control and Communication (UCC) protocol level, and it's specified in more detail 🌈

II - A HIERARCHY OF PROTOCOLS πŸ¦‹

So it's convenient and useful to see the network as a hierarchy of protocol and implementation levels. A layered protocol helps independent software and hardware development, and it lets you add or swap out certain levels in experimental or special-purpose systems ✨

The initial network communications system is a hierarchy of three systems. Each one is more general than the one below it and has less privilege:

  1. IMP Network: The network of IMPs and physical communication lines is the basic resource. Higher-level systems turn it into more generalized communication facilities. The IMP network acts like a "wholesaler" of message transmission facilities to a highly privileged module inside each HOST πŸ’–
  2. Network Control Program: Each HOST has a module called the Network Control Program (NCP), which has sole control over communications between its HOST and the IMP network. It's the "retailer" of the wholesale facilities the IMP network provides. The NCP network can be seen as a higher-level communications system on top of the IMP network. It takes raw message transmission between HOSTs and turns it into communication facilities between ordinary unprivileged processes 🫢

Here's the picture:

              H O S T  A                      H O S T  C
    ______________________________       ______________________
   |                              |     |                      |
   |  ____   ____   ____   ____   |     |  ____   ____   ____  |
   | |Proc| |Proc| |Proc| |    |  |     | |Proc| |Proc| |    | |
   | | A  | | B  | | C  | |UCC |  |     | | D  | | E  | |UCC | |
   | |____| |____| |____| |____|  |     | |____| |____| |____| |
   |    |     |      |      |     |     |    |     |      |    |
  - - - - - - |- - - |- - - |- - -|- - -|- - |- - -|- - - |- - - - - -
   |    |     |      |      |   NCP NETWORK  |     |      |    |
   |    |     |      |      |     |     |    |     |      |    |
   |   _|_____|______|______|_    |     |   _|_____|______|_   |
   |  |                       |   |     |  |                |  |
   |  |      N C P   A        |   |     |  |   N C P   C    |  |
   |  |_______________________|   |     |  |________________|  |
   |                     ||       |     |       ||             |
   |_____________________||_______|     |_______||_____________|
                         ||                     ||
  - - - - - - - - - - - -|| - - - - - - - - - - ||- - - - - - - - - -
                         ||     IMP NETWORK     ||
                      ___||___              ____||__
                     |        |            |        |
                     |  IMP   |------------|  IMP   |
                     |   A    |            |   C    |
                     |________|            |________|
                         |                     |
                         |       ________      |
                         |      |        |     |
                         +------|  IMP   |-----+
                                |   B    |
                                |________|

                     FIG 1. Modular View Of Network
  1. User Control and Communication Module: The two systems above are enough for unprivileged processes that already exist to talk to each other. But one of the main early uses of the network is supposed to be creating a foreign user process by talking to the foreign HOST's logger. The User Control and Communication Module (UCC) provides the protocol a process needs to talk to a foreign HOST's logger and to send the first control messages to a process it created. That created process gets the same privileges as a local user process on the foreign HOST, subject to administrative control. The UCC talks through the NCP, much like any ordinary process does. Other than being able to close connections to a dead process, the UCC has no special network privileges. The UCC protocol is just one of several third-level protocols that could be built. For example, a set of batch processing systems connected through the NCP system might run a load-sharing protocol, but not a UCC 🧚

Part 1 is done, but we're not finished yet πŸ’… More parts are coming, so stay tuned 🌸

III. NETWORK CONTROL PROGRAM ✨

okay so every HOST runs a module called the Network Control Program (NCP), and it's the one in charge of ALL the network communications for that HOST πŸ’… The NCPs together make a distributed communication system that sets up communication paths between individual processes. The NCP protocol issues are basically two things: (i) defining these communication paths, and (ii) a system for coordinating the distributed NCP system so those paths stay up 🫢 We'll get into both below, bestie.

Sockets

Okay, so two processes talk through a simplex connection between two sockets: a send socket on one process and a receive socket on the other πŸ¦‹ Sockets have these characteristics:

Socket Identifier - this is how the whole network knows exactly which socket is which πŸ”₯ It's 48 bits, split up like this:

  • a. User Number (24 bits) - a socket is identified as belonging to a process by a user number, which is 8 bits of "home" HOST code plus 16 bits of user code assigned by the home HOST. Literally the same user number for all the sockets on ALL of their processes, on any HOST πŸ‘‘
  • b. Instance Tag (8 bits) - a user can have more than one process existing in the same HOST at once, so the instance tag tells you which process a socket belongs to 🧚 A user's first process at a HOST to use the network gets instance tag = 0, by convention.
  • c. HOST Number (8 bits) - the code of the HOST where the attached process lives 🌸
  • d. Socket Code (8 bits) - this gives you 128 send and 128 receive sockets in each process πŸ’– The low order bit decides it: "send" (= 1) or "receive" (= 0).

States of Sockets - every socket has a state 🌈 The NCP can have fancier, more transitory states too, but these three are the ones that matter conceptually:

  • a. Inactive - no process is currently around that has told the NCP it wants to listen to this socket. No other process can successfully talk to an inactive socket πŸ’€
  • b. Open - some process has agreed to listen for events on this socket, but it isn't connected yet ✨
  • c. Connected - this socket is currently connected to another socket πŸŽ€

Socket Event Queue - each open or connected socket gets its own queue of events for the owning process πŸ“¬ It's a chronologically ordered list of certain events that happen because one or more foreign processes try to connect or disconnect this socket. Each entry is the event type plus the identifier of the foreign socket involved. These event types are defined:

  • a. "request" - a foreign socket requests a connection. (Not queued if the local socket is already connected πŸ™ˆ)
  • b. "accept" - a foreign socket accepts the requested connection πŸ’œ
  • c. "reject" - a foreign socket rejects the requested connection πŸ’…
  • d. "close" - a foreign socket disconnects an existing connection 😭

A "request" event leaves the queue once it's accepted or rejected. The other events leave the queue as they get disclosed to the owning process πŸ“

Some events are meant to be transparent to the process that owns the socket, so they don't make entries in the event queue ✨

Okay, so the event queue is conceptually unlimited, but it seems necessary to put some practical limit on its length πŸ¦‹ When an event queue for a socket is full, any incoming event that would add to it should be discarded, and the sending NCP should be notified (via the ERR command described below). Iconic behaviour, honestly πŸ‘‘

NCP Control Communications

The NCP network coordinates its activities through control commands passed between its individual components 🫢 These commands mostly deal with creating and manipulating socket connections controlled by the NCP that gets the command. A control command is sent to a particular NCP by going to its HOST as a message over link number 1 (the control link), which is reserved for exactly that purpose πŸ”₯ The IMP network doesn't tell these messages apart from regular data messages that carry communication through a socket connection, so no special treatment there 🌸

The following NCP control commands are defined:

  • a. Request for Connection
RFC <local socket> <foreign socket> [<link no.>]

An NCP sends this command to a foreign NCP to try to start a connection between a local socket and a foreign socket ✨ If the foreign socket is open, the foreign NCP puts a "request" event into that socket's event queue, so the process that owns it can see it πŸ’– If the foreign process accepts, the foreign NCP sends back a positive acknowledgement in the form of another RFC πŸŽ€ To reject, it issues the CLS command (see below). An RFC gets automatically rejected without asking the owning process if the foreign socket is not open (inactive or connected) πŸ’€ Multiple RFCs to the same socket go into its event queue in the order they arrive 🌈 Any queued RFCs get automatically rejected by the NCP once the owning process decides to accept a connection πŸ™ˆ The NCP that controls the "receive" socket of the potentially connected pair picks the link number the messages will flow over πŸ‘‘

  • b. Close a Connection
CLS <local socket> <foreign socket>

An NCP issues this command to disconnect an existing connection, or to negatively acknowledge an RFC 😭 There's a potential race problem if an NCP closes a local send socket, because the CLS command could reach the foreign NCP before the last message over that socket connection does πŸ“ This race gets prevented by following two standards: (i) a CLS command for a local send socket isn't transmitted until the RFNM for the last message to the foreign socket comes back, and (ii) the foreign NCP processes all incoming messages in the order they were received πŸ’…

  • c. Block Output over a Connection
BLK <foreign send socket>

A process might read data through a receive socket slower than messages are coming in, so the NCP's buffers can start to clog up πŸ₯² The NCP issues this command to a foreign NCP to block further transmission over the socket pair until the receiving process catches up 🫢

  • d. Resume Output over a Blocked Connection
RSM <foreign send socket>

An NCP issues this command to unblock a previously blocked connection πŸ¦‹

  • e. Interrupt the Process Attached to a Connection
INT <foreign socket>

Getting this message makes the foreign NCP immediately interrupt the foreign process attached to <foreign socket>, as long as it's connected to a local socket ⚑ Data already in transit within the NCP network over the interrupted connection will still be transmitted to the destination socket πŸ’– "Interrupt" means the process immediately breaks off its current execution and runs some standard procedure. That procedure is not defined at this protocol level 🧚

  • f. Report an Erroneous Command to a Foreign NCP
ERR <code> <command length> <command in error>

This command reports spurious network commands or messages, or overload conditions that stop a command from being processed 🚨 <code> specifies the error type. If <code> specifies an erroneous network command, <command in error> is that command (not including the IMP header), and <command length> is an integer giving its length in bits πŸ“ If <code> specifies an erroneous message, <command in error> only contains the link number the erroneous message was sent over 🌸 (This is slightly modified from the specification in NWG/RFC 40.)

  • g. Network Test Command
ECO <48 bit code> <echo switch>

An NCP can test the quality of communications between itself and a foreign NCP by sending it an ECO command with an arbitrary <48 bit code> (same length as a socket identifier) and an <echo switch> set to 'on' 🫧 An NCP that receives such an ECO command should immediately send back an acknowledging ECO with the same <48 bit code> and <echo switch> set to 'off' to the originating NCP πŸ’œ An NCP does not acknowledge an ECO with <echo switch> 'off' πŸ™ˆ We feel this command is going to be a huge help during the initial shakedown of the entire network πŸ”₯

  • h. No Operation Command
NOP

An NCP discards this command as soon as it arrives 🧚

User Interface to the NCP ✨

Okay so every HOST has an interface where a local process can use the network, but the NCP is the one in charge πŸ’… The exact specification of this interface is not a network protocol issue, since each installation will have its own interface keyed to its particular requirements. That part is up to each installation πŸ™ˆ The protocol requirements for the user interface to an NCP are that it provide all intended network functions and no illegal privileges. Examples of such illegal privileges include the ability to masquerade as another process, eavesdrop on communications not intended for it, or to induce the NCP to send out spurious network commands or messages. Absolutely not πŸ’€

We outline here an interface based on the Carr, Crocker, and Cerf proposal that is sufficient to fully utilize the network. This particular set of calls is mainly for illustration, but it shows the types of functions you need πŸ¦‹

The following calls to the NCP are available:

a. LISTEN <my 8 bit socket code>

A user opens this socket, creating an empty event queue for it. This LISTEN call may block waiting for the first "request" event, or it may return immediately. πŸŽ€

b. INIT <my socket code> <foreign socket>

A user attempts to connect <my socket> to <foreign socket>. The local NCP sends an RFC to the foreign NCP requesting that the connection be created. The returned acknowledgemnet is either an RFC (request accepted) or CLS (request rejected). At the caller's option, the INIT call blocks on the expected "accept" or "reject" event, or it can return immediately without waiting. In this case the user must call STATUS (see below) at a later time to determine the action by the foreign NCP. When a blocked INIT call returns, the "accept" or "reject" event is removed from the event queue. 🧚

c. STATUS <my socket code>

This call reports out the earliest previously unreported event in the queue of <my socket>. The STATUS call deletes the event from the queue if that type of event is deleteable by disclosure. ✨

d. ACCEPT <my socket code>

The user accepts connection with the foreign socket whose "request" event is earliest in the event queue for <my socket>. An acknowledging RFC is sent to the accepted foreign socket, and the "request" event is deleted from the event queue. Should any other "request" event exist in the queue, the NCP automatically denies connection by sending out a CLS command and deleting the event. Main character decisions only πŸ‘‘

e. REJECT <my socket code>

The user rejects connection with the foreign socket whose "request" event is earliest in the event queue for <my socket>. The NCP sends out a CLS command and deletes the "request" event from the queue. πŸ’€

f. CLOSE <my socket code>

The user directs the NCP to disconnect any active connection to this socket and to deactivate the socket. The NCP sends out a CLS command to the foreign socket if a connection has existed. The status of the foreign socket also becomes closed once the "close" event is disclosed to the foreign process. 🌸

g. INTERRUPT <my socket code>

The user directs the NCP to send out an INT command to the foreign socket connected to <my socket>. πŸ”₯

h. TRANSMIT <my socket code> <pointer> <nbits>

The user wishes to read (<my socket> is receive) or write (<my socket> is send) <nbits> of data into or out of an area pointed to by <pointer>. A call to write returns immediately after the NCP has queued the data to send a message over the connection. The call to write blocks only if the connection is blocked or if the local NCP is too loaded to process the request immediately. Data to be transmitted over a connection is formatted into one or more IMP messages of maximum length 8095 bits and transmitted to the foreign HOST over the link number specified in the RFC sent by the NCP controlling the receiving connection. A "close" event in the event queue for <my socket> is disclosed through the action of TRANSMIT. A call to write discloses the "close" event immediately. A read call discloses it when all data has been read. πŸ¦‹


The History of a Connection From a User View

An Illustrative Example

Say process 'a' on HOST A wants to connect with process 'b' on HOST B. Before any communication can happen, two conditions must be fulfilled:

a. process 'a' must be able to specify to its NCP a socket in 'b's socket space to which it wants to connect.

b. process 'b' must already be LISTENing to this socket.

1. Establishing the Connection

a. process 'b' LISTENs to socket 'Bb9'.

b. process 'a' INITs 'Bb9' to its 'Aa12'. The NCP at A generates an RFC specifying link number = 47, which it chooses from its available set of links. This is the link over which it will receive messages if the connection is ACCEPTed by process 'b'. πŸŽ€

c. process 'b' is informed of A's INIT request. He may REJECT connection (NCP B sends back a CLS) or ACCEPT (NCP B sends back an RFC).

d. If process 'b' ACCEPTs, the confirming RFC establishes the connection, and messages can now flow. 🫢

          HOST  A               |          HOST B
          INITIATOR             |          ACCEPTOR
          PROCESS 'a'           |          PROCESS 'b'
                                |
                                |
                                |  a. LISTEN 'socket code 9'
                                |
                                |
 b. INIT 'socket code 12' 'Bb9' |
      RFC 'AA12' 'Bb9' 'link 47' ==========>
                                |
                                | c. ACCEPT 'socket code 9'
                                |        RFC 'Bb9' 'Aa12'
                                |
                                | d. TRANSMIT 'send buffer' 'len'
                                |                        'socket 9'
                     <============== IMP message 'link 47' 'send buffer'
                                |
 e. TRANSMIT 'rec buffer' 'length'
                    'socket 12' ============>
                                |
                                | f. CLOSE 'socket code 9'
                                |
                             last RFNM ===>
                      <============== CLS 'Bb9' 'Aa12'
     closes socket 'Aa12'       |
                                |

     FIG 2.  Establishing and Communicating over a Socket Connection

2. Sending Messages over a Connection.

a. Process 'b' issues a TRANSMIT call to send data through the connection. NCP B formats this into an IMP message and sends it to NCP A with link number = 47 as specified by A's RFC. πŸ“¨

b. NCP A receives the raw message from NCP B with link number = 47. NCP A uses this link number in deciding who the intended recipient is, and stores the message in a buffer for the recipient process. 🧠

c. Process 'a' may issue a read (TRANSMIT) call for socket code 12 at any arbitrary time. The read call blocks if there is no data pending for the socket. The read call picks up the specified number of bits transmitted over socket code 12, perhaps across an IMP message boundary. The boundaries of the IMP messages are invisible to the read call. 🌈

d. Should process 'b' send data over the connection at a faster rate than process 'a' picks it up, NCP A can issue a BLK command to NCP B if A's buffers start filling. Later, when process 'a' catches up, NCP A can tell B to resume transmission via an RSM command. πŸ“

3. Process 'b' Closes the Connection

a. Process 'b' decides to close the connection, and it issues the CLOSE call to NCP B. To avoid race problems B waits for the RFNM from the previous message over this connection, then sends the CLS command to NCP A. When the RFNM from the CLS command message returns, NCP B flushes socket 'Bb9' from its tables, effecting the close at its end and deactivating 'Bb9'. πŸ‘‹

b. Because of sequential processing within NCP A, the last message to socket 'Aa12' is guaranteed to have been directed to a process before the CLS from NCP B comes through. Upon receipt of the CLS from B, NCP A marks socket 'Aa12' as "close pending" and places a "close" event into the event queue of 'Aa12'. πŸ’œ

c. Process 'a' can still issue read calls for socket 'Aa12' while there is buffered data pending. When 'a' issues a read call after the buffer has been emptied, the "close" event is disclosed to inform 'a' of the closure, and socket 'Aa12' is flushed from the tables of NCP A. ✨

4. Process 'a' Closes the Connection

a. Let us return to step 2. and assume that process 'a' wants to close the connection from its end. There is no race problem because we assume that once 'a' issues a CLOSE call, it no longer wants to read messages over that socket. πŸ™…β€β™€οΈ

b. Assume that process 'a' issues a CLOSE call on socket 'Aa12'. NCP A immediately sends out a CLS command to NCP B and marks socket 'Aa12' as "close pending". Any data buffered for read on 'Aa12' is discarded. To allow remaining messages already in transit from process 'b' to percolate through the IMP network to NCP A and be discarded without error comments, NCP A retains 'Aa12' in its tables for a suitable period of time after receiving the RFNM from the CLS command. During this period NCP A discards all messages received over the closing connection. After allowing a reasonable amount of time for these dead messages to come in, NCP A flushes 'Aa12' from its tables, effectively closing the connection and deactivating 'Aa12'. Further messages to socket 'Aa12' result in NCP A sending an ERR "erroneous command" to the originating NCP. Dead messages get the ignore treatment πŸ’€

c. When NCP B receives the CLS command, socket 'Bb9' is marked as "close pending", and the CLS event is placed into the event queue of 'Bb9'. The next time process 'b' wishes to write over that socket, the CLS event is disclosed to inform him of the closure, and socket 'Bb9' is removed from NCP B's tables. πŸ¦‹

IV - User Control and Communication Protocol πŸŽ€

okay so bestie, there has to be some process that's always listening out for anybody on the network πŸ‘€ and then makes a new process for them once it's checked who they are. That process is the logger πŸ’…. It talks to the network through the network-related User Control and Communication (UCC) module, which is where the protocol actually lives. The UCC process doesn't get any special network powers either πŸ™ˆ, with exactly one exception: it's allowed to CLOSE connections belonging to dead processes.

So here's the vibe. Under UCC, a "requestor" process (the one asking for a new process to be made) keeps two full-duplex pseudo-typewriter connections open πŸ¦‹. One goes to the foreign logger, which is how the requestor tells the logger who it is and, after login, gets basic health info about the created process back. The other goes straight to the created process, for control communication. ✨

Why two? Because having two full-duplex connections means you don't have reconnection problems, both when the logger hands communication over to the created process and when it needs to take control back 🫢. The tradeoff is pretty modest: the requestor has to switch its typewriter communication between the two sets of connections.

Here's how it basically goes down 🧚: the requestor first reserves four of its sockets with contiguous socket codes. Then it "signals" the UCC and names one of those sockets. From that signal, the UCC knows who's calling, which requestor socket pair it should talk to the requestor on, and which requestor socket pair the created process should use. More detail is coming below πŸ‘‡.

Establishing and Operating a Remote Process 🌸

okay this part is the step-by-step, so pay attention bestie πŸ’–. Every HOST's UCC always keeps a send socket with user number = 0, instance tag = 0 open (active and unconnected) as its "signal" socket πŸ”₯. It keeps checking that socket for INITs. If you want a process created at that HOST, you have to signal the UCC first, by sending an INIT to that socket.

The requesting process needs four free sockets with contiguous socket codes: <base_socket> (receive) through <base_socket+3> (send) ✨. The high-numbered send/receive pair is for typewriter communication with the foreign UCC, and the low-numbered pair is for typewriter communication with the created process πŸŽ€.

  1. The "requestor" process calls LISTEN twice to open the <base_socket+2> and <base_socket+3> receive/send pair, which is what it'll use to talk to the foreign UCC πŸ’…. Then it sends a "signalling" INIT call on <base_socket> to the UCC "signal" socket. All the UCC does with that "signalling" INIT is note down the socket number <base_socket> it came from πŸ‘€. Then it immediately REJECTs the request so its "signal" socket stays open for other signals πŸ’œ.
  2. Once the requestor gets the expected REJECT on its initial INIT call to the UCC's signal socket, it issues LISTENs for <base_socket> and <base_socket+1>. (The created process will INIT these sockets to set up control communication with the requestor 🧚.) Then the requestor blocks by calling STATUS <base_socket+2> 🫠.
  3. The UCC INITs a free send/receive socket pair to the requestor's <base_socket+2> and <base_socket+3>, which is where the requestor is presumably LISTENing πŸ¦‹. The requestor called STATUS <base_socket+2> with the block option after LISTENing on both sockets, so when the INIT from the foreign UCC shows up, STATUS returns with the INIT indication ✨. The requestor checks that the UCC is the process calling, then ACCEPTs the call. After that it calls STATUS <base_socket+3> and returns once the INIT for that socket arrives, then does the same verify-and-ACCEPT thing πŸ’…. (Which socket gets STATUS first is an arbitrary choice, fr.) Two-way communication is established once the requestor has ACCEPTed both INITs from the UCC πŸŽ€. This connection stays up during the login ritual and for the whole life of the created process 🌈. If the requestor doesn't respond properly to the UCC's INITs within a limited amount of time, the UCC gives up on the connection attempt πŸ’€.
  4. Next the requestor has to do the login ritual with the UCC πŸ”. (The initial protocol might standardize the login ritual.) If the logger isn't satisfied and wants to cut the requestor off, the UCC module CLOSEs both <base_socket+2> and <base_socket+3> πŸ™…β€β™€οΈ, maybe after the logger sends a suitable message first.
  5. If the logger is satisfied, it creates a process for the user πŸ₯³. The UCC keeps a direct line to the requestor, but now that connection is only used to report basic information about the created process πŸ“Š.
  6. The very first thing a created process does is set up a dual pseudo-typewriter control connection with its requestor πŸ’–. It INITs one of its send/receive socket pairs to the requestor's <base_socket> and <base_socket+1> ✨. If both requests get ACCEPTed, the created process sends an initial message over that connection, then goes to command level, where it waits for a typewriter command message over the connection 🫢. If the created process can't set up duplex communication with the requestor, it should destroy itself πŸ’€. After that, the UCC will either CLOSE its own connections with the requestor or arrange for another process to be created 🧚.
  7. When a created process logs out, the UCC uses a privileged entry to the NCP to CLOSE all connections between the dead process and other processes, and to deactivate all open sockets of the dead process 🧹. The UCC sends a message back to the requestor, then CLOSEs the dual connections between it and the requestor πŸ‘‹.
  8. The INTERRUPT call has a standard "quit" meaning when it's sent from a requestor process to a created process over the requestor's receive socket <base_socket> πŸ›‘. All pending output from the created process is aborted, and it enters "command level", where it waits for a command over the typewriter connection to the requestor πŸŽ€. An interrupted process can be resumed by sending it a "start" command ▢️. (Note that the rule about pending output is more restrictive than the one the INT NCP command implements πŸ‘€.)

This document was prepared through the use of the MULTICS "runoff" command πŸ“œ. A source file made of mixed text and "runoff" requests was created with the "qed" text editor. Then the "runoff" command compiled that file into a finished copy. The latest version of this document lives online in MULTICS, in the segment:

>udd>Multics>Meyer>network_protocol.runoff

(END)

Here's the figure, bestie πŸ–ΌοΈ:

      REQUESTOR                                  FOREIGN
      PROCESS                                    LOGGER
      --------------                             -------------
      a. LISTEN to sockets
      <base_socket+2> and
      <base_socket+3> to be
      connected to foreign logger.

      b. INIT <base_socket>
      to "signal" socket of
      foreign logger.
                =======================================>

                                                c. remember <base_socket>
                                                   and REJECT connection
                                                   to signal socket.

      d. LISTEN to sockets                      e. INIT a logger socket
      <base_socket> and                            pair to the requestor's
      <base_socket_1> to be                       <base_socket+2> and
      connected to the created  process.          <base_socket+3>.
                                                   /
                       <==========================/

      f. ACCEPT connection
      with sockets from
      foreign logger.

                             PERFORM LOGIN RITUAL
                                                CREATED
                                                PROCESS
                                                -------------
                                                g. INIT any socket pair
                                                   to requestor's
                                                   <base_socket> and
                                                   <base_socket+1>
                                                    /
                       <===========================/
      h. ACCEPT connection
      with sockets from created
      process.

               FIG. 4 Establishing a Process at a Foreign HOST
          [ This RFC was put into machine readable form for entry ]
          [ into the online RFC archives by Miles McCredie 11/99  ]

That's the end of the doc, bestie! πŸŒˆπŸ’– Those four sockets, the two connections, and the step-by-step handshake are all you need to remember πŸ’…βœ¨

πŸ“¦ where this page comes from