RFC 426

Reconnection Protocol

πŸ“… published January 1973, from ietf

RFC 426: Reconnection Protocol πŸ’–

Okay bestie, this one is a classic πŸ¦‹. It's by Bob Thomas at BBN-TENEX, dated 23 January 1973, and it's NIC 13011. The categories are Protocols and TELNET, and the references are 36,318,333,435 πŸ“š. The header doesn't say it obsoletes or updates anything, so it's a fresh start 🌸.

There are times when you'd want to move one or both ends of a connection from one host to another, and this note is all about that 🧚. It shows a bunch of situations where reconnecting is super useful, gives a mechanism for it, sketches how that mechanism could get added to the Host-Host or TELNET protocol, and suggests where it should live in the protocol hierarchy. It's giving main character energy πŸ’…βœ¨

1. Some Examples: ✨

A. Picture an executive program that TIP users can use to check network status, send messages, link up with other users, and more πŸ“¬. The TIP doesn't have much in the way of resources, so the executive would probably run on one or more bigger hosts that are willing to share some of their resources with the TIP. See Figure 1 πŸŽ€.

The TIP user types something like "@ EXEC" πŸ’». The TIP then ICPs to Host1's executive port. After the user gets the latest network news and maybe sends a few messages, they're ready to log into Host2 (which is generally not the same as Host1) and get some work done πŸ™Œ. At that point, they want to tell the executive that they're ready to use Host2 and have the executive hand them off. So the executive first talks to Host2 and tells it to expect a call from the TIP, and then tells the TIP to reconnect to Host2 πŸ”. When the user logs off Host2, they can get passed back to the executive at Host1, ready to do more stuff somewhere else 🌈. The whole reconnection happens invisibly to the TIP user, so it's totally seamless 🫢

                            Reconnection
          ______               |              ______
         |      |              |             |      |
         | EXEC |<-------------+------------>| USER |
         |______|              |  /          |______|
           Host1               V /              TIP
                 ______         /
                |      |<------/
                |______|
                 Host2
                               Figure 1

B. Now imagine you could use the same name and password (and maybe account) to log into any server on the network πŸ”. For security and economy reasons, though, you wouldn't want every name and password stored at every site πŸ™ˆ. So if a user wants to use a Host that doesn't have their name or password locally, they connect to it and try to log in like normal (see Figure 2). The Host notices it doesn't know the user, so it hands them off to a network authentication service that can figure out whether they're really who they say they are πŸ•΅οΈβ€β™€οΈ. If they pass the test, they get handed back to the Host, which can then give them service πŸ’–. The vibe is that bouncing the user back and forth between the Host and the Authenticator should be invisible to the user ✨

   (a)   ______      for authentication     ______
        |      |            |              |      |
        |      |<-----------+------------->| User |
        |______|            | /            |______|
          Host              |/
                            X
                           /|
             _______      / |
            |       |    /  v
            |       |<---
            |_______|
          Authenticator

   (b)
         ______                             ______
        |      |                           |      |
        |      |<--\             ^     /-->| User |
        |______|    \            |    /    |______|
          Host       \           |   /
                     ------------+--/
                                 | /
                                 |/
                                 |
                                /|
                               / |
                              /  | authentication
             _______         /   | complete
            |       |       /
            |       |<------
            |_______|
          Authenticator

                           Figure 2

And if the user doesn't trust the Host and is worried it might read their password instead of passing them to the authenticator? No stress 😀. They can just connect straight to the authentication service. After they authenticate, the Authenticator can pass them off to the Host 🫑

