What is the difference between the WILL
and DO
request?
There is a very important concept involved here, that you need to understand when implementing a Telnet server or client, otherwise your implementation might misbehave in rather odd ways:
Every numbered option that can be negotiated actually has two independent sets of states associated with it - one set of states is associated with the communication from you (the application you are implementing, be it a client or server) to the peer (the communication partner that sits at the other end of the line, be it a server or client) and the other set of states is associated with the opposite direction of communication from the peer to you.
You must keep and handle both sets of states independently if you want to prevent negotiation loops and undesired behavior for the user.
There may be some interoperation between the both sets of states involved, depending on what the option does (you should read the particular RFC for each option you intent to support), but you best implement that on a higher level of abstraction. The basic option negotiation in both directions needs to be independent.
Let's take option 0 TRANSMIT-BINARY
as an example. One set of states is about whether you will send bytes using all 8 bits (binary) to the peer and the other is about whether the peer will send binary to you. All 4 combinations are possible (you 7-bit & peer 7-bit, you binary & peer 7-bit, you 7-bit & peer binary, you binary & peer binary) and changing the option for one direction doesn't (directly) change the same option for the other direction.
If you send an IAC
WILL
TRANSMIT-BINARY
, you are talking about the direction from you to the peer and you are effectively asking the peer to allow you send binary. The peer can answer either DO
or DONT
.
If you send an IAC
DO
TRANSMIT-BINARY
, you are instead talking about the direction from the peer to you and you are effectively asking the peer to start transmitting binary if it is able to and willing. The peer can answer either WILL
or WONT
.
However, if the peer sends an IAC
WILL
TRANSMIT-BINARY
(as opposed to you sending it), it is talking about the direction from the peer to you and it is effectively asking you to allow it send binary. You can answer either DO
or DONT
.
Analogously, if the peer sends an IAC
DO
TRANSMIT-BINARY
, it is talking about the direction from you to the peer and it is effectively asking you to start transmitting binary if you are able to and willing. You can answer either WILL
or WONT
.
Similar things can be said about requests initiated with WONT
and DONT
, with the important difference that the only allowed replies to those are DONT
and WONT
respectively. That means options can always and at any time be turned off (while turning them on is subject to mutual agreement).
You may want to read RFC 1143, which is suggesting a way to implement the negotiation and the associated sets of states.
About the meaning of NVT
What they are talking about there is that the NVT
is a specification of a basic set of fallback properties and behaviors. I.e. if all negotiable options are off (they are required to be off at the start of the connection and if some are turned on during the session, you can turn them all off again, if you so desire), what you have is the minimal set of defined behaviours, you are left with the functionality specified as NVT
Turning options on diverges from the specified basic NVT
.
What this all means is that either end can just refuse turning on any options and then just behave in the same manner as is specified for a Network Virtual Terminal in the relevant RFC's and it can be sufficiently sure that the other end supports that mode of operation in some way (as operating with any and all options turned off is mandated in the standard).