aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/dccp.h8
-rw-r--r--net/dccp/ipv4.c8
-rw-r--r--net/dccp/ipv6.c8
-rw-r--r--net/dccp/minisocks.c18
-rw-r--r--net/dccp/output.c10
5 files changed, 32 insertions, 20 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 710c04302a15..eaf95a023af4 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -376,8 +376,10 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
376/** 376/**
377 * struct dccp_request_sock - represent DCCP-specific connection request 377 * struct dccp_request_sock - represent DCCP-specific connection request
378 * @dreq_inet_rsk: structure inherited from 378 * @dreq_inet_rsk: structure inherited from
379 * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1) 379 * @dreq_iss: initial sequence number, sent on the first Response (RFC 4340, 7.1)
380 * @dreq_isr: initial sequence number received on the Request 380 * @dreq_gss: greatest sequence number sent (for retransmitted Responses)
381 * @dreq_isr: initial sequence number received in the first Request
382 * @dreq_gsr: greatest sequence number received (for retransmitted Request(s))
381 * @dreq_service: service code present on the Request (there is just one) 383 * @dreq_service: service code present on the Request (there is just one)
382 * @dreq_featneg: feature negotiation options for this connection 384 * @dreq_featneg: feature negotiation options for this connection
383 * The following two fields are analogous to the ones in dccp_sock: 385 * The following two fields are analogous to the ones in dccp_sock:
@@ -387,7 +389,9 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
387struct dccp_request_sock { 389struct dccp_request_sock {
388 struct inet_request_sock dreq_inet_rsk; 390 struct inet_request_sock dreq_inet_rsk;
389 __u64 dreq_iss; 391 __u64 dreq_iss;
392 __u64 dreq_gss;
390 __u64 dreq_isr; 393 __u64 dreq_isr;
394 __u64 dreq_gsr;
391 __be32 dreq_service; 395 __be32 dreq_service;
392 struct list_head dreq_featneg; 396 struct list_head dreq_featneg;
393 __u32 dreq_timestamp_echo; 397 __u32 dreq_timestamp_echo;
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 1c67fe8ff90d..caf6e1734b62 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -300,7 +300,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
300 */ 300 */
301 WARN_ON(req->sk); 301 WARN_ON(req->sk);
302 302
303 if (seq != dccp_rsk(req)->dreq_iss) { 303 if (!between48(seq, dccp_rsk(req)->dreq_iss,
304 dccp_rsk(req)->dreq_gss)) {
304 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); 305 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
305 goto out; 306 goto out;
306 } 307 }
@@ -639,11 +640,12 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
639 * 640 *
640 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie 641 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
641 * 642 *
642 * In fact we defer setting S.GSR, S.SWL, S.SWH to 643 * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
643 * dccp_create_openreq_child.
644 */ 644 */
645 dreq->dreq_isr = dcb->dccpd_seq; 645 dreq->dreq_isr = dcb->dccpd_seq;
646 dreq->dreq_gsr = dreq->dreq_isr;
646 dreq->dreq_iss = dccp_v4_init_sequence(skb); 647 dreq->dreq_iss = dccp_v4_init_sequence(skb);
648 dreq->dreq_gss = dreq->dreq_iss;
647 dreq->dreq_service = service; 649 dreq->dreq_service = service;
648 650
649 if (dccp_v4_send_response(sk, req, NULL)) 651 if (dccp_v4_send_response(sk, req, NULL))
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index ce903f747e64..4dc588f520e0 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -193,7 +193,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
193 */ 193 */
194 WARN_ON(req->sk != NULL); 194 WARN_ON(req->sk != NULL);
195 195
196 if (seq != dccp_rsk(req)->dreq_iss) { 196 if (!between48(seq, dccp_rsk(req)->dreq_iss,
197 dccp_rsk(req)->dreq_gss)) {
197 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); 198 NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
198 goto out; 199 goto out;
199 } 200 }
@@ -440,11 +441,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
440 * 441 *
441 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie 442 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
442 * 443 *
443 * In fact we defer setting S.GSR, S.SWL, S.SWH to 444 * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
444 * dccp_create_openreq_child.
445 */ 445 */
446 dreq->dreq_isr = dcb->dccpd_seq; 446 dreq->dreq_isr = dcb->dccpd_seq;
447 dreq->dreq_gsr = dreq->dreq_isr;
447 dreq->dreq_iss = dccp_v6_init_sequence(skb); 448 dreq->dreq_iss = dccp_v6_init_sequence(skb);
449 dreq->dreq_gss = dreq->dreq_iss;
448 dreq->dreq_service = service; 450 dreq->dreq_service = service;
449 451
450 if (dccp_v6_send_response(sk, req, NULL)) 452 if (dccp_v6_send_response(sk, req, NULL))
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 5a7f90bbffac..ea850ce35d4a 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -127,9 +127,11 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
127 * activation below, as these windows all depend on the local 127 * activation below, as these windows all depend on the local
128 * and remote Sequence Window feature values (7.5.2). 128 * and remote Sequence Window feature values (7.5.2).
129 */ 129 */
130 newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss; 130 newdp->dccps_iss = dreq->dreq_iss;
131 newdp->dccps_gss = dreq->dreq_gss;
131 newdp->dccps_gar = newdp->dccps_iss; 132 newdp->dccps_gar = newdp->dccps_iss;
132 newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr; 133 newdp->dccps_isr = dreq->dreq_isr;
134 newdp->dccps_gsr = dreq->dreq_gsr;
133 135
134 /* 136 /*
135 * Activate features: initialise CCIDs, sequence windows etc. 137 * Activate features: initialise CCIDs, sequence windows etc.
@@ -164,9 +166,9 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
164 /* Check for retransmitted REQUEST */ 166 /* Check for retransmitted REQUEST */
165 if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { 167 if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) {
166 168
167 if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_isr)) { 169 if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_gsr)) {
168 dccp_pr_debug("Retransmitted REQUEST\n"); 170 dccp_pr_debug("Retransmitted REQUEST\n");
169 dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq; 171 dreq->dreq_gsr = DCCP_SKB_CB(skb)->dccpd_seq;
170 /* 172 /*
171 * Send another RESPONSE packet 173 * Send another RESPONSE packet
172 * To protect against Request floods, increment retrans 174 * To protect against Request floods, increment retrans
@@ -186,12 +188,14 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
186 goto drop; 188 goto drop;
187 189
188 /* Invalid ACK */ 190 /* Invalid ACK */
189 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != dreq->dreq_iss) { 191 if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
192 dreq->dreq_iss, dreq->dreq_gss)) {
190 dccp_pr_debug("Invalid ACK number: ack_seq=%llu, " 193 dccp_pr_debug("Invalid ACK number: ack_seq=%llu, "
191 "dreq_iss=%llu\n", 194 "dreq_iss=%llu, dreq_gss=%llu\n",
192 (unsigned long long) 195 (unsigned long long)
193 DCCP_SKB_CB(skb)->dccpd_ack_seq, 196 DCCP_SKB_CB(skb)->dccpd_ack_seq,
194 (unsigned long long) dreq->dreq_iss); 197 (unsigned long long) dreq->dreq_iss,
198 (unsigned long long) dreq->dreq_gss);
195 goto drop; 199 goto drop;
196 } 200 }
197 201
diff --git a/net/dccp/output.c b/net/dccp/output.c
index dede3edb8849..787367308797 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -408,10 +408,10 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
408 skb_dst_set(skb, dst_clone(dst)); 408 skb_dst_set(skb, dst_clone(dst));
409 409
410 dreq = dccp_rsk(req); 410 dreq = dccp_rsk(req);
411 if (inet_rsk(req)->acked) /* increase ISS upon retransmission */ 411 if (inet_rsk(req)->acked) /* increase GSS upon retransmission */
412 dccp_inc_seqno(&dreq->dreq_iss); 412 dccp_inc_seqno(&dreq->dreq_gss);
413 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; 413 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
414 DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; 414 DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_gss;
415 415
416 /* Resolve feature dependencies resulting from choice of CCID */ 416 /* Resolve feature dependencies resulting from choice of CCID */
417 if (dccp_feat_server_ccid_dependencies(dreq)) 417 if (dccp_feat_server_ccid_dependencies(dreq))
@@ -429,8 +429,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
429 DCCP_SKB_CB(skb)->dccpd_opt_len) / 4; 429 DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
430 dh->dccph_type = DCCP_PKT_RESPONSE; 430 dh->dccph_type = DCCP_PKT_RESPONSE;
431 dh->dccph_x = 1; 431 dh->dccph_x = 1;
432 dccp_hdr_set_seq(dh, dreq->dreq_iss); 432 dccp_hdr_set_seq(dh, dreq->dreq_gss);
433 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr); 433 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_gsr);
434 dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service; 434 dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
435 435
436 dccp_csum_outgoing(skb); 436 dccp_csum_outgoing(skb);