C. The McROSS air traffic simulation system (see 1972 SJCC paper) already supports reconnection, and it's honestly iconic πŸ‘‘. It lets an ongoing simulation reconfigure itself by letting parts move from computer to computer πŸ›«. For example, in a simulation of air traffic in the Northeast, the program fragment that simulates the New York Enroute airspace can move from Host2 to Host5 (see Figure 3) ✈️. As part of that reconfiguration, the New York Terminal area simulator and the Boston Enroute area simulator break their connections with the New York Enroute simulator at Host2 and reconnect to it at Host5 πŸ¦‹

   NY Terminal     NY Enroute    Boston Enroute  Boston Terminal
     _____            _____            _____         _____
    |     |      /   |     |   \      |     |       |     |
    |Host1|<----/--->|Host2|<---\---->|Host3|<----->|Host4|
    |_____|  \ /     |_____|     \ /  |_____|       |_____|
              X        move       X
             / \        |        / \
             |  \       V       /  |
             V   \    _____    /   V
      reconnect   \  |     |  /   reconnect
                   ->|Host5|<-
                     |_____|
                    NY Enroute

                             Figure 3

2. A Reconnection Mechanism ✨

okay bestie, so the reconnection mechanism can live in either the existing Host-Host protocol or in TELNET πŸ’– we'll explain the mechanism first and then talk through how it fits into each protocol πŸŽ€

The mechanism has four commands:

Reconnect Request: RRQ <path>
Reconnect OK:      ROK <path>
Reconnect No:      RNO <path>
Reconnect Do:      RDO <path> <new destination>

where <path> is the communication path that's getting redirected to <new destination> πŸ¦‹

Let's say H1 wants to move its end of the communication path A-C off of itself and onto port D at H3 (see figure 4) 🌸

     (a) situation                 (b) desired situation

     H2          H3                  H2           H3
    ___         ___                 ___          ___
   |   |       |   |               |   |        |   |
   |  C|<-+    |D  |               |  C|<------>|D  |
   |___|  |    |___|               |___|        |___|
          |
          |
          |   ___                             ___
          |  |   |                           |   |
          +->|A  |                           |A  |
             |___|                           |___|
               H1                              H1

                          Figure 4

The reconnection happens in steps, and it's giving organized πŸ’…

  • a. H1 sets things up by sending RRQ to H2:
H1->H2:   RRQ (path A-C)
  • b. H2 says yes to reconnecting and acknowledges with ROK:
H2->H1:   ROK (path C-A)
  • c. H1 sees that H2 agreed to reconnect and tells H2 to go ahead:
H1->H2:   RDO (path A-C) (Host H3, Port D)
  • d. H1 breaks paths A-C. H2 breaks path C-A and starts path C-D. πŸ”₯

H1 has to have already lined up H3's cooperation for this to work, obviously πŸ™„ One way H1 could do that is by setting up the path B-D and then running the reconnection exchange with H3 at the same time as the one with H2 (see Figure 5) πŸ‘‘

H1->H3:  RRQ (path B-D)
H3->H1:  ROK (path D-B)
H1->H3:  RDO (path B-D) (Host H2, Port C)

      H2                                   H3
    ______                               ______
   |      |                             |      |
   |   C  |                             |  D   |
    ---\--                               -/----
        \       /-->          <--\       /
          \- -/--- --- --- --- --- \---/
           \ /                      \ /
            X                        X
           / \                      / \
          /   \                    /   \
reconnection   \                  /   reconnection
                \    ________    /
                 ---|A      B|---
                    |        |
                    |________|
                        H1

                      Figure 5

Either party can use the RNO command to refuse or abort the reconnection πŸ™…β€β™€οΈ H2 could answer H1's RRQ with RNO, and H1 can abort by answering ROK with RNO instead of RDO πŸ’€

Making sure messages in transit don't get lost during the reconnection is pretty easy 🧚 Once H1 receives the ROK message, that counts as saying no more messages are coming from H2. Same deal the other way: when H2 receives RDO from H1, that counts as saying no more messages are coming from H1 🫢

Now for the last piece of the spec, the case where two "adjacent" entities both try to start reconnections at the same time 😭

   (a) situation               (b) desired situation

     H1            H4                H1            H4
    ____          ____              ____          ____
   |    |        |    |            |    |        |    |
   |   C|        |E   |            |   C|--------|E   |
   |____|        |____|            |____|        |____|

     H2            H3                H2            H3
    ____          ____              ____          ____
   |    |        |    |            |    |        |    |
   |   B|--------|D   |            |   B|        |D   |
   |____|        |____|            |____|        |____|

H2 and H3 "simultaneously" try to set up a reconnection:

H2->H3:  RRQ (path B-D)
H3->H2:  RRQ (path D-B)

So H2 gets an RRQ from H3 instead of the ROK or RNO it was waiting for in response to its own RRQ to H3 🀯 This "race" can be settled by running the reconnections one after the other instead of at the same time: one entity (say H2) does its reconnect first, and then the other (H3) does theirs. There are a few ways to decide who goes first. The simplest is to base it on sockets and site addresses: whichever entity has the largest 40 bit number, made by putting the 32 bit socket number next to the 8 bit site address, goes first. With that mechanism, the rule is:

If H2 receives an RRQ from H3 in response to an RRQ of its own:
   (let NH2,NH3 = the 40 bit numbers corresponding to H2 and H[2])
  • a. if NH2>NH3 then both H2 and H3 interpret H3's RRQ as an ROK in response to H2's RRQ.
  • b. if NH2<NH3 then both interpret H3's RRQ as an RNO in response to H2's RRQ. This is the only case where it actually makes sense to "ignore" the refusal and try again, of course waiting until the first reconnect finishes before doing so. 🌈

Once the order is decided, the reconnection goes ahead as if there was never a conflict πŸŽ€

Here's the diagram for the legal protocol command and response exchange sequences for a reconnection started by P πŸ’œ

                     ___                 ___
                    | P |---------------| Q |
                    |___|               |___|
 ____________________
| P --> Q ||  R R Q  |
|_________||_________|
               |
     +---------+
     |
 ____V_______________________________________
|         ||         |             |         |
| Q --> P ||  R O K  |  R N O  ----|  R R Q  |
|         ||         |         | E |         |
|_________||_________|_________|___|_________|
                |                       |
   +------------+                       v
   |                      Yes   +----------+   No
   |   +------------------------| NP > NQ? |------+
   |   |                        +----------+      |
 __v___v_______________________________           |
|         ||             |             |          |
| P --> Q ||  R D O  ----|  R N O  ----|          |
|         ||         | E |         | E |          |
|_________||_________|___|_________|___|          |
                                                  |
     +--------------------------------------------+
     |
 ____v_________________________________
|         ||             |             |
| Q --> P ||  R D O  ----|  R N O  ----|
|         ||         | E |         | E |
|_________||_________|___|_________|___|

NP and NQ are the 40 bit numbers for P and Q, and E marks the end of the sequence 🧚


3. Adding the Reconnection Mechanism to Host-Host Protocol πŸ’…

The four reconnect commands could go straight into the Host-Host protocol like this πŸ¦‹

RRQ <my socket> <your socket>
ROK <my socket> <your socket>
RNO <my socket> <your socket>
RDO <my socket> <your socket> <new host> <new socket>

The ROK and RDO commands for a send connection should not be sent until there are no messages in transit over the connection ✨ The RDO command is to be interpreted as a CLS πŸ™ˆ

Here's how the reconnection goes πŸ‘‘

  H2           H3                    H2           H3
 ___          ___                   ___          ___
|   |        |   |                 |  C|--------|D  |
|_C_|        |_D_|                 |___|        |___|
  |            |
  |            |        ===>
  |    ____    |                          ____
   ---|A  B|---                          |    |
      |____|                             |____|
        H1                                 H1

and it could be carried out like this:

H1->H2:  RRQ A C
H1->H3:  RRQ B D
H2->H1:  ROK C A
H3->H1:  ROK D B
H1->H2:  RDO A C H3 D
H1->H3:  RDO B D H2 C
H2->H1:  CLS C A
H3->H1:  CLS D B
H2->H3:  STR C D size
H3->H2:  RTS D C link

Heads up: the STR from H2 can reach H3 before the RDO from H1 does πŸ‘€ H3 has to be ready to queue that RFC until it gets an RDO or RNO from H1. Put another way, when a local socket sends an ROK, the socket moves from an "open" state to a "reconnect pending" state, and it signals that it's willing to queue later RFC's until a "matching" RDO or RNO shows up 🌸

