RFC 357

Echoing strategy for satellite links

πŸ“… published June 1972, from ietf

Here's the title block, all the important facts up top:

  • Written by: John Davidson (University of Hawaii), Will Crowther (BBN), John McConnell (ILLIAC), and Jon Postel (UCLA) 🫢
  • NIC number: 10599
  • Categories: Remote Controlled Echoing, Satellite, TELNET πŸ›°οΈ
  • Date: June 26, 1972 πŸ“…
  • References: RFC's 346, 355, 358, 318
  • Obsoletes or updates: nothing listed in the header πŸ™…β€β™€οΈ

I. Introduction ✨

okay so, as mentioned in RFC 346 ("Satellite Considerations" by Jon Postel), interactive systems that do echoing for full-duplex terminals over the ARPANET get way more awkward to use as transmission delays go up 😭. The reason is literally math: a character's round trip time gets added on top of the server's inherent echo delay, so the terminal echo looks super sluggish. 🐒

For a terminal that's separated from its server by one satellite link, the delay is so big that even if the server echoed instantly, the gap between keying a character and seeing it printed is going to be nearly half a second. ⏳ If the character also gets routed through a portion of the surface net, the delay gets even bigger, obviously. People estimate echo delays of at least one second will not be uncommon. πŸ’€

This document describes a strategy that gets rid of the delay from simple echoing and lets the transmission delay hide inside the cost of computation only. 🧚 It's proposed as an optional addition to existing User TELNETs, and using it requires the explicit support of a cooperating server process. Main character energy for the server, honestly πŸ‘‘.

II. Standard Echo Strategy πŸ’…

Echoing for locally connected full-duplex terminals is normally handled at the server by a resident system task called the (e.g.) Terminal Handler. The Terminal Handler echoes on a one-for-one or simple replacement basis, and it buffers all typed input on behalf of the user process. πŸ“¦

So the user process can run as efficiently as possible, the Terminal Handler SHOULD collect characters until a complete command or parameter (or whatever) has been typed. Then, presumably, the process can do some serious computing πŸ”₯. Since the user process knows the syntax of the string it expects, it can tell the Terminal Handler which characters delimit completed parameters. Those characters are called 'Wakeup Characters', because the user process gets woken up as they're echoed. ⏰

Some commands the user types need an output response from the process. So the typed commands get followed by that response and stay separated from the commands after them, the Terminal Handler MUST suspend echoing of user type-ahead. πŸ™ˆ It can resume echoing (starting with the type-ahead, using the unechoed characters in the buffer) as soon as the process has stated, implicitly or explicitly, that the output response is complete.

Characters that make the Terminal Handler suspend echoing are called 'break characters'. The user process specifies them based on the syntax of the expected input. Normally, break characters are also wakeup characters. Some examples:

  1. A text editor MAY gobble up typed English sentences every time a period or question mark is echoed. Those two characters are wakeup characters only. There's no need to suspend echoing. ✍️
  2. In some systems, an ESC character gets used to invoke command recognition. The user who types
CO [ESC] ABC [ESC] XYZ

SHOULD see this as output:

COPY (FROM FILE) ABC (TO FILE) XYZ

The ESC is both a break and a wakeup. The printout SHOULD be the same no matter how fast the user types. 🀯

The server MUST provide a way for each user process to communicate the following to the Terminal Handler:

  1. the set of wakeup characters,
  2. the set of break characters,
  3. which break characters SHOULD and which SHOULD NOT be echoed (some break characters, like ESC in example 2, SHOULD NOT be echoed),
  4. completion of an output response,
  5. whether or not to echo characters. (Not echoing is useful in "hide your input" applications. πŸ™Š)

As for implementation, items 1 and 2 could be communicated by letting the user process specify a 128-bit table (for an ASCII device) with 1's set for each wakeup character, plus another table with 1's set for each break character. This gets pretty expensive in core memory as the number of terminals grows, though. The system MUST store these bit tables itself, because in most cases the user process won't be in core while the Terminal Handler is echoing. πŸ’Ύ

To cut down on storage, the system can make a limited number of supported break characters known to all its programmers, say 4, for the process, from, for example:

  • a. alphanumeric characters,
  • b. punctuation characters,
  • c. echoable control characters (including the bell and CR, etc.), or
  • d. non-echoable control characters (Control-C, etc.),

