RFC 6529

Host/Host Protocol for the ARPA Network

๐Ÿ“… published April 2012, from ietf

Host/Host Protocol for the ARPA Network ๐ŸŽ€

RFC 6529 ๐Ÿ’– Here's the title block so you're not hunting for it! The authors are A. McKenzie and S. Crocker. It's Historic (not a standard, just for the record ๐Ÿ“š), it's an Independent Submission, and it's dated April 2012. The ISSN is 2070-1721. The title block doesn't list anything it obsoletes or updates, so no drama there ๐Ÿ™ˆ

Abstract โœจ

okay so this doc basically reproduces the Host/Host Protocol that the ARPA Network Working Group built back in 1969, 1970, and 1971 ๐Ÿฆ‹ It explains how processes on separate Hosts talk to each other. The protocol handles juggling several streams of communication over one hardware interface, which covers addressing, flow control, setting up and tearing down connections, and other signaling ๐Ÿซถ It was the official ARPA Network protocol from January 1972 until the switch to TCP/IP in January 1983. It's getting an RFC now, super late, to help fill in the historical record ๐Ÿ’œ

Status of This Memo ๐Ÿ“

bestie, this is NOT an Internet Standards Track spec. It's published purely for the historical record ๐Ÿ›๏ธ

This document is a Historic Document for the Internet community. It's a contribution to the RFC Series that's independent of any other RFC stream. The RFC Editor picked to publish it at their discretion and makes no statement about whether you should implement or deploy it ๐Ÿคทโ€โ™€๏ธ Documents the RFC Editor approves for publication aren't candidates for any level of Internet Standard, see Section 2 of RFC 5741 ๐Ÿ’…

For the current status, any errata, and how to give feedback, check http://www.rfc-editor.org/info/rfc6529 โœจ

Copyright (c) 2012 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as in effect on the date of publication. Please read those carefully, because they describe your rights and restrictions for this document ๐Ÿ“œ

Table of Contents ๐Ÿงš

1. Introduction ....................................................3
2. A Few Comments on Nomenclature and Key Concepts .................4
3. Host/Host Protocol Document .....................................5
   (with its own table of contents on page 7)
4. Security Considerations ........................................34

1. Introduction โœจ

so the Host/Host Protocol for the ARPA Network was created in 1969, 1970, and 1971 by the Network Working Group, which was chaired by Steve Crocker, a graduate student at UCLA ๐ŸŽ“ A bunch of the RFCs with numbers under 72, plus RFCs 102, 107, 111, 124, 132, 154, and 179, dealt with building this protocol ๐Ÿ’…

The first official doc defining it was issued by Crocker on August 3, 1970, titled "Host-Host Protocol Document No. 1" (see citation in RFC 65) ๐Ÿ“ It was based on RFC 54 by Crocker, Postel, Newkirk, and Kraley. Revision of Document No. 1 started in mid-February 1971, as discussed in RFC 102. McKenzie is listed as the author of the January 1972 document that superseded Document No. 1, but it's more accurate to say McKenzie compiled and edited it. Most or all of the ideas came from other people ๐Ÿซถ

Document No. 1 never got an RFC number, because it wasn't meant to be a "request for comments." It was meant to be a standard for implementation ๐Ÿ“‹ It was one of a set of these standards kept as separate documentation by the Network Information Center (NIC) at Stanford Research Institute (SRI). The January 1972 version (NIC 8246), which is reproduced here, followed that same approach. Lots of people have pointed out that all later standards were issued as RFCs, so leaving the Host/Host Protocol spec out of the RFC series made a weird gap in the historical record ๐Ÿ•ณ๏ธ Filling that gap is the whole point of this RFC ๐Ÿฆ‹

In 1972, most ARPA Network documents, RFCs and others, were prepared and distributed in hard copy ๐Ÿ“„ The Host/Host Protocol doc was typed on a typewriter (probably an IBM Selectric) with interchangeable print elements, and it used italic and boldface fonts along with the regular one. Diagrams were drawn by a graphic artist and pasted into the typed doc ๐ŸŽจ RFCs have to use a single typeface, so boldface is shown with ALL CAPITALS or a double underline, and italics are shown with underscores around words instead of spaces ๐Ÿ’œ It's a little harder to read, but the emphasis from the original is preserved โœจ The pagination has changed, and we hope the page numbers were all fixed correctly ๐Ÿ™ˆ The original had three footnotes, which were moved into the text and set off by indentation and square brackets. A .pdf image of the original document is at http://www.cbi.umn.edu/hostedpublications/pdf/McKenzieNCP1972.pdf ๐Ÿ”—

2. A Few Comments on Nomenclature and Key Concepts ๐Ÿ’…

okay so in the protocol definition, "RFC" means "Request for Connection." That covers either a "Sender to Receiver" or a "Receiver to Sender" request to start a connection ๐Ÿคฏ Looking back, this was an unnecessarily confusing name choice, no cap ๐Ÿ˜ญ

When the protocol was defined, it went by the very undistinguished name "Host-Host Protocol." The acronym "NCP" meant "Network Control Program," which was the code that had to be added to the operating system on each host so it could interact with its Interface Message Processor (IMP) and manage multiple connections โญ Over time, especially around the switch to TCP/IP, people started calling this protocol "NCP," and the expansion changed to "Network Control Protocol" ๐ŸŒธ

This protocol was superseded by TCP. In this doc, it's called a second layer (or "level") protocol, while today TCP is usually called a layer 4 protocol ๐Ÿงš When this protocol was created, people expected that new layers would keep showing up on top of, below, and even in between existing layers ๐ŸŒˆ

This protocol used a separate channel, the control link, to manage connections. That approach got abandoned in later protocols ๐Ÿฆ‹

In this design, there was no checksum or other form of error control except for the RST. Earlier versions did have one, but it got removed at the insistence of the IMP designers, who argued hard that the underlying network of IMPs would never lose a packet or deliver one with errors ๐Ÿ’€ The IMP network was generally very reliable, but there were cases where the interface between the IMP and the host could drop bits. Also, experience with congestion control, as the network got used more heavily, made it clear that the host layer would have to deal with occasional losses in transmission ๐Ÿ˜ญ These changes were built into TCP ๐Ÿ’–

Uncertainty about timing constraints in protocol design shows up in this document, and it's still a source of ambiguity, limitation, and error in today's design processes ๐Ÿ™ˆ

3. Host/Host Protocol Document ๐ŸŽ€


                              Host/Host Protocol
                                   for the
                                 ARPA Network

























                    Prepared for the Network Working Group by
                       Alex McKenzie
                       BBN
                       January 1972

PREFACE ๐ŸŒธ

this section explains what the document covers and how it's organized, so let's get into it ๐Ÿ’…

This document specifies a protocol for communication between Host computers on the ARPA Network. Specifically, it covers connecting independent processes on different Hosts, controlling the flow of data over established connections, and several ancillary functions ๐Ÿซถ It's basically self-contained, but it's just one of several ARPA Network protocols. All the protocol specs are collected in the document _Current_Network_Protocols,_ NIC #7104 ๐Ÿ“š

This document supersedes NIC #7147 of the same title. The main differences between the two are:

  • prohibition of spontaneous RET, ERP, and RRP commands
  • a discussion of the problem of unanswered CLS commands (page 16)
  • a discussion of the implications of queueing and not queueing RFCs (page 14)
  • the strong recommendation that received ERR commands be logged, and some additional ERR specifications.

On top of those, a few minor editorial changes were made โœจ

Even though lots of people on the network know a lot about protocol issues, anyone with questions about Network protocols should start by reaching out to one of these three people ๐Ÿงš

Steve Crocker
Advanced Research Projects Agency
1400 Wilson Boulevard
Arlington, Virginia 22209
(202) 694-5921 or 5922

Alex McKenzie
Bolt Beranek and Newman Inc.
50 Moulton Street
Cambridge, Massachusetts 02133
(617) 491-1350 ext. 441

Jon Postel
University of California at Los Angeles
Computer Science Department
3732 Boelter Hall
Los Angeles, California 90024
(213) 325-2363

TABLE OF CONTENTS ๐Ÿ“

I.    INTRODUCTION..................................................8
      An overview of the multi-leveled protocol structure in the ARPA
      Network.

II.   COMMUNICATION CONCEPTS.......................................10
      Definitions of terminology and a description of the overall
      strategy used in Host-to-Host communication.

III.  NCP FUNCTIONS................................................13
      The meat of the document for the first-time reader.  Host-to-
      Host "commands" are introduced with descriptions of conditions
      of their use, discussion of possible problems, and other
      background material.

            Connection Establishment..........................13
            Connection Termination............................15
            Flow Control......................................17
            Interrupts........................................20
            Test Inquiry......................................20
            Reinitialization..................................21

IV.   DECLARATIVE SPECIFICATIONS...................................23
      Details for the NCP implementer.  A few additional "commands"
      are introduced, and those described in Section III are
      reviewed.  Formats and code and link assignments are specified.

            Message Format....................................23
            Link Assignment...................................25
            Control Messages..................................25
            Control Commands..................................25
            Opcode Assignment.................................31
            Control Command Summary...........................31

I. INTRODUCTION ๐Ÿฆ‹

The ARPA Network is giving "connect geographically separated computers" ๐ŸŒโœจ Those computers are called Hosts, and they're usually super different from each other in type, speed, word length, operating system, and so on. Each Host plugs into the network through a little local computer called an Interface Message Processor (IMP) ๐Ÿ–ฅ๏ธ. The whole network is built by linking these IMPs together, and they're all basically identical. The links are wideband lines rented from the telephone company ๐Ÿ“ž. Each IMP stores messages and forwards them to its neighbors. So when a Host wants to send something, it hands the message to its local IMP, and the first 32 bits of that message contain the "network address" of the destination Host ๐Ÿ“ฌ. The message hops from IMP to IMP until it reaches the destination IMP, which passes it along to the destination Host. Iconic delivery service ๐Ÿ’…

Now, the rules for how a Host and its local IMP talk to each other (the physical and logical message transfer) are in Bolt Beranek and Newman (BBN) Report No. 1822 ๐Ÿ“„. People usually call these the first-level protocol or the Host/IMP Protocol. But here's the tea: that protocol on its own isn't enough for two processes running on totally different Hosts to have a meaningful conversation ๐Ÿ™ˆ. They also need an agreement about how to start talking, how to read the data that comes in, and so on. Every pair of Hosts could make those agreements themselves, but that would be a lot of extra work for everyone. A more general setup makes way more sense to minimize the implementation needed for Network-wide communication ๐Ÿง . So the Host organizations formed a Network Working Group (NWG) to swap ideas and come up with more specs for Host-to-Host communication ๐Ÿซถ

The NWG went with a "layered" approach to the protocol specs ๐ŸŽ‚ The innermost layer is the Host/IMP protocol. The next layer covers how communication paths get set up, how buffer space gets managed at each end of a path, and how to "interrupt" a path ๐Ÿ›‘ This one is used by every higher-level protocol, and it's called the second-level protocol, or the Host/Host protocol. (Fun fact: even though the IMP sub-network does message switching, the Host/Host protocol is based on line switching ๐Ÿคฏ) Here are some more layers that were being developed or planned:

  1. An Initial Connection Protocol (ICP) ๐Ÿ”Œ which gives several processes a neat, standard way to get simultaneous access to one specific process (like the "logger") on another Host.
  2. A Telecommunication Network (TELNET) protocol ๐Ÿ’ป which "maps" an arbitrary keyboard-printer terminal onto a Network Virtual Terminal (NVT). This lets a terminal user at one Host talk to a terminal-serving process at another site that "expects" a local terminal that's logically different from the remote one actually being used ๐ŸŽ€ TELNET says the ICP is used to set up the communication path between the terminal user and the terminal-service process.
  3. A Data Transfer protocol ๐Ÿ“ฆ to specify standard ways of formatting data before it's shipped through the network.
  4. A File Transfer protocol ๐Ÿ“ to specify how to read, write, and update files stored on a remote Host. The File Transfer protocol says the actual data transmission should follow the Data Transfer protocol ๐Ÿ’–
  5. A Graphics protocol ๐ŸŽจ to specify how graphics display information gets exchanged.
  6. A Remote Job Service (RJS) protocol ๐Ÿงพ to specify how to submit input to, get output from, and control Hosts that offer batch processing facilities.

The rest of this document describes and specifies the Host/Host, or second-level, protocol as the Network Working Group put it together ๐Ÿ‘‘

II. COMMUNICATION CONCEPTS โœจ

The IMP sub-network puts a bunch of physical restrictions on communication between Hosts ๐Ÿšง Those restrictions are laid out in BBN Report Number 1822. The concepts that matter most for designing the Host/Host protocol are leaders, messages, padding, links, and message types ๐Ÿงฉ This discussion assumes you already know these concepts, so bestie, make sure you've got them down first ๐Ÿ™ˆ

Okay, real talk: hardware and operating systems across Hosts are all over the place ๐Ÿคช But most of these systems are built around multiprogramming ๐Ÿ’… Each Host can support several users at once, and each user can run one or more processes. Lots of those processes want to use the network at the same time, so a fundamental requirement of the Host/Host protocol is to provide process-to-process communication over the network ๐Ÿฆ‹ The first-level protocol only knows about Hosts. But the processes running inside a single Host are usually independent of each other, so the second-level protocol needs a richer addressing structure ๐ŸŒธ

The Host/Host protocol was also shaped by the fact that most process-to-process communication isn't just one lonely message. It's usually a sequence of messages ๐Ÿ“š For example, one process might send a huge chunk of information, like an entire database, to another process. Or two processes might have a chatty interactive conversation with lots of back-and-forth exchanges ๐Ÿ’ฌ

These considerations led to the ideas of connections, a Network Control Program, a "control link", "control commands", connection byte size, message headers, and sockets ๐ŸŽ€

A connection is an extension of a link ๐Ÿ”— It couples two processes so that the output from one becomes the input of the other. Connections are simplex (aka unidirectional), so if two processes want to talk in both directions, they need two connections ๐Ÿ’œ

Processes inside a Host talk to the rest of the network through a Network Control Program (NCP) that lives in that Host and implements the second-level protocol ๐Ÿงš The NCP's main job is to set up connections, break connections, and control the data flow over them. We'll describe the NCP as if it were part of the operating system of a multiprogramming Host, even though the way an NCP actually gets implemented might be different on some Hosts ๐Ÿ–ฅ๏ธ

To do its job, the NCP of one Host has to talk to the NCPs of other Hosts ๐Ÿซ‚ So a particular link between each pair of Hosts has been designated as the control link. Messages sent over the control link are called control messages, and an NCP must always interpret them as a sequence of one or more control commands ๐Ÿงพ For example, one kind of control command starts a connection, while another kind says a connection has been terminated ๐Ÿ›‘

[*Note: In BBN Report Number 1822, messages of non-zero type are called control messages, and they're used to control the flow of information between a Host and its IMP. In this document, the term "control message" refers to a message of type zero sent over the control link. The IMPs don't pay any special attention to these messages.]

Here's a big one ๐Ÿคฏ The idea of a message, like we just used it, is basically an artifact of the IMP sub-network. Network message boundaries might not mean much at all to the processes doing the communicating ๐Ÿ’ญ So it was decided that the NCP, rather than each transmitting process, should be responsible for chopping up interprocess communication into network messages โœ‚๏ธ That means the second-level protocol has a principle: no significance may be inferred from message boundaries by a receiving process ๐Ÿšซ The only exception to this principle is in control messages, each of which must contain an integral number of control commands ๐Ÿ“

Since the transmitting NCP picks the message boundaries, the receiving NCP has to be ready to glue successive messages from the network back together into one transmission (or split them up differently) for delivery to the receiving process ๐Ÿงฉ Hosts also have different word sizes, so a message from the network might end in the middle of a word at the receiving end. Then concatenating the next message could mean the receiving Host has to do a lot of bit-shifting ๐Ÿ˜ฉ Bit-shifting is usually super costly in processing time, so the protocol includes the ideas of connection byte size and message headers to help ๐Ÿ’…

As part of setting up a connection, the processes involved have to agree on a connection byte size. Every message sent over the connection then has to contain an integral number of bytes of that size ๐Ÿ“ So the pair of processes can pick a mutually convenient byte size, for example the least common multiple of their Host word lengths ๐Ÿฆ„ Here's the key thing: the ability to choose a byte size must be available to the processes involved in the connection. An NCP is prohibited from imposing an arbitrary byte size on any process running in its own Host ๐Ÿ™…โ€โ™€๏ธ An outer layer of protocol may also specify a byte size to be used by that protocol. And if some NCP can't handle that byte size, then that outer layer of protocol won't be implementable on that Host ๐Ÿ’€

The IMP sub-network requires that the first 32 bits of each message (called the leader) contain addressing information, including the destination Host address and the link number ๐Ÿ“ฌ The second-level protocol stretches the required information at the start of each message to a total of 72 bits. These 72 bits are called the message header ๐ŸŽ€ The 72-bit length was picked because most Hosts either work comfortably with 8-bit units of data or have word lengths of 18 or 36 bits, and 72 is the least common multiple of those lengths ๐Ÿงฎ So the message header length should cut down on bit-shifting problems for many Hosts ๐Ÿ™Œ On top of the leader, the message header includes a field giving the byte size used in the message, a field giving the number of bytes in the message, and "filler" fields ๐Ÿงธ The full format of the message header is described in Section IV ๐Ÿ’–

One more major concern for the second-level protocol is a way to refer to processes on other Hosts ๐ŸŒ Every Host has its own internal scheme for naming processes, but those schemes are usually different from each other and might even be incompatible ๐Ÿ˜ตโ€๐Ÿ’ซ Since it isn't practical to force a common internal naming scheme on everyone, the protocol uses a standard intermediate name space, with a separate portion of that name space allocated to each Host ๐Ÿ—บ๏ธ Each Host must have the ability to map its internal process identifiers into its own portion of this name space ๐Ÿซถโœจ

The name space is made of sockets ๐Ÿ’–. A socket is one end of a connection, and a connection is fully specified by a pair of sockets, so two sockets make one connection โœจ. Each socket is identified by a Host number and a 32-bit socket number. The same 32-bit number on different Hosts means different sockets ๐ŸŒธ. A socket is either a receive_socket or a send_socket, and its low-order bit marks which one (0 = receive; 1 = send). That's the socket's gender ๐Ÿ’…. The sockets at either end of a connection must be of opposite gender. Apart from gender, the second level protocol places no constraints on how socket numbers are assigned within a Host ๐ŸŽ€.

III. NCP FUNCTIONS ๐Ÿ‘‘

The NCP's jobs are to establish connections, terminate connections, control flow, transmit interrupts, and respond to test inquiries ๐Ÿงš. This section explains how each of those works, and control commands are introduced as needed. Section IV puts the formats of all control commands together in one place ๐Ÿ“š.

Connection Establishment