4. Reconnection in TELNET Protocol ✨

okay so even if Host-Host protocol never directly supports reconnection, we could still put the mechanism into TELNET by adding five new commands πŸŽ€

RRQ
ROK
RNO
RDO <host> <socket>
RWT <host> <socket>

RRQ, ROK, RNO, RDO, and RWT are characters we'd pick from the range 128 to 255 πŸ’– The first three don't need any parameters because they just refer to whichever connection they arrive on. For RDO and RWT, <host> is an 8 bit (= 1 TELNET character) host address, and <socket> is a 32 bit (= 4 TELNET characters) number that names a TELNET receive socket on that host ✨

A pending reconnection can be activated with either RDO or RWT πŸ¦‹ Either one makes the sender first break its TELNET connection, then reopen the TELNET connection to the host and sockets that were specified. With RDO, the connection gets reopened by sending two RFC's. With RWT, it gets reopened by waiting for two RFC's 🫢

The RWT command exists to dodge races like the STR and CLS (RDO) one we talked about above 😭 In Host-Host protocol, the race gets avoided by putting a connection into "reconnect pending" state when ROK is transmitted. In TELNET, the initiator can avoid it by using RWT and RDO judiciously 🧚 For example, this reconnection:

  H2                           H3          H2           H3
+---+                        +---+       +---+   M    +---+
|   |----+             +---->|   |       |   |------->|   |
| Y | N  |             |  Q  | Z |   ==> | Y |   N    | Z |
|   |<-+ |      H1     | +---|   |       |   |<-------|   |
+---+  | | M  +---+  P | |   +---+       +---+        +---+
       | +--->|   |----+ |
       |      | X |      |                        H1
       +------|   |<-----+                      +---+
              +---+                             |   |
                H1                              | X |
                                                |   |
                                                +---+

could be done like this πŸ’…

        X->Y:  RRQ
        X->Z:  RRQ
        Y->X:  ROK
        Z->X:  ROK
        X->Y:  RWT  H3 P
        X closes connections to Y
        Y closes connections to X
        Y waits for STR and RTS from H3
        X->Z: RDO H2 N
        X closes connections to Z
        Z closes connections to X
        Z sends STR and RTS to H2 which Y answers with
          matching RTS and STR to complete reconnection

The reconnection mechanism for TELNET can fit neatly into the command format suggested by Cosell and Walden in RFC #435 🌈 Adding three new commands to TELNET does the trick:

     Prepare for Reconnect:                 RCP
     Begin Reconnect by sending RFC's:      RCS
     Begin Reconnect by waiting for RFC's:  RCW

Using these three commands plus the DO, DON'T, WILL, WON'T commands of RFC #435, the commands we proposed earlier turn into this πŸ‘‘

     RRQ => DO RCP
     ROK => WILL RCP
     RNO => WON'T RCP  ;for responses to DO RCP
            DON'T RCP  ;for responses to WILL RCP
                       ;i.e. used to cancel an RCP.
     RDO <host> <socket> => DO RCS <host> <socket>
     RWT <host> <socket> => DO RCW <host> <socket>

As RFC #435 points out, the iconic thing about this structure is that a host choosing not to implement reconnection doesn't even have to know what RCP means πŸ™ˆ All it needs to do in response to DO RCP is transmit WON'T RCP. no thinking required, periodt πŸ’€


5. Recommendation πŸ’œ

okay real talk, I think reconnection is a basic notion, and its proper home in the protocol hierarchy is the Host-Host level, where every higher-level protocol could use it πŸ”₯ The problem is that putting it there would require NCP rewrites. Reluctance to change NCP would probably be enough to kill interest in the proposal 😭

So, for pragmatic reasons, I recommend including the reconnection mechanism in TELNET as an "option" in the spirit of RFC #435 🫢 This can be done by adding the RCP, RCS, RCW commands to the TELNET protocol, as described in Section 4. Modifying user- and server-TELNET programs to handle these new commands should be straightforward ✨ If a reconnection option becomes part of the TELNET protocol, the TENEX hosts will support it 🌸 Also, the TIP guys (Walden and Cosell) have said they like the reconnection mechanism and have agreed, in principle, to implement it for TIPs if it's accepted as part of TELNET protocol πŸŽ€