and the process picks which break set(s) to use in a system call. πŸ“ž This needs no more than 4 bits of system storage per terminal, plus a single table that identifies the set(s) each of the 128 possible ASCII characters belongs to. Efficiency queen πŸ‘Έ.

For the user process to communicate item 3 to the Terminal Handler (which break characters SHOULD and which SHOULD NOT have echoed), it can specify another 4-bit field with 1's set for the break classes whose members SHOULD be echoed. For the 4 classes above, only 3 bits are needed, because members of class (d) are defined to be non-echoable. πŸ“

To communicate completion of an output response (item 4), the user process could issue an explicit system call. Or the Terminal Handler could assume completion when the user process requests input of the first character following the break. βœ…

"Hide your input" (item 5) gets communicated by a system call that specifies either:

(a) "break on every character and don't echo any break characters", or, for example (b) "don't echo anything and break on punctuation, or any control character" for an alphanumeric password,

depending on the syntax of the expression being hidden. πŸ”

III. Definitions πŸ“–

Several new terms need defining, and some are direct extensions of the terms used in the "standard echo strategy" description. There's no reason to insist that the four buffers presented all be implemented as individual constructs. They're logically separated just for clarity in the discussions that follow. 🧩

Remote Controlled Echoing (RCE)

This is the name for the echo strategy described in this document. Echoing gets controlled by the (remote) server but performed by the User TELNET. πŸŽ€

Input Buffer

This is a logical buffer a User TELNET uses to hold characters in sequence as they're received from the terminal keyboard (after they've been converted to NVT characters). ⌨️

Transmission Buffer

This is a logical buffer a User TELNET uses to hold NVT characters that have been typed but not yet transmitted to the server. πŸ“€

Output Buffer

This is a logical buffer a User TELNET uses to hold the NVT characters received from the server. πŸ“₯

This is a logical buffer residing in the User TELNET, from which characters get sent in sequence to the terminal printer. (The output buffer contains NVT characters, which MAY have to be converted to characters the actual terminal uses.) πŸ–¨οΈ

Break Classes

The 128 possible (7-bit) ASCII characters used by the Network Virtual Terminal can be partitioned into several quasi-equivalence classes (for example alphabetic, numeric, punctuation characters, etc.). These classes can be defined so that each character is a member of at least one class, although it MAY belong to more than one. πŸ—‚οΈ

A server process MAY indicate to a User TELNET that certain of these classes (or all, or none) are to be considered break classes. In other words, a break class is an equivalence class that's of special significance to the server process. In terms of the discussion in section II, the Server recognized 4 equivalence classes, and any combination of them might be designated as a break class by a particular process. 🌈

The RCE implementation will have more than 4 equivalence classes (perhaps as many as 8) to give more flexibility in choosing break character sets. ✨

Break Action

Two break actions are possible:

(1) a break character encountered in the input buffer IS moved to the print buffer at the appropriate time, or (2) a break character encountered in the input buffer IS NOT moved to the print buffer.

The server process will specify which break action SHOULD be followed. (The two actions correspond to echoing or not echoing the break character.) 🎭

IV. Description 🌸

(This description is written in terms of the TIP, which of course embodies a User TELNET.)

Remote Controlled Echoing is an attempt to remove the echo responsibility from the Terminal Handler and push it off into the TIP. Wakeup processing is still handled at the server. The process' interface (system calls, etc.) to the server's Terminal Handler doesn't need to change, but the (abbreviated) Terminal Handler (actually a Server TELNET) MUST find a way to relay the process' echo requirements to the TIP. It does this with TELNET commands and control information. System calls and echo parameters (break classes, etc.) peculiar to a particular serving Host MUST be interpreted by the Server Telnet commands. πŸ§šβ€β™€οΈ

Character Flow

Refer to figure 1. A character received from a full-duplex terminal gets converted to its NVT equivalent and placed in both the transmission AND the input buffers. The TIP's transmission strategy determines when it gets removed from the transmission buffer, and the server's RCE control commands dictate when it gets removed from the input buffer. πŸ”

A character received from the server gets placed in the output buffer. πŸ“¬

Of the three labeled paths DISCARD, ECHO and OUTPUT, exactly one is enabled at all times, and RCE commands dictate which one. So characters may:

  • (DISCARD:) be removed in sequence from the input buffer and discarded,
  • (ECHO:) be removed in sequence from the input buffer and placed in the print buffer, or
  • (OUTPUT:) be removed in sequence from the output buffer and placed in the print buffer.

