diff options
author | David S. Miller <davem@davemloft.net> | 2010-10-12 14:43:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-12 14:43:42 -0400 |
commit | 8fa6e3d4549271a5b4094893f059bb95f99a8fde (patch) | |
tree | 4c8ae1be73e4749f782cc3f18ec6e42650b8f872 | |
parent | c239f279e571a272c1b32a1e84b8fa037b68f49c (diff) | |
parent | 2f34b32977ade4249601f35f7eb0cdd56b4e0f89 (diff) |
Merge branch 'dccp' of git://eden-feed.erg.abdn.ac.uk/net-next-2.6
-rw-r--r-- | net/dccp/ccid.h | 6 | ||||
-rw-r--r-- | net/dccp/ccids/ccid2.c | 2 | ||||
-rw-r--r-- | net/dccp/ccids/ccid3.c | 3 | ||||
-rw-r--r-- | net/dccp/dccp.h | 44 | ||||
-rw-r--r-- | net/dccp/input.c | 20 | ||||
-rw-r--r-- | net/dccp/minisocks.c | 30 | ||||
-rw-r--r-- | net/dccp/options.c | 2 | ||||
-rw-r--r-- | net/dccp/output.c | 20 | ||||
-rw-r--r-- | net/dccp/proto.c | 2 |
9 files changed, 66 insertions, 63 deletions
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 6d16a9070ff0..117fb093dcaf 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h | |||
@@ -73,7 +73,7 @@ struct ccid_operations { | |||
73 | int (*ccid_hc_tx_send_packet)(struct sock *sk, | 73 | int (*ccid_hc_tx_send_packet)(struct sock *sk, |
74 | struct sk_buff *skb); | 74 | struct sk_buff *skb); |
75 | void (*ccid_hc_tx_packet_sent)(struct sock *sk, | 75 | void (*ccid_hc_tx_packet_sent)(struct sock *sk, |
76 | int more, unsigned int len); | 76 | unsigned int len); |
77 | void (*ccid_hc_rx_get_info)(struct sock *sk, | 77 | void (*ccid_hc_rx_get_info)(struct sock *sk, |
78 | struct tcp_info *info); | 78 | struct tcp_info *info); |
79 | void (*ccid_hc_tx_get_info)(struct sock *sk, | 79 | void (*ccid_hc_tx_get_info)(struct sock *sk, |
@@ -144,10 +144,10 @@ static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, | |||
144 | } | 144 | } |
145 | 145 | ||
146 | static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, | 146 | static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, |
147 | int more, unsigned int len) | 147 | unsigned int len) |
148 | { | 148 | { |
149 | if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL) | 149 | if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL) |
150 | ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, more, len); | 150 | ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, len); |
151 | } | 151 | } |
152 | 152 | ||
153 | static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk, | 153 | static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk, |
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index dc18172b1e59..d850e291f87c 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
@@ -151,7 +151,7 @@ out: | |||
151 | sock_put(sk); | 151 | sock_put(sk); |
152 | } | 152 | } |
153 | 153 | ||
154 | static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) | 154 | static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len) |
155 | { | 155 | { |
156 | struct dccp_sock *dp = dccp_sk(sk); | 156 | struct dccp_sock *dp = dccp_sk(sk); |
157 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); | 157 | struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index c3f3a25bbd7a..3060a60ed5ab 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -351,8 +351,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) | |||
351 | return 0; | 351 | return 0; |
352 | } | 352 | } |
353 | 353 | ||
354 | static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, | 354 | static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len) |
355 | unsigned int len) | ||
356 | { | 355 | { |
357 | struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); | 356 | struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); |
358 | 357 | ||
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 019d6ffee354..3eb264b60823 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -153,18 +153,27 @@ static inline u64 max48(const u64 seq1, const u64 seq2) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | /** | 155 | /** |
156 | * dccp_loss_free - Evaluates condition for data loss from RFC 4340, 7.7.1 | 156 | * dccp_loss_count - Approximate the number of lost data packets in a burst loss |
157 | * @s1: start sequence number | 157 | * @s1: last known sequence number before the loss ('hole') |
158 | * @s2: end sequence number | 158 | * @s2: first sequence number seen after the 'hole' |
159 | * @ndp: NDP count on packet with sequence number @s2 | 159 | * @ndp: NDP count on packet with sequence number @s2 |
160 | * Returns true if the sequence range s1...s2 has no data loss. | ||
161 | */ | 160 | */ |
162 | static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) | 161 | static inline u64 dccp_loss_count(const u64 s1, const u64 s2, const u64 ndp) |
163 | { | 162 | { |
164 | s64 delta = dccp_delta_seqno(s1, s2); | 163 | s64 delta = dccp_delta_seqno(s1, s2); |
165 | 164 | ||
166 | WARN_ON(delta < 0); | 165 | WARN_ON(delta < 0); |
167 | return (u64)delta <= ndp + 1; | 166 | delta -= ndp + 1; |
167 | |||
168 | return delta > 0 ? delta : 0; | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * dccp_loss_free - Evaluate condition for data loss from RFC 4340, 7.7.1 | ||
173 | */ | ||
174 | static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) | ||
175 | { | ||
176 | return dccp_loss_count(s1, s2, ndp) == 0; | ||
168 | } | 177 | } |
169 | 178 | ||
170 | enum { | 179 | enum { |
@@ -414,6 +423,23 @@ static inline void dccp_update_gsr(struct sock *sk, u64 seq) | |||
414 | dp->dccps_gsr = seq; | 423 | dp->dccps_gsr = seq; |
415 | /* Sequence validity window depends on remote Sequence Window (7.5.1) */ | 424 | /* Sequence validity window depends on remote Sequence Window (7.5.1) */ |
416 | dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4); | 425 | dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4); |
426 | /* | ||
427 | * Adjust SWL so that it is not below ISR. In contrast to RFC 4340, | ||
428 | * 7.5.1 we perform this check beyond the initial handshake: W/W' are | ||
429 | * always > 32, so for the first W/W' packets in the lifetime of a | ||
430 | * connection we always have to adjust SWL. | ||
431 | * A second reason why we are doing this is that the window depends on | ||
432 | * the feature-remote value of Sequence Window: nothing stops the peer | ||
433 | * from updating this value while we are busy adjusting SWL for the | ||
434 | * first W packets (we would have to count from scratch again then). | ||
435 | * Therefore it is safer to always make sure that the Sequence Window | ||
436 | * is not artificially extended by a peer who grows SWL downwards by | ||
437 | * continually updating the feature-remote Sequence-Window. | ||
438 | * If sequence numbers wrap it is bad luck. But that will take a while | ||
439 | * (48 bit), and this measure prevents Sequence-number attacks. | ||
440 | */ | ||
441 | if (before48(dp->dccps_swl, dp->dccps_isr)) | ||
442 | dp->dccps_swl = dp->dccps_isr; | ||
417 | dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4); | 443 | dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4); |
418 | } | 444 | } |
419 | 445 | ||
@@ -424,14 +450,16 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq) | |||
424 | dp->dccps_gss = seq; | 450 | dp->dccps_gss = seq; |
425 | /* Ack validity window depends on local Sequence Window value (7.5.1) */ | 451 | /* Ack validity window depends on local Sequence Window value (7.5.1) */ |
426 | dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win); | 452 | dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win); |
453 | /* Adjust AWL so that it is not below ISS - see comment above for SWL */ | ||
454 | if (before48(dp->dccps_awl, dp->dccps_iss)) | ||
455 | dp->dccps_awl = dp->dccps_iss; | ||
427 | dp->dccps_awh = dp->dccps_gss; | 456 | dp->dccps_awh = dp->dccps_gss; |
428 | } | 457 | } |
429 | 458 | ||
430 | static inline int dccp_ack_pending(const struct sock *sk) | 459 | static inline int dccp_ack_pending(const struct sock *sk) |
431 | { | 460 | { |
432 | const struct dccp_sock *dp = dccp_sk(sk); | 461 | const struct dccp_sock *dp = dccp_sk(sk); |
433 | return dp->dccps_timestamp_echo != 0 || | 462 | return (dp->dccps_hc_rx_ackvec != NULL && |
434 | (dp->dccps_hc_rx_ackvec != NULL && | ||
435 | dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) || | 463 | dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) || |
436 | inet_csk_ack_scheduled(sk); | 464 | inet_csk_ack_scheduled(sk); |
437 | } | 465 | } |
diff --git a/net/dccp/input.c b/net/dccp/input.c index 10c957a88f4f..265985370fa1 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -259,7 +259,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) | |||
259 | sysctl_dccp_sync_ratelimit))) | 259 | sysctl_dccp_sync_ratelimit))) |
260 | return 0; | 260 | return 0; |
261 | 261 | ||
262 | DCCP_WARN("DCCP: Step 6 failed for %s packet, " | 262 | DCCP_WARN("Step 6 failed for %s packet, " |
263 | "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " | 263 | "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " |
264 | "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " | 264 | "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " |
265 | "sending SYNC...\n", dccp_packet_name(dh->dccph_type), | 265 | "sending SYNC...\n", dccp_packet_name(dh->dccph_type), |
@@ -441,20 +441,14 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, | |||
441 | kfree_skb(sk->sk_send_head); | 441 | kfree_skb(sk->sk_send_head); |
442 | sk->sk_send_head = NULL; | 442 | sk->sk_send_head = NULL; |
443 | 443 | ||
444 | dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; | ||
445 | dccp_update_gsr(sk, dp->dccps_isr); | ||
446 | /* | 444 | /* |
447 | * SWL and AWL are initially adjusted so that they are not less than | 445 | * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect |
448 | * the initial Sequence Numbers received and sent, respectively: | 446 | * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH |
449 | * SWL := max(GSR + 1 - floor(W/4), ISR), | 447 | * is done as part of activating the feature values below, since |
450 | * AWL := max(GSS - W' + 1, ISS). | 448 | * these settings depend on the local/remote Sequence Window |
451 | * These adjustments MUST be applied only at the beginning of the | 449 | * features, which were undefined or not confirmed until now. |
452 | * connection. | ||
453 | * | ||
454 | * AWL was adjusted in dccp_v4_connect -acme | ||
455 | */ | 450 | */ |
456 | dccp_set_seqno(&dp->dccps_swl, | 451 | dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; |
457 | max48(dp->dccps_swl, dp->dccps_isr)); | ||
458 | 452 | ||
459 | dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); | 453 | dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); |
460 | 454 | ||
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index 128b089d3aef..d7041a0963af 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c | |||
@@ -121,30 +121,18 @@ struct sock *dccp_create_openreq_child(struct sock *sk, | |||
121 | * | 121 | * |
122 | * Choose S.ISS (initial seqno) or set from Init Cookies | 122 | * Choose S.ISS (initial seqno) or set from Init Cookies |
123 | * Initialize S.GAR := S.ISS | 123 | * Initialize S.GAR := S.ISS |
124 | * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies | 124 | * Set S.ISR, S.GSR from packet (or Init Cookies) |
125 | */ | 125 | * |
126 | newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss; | 126 | * Setting AWL/AWH and SWL/SWH happens as part of the feature |
127 | dccp_update_gss(newsk, dreq->dreq_iss); | 127 | * activation below, as these windows all depend on the local |
128 | 128 | * and remote Sequence Window feature values (7.5.2). | |
129 | newdp->dccps_isr = dreq->dreq_isr; | ||
130 | dccp_update_gsr(newsk, dreq->dreq_isr); | ||
131 | |||
132 | /* | ||
133 | * SWL and AWL are initially adjusted so that they are not less than | ||
134 | * the initial Sequence Numbers received and sent, respectively: | ||
135 | * SWL := max(GSR + 1 - floor(W/4), ISR), | ||
136 | * AWL := max(GSS - W' + 1, ISS). | ||
137 | * These adjustments MUST be applied only at the beginning of the | ||
138 | * connection. | ||
139 | */ | 129 | */ |
140 | dccp_set_seqno(&newdp->dccps_swl, | 130 | newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss; |
141 | max48(newdp->dccps_swl, newdp->dccps_isr)); | 131 | newdp->dccps_gar = newdp->dccps_iss; |
142 | dccp_set_seqno(&newdp->dccps_awl, | 132 | newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr; |
143 | max48(newdp->dccps_awl, newdp->dccps_iss)); | ||
144 | 133 | ||
145 | /* | 134 | /* |
146 | * Activate features after initialising the sequence numbers, | 135 | * Activate features: initialise CCIDs, sequence windows etc. |
147 | * since CCID initialisation may depend on GSS, ISR, ISS etc. | ||
148 | */ | 136 | */ |
149 | if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { | 137 | if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { |
150 | /* It is still raw copy of parent, so invalidate | 138 | /* It is still raw copy of parent, so invalidate |
diff --git a/net/dccp/options.c b/net/dccp/options.c index d4b1ae0daacb..cd3061813009 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -163,6 +163,8 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, | |||
163 | dccp_role(sk), ntohl(opt_val), | 163 | dccp_role(sk), ntohl(opt_val), |
164 | (unsigned long long) | 164 | (unsigned long long) |
165 | DCCP_SKB_CB(skb)->dccpd_ack_seq); | 165 | DCCP_SKB_CB(skb)->dccpd_ack_seq); |
166 | /* schedule an Ack in case this sender is quiescent */ | ||
167 | inet_csk_schedule_ack(sk); | ||
166 | break; | 168 | break; |
167 | case DCCPO_TIMESTAMP_ECHO: | 169 | case DCCPO_TIMESTAMP_ECHO: |
168 | if (len != 4 && len != 6 && len != 8) | 170 | if (len != 4 && len != 6 && len != 8) |
diff --git a/net/dccp/output.c b/net/dccp/output.c index aadbdb58758b..a988fe9ffcba 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c | |||
@@ -304,7 +304,7 @@ void dccp_write_xmit(struct sock *sk, int block) | |||
304 | dcb->dccpd_type = DCCP_PKT_DATA; | 304 | dcb->dccpd_type = DCCP_PKT_DATA; |
305 | 305 | ||
306 | err = dccp_transmit_skb(sk, skb); | 306 | err = dccp_transmit_skb(sk, skb); |
307 | ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len); | 307 | ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); |
308 | if (err) | 308 | if (err) |
309 | DCCP_BUG("err=%d after ccid_hc_tx_packet_sent", | 309 | DCCP_BUG("err=%d after ccid_hc_tx_packet_sent", |
310 | err); | 310 | err); |
@@ -474,8 +474,9 @@ int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code) | |||
474 | /* | 474 | /* |
475 | * Do all connect socket setups that can be done AF independent. | 475 | * Do all connect socket setups that can be done AF independent. |
476 | */ | 476 | */ |
477 | static inline void dccp_connect_init(struct sock *sk) | 477 | int dccp_connect(struct sock *sk) |
478 | { | 478 | { |
479 | struct sk_buff *skb; | ||
479 | struct dccp_sock *dp = dccp_sk(sk); | 480 | struct dccp_sock *dp = dccp_sk(sk); |
480 | struct dst_entry *dst = __sk_dst_get(sk); | 481 | struct dst_entry *dst = __sk_dst_get(sk); |
481 | struct inet_connection_sock *icsk = inet_csk(sk); | 482 | struct inet_connection_sock *icsk = inet_csk(sk); |
@@ -485,22 +486,12 @@ static inline void dccp_connect_init(struct sock *sk) | |||
485 | 486 | ||
486 | dccp_sync_mss(sk, dst_mtu(dst)); | 487 | dccp_sync_mss(sk, dst_mtu(dst)); |
487 | 488 | ||
488 | /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */ | ||
489 | dp->dccps_gar = dp->dccps_iss; | ||
490 | |||
491 | icsk->icsk_retransmits = 0; | ||
492 | } | ||
493 | |||
494 | int dccp_connect(struct sock *sk) | ||
495 | { | ||
496 | struct sk_buff *skb; | ||
497 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
498 | |||
499 | /* do not connect if feature negotiation setup fails */ | 489 | /* do not connect if feature negotiation setup fails */ |
500 | if (dccp_feat_finalise_settings(dccp_sk(sk))) | 490 | if (dccp_feat_finalise_settings(dccp_sk(sk))) |
501 | return -EPROTO; | 491 | return -EPROTO; |
502 | 492 | ||
503 | dccp_connect_init(sk); | 493 | /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */ |
494 | dp->dccps_gar = dp->dccps_iss; | ||
504 | 495 | ||
505 | skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation); | 496 | skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation); |
506 | if (unlikely(skb == NULL)) | 497 | if (unlikely(skb == NULL)) |
@@ -516,6 +507,7 @@ int dccp_connect(struct sock *sk) | |||
516 | DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); | 507 | DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); |
517 | 508 | ||
518 | /* Timer for repeating the REQUEST until an answer. */ | 509 | /* Timer for repeating the REQUEST until an answer. */ |
510 | icsk->icsk_retransmits = 0; | ||
519 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, | 511 | inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, |
520 | icsk->icsk_rto, DCCP_RTO_MAX); | 512 | icsk->icsk_rto, DCCP_RTO_MAX); |
521 | return 0; | 513 | return 0; |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index b054ba1f55d2..7e5fc04eb6d1 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -944,7 +944,7 @@ void dccp_close(struct sock *sk, long timeout) | |||
944 | 944 | ||
945 | if (data_was_unread) { | 945 | if (data_was_unread) { |
946 | /* Unread data was tossed, send an appropriate Reset Code */ | 946 | /* Unread data was tossed, send an appropriate Reset Code */ |
947 | DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread); | 947 | DCCP_WARN("ABORT with %u bytes unread\n", data_was_unread); |
948 | dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED); | 948 | dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED); |
949 | dccp_set_state(sk, DCCP_CLOSED); | 949 | dccp_set_state(sk, DCCP_CLOSED); |
950 | } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { | 950 | } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { |