1 | |
---|
2 | Three pieces of state need to be kept for each side of each option. |
---|
3 | (You need the localside, sending WILL/WONT & receiving DO/DONT, and |
---|
4 | the remoteside, sending DO/DONT and receiving WILL/WONT) |
---|
5 | |
---|
6 | MY_STATE: What state am I in? |
---|
7 | WANT_STATE: What state do I want? |
---|
8 | WANT_RESP: How many requests have I initiated? |
---|
9 | |
---|
10 | Default values: |
---|
11 | MY_STATE = WANT_STATE = DONT |
---|
12 | WANT_RESP = 0 |
---|
13 | |
---|
14 | The local setup will change based on the state of the Telnet |
---|
15 | variables. When we are the originator, we can either make the |
---|
16 | local setup changes at option request time (in which case if |
---|
17 | the option is denied we need to change things back) or when |
---|
18 | the option is acknowledged. |
---|
19 | |
---|
20 | To initiate a switch to NEW_STATE: |
---|
21 | |
---|
22 | if ((WANT_RESP == 0 && NEW_STATE == MY_STATE) || |
---|
23 | WANT_STATE == NEW_STATE) { |
---|
24 | do nothing; |
---|
25 | } else { |
---|
26 | /* |
---|
27 | * This is where the logic goes to change the local setup |
---|
28 | * if we are doing so at request initiation |
---|
29 | */ |
---|
30 | WANT_STATE = NEW_STATE; |
---|
31 | send NEW_STATE; |
---|
32 | WANT_RESP += 1; |
---|
33 | } |
---|
34 | |
---|
35 | When receiving NEW_STATE: |
---|
36 | |
---|
37 | if (WANT_RESP) { |
---|
38 | --WANT_RESP; |
---|
39 | if (WANT_RESP && (NEW_STATE == MY_STATE)) |
---|
40 | --WANT_RESP; |
---|
41 | } |
---|
42 | if (WANT_RESP == 0) { |
---|
43 | if (NEW_STATE != WANT_STATE) { |
---|
44 | /* |
---|
45 | * This is where the logic goes to decide if it is ok |
---|
46 | * to switch to NEW_STATE, and if so, do any necessary |
---|
47 | * local setup changes. |
---|
48 | */ |
---|
49 | if (ok_to_switch_to NEW_STATE) |
---|
50 | WANT_STATE = NEW_STATE; |
---|
51 | else |
---|
52 | WANT_RESP++; |
---|
53 | * if (MY_STATE != WANT_STATE) |
---|
54 | reply with WANT_STATE; |
---|
55 | } else { |
---|
56 | /* |
---|
57 | * This is where the logic goes to change the local setup |
---|
58 | * if we are doing so at request acknowledgment |
---|
59 | */ |
---|
60 | } |
---|
61 | } |
---|
62 | MY_STATE = NEW_STATE; |
---|
63 | |
---|
64 | * This if() line is not needed, it should be ok to always do the |
---|
65 | "reply with WANT_STATE". With the if() line, asking to turn on |
---|
66 | an option that the other side doesn't understand is: |
---|
67 | Send DO option |
---|
68 | Recv WONT option |
---|
69 | Without the if() line, it is: |
---|
70 | Send DO option |
---|
71 | Recv WONT option |
---|
72 | Send DONT option |
---|
73 | If the other side does not expect to receive the latter case, |
---|
74 | but generates the latter case, then there is a potential for |
---|
75 | option negotiation loops. An implementation that does not expect |
---|
76 | to get the second case should not generate it, an implementation |
---|
77 | that does expect to get it may or may not generate it, and things |
---|
78 | will still work. Being conservative in what we send, we have the |
---|
79 | if() statement in, but we expect the other side to generate the |
---|
80 | last response. |
---|