From the print buffer, they get converted from NVT characters and immediately sent to the terminal's printer. πŸ–¨οΈπŸ’–

The TIP's buffers are like a little conveyor belt for every keypress πŸŽ€

                              +----------------------+
                              | Terminal Keyboard    |
                              +----------------------+
                                           |
                                       Convert to NVT characters
      To       +-------------------+       |
   Server <----|Transmission Buffer|       |
               +-------------------+       |      +-----From Server
                        ^                  |      |
                        |------------------+      |
                        V                         V
                +-----------------+       +-----------------+
                | Input Buffer    |       |  Output Buffer  |
                +-----------------+       +-----------------+
                    |        |                    |
            DISCARD |        +--ECHO---+      +---+ OUTPUT
                    |                  |      |
                    V                  V      V
                   To          +----------------------+
              Oblivion         |     Print Buffer     |
                               +----------------------+
                                          |
                                      Convert from
                                     NVT Characters
                                          |
                                          V
                                 To Terminal Printer

                 Figure 1.  Character Flow within the TIP

Commands: Server to Host πŸ’Œ

Okay so these are the proposed TELNET commands the server process sends to the TIP 🫢 Heads up: commands (2) thru (5) should not be sent if RCE is not being used. πŸ™ˆ

(1) Use Remote Controlled Echoing. The server asks the TIP to employ the echo strategy described in this document. The TIP can respond either YES (I will use it) or NO. (It is suggested that the response YES also be "Use RCE" to eliminate race conditions.) πŸ‘‘

(2) Set Break Action. This is actually 2 commands πŸ’… The server can set the break action to echo or not echo a break character.

(3) Set Break Classes. This command specifies those equivalence classes which are to be considered break classes. It will be a two (8-bit) byte command πŸ¦‹

Note: The envisioned implementation requires the TIP to have a table with one entry per ASCII character. Each entry is formatted with one bit position for each equivalence class, and a bit is set or reset according as the given character is or is not a member of that class. The server sends a "Set Break Classes" command (1st byte) followed by a formatted control word (2nd byte) to the TIP with bit positions set for those equivalence classes which represent break classes for the server process.

When a (virtual) character is taken from the input buffer, the TIP does a table look-up indexed by the character. If a simple ANDing of the table entry with the terminal's control word yields a non-zero result, a break was received. (Receipt of a break character enables the OUTPUT path.) ✨

(4) Move to Break (MTB). This command directs the TIP to move characters in sequence from the input buffer to the print buffer until a break character is encountered. The break character will be moved or discarded depending on the previously-specified break action. (Essentially, MTB enables the ECHO path.) 🌸

(5) Delete to Break (DTB). This command directs the TIP to move characters in sequence from the input buffer and discard them until a break character is encountered. The break character will also be discarded. This provides a convenient mechanism for hiding a user's input. (DTB enables the DISCARD path.) πŸ™ˆπŸ”₯

Commands: User to Server 🧚

The USER may send (via TIP) a request to the server process requesting that it "Use Remote Controlled Echoing," to which the server must respond "YES" or "NO." Main character energy for the user, honestly πŸ’–

General Operation 🌈

Very simply, the Remote Controlled Echoing strategy works as follows. The Server TELNET will tell the TIP to (essentially)

   (1) echo a message,
   (2) print the process' response to that message,
   (3) echo the next message
   (4) print the response to that message
                . . .

etc., to effect an orderly listing of inputs and responses, much as would be imposed when using a half-duplex device. It's giving turn-taking πŸ’…

The actual interaction depends on the control commands. When a terminal-serving process is invoked on behalf of a TIP user, the Server TELNET will send the "Use RCE" command, and the TIP will respond "YES." Then the Server TELNET will send the "Set Break Action" and "Set Break Classes" commands to properly reflect the break strategy requested by the terminal-serving process. Lastly, the Server TELNET will send an MTB command. This enables the ECHO path. ✨

The TIP removes characters from the input buffer and places them in the print buffer. When it encounters a break character, it performs the break action specified, and enables the OUTPUT path.

Characters are then moved in sequence from the output buffer to the print buffer. When an MTB (or DTB) is encountered, it is discarded and the ECHO (DISCARD) path is enabled. Etcetera πŸ’€

The Server TELNET may change the break action or break classes after an interaction, but should normally do so prior to sending the MTB or DTB commands. It should only send an MTB (DTB) after all process output from the previous message has been sent. Timing is everything, bestie ⏰

Why Does This Work? πŸ€”

The RCE strategy described above produces the correct result at the user's terminal because it is, in essence, the same scheme used by the Terminal Handler, which normally provides the echoing at the serving site. Initially, the characters are echoed as they are typed. Then a break character is keyed, and echoing is suspended. If the process produces any output response, it is printed before echoing of subsequent input. It's the same trick the serving site already uses, just remote-controlled πŸŽ€

Echoing of the next command begins, if there is type-ahead, with the characters in the input buffer. Even if the input buffer is emptied, immediate echoing of keyed input from the terminal is provided, since the ECHO path remains enabled up to a break. πŸ¦‹

An Example ✨

(In the following, we assume all break characters are also wakeup characters and (carelessly) treat the two interchangeably.)

Suppose a TIP user attempts to login to a remote server with the properly formatted message

      LOG NAME PASSWORD [CR]

and the Server TELNET has requested the use of RCE. Presuming that the break (and wakeup) character sets are appropriately defined to include space and CR (and that the break action specifies they should be echoed), the primary sequence of RCE commands which will drive the TIP to produce the correct printout at the user's terminal is:

   (1) MTB (to print "LOG "), and since the space is a break
      character,
   (2) MTB (to print "NAME "),
   (3) DTB (to delete "PASSWORD [CR]" (See section VI, number
      11)), and perhaps a message followed by
   (4) MTB (to reenable the echo path).

We investigate in some detail how interaction at the process/Server TELNET interface causes these commands to be sent to the TIP πŸ”

When the EXEC is invoked, it issues a system call to set its break classes. The Server TELNET interprets the system call in terms of the classes supported by RCE, and sends the appropriate two-byte "Set Break Classes" (SBC) command to the TIP. A space is among the characters of the break set. 🌟

The EXEC asks for input, so the Server TELNET sends MTB ((1) above). We presume the EXEC blocks until some input is available. 😴

The EXEC is awakened when the first space arrives. It recognizes the LOG command to be a call upon the LOGIN subsystem, which it (promptly!) invokes. πŸƒβ€β™€οΈ

The LOGIN process issues a system call to set its break classes (this time both space and CR are included, and, as before, the Server TELNET forwards the command as an SBC). Then it asks for input (so the Server TELNET sends MTB ((2) above)), and blocks until the second space arrives. 🧠

When the LOGIN process has verified the existence of a user with name NAME, it issues a system call to suppress printing of the next parameter (the password). In compliance, the Server TELNET sends DTB ((3) above). 🀫

Once the password has been examined and verified, a message like

      [CR][LF] LOGIN COMPLETED [CR][LF]

can be sent, followed by a request for input. The Server TELNET thus forwards an MTB ((4) above), and the sequence is completed. Ta-da πŸŽ‰

Another example πŸ’œ

Suppose, in the above example, the user had typed

      LOG NAME[CR]

When the LOGIN process regained control, it would have noted that the break was a CR instead of a space. It then could have issued

      [LF]password =

which the Server TELNET would follow (when LOGIN requests print suppression) with DTB. When the TIP had finished its output, the DISCARD path would be enabled, and the user's terminal would have printed:

      LOG NAME[CR]
      password =
                 ^

with the cursor positioned just after the =. The TIP will hide the characters of the password. πŸ”’

Another Example πŸ“

Suppose a user were using a text editor, TEXT, to create a source file of English sentences. The TEXT subprocess might allow only non-formatting control characters (e.g., "Control-C") as break characters. The RCE strategy would allow the user to receive immediate echoing for all his input until he typed such a control character. Ngl, that's the most iconic use case of all πŸŒˆπŸ’…

V. Discussion ✨

okay so the Remote Controlled Echoing Strategy (RCE πŸ’…) is built to give a full-duplex terminal echoing that feels like it's plugged straight into its server πŸ”Œ. the long transmission delays only show up as extra processing at a break. honestly only the most interactive systems will ever notice 😭. like, if someone kicks off a long FORTRAN compilation, the start being half a second late won't be evident at all 🧚

Furthermore, people who can type a few messages ahead might only notice a processing delay after the very first break-interaction πŸ‘€. sending and processing the next messages can happen while the "echoes" and responses to earlier messages are still printing πŸ–¨οΈπŸ’–

Transmission considerations:

