Commit 8f9c208f authored by David S. Miller's avatar David S. Miller
parents 2b88f2de f541fb7e
...@@ -376,8 +376,10 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) ...@@ -376,8 +376,10 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
/** /**
* struct dccp_request_sock - represent DCCP-specific connection request * struct dccp_request_sock - represent DCCP-specific connection request
* @dreq_inet_rsk: structure inherited from * @dreq_inet_rsk: structure inherited from
* @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1) * @dreq_iss: initial sequence number, sent on the first Response (RFC 4340, 7.1)
* @dreq_isr: initial sequence number received on the Request * @dreq_gss: greatest sequence number sent (for retransmitted Responses)
* @dreq_isr: initial sequence number received in the first Request
* @dreq_gsr: greatest sequence number received (for retransmitted Request(s))
* @dreq_service: service code present on the Request (there is just one) * @dreq_service: service code present on the Request (there is just one)
* @dreq_featneg: feature negotiation options for this connection * @dreq_featneg: feature negotiation options for this connection
* The following two fields are analogous to the ones in dccp_sock: * 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) ...@@ -387,7 +389,9 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
struct dccp_request_sock { struct dccp_request_sock {
struct inet_request_sock dreq_inet_rsk; struct inet_request_sock dreq_inet_rsk;
__u64 dreq_iss; __u64 dreq_iss;
__u64 dreq_gss;
__u64 dreq_isr; __u64 dreq_isr;
__u64 dreq_gsr;
__be32 dreq_service; __be32 dreq_service;
struct list_head dreq_featneg; struct list_head dreq_featneg;
__u32 dreq_timestamp_echo; __u32 dreq_timestamp_echo;
......
...@@ -98,6 +98,7 @@ static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc) ...@@ -98,6 +98,7 @@ static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc)
{ {
hc->tx_t_ipi = scaled_div32(((u64)hc->tx_s) << 6, hc->tx_x); hc->tx_t_ipi = scaled_div32(((u64)hc->tx_s) << 6, hc->tx_x);
DCCP_BUG_ON(hc->tx_t_ipi == 0);
ccid3_pr_debug("t_ipi=%u, s=%u, X=%u\n", hc->tx_t_ipi, ccid3_pr_debug("t_ipi=%u, s=%u, X=%u\n", hc->tx_t_ipi,
hc->tx_s, (unsigned)(hc->tx_x >> 6)); hc->tx_s, (unsigned)(hc->tx_x >> 6));
} }
...@@ -236,8 +237,6 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) ...@@ -236,8 +237,6 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
* *
* Note that X_recv is scaled by 2^6 while X_calc is not * Note that X_recv is scaled by 2^6 while X_calc is not
*/ */
BUG_ON(hc->tx_p && !hc->tx_x_calc);
if (hc->tx_x_calc > (hc->tx_x_recv >> 5)) if (hc->tx_x_calc > (hc->tx_x_recv >> 5))
hc->tx_x_recv = hc->tx_x_recv =
max(hc->tx_x_recv / 2, max(hc->tx_x_recv / 2,
......
...@@ -300,7 +300,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) ...@@ -300,7 +300,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
*/ */
WARN_ON(req->sk); WARN_ON(req->sk);
if (seq != dccp_rsk(req)->dreq_iss) { if (!between48(seq, dccp_rsk(req)->dreq_iss,
dccp_rsk(req)->dreq_gss)) {
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
goto out; goto out;
} }
...@@ -639,11 +640,12 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) ...@@ -639,11 +640,12 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
* *
* Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
* *
* In fact we defer setting S.GSR, S.SWL, S.SWH to * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
* dccp_create_openreq_child.
*/ */
dreq->dreq_isr = dcb->dccpd_seq; dreq->dreq_isr = dcb->dccpd_seq;
dreq->dreq_gsr = dreq->dreq_isr;
dreq->dreq_iss = dccp_v4_init_sequence(skb); dreq->dreq_iss = dccp_v4_init_sequence(skb);
dreq->dreq_gss = dreq->dreq_iss;
dreq->dreq_service = service; dreq->dreq_service = service;
if (dccp_v4_send_response(sk, req, NULL)) if (dccp_v4_send_response(sk, req, NULL))
......
...@@ -193,7 +193,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -193,7 +193,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
*/ */
WARN_ON(req->sk != NULL); WARN_ON(req->sk != NULL);
if (seq != dccp_rsk(req)->dreq_iss) { if (!between48(seq, dccp_rsk(req)->dreq_iss,
dccp_rsk(req)->dreq_gss)) {
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
goto out; goto out;
} }
...@@ -440,11 +441,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) ...@@ -440,11 +441,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
* *
* Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
* *
* In fact we defer setting S.GSR, S.SWL, S.SWH to * Setting S.SWL/S.SWH to is deferred to dccp_create_openreq_child().
* dccp_create_openreq_child.
*/ */
dreq->dreq_isr = dcb->dccpd_seq; dreq->dreq_isr = dcb->dccpd_seq;
dreq->dreq_gsr = dreq->dreq_isr;
dreq->dreq_iss = dccp_v6_init_sequence(skb); dreq->dreq_iss = dccp_v6_init_sequence(skb);
dreq->dreq_gss = dreq->dreq_iss;
dreq->dreq_service = service; dreq->dreq_service = service;
if (dccp_v6_send_response(sk, req, NULL)) if (dccp_v6_send_response(sk, req, NULL))
......
...@@ -127,9 +127,11 @@ struct sock *dccp_create_openreq_child(struct sock *sk, ...@@ -127,9 +127,11 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
* activation below, as these windows all depend on the local * activation below, as these windows all depend on the local
* and remote Sequence Window feature values (7.5.2). * and remote Sequence Window feature values (7.5.2).
*/ */
newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss; newdp->dccps_iss = dreq->dreq_iss;
newdp->dccps_gss = dreq->dreq_gss;
newdp->dccps_gar = newdp->dccps_iss; newdp->dccps_gar = newdp->dccps_iss;
newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr; newdp->dccps_isr = dreq->dreq_isr;
newdp->dccps_gsr = dreq->dreq_gsr;
/* /*
* Activate features: initialise CCIDs, sequence windows etc. * Activate features: initialise CCIDs, sequence windows etc.
...@@ -164,9 +166,9 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, ...@@ -164,9 +166,9 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
/* Check for retransmitted REQUEST */ /* Check for retransmitted REQUEST */
if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) {
if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_isr)) { if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_gsr)) {
dccp_pr_debug("Retransmitted REQUEST\n"); dccp_pr_debug("Retransmitted REQUEST\n");
dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq; dreq->dreq_gsr = DCCP_SKB_CB(skb)->dccpd_seq;
/* /*
* Send another RESPONSE packet * Send another RESPONSE packet
* To protect against Request floods, increment retrans * To protect against Request floods, increment retrans
...@@ -186,12 +188,14 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb, ...@@ -186,12 +188,14 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
goto drop; goto drop;
/* Invalid ACK */ /* Invalid ACK */
if (DCCP_SKB_CB(skb)->dccpd_ack_seq != dreq->dreq_iss) { if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
dreq->dreq_iss, dreq->dreq_gss)) {
dccp_pr_debug("Invalid ACK number: ack_seq=%llu, " dccp_pr_debug("Invalid ACK number: ack_seq=%llu, "
"dreq_iss=%llu\n", "dreq_iss=%llu, dreq_gss=%llu\n",
(unsigned long long) (unsigned long long)
DCCP_SKB_CB(skb)->dccpd_ack_seq, DCCP_SKB_CB(skb)->dccpd_ack_seq,
(unsigned long long) dreq->dreq_iss); (unsigned long long) dreq->dreq_iss,
(unsigned long long) dreq->dreq_gss);
goto drop; goto drop;
} }
......
...@@ -408,10 +408,10 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, ...@@ -408,10 +408,10 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
skb_dst_set(skb, dst_clone(dst)); skb_dst_set(skb, dst_clone(dst));
dreq = dccp_rsk(req); dreq = dccp_rsk(req);
if (inet_rsk(req)->acked) /* increase ISS upon retransmission */ if (inet_rsk(req)->acked) /* increase GSS upon retransmission */
dccp_inc_seqno(&dreq->dreq_iss); dccp_inc_seqno(&dreq->dreq_gss);
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_gss;
/* Resolve feature dependencies resulting from choice of CCID */ /* Resolve feature dependencies resulting from choice of CCID */
if (dccp_feat_server_ccid_dependencies(dreq)) 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,8 +429,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
DCCP_SKB_CB(skb)->dccpd_opt_len) / 4; DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
dh->dccph_type = DCCP_PKT_RESPONSE; dh->dccph_type = DCCP_PKT_RESPONSE;
dh->dccph_x = 1; dh->dccph_x = 1;
dccp_hdr_set_seq(dh, dreq->dreq_iss); dccp_hdr_set_seq(dh, dreq->dreq_gss);
dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr); dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_gsr);
dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service; dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
dccp_csum_outgoing(skb); dccp_csum_outgoing(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment