RFC 442
Current flow-control scheme for IMPSYS
The Current Flow-Control Scheme for IMPSYS πβ¨
- Network Working Group πΈ
- Request for Comments: 442 π
- NIC: 13774
- Author: V. Cerf π
- Date: 24 January 1973 π
- Category, status, obsoletes, and updates: this RFC doesn't list any of these in its header, so there's nothing to report π
Okay bestie, so this one is all about how the IMP operating system (IMPSYS) handles flow control π¦. BB&N's quarterly report #13 walks through part of the current flow-control scheme in IMPSYS π. Then on March 16, 1972, there was a meeting at BB&N all about this new scheme, for the interested network participants π§.
This note is my own understanding of the flow-control mechanism, so take it as my take π. The essential goal is to:
- eliminate unnecessary retransmissions when the load is heavy π₯
- eliminate the retransmission time-out period when the load is light π
- increase bandwidth π
- prevent re-assembly lock-up π
- control traffic from HOSTS into the net more strictly than the earlier link blocking method π«Ά
- secure the rights of life, liberty, and the pursuit of happiness for ourselves and our posterity,...oops. π
Source IMP-to-Destination IMP Protocol π¦
Okay so there are two different protocols, and which one you get depends on the message length: single packet or multi-packet π. We'll start with the single packet case β¨.
Source Imp Destination Imp
---------- ---------------
case 1) message (1) + implicit req (1)--->
<--- RFNM (arrived ok)
[discard copy of msg]
case 2) message (1) + implicit req (1)---> no room, don't respond
<--- All (1) (room available)
message (1) --->
[discard copy of msg] <--- RFNM (arrived ok)
In case 1, a single packet message gets sent to the destination IMP π¨. That message also works as an implicit request for single packet buffer space ποΈ. If there's room, like in case 1, the destination IMP answers with an RFNM π₯³. The source IMP was holding onto a copy of the message, and once it gets that RFNM, it deletes its copy and moves on π§Ή.
Case 2 is what happens when the source IMP sends a message to a destination IMP that has no room for the one-packet message π¬. The message still counts as a request for single packet buffer space. The destination IMP records it in a first-come-first-served buffer reservation request queue π. When space opens up, the destination IMP sends an ALL (1) back to the requesting source IMP π. Then the source can send the single packet message again, and this time it knows the space is reserved at the destination π«Ά.
For multi-packet messages, things work a bit differently π. When a message comes into an IMP from a HOST, and the "last bit" flag isn't set by the time the number of bits in a maximum length single packet has arrived, the IMP halts the HOST->IMP transmission line π. While the line is paused, it figures out whether space has been reserved at the destination IMP π. If space (8 packets worth) has been reserved, the HOST->IMP line gets re-opened and the message is sent out normally π. If space hasn't been reserved, the HOST->IMP line stays closed while the source IMP asks for multi-packet buffer storage at the destination IMP π. Once 8 buffers are available, the destination IMP responds with an ALL (8) β . The source IMP then transmits the message and waits for a combination RFNM and ALL (8) from the destination IMP π. The destination IMP delays its RFNM, if necessary, until it has another 8 buffers available for the next multi-packet message π§Ί.
Here's how that sequence looks:
Source IMP Destination IMP
---------- ---------------
H-> I line
----------> First packet of multipacket
arrives. Halt H->I line and
send REQ (8) -------------->
start 30 sec. Time-out
If time-out, resend
REQ (8) and restart -------->
time-out.
<--------ALL (8) when available. Start
long term (2 min.) time-out.
On time-out, reset all
outstanding reservations.
Send the message:
| ----------->
Start 30 sec. time-out
for INComplete transmission.
If time-out, send INC?----->
<------On recept of message, send
RFNM + implicit ALL (8). On
receipt of INC? send RFNM +
ALL(8) if MSG(8) received,
or send INC! if MSG(8) not
received. Start 2 min. time-out
on ALL(8).
Queue ALL(8); start 125 ms.
time-out when it reaches
head of queue. If time-out
on ALL(8), send GVB(8)----->
<----- Ack.
else send next message ----->
β° Here's the key point: after the source IMP gets an RFNM and an implicit ALL(8) from the destination IMP, it has 125 msec to start sending at least the first packet of a multi-packet message to the destination IMP. The source IMP can have several allocate responses queued up, and in that case the time-outs happen one after the other, since one has to time out before the next 125 msec time-out can start π.
Also, the source IMP has time-outs that make it send INC? messages to the destination IMP if it hasn't gotten a response to some earlier message π°οΈ. It's giving careful, persistent little reminder energy π.
ACK Mechanism π
okay so IMPs treat their physical channels (phone lines) like they're pairs of simplex communications paths πβ¨. Each IMPSYS has a sender module and a receiver module for each full duplex channel, and each module has an "ODD/EVEN" bit that tracks the state of the last packet on the line. The whole point is that the sender module "blocks" a channel until the matching receiver has sent back a packet saying "yep, got it" from the other end. That's called an acknowledgment π«Ά
In the present system, acknowledgments are separate IMP-IMP packets. In the new system, they're just a single bit in a packet flowing the opposite way on the reverse path of a full duplex channel π
Every packet sent between IMPs has an ACK bit and an OE bit, like this:
P A
O C
E K
+-------+-----+------------------------+-----+----------+
typical packet | | | | | |
| | | | | |
+-------+-----+------------------------+-----+----------+
Some terminology, bestie π§: POE is the packet OE bit, and SOE and ROE are the send module OE bit and the receive module OE bit. For two IMPs, A and B, SOE/A and SOE/B are the two send module OE bits at IMPs A and B respectively.
The rules of operation go like this:
Sender
------
if ACK != SOE then do nothing
--
else SOE <- !SOE (i.e. flip SOE bit) and free channel.
----
Receiver
--------
if POE = ROE then packet is a duplicate so throw it away.
--
else ROE <- !ROE
----
Whenever a packet is sent by the send module, its two bits, POE and ACK, get set up like this:
POE <- SOE
ACK <- ROE
The mechanism is designed to use real traffic to do the acknowledgment work, piggy-backing the ACK bits in the header of real packets π. If there's no real packet waiting to go in the opposite direction, a fake packet gets assembled that just carries the ACK. The receiving side doesn't acknowledge that fake one though π
We have an example of how this works between two IMPs, and it's honestly so satisfying ππ₯:
IMP A IMP B
----- -----
ROE | SOE ROE | SOE
| POE ACK |
| +-----------+ |
IMP A blocks send 1 | 0 (1)| 0 1 |-> 1 | 0 IMP B NOPS,
channel. | +-----------+ | flips ROE
| |
| POE ACK |
| +-----------+ |
IMP A frees send 0 | 1 <-| 0 0 |(2) 0 | 0 IMP B blocks
channel, | +-----------+ | channel for
Flips SOE | | new traffic
| POE ACK |
IMP A blocks send | +-----------+ crashes|
channel | (3)| 1 0 |->or gets|
| +-----------+ lost |
| |
| POE ACK |
IMP A detects packet | +-----------+ |
duplicate (POE=ROE) 0 | 1 <-| 0 0 |(2) 0 | 0 IMP B
so does not change | +-----------+ | retransmits no
SOE bit. | | ACK received
| POE ACK |
IMP A retransmits | +-----------+ | IMP B flips
packet 3 | (3)| 1 0 |-> 1 | 1 SOE, unblocks
| +-----------+ | channel, and
| | flips ROE.
| POE ACK |
IMP A flips ROE, | +-----------+ |
flips SOE 1 | 0 <-| 1 1 |(4) |
| +-----------+ |
| |
In fact, each send/receive module has 8 OE bits, so up to 8 packets can be outstanding in either direction π¦
How things really work β¨
Actually, a single send module is in charge of trying to transmit packets out on the 8 pseudo-channels π. Each channel has a two-bit state (on top of its OE bit). Each channel is either FREE or IN USE, and if it's IN USE, it may be sending an OLD or NEW packet π
start state F = free
| I = in use
V X = don_t care
+-----+ +------+ N = new packet
| FX | --------------> | I, N | O = old packet
+-----+ +------+
^ |
| |
| |
| |
ACK | |
received | |
| V
| +------+
+-------------------| I, O |---+
+------+ |
^ | re-transmissions
+------+
Between IMPs, packets keep getting sent over and over until they're acknowledged. BUT the choice of what to send is ordered by priority, like this π:
- Priority Packets (as marked by HOST)
- Non-Priority Packet
- Unacknowledged packets (on I,O state channels)
- Others
Someone pointed out that a heavy load of type (1) and (2) traffic might stop retransmissions from happening at all π. W. Crowther replied that the bug would be fixed by a 125 ms time-out that forces retransmission of old packets in class (3). Iconic answer π«Ά
Note that each packet must carry a "pseudo-channel" number to identify the POE-to-channel association, plus 8 ACK bits (which are positionally associated with the pseudo-channels). So a single packet can ACK up to 8 packets at once πβ¨
[This RFC was put into machine readable form for entry]
[into the online RFC archives by Helene Morin, Via Genie, 12/99]
π¦ where this page comes from
- ietf: rfc442 1973-01
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms