Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[sfrench/cifs-2.6.git] / include / linux / dccp.h
index f3fc4392e93d74a470c94c40813851e5042d3518..aa0737019e37da6e759ea95e026088cbbfc6518d 100644 (file)
@@ -144,6 +144,8 @@ enum dccp_reset_codes {
        DCCP_RESET_CODE_TOO_BUSY,
        DCCP_RESET_CODE_BAD_INIT_COOKIE,
        DCCP_RESET_CODE_AGGRESSION_PENALTY,
+
+       DCCP_MAX_RESET_CODES            /* Leave at the end!  */
 };
 
 /* DCCP options */
@@ -203,6 +205,7 @@ struct dccp_so_feat {
 #define DCCP_SOCKOPT_CHANGE_L          3
 #define DCCP_SOCKOPT_CHANGE_R          4
 #define DCCP_SOCKOPT_GET_CUR_MPS       5
+#define DCCP_SOCKOPT_SERVER_TIMEWAIT   6
 #define DCCP_SOCKOPT_SEND_CSCOV                10
 #define DCCP_SOCKOPT_RECV_CSCOV                11
 #define DCCP_SOCKOPT_CCID_RX_INFO      128
@@ -225,37 +228,50 @@ struct dccp_so_feat {
 #include <net/tcp_states.h>
 
 enum dccp_state {
-       DCCP_OPEN       = TCP_ESTABLISHED,
-       DCCP_REQUESTING = TCP_SYN_SENT,
-       DCCP_PARTOPEN   = TCP_FIN_WAIT1, /* FIXME:
-                                           This mapping is horrible, but TCP has
-                                           no matching state for DCCP_PARTOPEN,
-                                           as TCP_SYN_RECV is already used by
-                                           DCCP_RESPOND, why don't stop using TCP
-                                           mapping of states? OK, now we don't use
-                                           sk_stream_sendmsg anymore, so doesn't
-                                           seem to exist any reason for us to
-                                           do the TCP mapping here */
-       DCCP_LISTEN     = TCP_LISTEN,
-       DCCP_RESPOND    = TCP_SYN_RECV,
-       DCCP_CLOSING    = TCP_CLOSING,
-       DCCP_TIME_WAIT  = TCP_TIME_WAIT,
-       DCCP_CLOSED     = TCP_CLOSE,
-       DCCP_MAX_STATES = TCP_MAX_STATES,
+       DCCP_OPEN            = TCP_ESTABLISHED,
+       DCCP_REQUESTING      = TCP_SYN_SENT,
+       DCCP_LISTEN          = TCP_LISTEN,
+       DCCP_RESPOND         = TCP_SYN_RECV,
+       /*
+        * States involved in closing a DCCP connection:
+        * 1) ACTIVE_CLOSEREQ is entered by a server sending a CloseReq.
+        *
+        * 2) CLOSING can have three different meanings (RFC 4340, 8.3):
+        *  a. Client has performed active-close, has sent a Close to the server
+        *     from state OPEN or PARTOPEN, and is waiting for the final Reset
+        *     (in this case, SOCK_DONE == 1).
+        *  b. Client is asked to perform passive-close, by receiving a CloseReq
+        *     in (PART)OPEN state. It sends a Close and waits for final Reset
+        *     (in this case, SOCK_DONE == 0).
+        *  c. Server performs an active-close as in (a), keeps TIMEWAIT state.
+        *
+        * 3) The following intermediate states are employed to give passively
+        *    closing nodes a chance to process their unread data:
+        *    - PASSIVE_CLOSE    (from OPEN => CLOSED) and
+        *    - PASSIVE_CLOSEREQ (from (PART)OPEN to CLOSING; case (b) above).
+        */
+       DCCP_ACTIVE_CLOSEREQ = TCP_FIN_WAIT1,
+       DCCP_PASSIVE_CLOSE   = TCP_CLOSE_WAIT,  /* any node receiving a Close */
+       DCCP_CLOSING         = TCP_CLOSING,
+       DCCP_TIME_WAIT       = TCP_TIME_WAIT,
+       DCCP_CLOSED          = TCP_CLOSE,
+       DCCP_PARTOPEN        = TCP_MAX_STATES,
+       DCCP_PASSIVE_CLOSEREQ,                  /* clients receiving CloseReq */
+       DCCP_MAX_STATES
 };
 
-#define DCCP_STATE_MASK 0xf
-#define DCCP_ACTION_FIN (1<<7)
+#define DCCP_STATE_MASK 0x1f
 
 enum {
-       DCCPF_OPEN       = TCPF_ESTABLISHED,
-       DCCPF_REQUESTING = TCPF_SYN_SENT,
-       DCCPF_PARTOPEN   = TCPF_FIN_WAIT1,
-       DCCPF_LISTEN     = TCPF_LISTEN,
-       DCCPF_RESPOND    = TCPF_SYN_RECV,
-       DCCPF_CLOSING    = TCPF_CLOSING,
-       DCCPF_TIME_WAIT  = TCPF_TIME_WAIT,
-       DCCPF_CLOSED     = TCPF_CLOSE,
+       DCCPF_OPEN            = TCPF_ESTABLISHED,
+       DCCPF_REQUESTING      = TCPF_SYN_SENT,
+       DCCPF_LISTEN          = TCPF_LISTEN,
+       DCCPF_RESPOND         = TCPF_SYN_RECV,
+       DCCPF_ACTIVE_CLOSEREQ = TCPF_FIN_WAIT1,
+       DCCPF_CLOSING         = TCPF_CLOSING,
+       DCCPF_TIME_WAIT       = TCPF_TIME_WAIT,
+       DCCPF_CLOSED          = TCPF_CLOSE,
+       DCCPF_PARTOPEN        = (1 << DCCP_PARTOPEN),
 };
 
 static inline struct dccp_hdr *dccp_hdr(const struct sk_buff *skb)
@@ -270,10 +286,9 @@ static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen)
        return memset(skb_transport_header(skb), 0, headlen);
 }
 
