[DCCP]: Implement both feature-local and feature-remote Sequence Window feature

This adds full support for both 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 changes are introduced:
  * integrated new socket fields into dccp_sk;
  * updated the update_gsr/gss routines with regard to these fields, using 
modulo-48 arithmetic;
  * 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
        (i)   rcv_wnd is not used by the code anywhere;
        (ii)  sequence number checks are not done in the LISTEN state (table in 
7.5.3);
        (iii) dccp_check_req already performs more stringent checks on the Ack 
number validity.

Until the handshake completes with activating negotiated values, the 
Sequence-Window default values
(100) are used. As indicated by the comment, I think that this is more than 
enough. Further, it only
applies to the client, since:
  * client's AWL is set in dccp_connect_init(),
  * client's SWL is set in dccp_rcv_request_sent_state_process() (from the ISR 
of the Response),
  * server's AWL/SWL are set when the new child socket is created in 
dccp_create_openreq_child();
    but at this stage dccp_feat_activate_values() has already updated the 
local/remote Sequence
    Window feature of the server, so it is using the latest values,
  * dccp_check_req() (used on reqsk's) does not need AWL/SWL and performs more 
stringent checks.

Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
---
 Documentation/networking/dccp.txt |    3 ++-
 include/linux/dccp.h              |    6 ++++--
 net/dccp/dccp.h                   |   16 +++++++---------
 net/dccp/feat.c                   |   13 +++++++++++++
 net/dccp/minisocks.c              |   12 ++++--------
 5 files changed, 30 insertions(+), 20 deletions(-)

--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -1082,6 +1082,19 @@ int dccp_feat_init(struct sock *sk)
                rc = dccp_feat_register_sp(fn, sp[i].feat_num, sp[i].is_local,
                                        sp[i].mandatory, sp[i].val, sp[i].len);
 
+       /*
+        * Initial values for the remote and local Sequence Window feature. This
+        * is only for the client startup phase, to seed AWL/SWL. Until then,
+        *  - the default of 100 is enough for 75 Request-retransmissions,
+        *  - sequence window checks are not performed in state LISTEN/REQUEST,
+        *  - the only Ack window check is for the Ack completing the handshake.
+        * After the handshake, local/remote Sequence Window will be updated
+        * with the negotiated values (or the defaults again if not different).
+        * The server's AWL/SWL derive directly from the negotiated values.
+        */
+       for (i = 0; rc == 0 && i <= 1; i++)
+               rc = dccp_feat_activate(sk, DCCPF_SEQUENCE_WINDOW, i, NULL);
+
        kfree(sp[0].val);
        kfree(sp[1].val);
        return rc;
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -380,12 +380,10 @@ static inline unsigned int dccp_hdr_len(
   *
   * Will be used to pass the state from dccp_request_sock to dccp_sock.
   *
-  * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2)
   * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2)
   * @dccpms_ack_ratio - Ack Ratio Feature (section 11.3)
   */
 struct dccp_minisock {
-       __u64                   dccpms_sequence_window;
        __u8                    dccpms_send_ndp_count;
        __u8                    dccpms_ack_ratio;
 };
@@ -486,6 +484,8 @@ struct dccp_ackvec;
  * @dccps_tstamp - most recently received timestamp to echo (RFC 4340, 13.1)
  * @dccps_l_ack_ratio - feature-local Ack Ratio
  * @dccps_r_ack_ratio - feature-remote Ack Ratio
+ * @dccps_l_seq_win - local Sequence Window (influences ack number validity)
+ * @dccps_r_seq_win - remote Sequence Window (influences seq number validity)
  * @dccps_pcslen - sender   partial checksum coverage (via sockopt)
  * @dccps_pcrlen - receiver partial checksum coverage (via sockopt)
  * @dccps_ndp_count - number of Non Data Packets since last data packet
@@ -523,6 +523,8 @@ struct dccp_sock {
        struct dccp_ts_echo             *dccps_tstamp;
        __u16                           dccps_l_ack_ratio;
        __u16                           dccps_r_ack_ratio;
+       __u64                           dccps_l_seq_win:48;
+       __u64                           dccps_r_seq_win:48;
        __u8                            dccps_pcslen:4;
        __u8                            dccps_pcrlen:4;
        unsigned long                   dccps_ndp_count;
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -390,23 +390,21 @@ static inline void dccp_hdr_set_ack(stru
 static inline void dccp_update_gsr(struct sock *sk, u64 seq)
 {
        struct dccp_sock *dp = dccp_sk(sk);
-       const struct dccp_minisock *dmsk = dccp_msk(sk);
 
        dp->dccps_gsr = seq;
-       dccp_set_seqno(&dp->dccps_swl,
-                      dp->dccps_gsr + 1 - (dmsk->dccpms_sequence_window / 4));
-       dccp_set_seqno(&dp->dccps_swh,
-                      dp->dccps_gsr + (3 * dmsk->dccpms_sequence_window) / 4);
+       /* Sequence validity window depends on remote Sequence Window (7.5.1) */
+       dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4);
+       dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4);
 }
 
 static inline void dccp_update_gss(struct sock *sk, u64 seq)
 {
        struct dccp_sock *dp = dccp_sk(sk);
 
-       dp->dccps_awh = dp->dccps_gss = seq;
-       dccp_set_seqno(&dp->dccps_awl,
-                      (dp->dccps_gss -
-                       dccp_msk(sk)->dccpms_sequence_window + 1));
+       dp->dccps_gss = seq;
+       /* Ack validity window depends on local Sequence Window value (7.5.1) */
+       dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win);
+       dp->dccps_awh = dp->dccps_gss;
 }
 
 static inline int dccp_ack_pending(const struct sock *sk)
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -44,7 +44,6 @@ EXPORT_SYMBOL_GPL(dccp_death_row);
 
 void dccp_minisock_init(struct dccp_minisock *dmsk)
 {
-       dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window;
        dmsk->dccpms_ack_ratio       = sysctl_dccp_feat_ack_ratio;
 }
 
@@ -111,7 +110,6 @@ struct sock *dccp_create_openreq_child(s
                struct dccp_request_sock *dreq = dccp_rsk(req);
                struct inet_connection_sock *newicsk = inet_csk(newsk);
                struct dccp_sock *newdp = dccp_sk(newsk);
-               struct dccp_minisock *newdmsk = dccp_msk(newsk);
 
                newdp->dccps_role          = DCCP_ROLE_SERVER;
                newdp->dccps_hc_rx_ackvec  = NULL;
@@ -129,9 +127,6 @@ struct sock *dccp_create_openreq_child(s
                 *    Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
                 */
 
-               /* See dccp_v4_conn_request */
-               newdmsk->dccpms_sequence_window = req->rcv_wnd;
-
                newdp->dccps_gar = newdp->dccps_isr = dreq->dreq_isr;
                dccp_update_gsr(newsk, dreq->dreq_isr);
 
@@ -289,7 +284,6 @@ int dccp_reqsk_init(struct request_sock 
 
        inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
        inet_rsk(req)->acked    = 0;
-       req->rcv_wnd            = sysctl_dccp_feat_sequence_window;
        dreq->dreq_tstamp       = NULL;
 
        /* inherit feature negotiation options from listening socket */
@@ -325,8 +319,10 @@ int dccp_hdlr_ccid(struct sock *sk, u64 
 
 int dccp_hdlr_seq_win(struct sock *sk, u64 seq_win, bool rx)
 {
-       if (!rx)
-               dccp_msk(sk)->dccpms_sequence_window = seq_win;
+       if (rx)
+               dccp_sk(sk)->dccps_r_seq_win = seq_win;
+       else
+               dccp_sk(sk)->dccps_l_seq_win = seq_win;
        return 0;
 }
 
--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -147,7 +147,8 @@ ack_ratio = 2
        The default Ack Ratio (sec. 11.3) to use.
 
 seq_window = 100
-       The initial sequence window (sec. 7.5.2).
+       The initial sequence window (sec. 7.5.2) of the sender. This influences
+       the local ackno validity and the remote seqno validity windows (7.5.1).
 
 tx_qlen = 5
        The size of the transmit buffer in packets. A value of 0 corresponds
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to