Putting reconnection at the TELNET level instead of the Host-Host level is admittedly a compromise πŸ™ˆ Still, it makes the sort of activity described in Examples A and B of Section 1 possible, so it's worth it πŸ’–


6. Additional Remarks 🌸

A. Reconnection isn't a new notion, bestie πŸ¦‹ An early proposal for Host-Host protocol (RFC #36) already included facilities to support reconnection. The reconnection mechanism in RFC #36 assumes a setup where entities are "daisy-chained" together by connections:

       __      __      __      __      __
   ___|  |____|  |____|  |____|  |____|  |___
      |__|    |__|    |__|    |__|    |__|

and it spells out how one or more entities can break out of the chain. As suggested above (Figure 5), the mechanism proposed in this note supports that same kind of reconnection ✨

B. In practice, simultaneous reconnect initiation by adjacent entities would be relatively rare πŸ“

C. The way RFC #36 handles simultaneous reconnection attempts by entities adjacent in the chain is to do the reconnect as a single, carefully coordinated, global reconnect. Honestly, I think the sequence of locally coordinated reconnects proposed above is better πŸ’… When N adjacent entities simultaneously attempt reconnection, the single, globally coordinated reconnect outlined in RFC #36 needs ~N^2 control messages, whereas the sequential locally coordinated reconnect needs ~N πŸ“ˆ

D. A word about security is in order, and it's a big one 😭 It should be clear that the decision to accept or reject a particular reconnection request belongs to the entity using the connection (the person at a terminal, or a process). In many cases that entity may choose to hand off that responsibility to its NCP or TELNET (e.g., Example A, Section 1). However, the interface a Host provides to the reconnection mechanism should include ways for local entities to control how they respond to remotely initiated reconnection requests πŸ›‘οΈ For example, a user-TELNET might support several modes of operation for remotely initiated reconnections:

  1. transparent: all requested reconnections are to be performed in a way that is invisible to the user;
  2. visible: all requested reconnections are to be performed, and the user is to be informed whenever a reconnection occurs;
  3. confirmation: the user is to be informed of each reconnection request, which he may accept or reject;
  4. rejection: all requested reconnects are to be rejected.

E. Reconnection can be achieved almost trivially within the Message Switched Protocol (MSP) proposed by Bressler, Murphy and Walden in RFC #333 (within MSP, "reconnection" is probably not the correct term) 🧚 For example, using the following conventions with that MSP (expressed in the terminology of RFC #333) supports reconnection:

  1. unless a reconnection is in progress, rendezvous is to occur at the sending site;
  2. the receiving end of a communication path can be moved by passing the names of the rendezvous site and the ports to the new receiver;
  3. receipt of an OUT message for which the source site differs from the rendezvous site signals that the sending end is being moved; the source site should be used as the rendezvous site for subsequent IN messages;
  4. the sending end of a communication path can be moved by passing the names of the ports to the new sender; to complete the move, the new sender uses the previous sender's site as rendezvous site for its first OUT message and its own site as rendezvous for subsequent OUT messages.

As simple and appealing as this procedure is, I doubt it would be used in practice if MSP were implemented as a replacement for, or alternative to, the existing Host-Host protocol 😬 The reason is that passing ports from Host to Host (needlessly) complicates port name allocation, because it requires cooperation among Hosts to manage the allocation. For example, before a Host can safely allocate a port name for use by a local process, it must not only make sure the port isn't in use locally, but also that no process out in the network is using it. The inter-Host cooperation needed to support passing ports among Hosts probably can't be reliably achieved in practice πŸ’€ Therefore, port passage of the sort described in RFC #333 should not be supported at the Host-Host protocol level. For this reason, I feel that within an MSP, "reconnection" would be best handled by a mechanism such as the one proposed in this note πŸ’–

[ This RFC was put into machine readable form for entry ] [ into the online RFC archives by Anthony Anderberg 4/99 ]

πŸ“¦ where this page comes from