-static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb)
+static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh)
 {
-       return (struct dccp_hdr_ext *)(skb_transport_header(skb) +
-                                      sizeof(struct dccp_hdr));
+       return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh));
 }
 
 static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh)
@@ -287,13 +302,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
        return __dccp_basic_hdr_len(dh);
 }
 
-static inline __u64 dccp_hdr_seq(const struct sk_buff *skb)
+static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh)
 {
-       const struct dccp_hdr *dh = dccp_hdr(skb);
        __u64 seq_nr =  ntohs(dh->dccph_seq);
 
        if (dh->dccph_x != 0)
-               seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low);
+               seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low);
        else
                seq_nr += (u32)dh->dccph_seq2 << 16;
 
@@ -393,13 +407,23 @@ struct dccp_opt_pend {
 
 extern void dccp_minisock_init(struct dccp_minisock *dmsk);
 
-extern int dccp_parse_options(struct sock *sk, struct sk_buff *skb);
-
+/**
+ * struct dccp_request_sock  -  represent DCCP-specific connection request
+ * @dreq_inet_rsk: structure inherited from
+ * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1)
+ * @dreq_isr: initial sequence number received on the Request
+ * @dreq_service: service code present on the Request (there is just one)
+ * The following two fields are analogous to the ones in dccp_sock:
+ * @dreq_timestamp_echo: last received timestamp to echo (13.1)
+ * @dreq_timestamp_echo: the time of receiving the last @dreq_timestamp_echo
+ */
 struct dccp_request_sock {
        struct inet_request_sock dreq_inet_rsk;
        __u64                    dreq_iss;
        __u64                    dreq_isr;
        __be32                   dreq_service;
+       __u32                    dreq_timestamp_echo;
+       __u32                    dreq_timestamp_time;
 };
 
 static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
@@ -409,6 +433,9 @@ static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
 
 extern struct inet_timewait_death_row dccp_death_row;
 
+extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
+                             struct sk_buff *skb);
+
 struct dccp_options_received {
        u32     dccpor_ndp; /* only 24 bits */
        u32     dccpor_timestamp;
@@ -462,8 +489,8 @@ struct dccp_ackvec;
  * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss
  * @dccps_service - first (passive sock) or unique (active sock) service code
  * @dccps_service_list - second .. last service code on passive socket
- * @dccps_timestamp_time - time of latest TIMESTAMP option
  * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
+ * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo
  * @dccps_l_ack_ratio - feature-local Ack Ratio
  * @dccps_r_ack_ratio - feature-remote Ack Ratio
  * @dccps_pcslen - sender   partial checksum coverage (via sockopt)
@@ -479,6 +506,7 @@ struct dccp_ackvec;
  * @dccps_role - role of this sock, one of %dccp_role
  * @dccps_hc_rx_insert_options - receiver wants to add options when acking
  * @dccps_hc_tx_insert_options - sender wants to add options when sending
+ * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3)
  * @dccps_xmit_timer - timer for when CCID is not ready to send
  * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs)
  */
@@ -497,15 +525,15 @@ struct dccp_sock {
        __u64                           dccps_gsr;
        __u64                           dccps_gar;
        __be32                          dccps_service;
+       __u32                           dccps_mss_cache;
        struct dccp_service_list        *dccps_service_list;
-       ktime_t                         dccps_timestamp_time;
        __u32                           dccps_timestamp_echo;
+       __u32                           dccps_timestamp_time;
        __u16                           dccps_l_ack_ratio;
        __u16                           dccps_r_ack_ratio;
        __u16                           dccps_pcslen;
        __u16                           dccps_pcrlen;
        unsigned long                   dccps_ndp_count;
-       __u32                           dccps_mss_cache;
        unsigned long                   dccps_rate_last;
        struct dccp_minisock            dccps_minisock;
        struct dccp_ackvec              *dccps_hc_rx_ackvec;
@@ -515,6 +543,7 @@ struct dccp_sock {
        enum dccp_role                  dccps_role:2;
        __u8                            dccps_hc_rx_insert_options:1;
        __u8                            dccps_hc_tx_insert_options:1;
+       __u8                            dccps_server_timewait:1;
        struct timer_list               dccps_xmit_timer;
 };