aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2009-01-16 18:36:31 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-21 17:34:04 -0500
commit792b48780e8b6435d017cef4b5c304876a48653e (patch)
tree6949d6058f4d84f171a339e580ca906d30d67fad
parentf90f92eed74251034f251e3cdf4fa5c4c1f09df0 (diff)
dccp: Implement both feature-local and feature-remote Sequence Window feature
This adds full support for local/remote Sequence Window feature, from which the * sequence-number-validity (W) and * acknowledgment-number-validity (W') windows derive as specified in RFC 4340, 7.5.3. Specifically, the following is contained in this patch: * integrated new socket fields into dccp_sk; * updated the update_gsr/gss routines with regard to these fields; * updated handler code: the Sequence Window feature is located at the TX side, so the local feature is meant if the handler-rx flag is false; * the initialisation of `rcv_wnd' in reqsk is removed, since - rcv_wnd is not used by the code anywhere; - sequence number checks are not done in the LISTEN state (cf. 7.5.3); - dccp_check_req checks the Ack number validity more rigorously; * the `struct dccp_minisock' became empty and is now removed. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/dccp.txt3
-rw-r--r--include/linux/dccp.h24
-rw-r--r--net/dccp/dccp.h16
-rw-r--r--net/dccp/feat.c13
-rw-r--r--net/dccp/minisocks.c11
-rw-r--r--net/dccp/proto.c2
6 files changed, 24 insertions, 45 deletions
diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt
index 7a3bb1abb830..b132e4a3cf0f 100644
--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -141,7 +141,8 @@ rx_ccid = 2
141 Default CCID for the receiver-sender half-connection; see tx_ccid. 141 Default CCID for the receiver-sender half-connection; see tx_ccid.
142 142
143seq_window = 100 143seq_window = 100
144 The initial sequence window (sec. 7.5.2). 144 The initial sequence window (sec. 7.5.2) of the sender. This influences
145 the local ackno validity and the remote seqno validity windows (7.5.1).
145 146
146tx_qlen = 5 147tx_qlen = 5
147 The size of the transmit buffer in packets. A value of 0 corresponds 148 The size of the transmit buffer in packets. A value of 0 corresponds
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 990e97fa1f07..7a0502ab383a 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -364,19 +364,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
364#define DCCPF_INITIAL_SEND_NDP_COUNT 1 364#define DCCPF_INITIAL_SEND_NDP_COUNT 1
365 365
366/** 366/**
367 * struct dccp_minisock - Minimal DCCP connection representation
368 *
369 * Will be used to pass the state from dccp_request_sock to dccp_sock.
370 *
371 * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2)
372 */
373struct dccp_minisock {
374 __u64 dccpms_sequence_window;
375};
376
377extern void dccp_minisock_init(struct dccp_minisock *dmsk);
378
379/**
380 * struct dccp_request_sock - represent DCCP-specific connection request 367 * struct dccp_request_sock - represent DCCP-specific connection request
381 * @dreq_inet_rsk: structure inherited from 368 * @dreq_inet_rsk: structure inherited from
382 * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1) 369 * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1)
@@ -464,13 +451,14 @@ struct dccp_ackvec;
464 * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo 451 * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo
465 * @dccps_l_ack_ratio - feature-local Ack Ratio 452 * @dccps_l_ack_ratio - feature-local Ack Ratio
466 * @dccps_r_ack_ratio - feature-remote Ack Ratio 453 * @dccps_r_ack_ratio - feature-remote Ack Ratio
454 * @dccps_l_seq_win - local Sequence Window (influences ack number validity)
455 * @dccps_r_seq_win - remote Sequence Window (influences seq number validity)
467 * @dccps_pcslen - sender partial checksum coverage (via sockopt) 456 * @dccps_pcslen - sender partial checksum coverage (via sockopt)
468 * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) 457 * @dccps_pcrlen - receiver partial checksum coverage (via sockopt)
469 * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2) 458 * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2)
470 * @dccps_ndp_count - number of Non Data Packets since last data packet 459 * @dccps_ndp_count - number of Non Data Packets since last data packet
471 * @dccps_mss_cache - current value of MSS (path MTU minus header sizes) 460 * @dccps_mss_cache - current value of MSS (path MTU minus header sizes)
472 * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4) 461 * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4)
473 * @dccps_minisock - associated minisock (accessed via dccp_msk)
474 * @dccps_featneg - tracks feature-negotiation state (mostly during handshake) 462 * @dccps_featneg - tracks feature-negotiation state (mostly during handshake)
475 * @dccps_hc_rx_ackvec - rx half connection ack vector 463 * @dccps_hc_rx_ackvec - rx half connection ack vector
476 * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) 464 * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection)
@@ -504,12 +492,13 @@ struct dccp_sock {
504 __u32 dccps_timestamp_time; 492 __u32 dccps_timestamp_time;
505 __u16 dccps_l_ack_ratio; 493 __u16 dccps_l_ack_ratio;
506 __u16 dccps_r_ack_ratio; 494 __u16 dccps_r_ack_ratio;
495 __u64 dccps_l_seq_win:48;
496 __u64 dccps_r_seq_win:48;
507 __u8 dccps_pcslen:4; 497 __u8 dccps_pcslen:4;
508 __u8 dccps_pcrlen:4; 498 __u8 dccps_pcrlen:4;
509 __u8 dccps_send_ndp_count:1; 499 __u8 dccps_send_ndp_count:1;
510 __u64 dccps_ndp_count:48; 500 __u64 dccps_ndp_count:48;
511 unsigned long dccps_rate_last; 501 unsigned long dccps_rate_last;
512 struct dccp_minisock dccps_minisock;
513 struct list_head dccps_featneg; 502 struct list_head dccps_featneg;
514 struct dccp_ackvec *dccps_hc_rx_ackvec; 503 struct dccp_ackvec *dccps_hc_rx_ackvec;
515 struct ccid *dccps_hc_rx_ccid; 504 struct ccid *dccps_hc_rx_ccid;
@@ -527,11 +516,6 @@ static inline struct dccp_sock *dccp_sk(const struct sock *sk)
527 return (struct dccp_sock *)sk; 516 return (struct dccp_sock *)sk;
528} 517}
529 518
530static inline struct dccp_minisock *dccp_msk(const struct sock *sk)
531{
532 return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock;
533}
534
535static inline const char *dccp_role(const struct sock *sk) 519static inline const char *dccp_role(const struct sock *sk)
536{ 520{
537 switch (dccp_sk(sk)->dccps_role) { 521 switch (dccp_sk(sk)->dccps_role) {
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index f2230fc168e1..04ae91898a68 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -409,23 +409,21 @@ static inline void dccp_hdr_set_ack(struct dccp_hdr_ack_bits *dhack,
409static inline void dccp_update_gsr(struct sock *sk, u64 seq) 409static inline void dccp_update_gsr(struct sock *sk, u64 seq)
410{ 410{
411 struct dccp_sock *dp = dccp_sk(sk); 411 struct dccp_sock *dp = dccp_sk(sk);
412 const struct dccp_minisock *dmsk = dccp_msk(sk);
413 412
414 dp->dccps_gsr = seq; 413 dp->dccps_gsr = seq;
415 dccp_set_seqno(&dp->dccps_swl, 414 /* Sequence validity window depends on remote Sequence Window (7.5.1) */
416 dp->dccps_gsr + 1 - (dmsk->dccpms_sequence_window / 4)); 415 dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4);
417 dccp_set_seqno(&dp->dccps_swh, 416 dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4);
418 dp->dccps_gsr + (3 * dmsk->dccpms_sequence_window) / 4);
419} 417}
420 418
421static inline void dccp_update_gss(struct sock *sk, u64 seq) 419static inline void dccp_update_gss(struct sock *sk, u64 seq)
422{ 420{
423 struct dccp_sock *dp = dccp_sk(sk); 421 struct dccp_sock *dp = dccp_sk(sk);
424 422
425 dp->dccps_awh = dp->dccps_gss = seq; 423 dp->dccps_gss = seq;
426 dccp_set_seqno(&dp->dccps_awl, 424 /* Ack validity window depends on local Sequence Window value (7.5.1) */
427 (dp->dccps_gss - 425 dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win);
428 dccp_msk(sk)->dccpms_sequence_window + 1)); 426 dp->dccps_awh = dp->dccps_gss;
429} 427}
430 428
431static inline int dccp_ack_pending(const struct sock *sk) 429static inline int dccp_ack_pending(const struct sock *sk)
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 67ffac9905f8..7303f79705d2 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -51,8 +51,17 @@ static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
51 51
52static int dccp_hdlr_seq_win(struct sock *sk, u64 seq_win, bool rx) 52static int dccp_hdlr_seq_win(struct sock *sk, u64 seq_win, bool rx)
53{ 53{
54 if (!rx) 54 struct dccp_sock *dp = dccp_sk(sk);
55 dccp_msk(sk)->dccpms_sequence_window = seq_win; 55
56 if (rx) {
57 dp->dccps_r_seq_win = seq_win;
58 /* propagate changes to update SWL/SWH */
59 dccp_update_gsr(sk, dp->dccps_gsr);
60 } else {
61 dp->dccps_l_seq_win = seq_win;
62 /* propagate changes to update AWL */
63 dccp_update_gss(sk, dp->dccps_gss);
64 }
56 return 0; 65 return 0;
57} 66}
58 67
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 6821ae33dd37..5ca49cec95f5 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -42,11 +42,6 @@ struct inet_timewait_death_row dccp_death_row = {
42 42
43EXPORT_SYMBOL_GPL(dccp_death_row); 43EXPORT_SYMBOL_GPL(dccp_death_row);
44 44
45void dccp_minisock_init(struct dccp_minisock *dmsk)
46{
47 dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window;
48}
49
50void dccp_time_wait(struct sock *sk, int state, int timeo) 45void dccp_time_wait(struct sock *sk, int state, int timeo)
51{ 46{
52 struct inet_timewait_sock *tw = NULL; 47 struct inet_timewait_sock *tw = NULL;
@@ -110,7 +105,6 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
110 struct dccp_request_sock *dreq = dccp_rsk(req); 105 struct dccp_request_sock *dreq = dccp_rsk(req);
111 struct inet_connection_sock *newicsk = inet_csk(newsk); 106 struct inet_connection_sock *newicsk = inet_csk(newsk);
112 struct dccp_sock *newdp = dccp_sk(newsk); 107 struct dccp_sock *newdp = dccp_sk(newsk);
113 struct dccp_minisock *newdmsk = dccp_msk(newsk);
114 108
115 newdp->dccps_role = DCCP_ROLE_SERVER; 109 newdp->dccps_role = DCCP_ROLE_SERVER;
116 newdp->dccps_hc_rx_ackvec = NULL; 110 newdp->dccps_hc_rx_ackvec = NULL;
@@ -128,10 +122,6 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
128 * Initialize S.GAR := S.ISS 122 * Initialize S.GAR := S.ISS
129 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies 123 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
130 */ 124 */
131
132 /* See dccp_v4_conn_request */
133 newdmsk->dccpms_sequence_window = req->rcv_wnd;
134
135 newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss; 125 newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss;
136 dccp_update_gss(newsk, dreq->dreq_iss); 126 dccp_update_gss(newsk, dreq->dreq_iss);
137 127
@@ -290,7 +280,6 @@ int dccp_reqsk_init(struct request_sock *req,
290 inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport; 280 inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
291 inet_rsk(req)->loc_port = dccp_hdr(skb)->dccph_dport; 281 inet_rsk(req)->loc_port = dccp_hdr(skb)->dccph_dport;
292 inet_rsk(req)->acked = 0; 282 inet_rsk(req)->acked = 0;
293 req->rcv_wnd = sysctl_dccp_feat_sequence_window;
294 dreq->dreq_timestamp_echo = 0; 283 dreq->dreq_timestamp_echo = 0;
295 284
296 /* inherit feature negotiation options from listening socket */ 285 /* inherit feature negotiation options from listening socket */
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 945b4d5d23b3..314a1b5c033c 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -174,8 +174,6 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
174 struct dccp_sock *dp = dccp_sk(sk); 174 struct dccp_sock *dp = dccp_sk(sk);
175 struct inet_connection_sock *icsk = inet_csk(sk); 175 struct inet_connection_sock *icsk = inet_csk(sk);
176 176
177 dccp_minisock_init(&dp->dccps_minisock);
178
179 icsk->icsk_rto = DCCP_TIMEOUT_INIT; 177 icsk->icsk_rto = DCCP_TIMEOUT_INIT;
180 icsk->icsk_syn_retries = sysctl_dccp_request_retries; 178 icsk->icsk_syn_retries = sysctl_dccp_request_retries;
181 sk->sk_state = DCCP_CLOSED; 179 sk->sk_state = DCCP_CLOSED;