III - Network Control Program
Each HOST implements a module called the Network Control Program (NCP) which controls all network communications involving that HOST. The network of NCPs forms a distributed communication system that implements communication paths between individual processes. The NCP protocol issues involve: (i) the definition of these communication paths, and (ii) a system for coordinating the distributed NCP system in maintaining these communication paths. These are discussed below.
Sockets
Communication between two processes is made through a simplex connection between two sockets: a send socket attached to one process and a receive socket attached to another process. Sockets have the following characteristics:
Socket Identifier - A socket identifier is used throughout the network to uniquely identify a socket. It consists of 48 bits, having the following components:
-
User Number (24 bits) - A socket attached to a process is identified as belonging to that process by a user number consisting of 8 bits of "home" HOST code plus 16 bits of user code assigned by the home HOST. This user number is the same for all sockets attached to any of his processes in any HOST.
-
Instance Tag (8 bits) - More than one process belonging to a user may simultaneously exist within a single HOST. The instance tag identifies the particular process to which a socket belongs. A user's first process at a HOST to use the network receives instance tag = 0 by convention.
-
HOST Number (8 bits) - This is the code of the HOST on which the attached process exists.
-
Socket Code (8 bits) - This code provides for 128 send and 128 receive sockets in each process. The low order bit determines whether this is a "send" (= 1) or "receive" (= 0) socket.
States of Sockets - Each socket has an associated state. The NCP may implement more transitory states of a socket, but the three following are of conceptual importance.
-
Inactive - there is no currently existing process which has told the NCP that it wishes to listen to this socket. No other process can successfully communicate with an inactive socket.
-
Open - Some process has agreed to listen to events concerning this socket but it is not yet connected.
-
Connected - This socket is currently connected to another socket.
Socket Event Queue - A queue of events to be disclosed to the owning process is maintained for each open or connected socket. It consists of a chronologically ordered list of certain events generated by the action of one or more foreign processes trying to connect or disconnect this socket. An entry in the event queue consists of the event type plus the identifier of the foreign socket concerned. The following event types are defined:
-
"request" - a foreign socket requests connection. (not queued if local socket is already connected)
-
"accept" - a foreign socket accepts requested connection.
-
"reject" - a foreign socket rejects requested connection.
-
"close" - a foreign socket disconnects an existing connection.
A "request" event is removed from the queue when it is accepted or rejected. The other events are removed from the queue as they are disclosed to the owning process.
Some events are intended to be transparent to the process owning the socket, and they do not generate entries in the event queue.
Although an event queue is conceptually unlimited, it seems necessary to place some practical limit on its length. When an event queue for a socket is full, any incoming event that would add to the queue should be discarded and the sending NCP notified (via ERR command described below).
NCP Control Communications
The NCP network coordinates its activities through control commands passed between its individual components. These commands generally concern the creation and manipulation of socket connections controlled by the NCP receiving the command. A control command is directed to a particular NCP by being sent to its HOST as a message over link number 1 (designated as the control link), which is reserved for that purpose. The IMP network does not distinguish between these messages and regular data messages implementing communication through a socket connection.
The following NCP control commands are defined:
-
Request for Connection
RFC <local socket> <foreign socket> [<link no.>]An NCP directs this command to a foreign NCP to attempt to initiate a connection between a local socket and a foreign socket. If the foreign socket is open, the foreign NCP places a "request" event into the socket's event queue for disclosure to the process that owns it. If the foreign process accepts, the foreign NCP returns a positive acknowledgement in the form of another RFC. It rejects connection by issuing the CLS command (see below). An RFC is automatically rejected without consulting the owning process if the foreign socket is not open (inactive or connected). Multiple RFCs to the same socket are placed into its event queue in order of receipt. Any queued RFCs are automatically rejected by the NCP once the owning process decides to accept a connection. The NCP which has control of the "receive" socket of the potentially connected pair designates a link number over which messages are to flow.
-
Close a Connection
CLS <local socket> <foreign socket>An NCP issues this network command to disconnect an existing connection or to negatively acknowledge an RFC. There is a potential race problem if an NCP closes a local send socket in that the CLS command may reach the foreign NCP prior to the last message over that socket connection. This race is prevented by adhering to two standards: (i) A CLS command for a local send socket is not 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 received.
-
Block Output over a Connection
BLK <foreign send socket>A process may read data through a receive socket slower than messages are coming in and thus the NCP's buffers may tend 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.
-
Resume Output over a Blocked Connection
RSM <foreign send socket>An NCP issues this command to unblock a previously blocked connection.
-
Interrupt the Process Attached to a Connection
INT <foreign socket>Receipt of this message causes the foreign NCP to immediately interrupt the foreign process attached to <foreign socket> if it is connected to a local socket. Data already in transit within the NCP network over the interrupted connection will be transmitted to the destination socket. The meaning of "interrupt" is that the process will immediately break off its current execution and execute some standard procedure. That procedure is not defined at this protocol level.
-
Report an Erroneous Command to a Foreign NCP
ERR <code> <command length> <command in error>This command is used to report spurious network commands or messages, or overload conditions that prevent processing of the command. <code> specifies the error type. If <code> specifies an erroneous network command, <command in error> is that command (not including IMP header) and <command length> is an integer specifying its length in bits. If <code> specifies an erroneous message, <command in error> contains only the link number over which the erroneous message was transmitted. (This is slightly modified from the specification in NWG/RFC 40.)
-
Network Test Command
ECO <48 bit code> <echo switch>An NCP may test the quality of communications between it and a foreign NCP by directing to it an ECO command with an arbitrary <48 bit code> (of the same length as a socket identifier) and <echo switch> 'on'. An NCP receiving such a ECO command should immediately send an acknowledging ECO with the same <48 bit code> and <echo switch> 'off' to the originating NCP. An NCP does not acknowledge an ECO with <echo switch> 'off'. We feel that this command will be of considerable aid in the initial shakedown of the entire network.
-
No Operation Command
NOPAn NCP discards this command upon receipt.
User Interface to the NCP
The NCP at each HOST has an interface through which a local process can exercise the network, subject to the control of the NCP. 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. 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.
We outline here an interface based on the Carr, Crocker, and Cerf proposal that is sufficient to fully utilize the network. While this particular set of calls is intended mainly for illustrative purposes, it indicates the types of functions necessary.
The following calls to the NCP are available:
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
INTERRUPT <my socket code>
The user directs the NCP to send out an INT command to the foreign socket connected to <my socket>.
-
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
Assume that process 'a' on HOST A wishes to establish connection with process 'b' on HOST B. Before communication can take place, two conditions must be fulfilled:
-
process 'a' must be able to specify to its NCP a socket in 'b's socket space to which it wants to connect.
-
process 'b' must already be LISTENing to this socket.
1. Establishing the Connection
-
process 'b' LISTENs to socket 'Bb9'.
-
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'.
-
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).
-
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' |
|
Figure 2: Establishing and Communicating over a Socket Connection
2. Sending Messages over a Connection
-
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.
-
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.
-
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.
-
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
-
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'.
-
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'.
-
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
-
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.
-
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.
-
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.