Summary

  • RFC 1080 let one Telnet process ask another to enable or disable software flow control, but only after a DO/WILL agreement established that narrow authority.
  • The option governed output from the user Telnet process to its attached terminal. It did not pause TCP, stop the remote application, authenticate a peer or prove that a local driver applied a request.
  • Agreement forced a known initial enabled state; revoking the option ended further commands and could return the client to an implementation-defined default rather than the last requested mode.

One keystroke, two possible meanings

The Network Virtual Terminal in RFC 854 could generate every one of the 128 US-ASCII codes. That completeness mattered to programs. An editor might bind Control-S or Control-Q to an application command and expect the byte to arrive intact.

A physical terminal had another use for the same values. Software flow control commonly treated Control-S as XOFF, a request to stop terminal output, and Control-Q as XON, a request to resume it. A terminal driver could consume those keystrokes locally. They would never reach the remote application.

Neither interpretation was universally correct. If a terminal buffer was filling, interception protected the display. If an editor needed the character, interception destroyed input. The problem was not an ambiguous wire encoding; it was authority over a local character gate whose state had to follow the remote program’s needs.

RFC 1080, published in November 1988, gave that problem Telnet option 33: TOGGLE-FLOW-CONTROL. Its compact design is useful because it names exactly what could be delegated and what remained local.

Consent came before commands

RFC 855 described Telnet subnegotiation as a two-stage operation. The parties first agree that an option may be used. Only then do they discuss its parameters. For option 33, the usual host sent DO; the user Telnet process attached to the terminal answered WILL.

Those words had bounded meanings. DO said the sender was willing to issue enable and disable requests. WILL said the other process was willing to act on such requests. DONT and WONT refused those roles. A refusal did not report whether local flow control happened to be on or off; it only closed the protocol surface for changing it.

No ON or OFF subnegotiation was permitted before both DO and WILL had been exchanged. This ordering kept a state command from silently creating its own authority. The option could operate in both directions, but its normal shape was asymmetric: the remote host knew when its application needed literal control characters, while the user Telnet process owned the path to the terminal.

Agreement created a known state

Once agreement existed, the sender of DO could request OFF or ON. The receiver was not being asked to throttle the Internet connection. It was being asked whether software flow control should intercept characters on the output path from the user Telnet process to its attached terminal.

RFC 1080 added an important initialization rule. As soon as DO and WILL had been exchanged, the WILL sender had to enable flow control. The first state was therefore known without a separate ON command. A trace could distinguish three facts: the option was unavailable, the option had just become active with flow enabled, or a later subnegotiation had requested a different mode.

That rule did not create an acknowledgement for every change. ON and OFF were requests; the memo defined no response proving that a particular terminal driver had applied them. A packet capture showed the requested state at the option boundary, not necessarily the effective state inside the client or the output a person saw.

Unknown subnegotiation codes were to be ignored. The design could grow without breaking an older parser, but silence could not be promoted into evidence of support.

Revocation did not preserve the last mode

Either side could later send DONT or WONT. From that point, further option-33 subnegotiations were forbidden until another DO/WILL exchange reopened the surface.

Local behavior was deliberately less uniform. Flow control could return to an implementation-defined default. It was unsafe to assume that the last ON or OFF request remained effective. Revocation removed remote authority; it did not freeze the remote party’s most recent preference into local policy.

That distinction matters whenever session state is reconstructed from logs. A controller that stores only the last toggle can be wrong after a refusal, disconnect, process restart or new negotiation epoch. The applicable state depends on the active agreement and the client’s default, not merely on the newest command string in a database.

The option did not control the network

“Flow control” is an overloaded phrase. RFC 1080 covered one local segment: data travelling from the user Telnet process toward the attached terminal. It did not define TCP receive windows, retransmission behavior or congestion response. It did not tell the remote application to stop computing, and it did not prove that bytes already in buffers disappeared.

Nor did disabling software flow control mean “no control” in every sense. Hardware flow control used separate electrical signals and normally did not consume character values. Terminal-to-client input could have its own behavior. A claim about option 33 needed a direction, an observation point and a named mechanism.

The scope was small by design. A remote application could request access to two character values without acquiring ownership of the terminal, the client host or the network path.

Linemode located the rest of character processing

RFC 1184 later made local line editing explicit. A Telnet client could edit, echo or translate special characters locally and send completed lines rather than a packet rhythm driven by every keystroke. Its mode mask covered editing and signal trapping.

Flow logically belonged near those settings, yet RFC 1184 did not duplicate it. It directed implementations to the separate toggle-flow-control option. The separation prevented one broad “terminal mode” bit field from silently redefining another established state machine.

It also reveals the real architectural question: where is a character interpreted? The keyboard generates a value; the terminal driver may consume it; the Telnet client may translate it; the server application may finally receive it. A capture at one boundary cannot reconstruct all four outcomes.

RFC 1372 exposed an unacknowledged limit

RFC 1372 obsoleted RFC 1080 in 1992 while preserving its authority model. It added two requests for resuming paused output. RESTART-XON asked that only XON resume the flow. RESTART-ANY asked that any character except another XOFF do so.

This extension separated two questions that RFC 1080 had left together: is software flow control enabled, and which input releases it? The first became known on option agreement. The restart rule began in a system-dependent state until requested.

The protocol still had a hard evidence limit. A client unable to support both restart modes could ignore a request, and the server had no defined way to learn that it had done so. The RFC asked clients to make every effort; it did not manufacture confirmation.

In common drivers, XOFF and XON were eaten locally. Under restart-any behavior, the character that reopened output might continue onward unless it was XON. Even “resume” therefore did not imply identical character delivery.

Later serial control answered different questions

RFC 2217 used Telnet to control serial ports and defined several different surfaces. It could set inbound or outbound serial flow mechanisms. It also defined FLOWCONTROL-SUSPEND and FLOWCONTROL-RESUME, which paused both Telnet data and commands between a client and access server.

Those mechanisms must not be projected backward onto RFC 1080. A serial-port setting describes device behavior; a Telnet-session suspension gates a protocol exchange; option 33 changes how a user Telnet process treats local XON/XOFF. Similar names do not make the evidence interchangeable.

The IANA Telnet Options registry still lists Remote Flow Control at code 33 with RFC 1372 as its reference. That row preserves coordination. It does not show who implements the option today or whether any driver honors a particular request.

Five records, not one state label

A reliable account of option 33 needs five separate records:

  1. Consent: did DO and WILL establish the role in this session epoch?
  2. Request: which ON, OFF or restart command was sent while consent remained active?
  3. Applied local state: what did the client and terminal driver actually configure?
  4. Character handling: was a particular Control-S, Control-Q or restart character consumed or forwarded?
  5. Outcome: did visible output pause or resume, and did the application receive the intended input?

RFC 1080 supplies the first two and an initial-state rule. The others require local or end-to-end observation.

The historical lesson is not that remote control was dangerous by definition. It is that a useful remote power became interoperable because its scope, prerequisites and exit were narrow. Control-S was a command only while a particular local mechanism and a live option agreement made it one.

Sources and limits

RFC 854 supplies the NVT character context; RFC 855 the agreement-before-subnegotiation grammar; RFC 1080 the original option; RFC 1184 the neighboring Linemode boundary; RFC 1372 the restart extension; RFC 2217 the later serial and session controls; and IANA the registry record. They establish specifications and coordination, not current prevalence, a named deployment, authentication, confirmed driver state or a measured user outcome.