From e11d9d30802278af22e78d8c10f348b683670cd9 Mon Sep 17 00:00:00 2001
From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Mon, 13 Nov 2006 13:12:07 -0200
Subject: [DCCP]: Increment sequence numbers on retransmitted Response packets

Problem:
---
 net/dccp/minisocks.c | 16 +++++++++-------
 net/dccp/output.c    |  4 ++++
 2 files changed, 13 insertions(+), 7 deletions(-)

(limited to 'net/dccp')

diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index d3de696fe4b..5b2773efd7c 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -196,15 +196,17 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
 
 	/* Check for retransmitted REQUEST */
 	if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) {
-		if (after48(DCCP_SKB_CB(skb)->dccpd_seq,
-			    dccp_rsk(req)->dreq_isr)) {
-			struct dccp_request_sock *dreq = dccp_rsk(req);
+		struct dccp_request_sock *dreq = dccp_rsk(req);
 
+		if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_isr)) {
 			dccp_pr_debug("Retransmitted REQUEST\n");
-			/* Send another RESPONSE packet */
-			dccp_set_seqno(&dreq->dreq_iss, dreq->dreq_iss + 1);
-			dccp_set_seqno(&dreq->dreq_isr,
-				       DCCP_SKB_CB(skb)->dccpd_seq);
+			dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq;
+			/*
+			 * Send another RESPONSE packet
+			 * To protect against Request floods, increment retrans
+			 * counter (backoff, monitored by dccp_response_timer).
+			 */
+			req->retrans++;
 			req->rsk_ops->rtx_syn_ack(sk, req, NULL);
 		}
 		/* Network Duplicate, discard packet */
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 992caedd772..08ee5547a2f 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -332,6 +332,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
 	skb->dst = dst_clone(dst);
 
 	dreq = dccp_rsk(req);
+	if (inet_rsk(req)->acked)	/* increase ISS upon retransmission */
+		dccp_inc_seqno(&dreq->dreq_iss);
 	DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
 	DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_iss;
 
@@ -354,6 +356,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
 
 	dccp_csum_outgoing(skb);
 
+	/* We use `acked' to remember that a Response was already sent. */
+	inet_rsk(req)->acked = 1;
 	DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
 	return skb;
 }
-- 
cgit v1.2.3-70-g09d2