Oded,
I think I agree with your analysis, and believe that you have found an error
in the RFC.
There are two problems, the problem of shutting down the half-open connection,
and the problem of TIMEWAIT state. It is easier to solve the first problem.
(A) Partial solution: A half-open connection is closed, but the crashed
endpoint cannot restart the connection for 2MSL due to TIMEWAIT state.
==> Change Section 7.5.4 so that Sync packets sent in response to Request
packets also acknowledge GSR:
o A sequence-invalid DCCP-Reset or DCCP-Request packet MUST elicit a
DCCP-Sync packet in response (subject to a possible rate limit). This
response packet MUST use a new Sequence Number, and thus will
increase GSS; GSR will not change, however, since the received
packet was sequence-invalid. The response packet's
Acknowledgement Number MUST equal GSR.
==> Change Step 4 in the pseudocode so that Resets generated in REQUEST state
use Sequence and Acknowledgement Numbers from the input packet:
Step 4: Prepare sequence numbers in REQUEST
If S.state == REQUEST,
If (P.type == Response or P.type == Reset)
and S.AWL <= P.ackno <= S.AWH,
/* Set sequence number variables corresponding to the
other endpoint, so P will pass the tests in Step 6 */
Set S.GSR, S.ISR, S.SWL, S.SWH
/* Response processing continues in Step 10; Reset
processing continues in Step 9 */
Otherwise,
/* Only Response and Reset are valid in REQUEST state */
/* The following Reset's Sequence and Acknowledgement Numbers
are taken from the input packet; see Section 8.3.1.
The Reset does NOT update GSS. */
Generate Reset(Packet Error)
Drop packet and return
That would lead to the following sequence.
DCCP A DCCP B
(GSS=1,GSR=10) (GSS=10,GSR=1)
(Crash)
CLOSED OPEN
REQUEST --> DCCP-Request(seq 400) --> ???
??? <-- DCCP-Sync(seq 11, ack 1) <-- OPEN (GSS=11,GSR=1)
REQUEST --> DCCP-Reset(seq 2, ack 11) --> TIMEWAIT
...
REQUEST --> DCCP-Request(seq 401) --> TIMEWAIT ???
CLOSED <-- DCCP-Reset(no connection, seq 0, ack 401)
(B) Complete solution: A half-open connection is reopened by the active endpoint.
==> As above, change Section 7.5.4 so that Sync packets sent in response to
Request packets also acknowledge GSR:
o A sequence-invalid DCCP-Reset or DCCP-Request packet MUST elicit a
DCCP-Sync packet in response (subject to a possible rate limit). This
response packet MUST use a new Sequence Number, and thus will
increase GSS; GSR will not change, however, since the received
packet was sequence-invalid. The response packet's
Acknowledgement Number MUST equal GSR.
==> Change Step 4 in the pseudocode so that Sync packets received in REQUEST
state generate Close packets, not Reset packets. As above, Close and Reset
packets generated in REQUEST state use Sequence and Acknowledgement Numbers
from the input packet:
Step 4: Prepare sequence numbers in REQUEST
If S.state == REQUEST,
If (P.type == Response or P.type == Reset)
and S.AWL <= P.ackno <= S.AWH,
/* Set sequence number variables corresponding to the
other endpoint, so P will pass the tests in Step 6 */
Set S.GSR, S.ISR, S.SWL, S.SWH
/* Response processing continues in Step 10; Reset
processing continues in Step 9 */
Otherwise, if P.type == Sync and S.AWL <= P.ackno <= S.AWH,
/* Half-open connection recovery */
/* The following Close's Sequence and Acknowledgement Numbers
are taken from the input packet; see Section 8.3.1.
The Close does NOT update GSS. */
Generate Close
Drop packet and return
Otherwise,
/* Only Response and Reset are valid in REQUEST state */
/* The following Reset's Sequence and Acknowledgement Numbers
are taken from the input packet; see Section 8.3.1.
The Reset does NOT update GSS. */
Generate Reset(Packet Error) unless P.type == Reset
Drop packet and return
That would lead to the following sequence.
DCCP A DCCP B
(GSS=1,GSR=10) (GSS=10,GSR=1)
(Crash)
CLOSED OPEN
REQUEST --> DCCP-Request(seq 400) --> ???
??? <-- DCCP-Sync(seq 11, ack 1) <-- OPEN (GSS=11,GSR=1)
REQUEST --> DCCP-Close(seq 2, ack 11) --> CLOSED/LISTEN
??? ignored <-- DCCP-Reset(seq 12, ack 2) <--
... retransmit ...
REQUEST --> DCCP-Request(seq 401) --> ... proceeds as usual.
I would greatly appreciate feedback on this. Mark?
Eddie
ods15@xxxxxxxxxxxxxxxx wrote:
Hi all, I'm looking at the RFC, and I am having trouble understanding this
example in 7.5.6:
The final example demonstrates recovery from a half-open connection.
DCCP A DCCP B
(GSS=1,GSR=10) (GSS=10,GSR=1)
(Crash)
CLOSED OPEN
REQUEST --> DCCP-Request(seq 400) --> ???
!! <-- DCCP-Sync(seq 11, ack 400) <-- OPEN
REQUEST --> DCCP-Reset(seq 401, ack 11) --> (Abort)
REQUEST CLOSED
REQUEST --> DCCP-Request(seq 402) --> ...
The RFC mandates that sequence invalid packets (in this case, the
Request), do NOT update GSR, but cause a Sync asking about that same
sequence number.
In this case, wouldn't "DCCP B" ignore the reset, because it has a bad
sequence number?
Additionally, won't the Reset cause "DCCP B" to go into TIMEWAIT, and not
CLOSED?
The best flow I can see for this is the following:
DCCP A DCCP B
(GSS=1,GSR=10) (GSS=10,GSR=1)
(Crash)
CLOSED OPEN
REQUEST --> DCCP-Request(seq 400) --> ???
!! <-- DCCP-Sync(seq 11, ack 400) <-- OPEN
REQUEST --> DCCP-Reset(seq 401, ack 11) --> ??? (GSR=1)
===== as mandated for bad sequence Resets, a Sync is sent with the real GSR ====
!! <-- DCCP-Sync(seq 11, ack 1) <-- OPEN
ackno out of range; ignore
... Now what?
Am I misunderstanding something?
- Oded