The commands used to establish a connection are STR (sender-to-receiver) and RTS (receiver-to-sender) ๐Ÿฆ‹.

           8*         32               32           8
        +----------------------------------------------+
        | STR |   send socket  | receive socket | size |
        +----------------------------------------------+
      [*The number shown above each control command field is the length
      of that field in bits.]
           8          32               32           8
        +----------------------------------------------+
        | RTS | receive socket |  send socket   | link |
        +----------------------------------------------+

The STR command goes from a prospective sender to a prospective receiver, and the RTS goes from a prospective receiver to a prospective sender ๐Ÿ’Œ. The send socket field names a socket local to the prospective sender, and the receive socket field names a socket local to the prospective receiver. In the STR command, the "size" field holds an unsigned binary number (in the range 1 to 255; zero is prohibited) that sets the byte size used for all messages over the connection ๐Ÿ“. In the RTS command, the "link" field specifies a link number, and all messages over the connection must be sent over the link with that number ๐Ÿ”—. These two commands are called requests-for-connection (RFCs) ๐Ÿ’…. An STR and an RTS match if their receive socket fields match and their send socket fields match ๐Ÿ’ž. A connection is established once a matching pair of RFCs has been exchanged. Hosts are prohibited from establishing more than one connection to any local socket. ๐Ÿ™…โ€โ™€๏ธ

With respect to a particular connection, the Host containing the send socket is called the sending_Host, and the Host containing the receive socket is called the receiving_Host ๐Ÿง . A Host can connect one of its receive sockets to one of its own send sockets, which makes it both the sending Host and the receiving Host for that connection ๐Ÿชž.

These terms only apply to data flow. Control messages will, in general, be sent in both directions ๐Ÿ”.

A Host sends an RFC either to request a connection or to accept a foreign Host's request ๐Ÿค. Because RFC commands are used both for requesting and for accepting a connection, either of two cooperating processes can start connection establishment ๐Ÿ‘ฏ. So a family of processes can be created with connection-initiating actions built in, and the processes in that family can be started up (in different Hosts) in arbitrary order, as long as the Hosts involved do appropriate queueing (see below) ๐ŸŒˆ.

There is no prescribed lifetime for an RFC. A Host is permitted to queue incoming RFCs and hold off on a response for an arbitrarily long time ๐Ÿ•ฐ๏ธ. Or, if it doesn't have a matching RFC outstanding, it can reject requests immediately (see Connection Termination below) โŒ. For example, it could make sense for an NCP to queue an RFC that refers to a currently unused socket until a local process takes control of that socket number and tells the NCP to accept or reject the request ๐Ÿ›Ž๏ธ. The Host that sent the RFC might not be willing to wait forever, though, so it may abort the request ๐Ÿ˜ค. On the other hand, some NCP implementations may not have any space for queueing RFCs, and so can be expected to reject RFCs unless the RFC sequence was started locally ๐Ÿ™ˆ.

Queueing Considerations

The decision to queue, or not queue, incoming RFCs has big implications, and NCP implementers must not ignore them ๐Ÿšจ. Each queued RFC needs a small amount of memory in the Host doing the queueing ๐Ÿงบ. If every incoming RFC is queued until a local process seizes the local socket and accepts (or rejects) it, but no local process ever seizes the socket, the RFC must be queued "forever" ๐Ÿ˜ฑ. In theory this could happen infinitely many times (there's no reason not to queue several RFCs for a single local socket, letting the local process decide which, if any, to accept), which would require infinite storage for the RFC queue ๐Ÿ’€. On the other hand, if no queueing is performed, the cooperating processes described above will only be able to establish a desired connection by accident (when they start up such that one issues its RFC while the other's RFC is still in transit in the network). That is clearly an unlikely occurrence ๐ŸŽฒ.

Perhaps the most reasonable solution to these problems is for each NCP to give processes running in its own Host two options for attempting to initiate connections ๐ŸŒŸ. The first option lets a process cause an RFC to be sent to a specified remote socket, with the NCP notifying the process whether the RFC was accepted or rejected by the remote Host ๐Ÿ“ฌ. The second option lets a process tell its own NCP to "listen" for an RFC to a specified local socket from some remote socket (the process might also specify the particular remote socket and/or Host it wants to communicate with), and to accept the RFC (i.e., return a matching RFC) if and when it arrives ๐Ÿ‘‚. This also involves queueing ("listen" requests), but it's internal queueing, which the local Host can manage reasonably well ๐Ÿ—‚๏ธ. If this implementation were available, one of two cooperating processes could "listen" while the other caused a series of RFCs to be sent to the "listening" socket until one was accepted. That way no queueing of incoming RFCs would be required, although it would do no harm ๐Ÿซถ.

It is the intent of the protocol that each NCP should provide either the "listen" option described above or a SUBSTANTIAL queueing facility. This is not, however, an absolute requirement of the protocol ๐Ÿง.

Connection Termination

The command used to terminate a connection is CLS (close) ๐Ÿ”š.

        8        32            32
     +-----+-------------+-------------+
     | CLS |  my socket  | your socket |
     +-----+-------------+-------------+

Wait, the original has 8 spaces before the "+" line and 5 before "|"? Let me correct: the original is exactly:

           8        32            32
        +-----+-------------+-------------+
        | CLS |  my socket  | your socket |
        +-----+-------------+-------------+

The "my socket" field holds the socket local to the sender of the CLS command, and the "your socket" field holds the socket local to the receiver of the CLS command ๐Ÿ“ฎ. Each side must send and receive a CLS command before connection termination is completed and the sockets are free to participate in other connections. ๐ŸŽ‰

It's not necessary for a connection to be established (i.e., for both RFCs to be exchanged) before termination begins ๐Ÿ™ƒ. For example, if a Host wants to refuse a request for connection, it sends back a CLS instead of a matching RFC, and then waits for the initiating Host to acknowledge the refusal by returning a CLS ๐Ÿ™…. Similarly, if a Host wants to abort its outstanding request for a connection, it sends a CLS command, and the foreign Host is obliged to acknowledge the CLS with its own CLS ๐Ÿ›‘. Note that even though the connection was never established, CLS commands must be exchanged before the sockets are free for other use ๐Ÿงน.

After a connection is established, CLS commands sent by the receiver and by the sender have slightly different effects ๐Ÿ”€. A CLS sent by the sender says that no more messages will be sent over the connection. This command must not be sent if there is a message in transit over the connection. A CLS sent by the receiver acts as a demand on the sender to terminate transmission. But since there's a delay in getting the CLS to the sender, the receiver must expect more input ๐Ÿ“จ.

