1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2012 David Hoeppner. All rights reserved.
  14  */
  15 
  16 #ifndef _INET_DCCP_H
  17 #define _INET_DCCP_H
  18 
  19 #include <sys/inttypes.h>
  20 #include <sys/socket.h>
  21 #include <sys/socket_proto.h>
  22 
  23 #include <netinet/in.h>
  24 #include <netinet/ip6.h>
  25 #include <netinet/dccp.h>
  26 
  27 #include <inet/common.h>
  28 #include <inet/ip.h>
  29 #include <inet/ip6.h>
  30 #include <inet/tunables.h>
  31 #include <inet/dccp_stack.h>
  32 #include <inet/optcom.h>
  33 
  34 #ifdef  __cplusplus
  35 extern "C" {
  36 #endif
  37 
  38 /*
  39  * DCCP states
  40  */
  41 #define DCCPS_CLOSED            1
  42 #define DCCPS_BOUND             2
  43 #define DCCPS_REQUEST           3
  44 #define DCCPS_LISTEN            4
  45 #define DCCPS_PARTOPEN          5
  46 #define DCCPS_RESPOND           6
  47 #define DCCPS_OPEN              7
  48 #define DCCPS_CLOSING           8
  49 #define DCCPS_CLOSEREQ          9
  50 #define DCCPS_TIMEWAIT          10
  51 
  52 /*
  53  * DCCP header structures.
  54  */
  55 
  56 /* Generic protocol header (RFC 4340, Section 5.1.) */
  57 typedef struct dccphdr_s {
  58         uint8_t         dh_lport[2];
  59         uint8_t         dh_fport[2];
  60         uint8_t         dh_offset;
  61         uint8_t         dh_ccval:4,
  62                         dh_cscov:4;
  63         uint8_t         db_sum[2];
  64         uint8_t         dh_reserved:3,
  65                         dh_type:4,
  66                         dh_x:1;
  67         uint8_t         dh_res_seq;
  68         uint8_t         dh_seq[2];
  69 } dccph_t;
  70 
  71 #define DCCP_HDR_LENGTH(dccph)  \
  72         (((dccph_t *)dccph)->dh_offset * 4) /* XXX >> 2 */
  73 #define DCCP_MAX_HDR_LENGTH             1020
  74 #define DCCP_MIN_HEADER_LENGTH          12
  75 
  76 /* Generic protocol header aligned (RFC 4340, Section 5.1.) */
  77 typedef struct dccphdra_s {
  78         in_port_t       dha_lport;              /* Source port */
  79         in_port_t       dha_fport;              /* Destination port */
  80         uint8_t         dha_offset;             /* Data offset */
  81         uint8_t         dha_cscov:4,            /* Checksum coverage */
  82                         dha_ccval:4;            /* */
  83         uint16_t        dha_sum;                /* Checksum */
  84         uint8_t         dha_x:1,                /* Reserved */
  85                         dha_type:4,             /* Packet type */
  86                         dha_reserved:3;         /* Header type */
  87         uint8_t         dha_res_seq;
  88         uint16_t        dha_seq;                /* Partial sequence number */
  89 } dccpha_t;
  90 
  91 typedef struct dccphdra_ext_s {
  92         uint32_t        dha_ext_seq;
  93 } dccpha_ext_t;
  94 
  95 /* Acknowledgement number */
  96 typedef struct dccphdra_ack {
  97         uint16_t        dha_ack_reserved;
  98         uint16_t        dha_ack_high;
  99         uint32_t        dha_ack_low;
 100 } dccpha_ack_t;
 101 
 102 /* Service number */
 103 typedef struct dccphdra_srv {
 104         uint32_t        dha_srv_code;
 105 } dccpha_srv_t;
 106 
 107 /* Reset data */
 108 typedef struct dccphdra_reset {
 109         uint8_t         dha_reset_code;
 110         uint8_t         dha_reset_data[3];
 111 } dccpha_reset_t;
 112 
 113 /*
 114  * Control structure for each open TCP stream,
 115  * defined only within the kernel or for a kmem user.
 116  * NOTE: tcp_reinit_values MUST have a line for each field in this structure!
 117  */
 118 #if (defined(_KERNEL) || defined(_KMEMUSER))
 119 
 120 /* Internal DCCP structure */
 121 typedef struct dccp_s {
 122 
 123         conn_t          *dccp_connp;    /* Backpointer to conn_t */
 124         dccp_stack_t    *dccp_dccps;    /* Backpointer to dccp_stack_t */
 125 
 126         int32_t         dccp_state;
 127 
 128         uint64_t        dccp_last_rcv_lbolt;
 129 
 130         uint32_t        dccp_ibsegs;    /* Inbound segments on this stream */
 131         uint32_t        dccp_obsegs;    /* Outbound segments on this stream */
 132 
 133         uint32_t
 134                 dccp_hard_binding: 1,
 135                 dccp_loopback: 1,       /* Src and dst are the same machine */
 136                 dccp_localnet: 1,       /* Src and dst are on the same subnet */
 137                 dccp_active_open: 1,    /* This is a active open */
 138                 dccp_detached : 1,      /* If we're detached from a stream */
 139                 dccp_dummy: 1;
 140 
 141         uint32_t
 142                 dccp_tconnind_started: 1,
 143                 dccp_dummy2: 1;
 144 
 145         uint32_t
 146                 dccp_allow_short_seqnos: 1,
 147                 dccp_ecn_incapable: 1;
 148 
 149         /*
 150          * Timers and timestamps.
 151          */
 152         mblk_t          *dccp_timercache;       /* Timer cache */
 153 
 154         timeout_id_t    dccp_timer_tid;         /* Timer service id */
 155         timeout_id_t    dccp_ka_tid;            /* Keepalive timer id */
 156 
 157         clock_t         dccp_timestamp_init;    /* Time reference */
 158         int32_t         dccp_timestamp_echo;    /* Timestamp found in options */
 159         clock_t         dccp_timestamp;
 160 
 161         clock_t         dccp_first_timer_threshold;
 162         clock_t         dccp_second_timer_threshold;
 163         clock_t         dccp_first_ctimer_threshold;
 164         clock_t         dccp_second_ctimer_threshold;
 165 
 166         int32_t         dccp_ka_last_intrvl;    /* Last probe interval */
 167         uint32_t        dccp_ka_interval;       /* Keepalive interval */
 168         uint32_t        dccp_ka_rinterval;      /* Keepalive retransmit */
 169         uint32_t        dccp_ka_abort_thres;    /* Abort threshold */
 170         uint32_t        dccp_ka_cnt;            /* Probes counter */
 171 
 172         int64_t         dccp_last_recv_time;    /* Last segment recv time */
 173 
 174         int             dccp_conn_req_max;      /* # request allowed */
 175 
 176         int32_t         dccp_client_errno;      /* How the client screwed up */
 177 
 178         /*
 179          * Bind related.
 180          */
 181         struct dccp_s   *dccp_bind_hash;        /* Bind hash chain */
 182         struct dccp_s   *dccp_bind_hash_port;   /* Bound to the same port */
 183         struct dccp_s   **dccp_ptpbhn;
 184 
 185         struct dccphdra_s *dccp_dccpha;         /* Template header */
 186 
 187         mblk_t          *dccp_xmit_head;
 188 
 189         /*
 190          * Pointers into the header template.
 191          */
 192         ipha_t          *dccp_ipha;
 193         ip6_t           *dccp_ip6h;
 194 
 195         t_uscalar_t     dccp_acceptor_id;       /* ACCEPTOR_id */
 196 
 197         sock_connid_t   dccp_connid;
 198 
 199         /* Incrementing pending conn req ID */
 200         t_scalar_t      dccp_conn_req_seqnum;
 201 
 202         boolean_t       dccp_issocket;          /* This is a socket dccp */
 203 
 204         /* List of features being negotiated */
 205         list_t          dccp_features;
 206 
 207         struct dccp_s   *dccp_listener;         /* Our listener */
 208         struct dccp_s   *dccp_saved_listener;   /* Saved listener */
 209 
 210         kmutex_t        dccp_eager_lock;
 211 
 212         /*
 213          * Sequence numbers (Section 7.1.)
 214          */
 215         uint64_t        dccp_swl;       /* Sequence number window low */
 216         uint64_t        dccp_swh;       /* Sequence number window high */
 217         uint64_t        dccp_awl;       /* Ack number window low */
 218         uint64_t        dccp_awh;       /* Ack number window high */
 219         uint64_t        dccp_iss;       /* Initial sequence number sent */
 220         uint64_t        dccp_isr;       /* Initial sequence number received */
 221         uint64_t        dccp_osr;       /* First OPEN sequence number */
 222         uint64_t        dccp_gss;       /* Greatest sequence number sent */
 223         uint64_t        dccp_gsr;       /* Greatest sequence */
 224                                         /* number received */
 225         uint64_t        dccp_gar;       /* Greatest acknowledgement */
 226                                         /* number received */
 227 
 228         uint64_t        dccp_sequence_window;
 229 
 230         uint8_t         dccp_reset_code;
 231         uint8_t         dccp_reset_data[3];
 232 } dccp_t;
 233 
 234 typedef struct dccp_df_s {
 235         struct dccp_s   *df_dccp;
 236         kmutex_t        df_lock;
 237         uchar_t         df_pad[TF_CACHEL_PAD - (sizeof (dccp_t *) +
 238                             sizeof (kmutex_t))];
 239 } dccp_df_t;
 240 
 241 #endif  /* _KERNEL */
 242 
 243 #ifdef  __cplusplus
 244 }
 245 #endif
 246 
 247 #endif  /* _INET_DCCP_H */