In the standard echoing scheme, characters are buffered at the same server as they are keyed πŸŽ€. but the user process doesn't see them until a wakeup character has been typed. so a TIP using RCE could buffer characters in the transmission buffer until a wakeup happens and then send off the whole bunch πŸ“¦. unfortunately we chose, for simplicity, to keep all knowledge of wakeup characters at the serving site πŸ™ˆ. that means the TIP may buffer beyond a wakeup (if it isn't also a break) and delay the process from doing some useful work. however, since no output is expected from the process in this case, the user won't see any noticeable delay, except that the next break interaction may take a little longer ✨

If the TIP chooses to buffer input before transmission, it will transmit AT LEAST at every break character. the SERVER should be able to instruct the TIP to transmit more often if that's appropriate πŸ¦‹

An Example:

Conversational output LINKING is an example where the transmission strategy is kept separate from the break and wakeup strategies 🌸. transmission should happen on every character so each character can be promptly printed at each linked terminal, but no break or wakeup needs to occur until a special escape character is typed (this reawakens the EXEC, for example) 🫢

Conversational output linking also introduces another funny πŸ’€:

Unsolicited Output:

okay this one is spicy 🌢️. what happens when the ECHO (or DISCARD) path is enabled, but the input buffer is empty (i.e. immediate echoing is occurring) and something arrives in the output buffer? this "something" can't be a response to a previously keyed command, or the ECHO path would already be disabled. (this proof is left to the reader!) it's most likely a system message like

[CR][LF]SYSTEM WILL GO DOWN IN 5 MINUTES[CR][LF]

or a character arriving from another linked terminal πŸ‘€

since that kind of output doesn't fit neatly into our RCE scheme, the following kludge is proposed 🧸. unsolicited output should cause the OUTPUT path to be enabled. the occurrence of either an MTB (DTB) Or Empty Output Buffer will reenable the ECHO (DISCARD) path πŸ’œ


IV. Orthogonal Issues ✨

several other mechanisms could reasonably be bundled into this proposed addition to TELNET πŸŽ€. the problems that need more discussion include:

  1. some means should be provided for the server to clear the input, transmission, print and output buffers 🧹
  2. some means should be provided for the user to immediately clear the output buffer (i.e. suppress printing of lengthy output) πŸ™…β€β™€οΈ
  3. the server may want to ask about the number of characters remaining to be printed πŸ”’
  4. a special tag character may be required to note where clearing of the input buffer occurred 🏷️
  5. the TIP's transmission strategy should be specifiable by the server; perhaps a "Set Wakeup Classes" command should be implemented πŸŽ›οΈ
  6. the server should be able to cause the TIP to break on the n-th input character regardless of whatever a break character has been encountered πŸ’…
  7. should the TIP or the server be responsible for properly echoing a formatting control character such as a TAB? πŸ€”
  8. the proper equivalence classes of ASCII characters have to be finalized πŸ“š
  9. how should a CR be echoed? πŸ‘€
  10. should one-for-one echo replacement (e.g. "$" for ESC) or multi-character substitution (e.g. "^A" for Control-A) be provided by the TIP? πŸ€·β€β™€οΈ
  11. the proposed DTB command directs the TIP to also discard the delimiting break character. should the break character discard rather be dependent on setting the Break Action to "don't echo" before sending the DTB? 🧐

several of these issues will be addressed in RFC 358 🌈


VII. Conclusion ✨

this document has presented a proposed optional addition to the User TELNET πŸ¦‹. the next step is to run some simulations and incorporate RCE into an experimental version of TELNET πŸ§ͺ

no recommendation is made that the current TELNET be discarded, okay?? 🫢 for example, RCE should not be used for those half-duplex devices which perform their own "echoing". if RCE is adopted as an alternate means of echoing, changes to those TELNETs choosing not to implement it should be minimal. switching from RCE back to the current echo mechanism is an immediate result of either the user or the server sending a "You Echo" (or "I'll Echo") πŸ’–

much of the machinery required to implement RCE already exists at the interface between the server process and its Terminal Handler or Server TELNET πŸ§šβ€β™€οΈ. this means no server process needs to change, but the process' means of specifying break classes, break actions and echoing conventions must be interpreted by the Terminal Handler and reissued to the TIP in terms of the corresponding RCE commands. iconic, honestly πŸ‘‘βœ¨

     [ This RFC was put into machine readable form for entry ]
   [ into the online RFC archives by Erik J. Verbruggen 12/97 ]
πŸ“¦ where this page comes from