A Host should "quickly" acknowledge an incoming CLS so the foreign Host can purge its tables ๐Ÿงฝ. However, there is no prescribed time period in which a CLS must be acknowledged. โณ

Because the CLS command is used to initiate closing, aborting and refusing a connection, and also to acknowledge closing, aborting and refusing a connection, race conditions can occur ๐ŸŽ๏ธ. They don't lead to ambiguous or erroneous results, though, as these examples show ๐Ÿ’ก.

EXAMPLE 1: Suppose Host A sends Host B a request for connection, and then A sends a CLS to Host B because it's tired of waiting for a reply. Just as A sends its CLS to B, however, B sends a CLS to A to refuse the connection. A will "believe" B is acknowledging the abort, and B will "believe" A is acknowledging its refusal, but the outcome will be correct ๐Ÿคญ.

EXAMPLE 2: Suppose Host A sends Host B an RFC followed by a CLS, as in example 1. In this case, though, B sends a matching RFC to A just as A sends its CLS. Host A may "believe" the RFC is an attempt (on B's part) to establish a new connection, or it may understand the race condition. Either way, it can discard the RFC, since its socket is not yet free ๐Ÿ—‘๏ธ. Host B will "believe" the CLS is breaking an established connection, but the outcome is correct, because a matching CLS is the required response, and both A and B will then terminate the connection ๐ŸŽฏ.

Every NCP implementation has to deal with what to do if a matching CLS is not returned "quickly" by a foreign Host (i.e., if the foreign Host appears to be violating protocol in this respect) ๐Ÿ˜ฌ. One naive answer is to hold the connection in a partially closed state "forever," waiting for a matching CLS. There are two problems with this. First, the socket involved may be a "scarce resource," such as the "logger" socket specified by an Initial Connection Protocol (see NIC # 7101), which the local Host can't afford to tie up indefinitely ๐Ÿชซ. Second, a partially broken (or malicious) process in a foreign Host may send an unending stream of RFCs, which the local Host wants to refuse by sending CLS commands and waiting for a match. In the worst case, this could require 2^32 ! socket pairs to be stored before duplicates began to appear ๐Ÿฅต.

Clearly, no Host is prepared to store (or search) this much information ๐Ÿ™…โ€โ™€๏ธ๐Ÿ“ฆ.

A second possibility sometimes suggested is for the Host waiting for matching CLS commands (Host A) to send an RST (see page 20) to the offending Host (Host B), which would let all tables be reinitialized at both ends ๐Ÿ”„. This would be pretty unsatisfying for any user at Host A who happened to be doing useful work on Host B over network connections, since those connections would also be broken by the RST ๐Ÿ˜ญ.

Most implementers have spotted these problems and quietly picked their own timeout, after which they just "forget" a connection even if no CLS ever showed up ๐Ÿ™ˆ The danger is that if a second connection between the same pair of sockets gets set up later, and that first CLS finally shows up, the new connection is likely to get closed by accident ๐Ÿ˜ญ This can only happen if a Host breaks the protocol in two ways: first by not replying quickly to an incoming CLS, and second by letting a connection start on a socket it already thinks is in use ๐Ÿ’€ People have suggested the network adopt one standard timeout, but the NWG couldn't agree on a number that's short enough to be useful AND long enough for every Host to be happy ๐Ÿฅบ The timeouts in use seem to land somewhere between about one minute and about five minutes โฐ It must be emphasized that all of these timeouts, even though they're pretty common, fairly safe, and kinda useful, are a violation of the protocol, because using them can lead to connection ambiguities ๐Ÿšจ


Flow Control

Once a connection is set up, the sending Host sends its messages over the agreed link to the receiving Host ๐Ÿ’Œ The receiving NCP takes messages from its IMP and lines them up for its various processes. Messages can arrive faster than they can be processed, so a mechanism is REQUIRED that lets the receiving Host slow down the sending Host's flow ๐Ÿ›‘

The flow control mechanism needs the receiving Host to set aside buffer space for each connection and to tell the sending Host how much space is left ๐Ÿงบ The sending Host keeps track of how much room there is and never sends more data than it thinks the receiving Host can take ๐Ÿ’…

So here's how it works โœจ The sending Host keeps two counters for each connection, a message_counter and a bit_counter. Both start at zero when the connection is set up, and they go up whenever the receiving Host sends allocate (ALL) control commands, which we'll get to in a sec. When the sending Host's NCP sends a message, it subtracts one from the message counter and subtracts the text_length (defined below) from the bit counter. The sender is prohibited from sending if either counter would drop below zero ๐Ÿšซ The sending Host can also give back all or part of its message or bit space with a return (RET) command, but only after it gets a give-back (GVB) command from the receiving Host (more on that below) ๐Ÿ”

The text_length of a message is the product of the connection byte size and the byte count for that message, and both of those numbers live in the message header ๐Ÿ”ข Messages with a zero byte count, and therefore a zero text length, are specifically permitted ๐Ÿฅฐ Zero-length messages don't use any bit space allocation, but they do use message space allocation ๐Ÿ’œ The flow control mechanisms don't apply to the control link, since connections are never explicitly set up over that link ๐Ÿ™…โ€โ™€๏ธ

The control command that increases the sender's bit counter and message counter is ALL (allocate) ๐Ÿ“ˆ

        8      8       16           32
     +------------------------------------+
     | ALL | link | msg space | bit space |
     +------------------------------------+

This command is sent ONLY from the receiving Host to the sending Host, and it's legal ONLY when a connection using the link number in the "link" field is set up ๐ŸŽ€ The "msg space" and "bit space" fields are unsigned binary integers that say how much to increase the sender's message counter and bit counter (respectively) ๐Ÿ”ข The receiver is prohibited from raising the sender's message counter above (2^16 - 1), or the sender's bit counter above (2^32 - 1) ๐Ÿ™…โ€โ™€๏ธ Basically, the receiver has to keep its own counters that go up and down by the same rules as the sender's counters, so they stay in sync ๐Ÿซถ

The receiving Host can ask the sending Host to give back all or part of its current allocation ๐Ÿ™‹โ€โ™€๏ธ The control command for this request is GVB (give-back) ๐Ÿฆ‹

        8      8    8    8
     +----------------------+
     | GVB | link | fm | fb |
     +----------------------+

This command is sent ONLY from the receiving Host to the sending Host, and it's legal ONLY when a connection using the link number in the "link" field is set up ๐Ÿ’– The fields fm and fb are fractions (in 128ths) of the current message space allocation and bit space allocation (respectively) that should be given back. If either fraction is equal to or greater than one, all of that allocation MUST be returned ๐Ÿ’ฏ Fractions are used because, while messages are in transit, the sender and receiver might not agree on the exact allocation at every moment ๐ŸŒˆ

When a GVB command comes in, the sending Host MUST return at least* the requested portions of the message and bit space allocations ๐Ÿ™Œ (A sending Host is prohibited from giving back portions of its message and bit space allocations on its own, no vibes-based returns allowed ๐Ÿ™…โ€โ™€๏ธ) The control command for doing this is RET (return) ๐Ÿ”™

[*In particular, fractional returns MUST be rounded up, not truncated.]

        8      8       16           32
     +------------------------------------+
     | RET | link | msg space | bit space |
     +------------------------------------+

This command is sent ONLY from the sending Host to the receiving Host, and it's legal ONLY when a connection using the link number in the "link" field is set up AND a GVB command has already been received from the receiving Host ๐Ÿซง The "msg space" and "bit space" fields are unsigned binary integers showing how much the sender's message counter and bit counter (respectively) went down because of the RET activity, meaning how much message and bit space allocation is being returned ๐ŸŽ NCPs are obliged to answer a GVB with a RET "quickly," but there is no prescribed time period in which the answering RET MUST be sent โณ

Some Hosts only allocate as much space as they can actually guarantee for each link ๐Ÿ›ก๏ธ These Hosts will mostly use GVB just to reclaim space that's filling up super slowly or not at all ๐Ÿข Other Hosts over-allocate on purpose so they can use their space more efficiently ๐Ÿง  A Host like that will then need GVB whenever input on a particular link is coming in faster than it's being processed ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ


Interrupts

The second level protocol has a mechanism that lets transmission over a connection get "interrupted" โœ‹ What an "interrupt" actually means isn't defined at this level. It's left open for outer layers of protocol to use however they like ๐Ÿงš The interrupt command sent from the receiving Host to the sending Host is INR (interrupt-by-receiver) ๐Ÿ“ฃ

        8      8
     +------------+
     | INR | link |
     +------------+

The interrupt command sent from the sending Host to the receiving Host is INS (interrupt-by-sender) ๐Ÿ“ข

        8      8
     +------------+
     | INS | link |
     +------------+

INR and INS commands are legal ONLY when a connection using the link number in the "link" field is set up ๐Ÿ’…


Test Inquiry

Sometimes it's useful for one Host to check whether another Host can actually carry on network conversations ๐Ÿ‘€ The control command for this is ECO (echo) ๐Ÿชž

        8      8
     +------------+
     | ECO | data |
     +------------+

The "data" field MAY contain any bit configuration the sending Host picks ๐ŸŽจ When an NCP gets an ECO command, it MUST respond by sending the data back to the sender in an ERP (echo-reply) command ๐Ÿ”

        8      8
     +------------+
     | ERP | data |
     +------------+

A Host SHOULD "quickly" respond (with an ERP command) to an incoming ECO command ๐Ÿƒโ€โ™€๏ธ There's no prescribed time period, after an ECO is received, in which the ERP MUST be returned โฐ A Host is prohibited from sending an ERP when no ECO has been received, and from sending an ECO to a Host while a previous ECO to that Host is still "unanswered" ๐Ÿšซ Any of the following count as an "answer" to an ECO: information from the local IMP saying the ECO was discarded by the network (for example, IMP/Host message type 7 - Destination Dead), an ERP, an RST, or an RRP (see below) โœ…


Reinitialization

Sometimes, because of lost control messages, system "crashes," NCP errors, or other stuff, communication between two NCPs gets disrupted ๐Ÿ’” One possible result is that neither NCP can be sure its stored info about connections with the other Host matches what the other Host has stored ๐Ÿ˜ต In that situation, an NCP MAY want to reinitialize its tables and ask the other Host to do the same, and for this the protocol provides a pair of control commands: RST (reset) and RRP (reset-reply) ๐Ÿ”„

        8
     +-----+
     | RST |
     +-----+
        8
     +-----+
     | RRP |
     +-----+

The Host receiving an RST should treat it as a signal to purge its NCP tables of any entries that came from communication with the Host that sent the RST ๐Ÿงน The Host that sent the RST should likewise purge its NCP tables of any entries that came from communication with the Host it sent the RST to ๐Ÿซง The Host receiving the RST SHOULD acknowledge it by returning an RRP ๐Ÿ’Œ Once the first Host has sent an RST to the second Host, the first Host is not obliged to communicate with the second Host (except for responding to RST) until the second Host returns an RRP. ๐Ÿ™ˆ In fact, to avoid synchronization errors, the first Host SHOULD NOT communicate with the second until the RST is answered ๐Ÿค Of course, if the IMP subnetwork returns a "Destination Dead" (type 7) message in response to the control message carrying the RST, an RRP shouldn't be expected ๐Ÿ’€ If both NCPs decide to send RSTs at about the same time, each Host will receive an RST and each MUST answer with an RRP, even though its own RST hasn't been answered yet ๐Ÿ‘ฏโ€โ™€๏ธ

Some Hosts may choose to "broadcast" RSTs to the entire network when they "come up" ๐Ÿ“ก One way to do that would be to send an RST command to each of the 256 possible Host addresses. The IMP subnetwork would return a "Destination Dead" (type 7) message for every non-existent Host, as well as for every Host that's actually "dead" ๐Ÿ’€ However, no Host is ever obliged to transmit an RST command. ๐Ÿ™…โ€โ™€๏ธ

Hosts are prohibited from sending an RRP when no RST has been received ๐Ÿšซ Also, Hosts MAY send only one RST in a single control message, and they SHOULD wait a "reasonable time" before sending another RST to the same Host โณ Under these conditions, a single RRP counts as an "answer" to all RSTs sent to that Host, and any other RRPs arriving from that Host SHOULD be discarded ๐Ÿ—‘๏ธ


IV. DECLARATIVE SPECIFICATIONS โœจ

Message Format

All Host-to-Host messages (that is, messages of type zero) SHALL have a header 72 bits long, made up of the following fields (see Figure 1): ๐Ÿ“ฆ

Okay bestie, the header is where the magic starts, so let's break it down ๐ŸŽ€

  • Bits 1-32: Leader ๐Ÿงš The contents of this field must be constructed according to the specifications contained in BBN Report Number 1822.
  • Bits 33-40: Field M1 ๐Ÿ’… Must be zero.
  • Bits 41-48: Field S โœจ Connection byte size. This size must be identical to the byte size in the STR used in establishing the connection. If this message is being transmitted over the control link, the connection byte size must be 8.
  • Bits 49-64: Field C ๐Ÿ“ Byte Count. This field specifies the number of bytes in the text portion of the message. A zero value in the C field is explicitly permitted.
  • Bits 65-72: Field M2 ๐ŸŒธ Must be zero.

After the header, the message shall consist of a text field of C bytes, where each byte is S bits in length. After the text there will be M3 followed by padding. M3 is zero or more bits long and must be all zero. This field may be used to fill out a message to a word boundary ๐Ÿฆ‹

   |<---------------------------32 bits--------------------------->|
   |<----8 bits--->|<----8 bits--->|<-----------16 bits----------->|

   +---------------------------------------------------------------+
   |                                                               |
   |                             LEADER                            |
   |                                                               |
   +---------------------------------------------------------------|
   |               |               |                               |
   |    FIELD M1   |    FIELD S    |            FIELD C            |
   |               |               |                               |
   +---------------+---------------+-------------------------------+
   |               |               ^                               |
   |    FIELD M2   |               |                               |
   |               |               |                               |
   +---------------+               |                               |
   |                               |                               |
   |                               |                               |
   |                               |                               |
   |                               |                               |
   |                             TEXT                              |
   |                               |                               |
   |                               |                               |
   |                               |                               |
   |                               |                               |
   |                               |          +--------------------+
   |                               |          |                    |
   |                               |          |      FIELD M3      |
   |                               V          |                    |
   +-----------------------------------+------+--------------------+
   |                                   |
   |      10-----------------0         |<-------PADDING
   |                                   |
   +-----------------------------------+

                               Figure 1
                               ========

The message header has to do a lot ๐Ÿ˜ญ Most importantly, it must let the NCP at the receiving Host correctly identify the connection the message came in on. Given a set of messages from Host A to Host B, the only field in the header under the control of the NCP at Host B is the link number (assigned via the RTS control command). So each NCP must make sure that, at any given point in time, every connection it receives on gets its own unique link. Recall that the link is specified by the sender's address and the link number, so a unique link number must be assigned to each connection to a given Host ๐Ÿ’œ

Links are assigned as follows ๐ŸŒˆ

      Link number    Assignment
      ===========    ==========

      0              Control link

      2-71           Available for connections

      1, 72-190      Reserved - not for current use

      191            To be used only for measurement work under the
                     direction of the Network Measurement Center at UCLA

      192-255        Available for private experimental use.

Control Messages

Messages sent over the control link have the same format as other Host-to-Host messages. The connection byte size (Field S in the message header) must be 8. Control messages may not contain more than 120 bytes of text, so the value of the byte count (Field C in the message header) must be less than or equal to 120 ๐Ÿซถ

Control messages must contain an integral number of control commands. A single control command may not be split into parts that are transmitted in different control messages. No cutting commands in half, babe ๐Ÿ’…

Control Commands

Each control command begins with an 8-bit opcode. These opcodes have values of 0, 1, ... to permit table lookup upon receipt. Private experimental protocols should be tested using opcodes of 255, 254, ... Most of the control commands are more fully explained in Section III ๐Ÿงš

NOP - No operation

           8
        +-----+
        | NOP |
        +-----+

The NOP command may be sent at any time and should be discarded by the receiver. It may be useful for formatting control messages ๐ŸŒธ

RST - Reset

           8
        +-----+
        | RST |
        +-----+

The RST command is used by one Host to tell another that all information about previously existing connections, including partially terminated connections between the two Hosts, should be purged from the NCP tables of the Host receiving the RST. Except for responding to RSTs, the Host that sent the RST is not obliged to communicate further with the other Host until an RRP is received in response. Dramatic, but it's giving clean slate ๐Ÿงน

RRP - Reset reply

           8
        +-----+
        | RRP |
        +-----+

The RRP command must be sent in reply to an RST command ๐ŸŽ€

RTS - Request connection, receiver to sender

           8          32               32           8
        +----------------------------------------------+
        | RTS | receive socket |  send socket   | link |
        +----------------------------------------------+

The RTS command is used to establish a connection and is sent from the Host containing the receive socket to the Host containing the send socket. The link number for message transmission over the connection is assigned with this command. The "link" field must be between 2 and 71, inclusive โœจ

STR - Request connection, sender to receiver

           8          32               32           8
        +----------------------------------------------+
        | STR |   send socket  | receive socket | size |
        +----------------------------------------------+

The STR command is used to establish a connection and is sent from the Host containing the send socket to the Host containing the receive socket. The connection byte size is assigned with this command. The size must be between 1 and 255, inclusive ๐Ÿฆ‹

CLS - Close

           8        32            32
        +-----+-------------+-------------+
        | CLS |  my socket  | your socket |
        +-----+-------------+-------------+

The CLS command is used to terminate a connection. A connection doesn't need to be completely established before a CLS is sent ๐Ÿ“

ALL - Allocate

           8      8       16           32
        +------------------------------------+
        | ALL | link | msg space | bit space |
        +------------------------------------+

The ALL command is sent from a receiving Host to a sending Host to increase the sending Host's space counters. This command may be sent only while the connection is established. The receiving Host is prohibited from incrementing the Host's message counter above (2^16 - 1) or bit counter above (2^32 - 1) ๐Ÿ’–

GVB - Give back

           8      8    8    8
        +----------------------+
        | GVB | link | fm | fb |
        +----------------------+
                       ^    ^
                       |    +--- bit fraction
                       +-------- message fraction

The GVB command is sent from a receiving Host to a sending Host to request that the sending Host return all or part of its message space and/or bit space allocations. The "fractions" specify what portion (in 128ths) of each allocation must be returned. This command may be sent only while the connection is established ๐ŸŒˆ

RET - Return

           8      8       16           32
        +------------------------------------+
        | RET | link | msg space | bit space |
        +------------------------------------+

The RET command is sent from the sending Host to the receiving Host to return all or part of its message space and/or bit space allocations in response to a GVB command. This command may be sent only while the connection is established ๐Ÿงš

INR - Interrupt by receiver

           8      8
        +------------+
        | INR | link |
        +------------+

The INR command is sent from the receiving Host to the sending Host when the receiving process wants to interrupt the sending process. This command may be sent only while the connection is established โœ‹

INS - Interrupt by sender

           8      8
        +------------+
        | INS | link |
        +------------+

The INS command is sent from the sending Host to the receiving Host when the sending process wants to interrupt the receiving process. This command may be sent only while the connection is established ๐Ÿ‘‘

ECO - Echo request

           8      8
        +------------+
        | ECO | data |
        +------------+

The ECO command is used only for test purposes. The data field may be any bit configuration convenient to the Host sending the ECO command ๐Ÿ™ˆ

ERP - Echo reply

           8      8
        +------------+
        | ERP | data |
        +------------+

The ERP command must be sent in reply to an ECO command. The data field must be identical to the data field in the incoming ECO command ๐Ÿซถ

ERR - Error detected

           8      8                    80
        +-----+------+---------------------------- ~ -------------+
        | ERR | code |                data                        |
        +-----+------+---------------------------- ~ -------------+

The ERR command may be sent whenever a second level protocol error is detected in input from another Host. If the error condition has a predefined error code, the "code" field specifies the specific error, and the data field gives parameters. For other errors, the code field is zero and the data field is idiosyncratic to the sender. Implementers of Network Control Programs are expected to publish timely information about their ERR commands ๐Ÿ“ฃ

The ERR command is only useful if it isn't just thrown away by the receiver ๐Ÿ˜ญ So sites are urged to record incoming ERRs if possible, and to investigate their cause in conjunction with the sending site.

The following codes are defined. Additional codes may be defined later ๐Ÿ’…

a. Undefined (Error code = 0) ๐Ÿซ  The "data" field is idiosyncratic to the sender. Basically, whatever the sender wants it to be, bestie. ๐Ÿ’…

b. Illegal opcode (Error code = 1) ๐Ÿ™…โ€โ™€๏ธ An illegal opcode was detected in a control message. The "data" field contains the ten bytes of the control message beginning with the byte containing the illegal opcode. If the remainder of the control message contains less than ten bytes, fill will be necessary, and the value of the fill is zeros. So if the message runs short, you pad it out with zeros. Simple, but it matters. ๐Ÿงธ

c. Short parameter space (Error code = 2) ๐Ÿ˜ญ The end of a control message was encountered before all the required parameters of the control command being decoded were found. The "data" field contains the command in error, and the value of any fill necessary is zeros. The message just ran out before it finished saying everything, and that's the vibe we're flagging. ๐Ÿฅ€

d. Bad parameters (Error code = 3) ๐Ÿšฉ Erroneous parameters were found in a control command. For example, two receive or two send sockets in an STR, RTS, or CLS; a link number outside the range 2 to 71 (inclusive); an ALL containing a space allocation too large. The "data" field contains the command in error, and the value of any fill necessary is zeros. Two receive sockets in one command? Not it. ๐Ÿ’€

e. Request on a non-existent socket (Error code = 4) ๐Ÿ‘ป A request other than STR or RTS was made for a socket (or link) for which no RFC has been transmitted in either direction. This code is meant to indicate to the NCP receiving it that functions are being performed out of order. The "data" field contains the command in error, and the value of any fill necessary is zeros. Translation: you're trying to do the next step before the first one even happened. ๐Ÿ™ˆ

f. Socket (link) not connected (Error code = 5) ๐Ÿ”Œ There are two cases:

  1. A control command other than STR or RTS refers to a socket (or link) which is not part of an established connection. This code would be used when one RFC had been transmitted, but the matching RFC had not. It is meant to indicate the failure of the NCP receiving it to wait for a response to an RFC. The "data" field contains the command in error, and the value of any fill necessary is zeros. Somebody sent the first half of the handshake and then ghosted. ๐Ÿ‘€
  2. A message was received over a link which is not currently being used for any connection. The contents of the "data" field are the message header followed by the first eight bits of text (if any) or zeros. Mail for a link nobody's using, so it gets the message header plus a little bit of text, or zeros. ๐Ÿ“ญ

Opcode Assignment โœจ

Opcodes are defined to be eight-bit unsigned binary numbers. The values assigned to opcodes are:

   NOP = 0
   RTS = 1
   STR = 2
   CLS = 3
   ALL = 4
   GVB = 5
   RET = 6
   INR = 7
   INS = 8
   ECO = 9
   ERP = 10
   ERR = 11
   RST = 12
   RRP = 13

Control Command Summary ๐ŸŽ€

Here's the whole lineup of control commands, drawn out so you can see every field and its size. Each diagram shows the command's opcode and the fields that follow it, with the bit width of each field across the top.

           8
        +-----+
        | NOP |
        +-----+

           8          32               32           8
        +----------------------------------------------+
        | RTS | receive socket |  send socket   | link |
        +----------------------------------------------+

           8          32               32           8
        +----------------------------------------------+
        | STR |   send socket  | receive socket | size |
        +----------------------------------------------+

           8        32            32
        +-----+-------------+-------------+
        | CLS |  my socket  | your socket |
        +-----+-------------+-------------+

           8      8       16           32
        +------------------------------------+
        | ALL | link | msg space | bit space |
        +------------------------------------+

           8      8    8    8
        +----------------------+
        | GVB | link | fm | fb |
        +----------------------+

           8      8       16           32
        +------------------------------------+
        | RET | link | msg space | bit space |
        +------------------------------------+

           8      8
        +------------+
        | INR | link |
        +------------+

           8      8
        +------------+
        | INS | link |
        +------------+

           8      8
        +------------+
        | ECO | data |
        +------------+

           8      8
        +------------+
        | ERP | data |
        +------------+

           8      8                    80
        +-----+------+---------------------------- ~ -------------+
        | ERR | code |                data                        |
        +-----+------+---------------------------- ~ -------------+

           8
        +-----+
        | RST |
        +-----+

           8
        +-----+
        | RRP |
        +-----+

[ This is the end of the January 1972 document. ] ๐Ÿ

4. Security Considerations ๐Ÿ”

This document does not discuss any security considerations. Zero security considerations, so no drama here, just a very chill ending. ๐Ÿซถ

Authors' Addresses ๐Ÿ’Œ

Alexander McKenzie
PMB #4334, PO Box 2428
Pensacola, FL 32513
USA
EMail: amckenzie3@yahoo.com

Steve Crocker
5110 Edgemoor Lane
Bethesda, MD 20814
USA
EMail: steve@stevecrocker.com

And that's the whole thing, bestie! The Host/Host protocol doc, start to finish. We're literally the best protocol nerds. ๐ŸŒˆโœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from