Commands and option negotiation
Negotiate with WILL and DO
Read WILL, WONT, DO, and DONT as two independent conversations about who performs each Telnet option.
8 minute lesson
Telnet was built to connect wildly different systems. A 1970s mainframe and a modern laptop cannot assume the same terminal features, so options are negotiated instead of assumed. Both sides start from the plain NVT and upgrade from there, one option at a time.
Four commands express offers, requests, refusals, and instructions to stop:
WILL option: I offer to perform this optionWONT option: I refuse or will stop performing itDO option: please perform this optionDONT option: do not perform, or stop performing, it
On the wire, each is a three-byte sequence. IAC, then the command, then the option code:
255 251 opt IAC WILL opt
255 252 opt IAC WONT opt
255 253 opt IAC DO opt
255 254 opt IAC DONT opt
A side that agrees to WILL ECHO answers DO ECHO. A side that cannot support the offer answers DONT ECHO. The same works in reverse: you can request with DO, and the other side accepts with WILL or declines with WONT.
Refusal is always allowed. The rule from RFC 854 is that an option is only active once both sides have agreed. One side asking is never enough. This is why any implementation must handle a “no” gracefully: the plain NVT keeps working either way.
Two independent conversations
Each direction is negotiated independently. Supporting an option while sending does not automatically mean the same option is active while receiving.
Take ECHO. WILL ECHO from the server means “I will echo what you send me”. Whether the client also echoes in the other direction is a completely separate negotiation. Think of every option as two switches, one per direction, each needing agreement from both sides.
Avoid negotiation loops
Implementations must avoid negotiation loops. The classic bug: side A sends DO ECHO, side B acknowledges with WILL ECHO, side A treats the acknowledgment as a fresh offer and acknowledges back, and the two ping-pong forever.
The fix is to track the current state of each option. Do not acknowledge a state that is already active by sending the same request again and again. Only send a negotiation command when you want the state to change.
Lesson completed