After further experiments I am resubmitting this patch, using a higher RTT 
estimate
for the Close/CloseReq retransmission timer. 

The problem with the fallback RTT of 200ms is that it is lower than several link
types. I have experimented on (emulated) satellite links which have an RTT of 
~600ms.
What then happens is that the retransmission of the Close happens too early: the
second Close(Req) is sent before the reply from the peer arrives; when the peer 
gets
the retransmitted Close(Req), it has already torn down its end and replies with 
a
Reset ("No Connection").

This leads to a lot of noise on the wire, depending on the actual link RTT 
there may be
several retranmissions with subsequent Resets ("No Connection"). Furthermore, 
several
technologies have link RTTs greater than 200ms: WiMax for instance (~700ms) or 
GPRS.

The patch now uses 3 seconds, which coincides with the usec value of 
DCCP_SANE_RTT_MAX
and the TCP initial RTO.

I think that this is a better solution: in the normal case we have no packet 
loss and
hence the timer will be killed before it expires. When packet loss occurs we 
have the
retranmission to ensure that the connection is eventually taken down.

Will be uploaded to the test tree early next week.

INTER-DIFF:
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -578,13 +578,14 @@ void dccp_send_close(struct sock *sk, co
                 * Retransmission timer for active-close: RFC 4340, 8.3 requires
                 * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ
                 * state can be left. The initial timeout is 2 RTTs.
-                * Since we do not always have a CCID with RTT measurements, we
-                * use the fallback RTT from [RFC 4340, 3.4] (200ms).
+                * Since RTT measurement is done by the CCIDs, there is no easy
+                * way to get an RTT sample. The fallback RTT from RFC 4340, 3.4
+                * is too low (200ms); we use a high value to avoid unnecessary
+                * retransmissions when the link RTT is > 0.2 seconds.
+                * FIXME: Let main module sample RTTs and use that instead.
                 */
-               inet_csk(sk)->icsk_rto =
-                               2 * usecs_to_jiffies(DCCP_FALLBACK_RTT);
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                         inet_csk(sk)->icsk_rto, DCCP_RTO_MAX);
+                                         DCCP_TIMEOUT_INIT, DCCP_RTO_MAX);
        } else
                dccp_transmit_skb(sk, skb);
 }

-----------------------------> Patch v2 
<--------------------------------------------
[DCCP]: Shift the retransmit timer for active-close into output.c

When performing active close, RFC 4340, 8.3. requires to retransmit the
Close/CloseReq with a backoff-retransmit timer starting at intially 2 RTTs.

This patch shifts the existing code for active-close retransmit timer
into output.c, so that the retransmit timer is started when the first
Close/CloseReq is sent. Previously, the timer was started when, after
releasing the socket in dccp_close(), the actively-closing side had not yet
reached the CLOSED/TIMEWAIT state.

The patch further reduces the initial timeout from 3 seconds to the required
2 RTTs, where - in absence of a known RTT - the fallback value specified in
RFC 4340, 3.4 is used.

Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
---
 net/dccp/output.c |   13 ++++++++++++-
 net/dccp/proto.c  |   18 ------------------
 2 files changed, 12 insertions(+), 19 deletions(-)

--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -985,24 +985,6 @@ adjudge_to_death:
        if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED)
                goto out;
 
-       /*
-        * The last release_sock may have processed the CLOSE or RESET
-        * packet moving sock to CLOSED state, if not we have to fire
-        * the CLOSE/CLOSEREQ retransmission timer, see "8.3. Termination"
-        * in draft-ietf-dccp-spec-11. -acme
-        */
-       if (sk->sk_state == DCCP_CLOSING) {
-               /* FIXME: should start at 2 * RTT */
-               /* Timer for repeating the CLOSE/CLOSEREQ until an answer. */
-               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                         inet_csk(sk)->icsk_rto,
-                                         DCCP_RTO_MAX);
-#if 0
-               /* Yeah, we should use sk->sk_prot->orphan_count, etc */
-               dccp_set_state(sk, DCCP_CLOSED);
-#endif
-       }
-
        if (sk->sk_state == DCCP_CLOSED)
                inet_csk_destroy_sock(sk);
 
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -574,7 +574,18 @@ void dccp_send_close(struct sock *sk, co
                dccp_write_xmit(sk, 1);
                dccp_skb_entail(sk, skb);
                dccp_transmit_skb(sk, skb_clone(skb, prio));
-               /* FIXME do we need a retransmit timer here? */
+               /*
+                * Retransmission timer for active-close: RFC 4340, 8.3 requires
+                * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ
+                * state can be left. The initial timeout is 2 RTTs.
+                * Since RTT measurement is done by the CCIDs, there is no easy
+                * way to get an RTT sample. The fallback RTT from RFC 4340, 3.4
+                * is too low (200ms); we use a high value to avoid unnecessary
+                * retransmissions when the link RTT is > 0.2 seconds.
+                * FIXME: Let main module sample RTTs and use that instead.
+                */
+               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+                                         DCCP_TIMEOUT_INIT, DCCP_RTO_MAX);
        } else
                dccp_transmit_skb(sk, skb);
 }
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to