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_IMPL_H
  17 #define _INET_DCCP_IMPL_H
  18 
  19 #include <sys/int_types.h>
  20 #include <sys/netstack.h>
  21 #include <sys/socket.h>
  22 #include <sys/socket_proto.h>
  23 
  24 #include <netinet/in.h>
  25 #include <netinet/ip6.h>
  26 #include <netinet/dccp.h>
  27 
  28 #include <inet/common.h>
  29 #include <inet/dccp.h>
  30 #include <inet/ip.h>
  31 #include <inet/ip6.h>
  32 #include <inet/optcom.h>
  33 #include <inet/tunables.h>
  34 
  35 #include <inet/dccp_stack.h>
  36 
  37 #ifdef  __cplusplus
  38 extern "C" {
  39 #endif
  40 
  41 #ifdef  _KERNEL
  42 
  43 #define DCCP_MOD_ID             5999 /* XXX */
  44 
  45 extern struct qinit     dccp_sock_winit;
  46 extern struct qinit     dccp_winit;
  47 
  48 extern sock_downcalls_t sock_dccp_downcalls;
  49 
  50 #define DCCP_XMIT_LOWATER       (4 * 1024)
  51 #define DCCP_XMIT_HIWATER       49152
  52 #define DCCP_RECV_LOWATER       (2 * 1024)
  53 #define DCCP_RECV_HIWATER       128000
  54 
  55 #define TIDUSZ  4096    /* transport interface data unit size */
  56 
  57 /*
  58  * Bind hash array size and hash function.
  59  */
  60 #define DCCP_BIND_FANOUT_SIZE           128
  61 #define DCCP_BIND_HASH(lport, size)     ((ntohs((uint16_t)lport)) & (size - 1))
  62 
  63 /*
  64  * Was this tcp created via socket() interface?
  65  */
  66 #define DCCP_IS_SOCKET(dccp)    ((dccp)->dccp_issocket)
  67 
  68 /* Packet types (RFC 4340, Section 5.1.) */
  69 #define DCCP_PKT_REQUEST        0
  70 #define DCCP_PKT_RESPONSE       1
  71 #define DCCP_PKT_DATA           2
  72 #define DCCP_PKT_ACK            3
  73 #define DCCP_PKT_DATAACK        4
  74 #define DCCP_PKT_CLOSEREQ       5
  75 #define DCCP_PKT_CLOSE          6
  76 #define DCCP_PKT_RESET          7
  77 #define DCCP_PKT_SYNC           8
  78 #define DCCP_PKT_SYNCACK        9
  79 
  80 /*
  81  * DCCP options and features.
  82  */
  83 
  84 /*
  85  * Options types (RFC 4340, Section 5.8.)
  86  */
  87 #define DCCP_OPTION_PADDING             0
  88 #define DCCP_OPTION_MANDATORY           1
  89 #define DCCP_OPTION_SLOW_RECEIVER       2
  90 #define DCCP_OPTION_CHANGE_L            32
  91 #define DCCP_OPTION_CONFIRM_L           33
  92 #define DCCP_OPTION_CHANGE_R            34
  93 #define DCCP_OPTION_CONFIRM_R           35
  94 #define DCCP_OPTION_INIT_COOKIE         36
  95 #define DCCP_OPTION_NDP_COUNT           37
  96 #define DCCP_OPTION_ACK_VECTOR_1        38
  97 #define DCCP_OPTION_ACK_VECTOR_2        39
  98 #define DCCP_OPTION_DATA_DROPPED        40
  99 #define DCCP_OPTION_TIMESTAMP           41
 100 #define DCCP_OPTION_TIMESTAMP_ECHO      42
 101 #define DCCP_OPTION_ELAPSED_TIME        43
 102 #define DCCP_OPTION_DATA_CHECKSUM       44
 103 
 104 /*
 105  * Feature types (RFC 4340, Section 6.4.)
 106  */
 107 #define DCCP_FEATURE_CCID                       1
 108 #define DCCP_FEATURE_ALLOW_SHORT_SEQNOS         2
 109 #define DCCP_FEATURE_SEQUENCE_WINDOW            3
 110 #define DCCP_FEATURE_ECN_INCAPABLE              4
 111 #define DCCP_FEATURE_ACK_RATIO                  5
 112 #define DCCP_FEATURE_SEND_ACK_VECTOR            6
 113 #define DCCP_FEATURE_SEND_NDP_COUNT             7
 114 #define DCCP_FEATURE_MIN_CHECKSUM_COVERAGE      8
 115 #define DCCP_FEATURE_CHECK_DATA_CHECKSUM        9
 116 
 117 /*
 118  * Feature negotation states (RFC 4340, Section 6.6.2.)
 119  */
 120 #define DCCP_FEATURE_STATE_CHANGING             0
 121 #define DCCP_FEATURE_STATE_UNSTABLE             1
 122 #define DCCP_FEATURE_STATE_STABLE               2
 123 
 124 /*
 125  * Reset types (RFC 4230, Section 5.6.)
 126  */
 127 #define DCCP_RESET_UNSPECIFIED                  0
 128 #define DCCP_RESET_CLOSED                       1
 129 #define DCCP_RESET_ABORTED                      2
 130 #define DCCP_RESET_NO_CONNECTION                3
 131 #define DCCP_RESET_PACKET_ERROR                 4
 132 #define DCCP_RESET_OPTION_ERROR                 5
 133 #define DCCP_RESET_MANDATORY_ERROR              6
 134 #define DCCP_RESET_CONNECTION_REFUSED           7
 135 #define DCCP_RESET_BAD_SERVICE_CODE             8
 136 #define DCCP_RESET_TOO_BUSY                     9
 137 #define DCCP_RESET_BAD_INIT_COOKIE              10
 138 #define DCCP_RESET_AGGRESSION_PENALTY           11
 139 #define DCCP_RESET_RESERVED                     12
 140 
 141 typedef struct dccp_feature_s {
 142         list_node_t     df_next;
 143         uint8_t         df_option;
 144         uint8_t         df_type;
 145         uint8_t         df_state;
 146         uint64_t        df_value;
 147         boolean_t       df_mandatory;
 148 } dccp_feature_t;
 149 
 150 /* Options in DCCP header */
 151 typedef struct dccp_opt_s {
 152         int             type;
 153         boolean_t       mandatory;
 154 } dccp_opt_t;
 155 
 156 
 157 #define dccps_smallest_nonpriv_port     dccps_propinfo_tbl[0].prop_cur_uval
 158 #define dccps_smallest_anon_port        dccps_propinfo_tbl[1].prop_cur_uval
 159 #define dccps_largest_anon_port         dccps_propinfo_tbl[2].prop_cur_uval
 160 
 161 #define dccps_dbg                       dccps_propinfo_tbl[4].prop_cur_uval
 162 #define dccps_rst_sent_rate_enabled     dccps_propinfo_tbl[5].prop_cur_uval
 163 #define dccps_rst_sent_rate             dccps_propinfo_tbl[6].prop_cur_uval
 164 
 165 /*
 166  * Timers.
 167  */
 168 typedef struct dccp_timer_s {
 169         conn_t  *connp;
 170         void    (*dccpt_proc)(void *);
 171         callout_id_t    dccpt_tid;
 172 } dccp_timer_t;
 173 
 174 extern kmem_cache_t     *dccp_timercache;
 175 
 176 #define DCCP_TIMER(dccp, f, tim)        \
 177         dccp_timeout(dccp->dccp_connp, f, tim)
 178 
 179 #define DCCP_TIMER_CANCEL(dccp, id)     \
 180         dccp_timeout_cancel(dccp->dccp_connp, id)
 181 
 182 #define DCCP_TIMER_RESTART(dccp, intvl) {                       \
 183         if ((dccp)->dccp_timer_tid != 0)                     \
 184                 (void) DCCP_TIMER_CANCEL((dccp), (dccp)->dccp_timer_tid); \
 185         (dccp)->dccp_timer_tid = DCCP_TIMER((dccp), dccp_timer, (intvl)); \
 186 }
 187 
 188 extern struct qinit     dccp_rinitv4, dccp_rinitv6;
 189 
 190 extern optdb_obj_t      dccp_opt_obj;
 191 extern uint_t           dccp_max_optsize;
 192 
 193 extern int              dccp_squeue_flag;
 194 
 195 /*
 196  * Functions in dccp.c
 197  */
 198 extern int      dccp_build_hdrs(dccp_t *);
 199 extern conn_t   *dccp_create_common(cred_t *, boolean_t, boolean_t, int *);
 200 extern void     dccp_close_common(conn_t *, int);
 201 extern int      dccp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
 202                     boolean_t);
 203 extern int      dccp_do_unbind(conn_t *);
 204 extern int      dccp_do_listen(conn_t *, struct sockaddr *, socklen_t, int,
 205                     cred_t *, boolean_t);
 206 extern int      dccp_do_connect(conn_t *, const struct sockaddr *, socklen_t,
 207                     cred_t *, pid_t);
 208 extern void     dccp_init_values(dccp_t *, dccp_t *);
 209 extern void     dccp_free(dccp_t *);
 210 extern void     *dccp_get_conn(void *, dccp_stack_t *);
 211 extern int      dccp_set_destination(dccp_t *dccp);
 212 
 213 /*
 214  * Functions in dccp_bind.c
 215  */
 216 extern void     dccp_bind_hash_insert(dccp_df_t *, dccp_t *, int);
 217 extern void     dccp_bind_hash_remove(dccp_t *);
 218 extern int      dccp_bind_check(conn_t *, struct sockaddr *, socklen_t,
 219                     cred_t *cr, boolean_t);
 220 extern in_port_t dccp_bindi(dccp_t *, in_port_t, const in6_addr_t *, int,
 221                     boolean_t, boolean_t, boolean_t);
 222 extern in_port_t dccp_update_next_port(in_port_t, const dccp_t *, boolean_t);
 223 
 224 /*
 225  * Functions in dccp_features.c
 226  */
 227 extern void     dccp_parse_feature(dccp_t *, uint8_t, uint8_t, uchar_t *,
 228                     boolean_t);
 229 
 230 /*
 231  * Functions in dccp_stats.c
 232  */
 233 extern mblk_t   *dccp_snmp_get(queue_t *, mblk_t *, boolean_t);
 234 extern void     *dccp_kstat_init(netstackid_t);
 235 extern void     dccp_kstat_fini(netstackid_t, kstat_t *);
 236 extern void     *dccp_kstat2_init(netstackid_t);
 237 extern void     dccp_kstat2_fini(netstackid_t, kstat_t *);
 238 
 239 /*
 240  * Functions in dccp_socket.c
 241  */
 242 extern sock_lower_handle_t      dccp_create(int, int, int, sock_downcalls_t **,
 243                                     uint_t *, int *, int, cred_t *);
 244 extern int      dccp_fallback(sock_lower_handle_t, queue_t *, boolean_t,
 245                     so_proto_quiesced_cb_t, sock_quiesce_arg_t *);
 246 extern boolean_t        dccp_newconn_notify(dccp_t *, ip_recv_attr_t *);
 247 
 248 /*
 249  * Functions in dccp_input.c
 250  */
 251 extern void     dccp_icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *);
 252 extern void     dccp_input_data(void *, mblk_t *, void *, ip_recv_attr_t *);
 253 extern void     dccp_rsrv(queue_t *);
 254 extern void     dccp_input_listener_unbound(void *, mblk_t *, void *,
 255                     ip_recv_attr_t *);
 256 extern boolean_t dccp_verifyicmp(conn_t *, void *, icmph_t *, icmp6_t *,
 257                     ip_recv_attr_t *);
 258 
 259 /*
 260  * Functions in dccp_misc.c
 261  */
 262 extern void     dccp_stack_cpu_add(dccp_stack_t *, processorid_t);
 263 
 264 /*
 265  * Functions in dccp_options.c
 266  */
 267 extern int      dccp_parse_options(dccp_t *, dccpha_t *);
 268 extern void     dccp_process_options(dccp_t *, dccpha_t *);
 269 extern int      dccp_generate_options(dccp_t *, void **, size_t *);
 270 
 271 /*
 272  * Functions in dccp_output.c
 273  */
 274 extern void     dccp_wput(queue_t *, mblk_t *);
 275 extern void     dccp_wput_data(dccp_t *, mblk_t *, boolean_t);
 276 extern void     dccp_wput_sock(queue_t *, mblk_t *);
 277 extern void     dccp_wput_fallback(queue_t *, mblk_t *);
 278 extern void     dccp_output(void *, mblk_t *, void *, ip_recv_attr_t *);
 279 extern void     dccp_output_urgent(void *, mblk_t *, void *, ip_recv_attr_t *);
 280 extern void     dccp_close_output(void *, mblk_t *, void *, ip_recv_attr_t *);
 281 extern void     dccp_send_data(dccp_t *, mblk_t *);
 282 extern void     dccp_xmit_listeners_reset(mblk_t *, ip_recv_attr_t *,
 283                     ip_stack_t *, conn_t *);
 284 extern void     dccp_send_synack(void *, mblk_t *, void *, ip_recv_attr_t *);
 285 extern mblk_t   *dccp_xmit_mp(dccp_t *, mblk_t *, int32_t, int32_t *,
 286                     mblk_t **, uint32_t, boolean_t, uint32_t *, boolean_t);
 287 /* XXX following functions should be redone */
 288 extern mblk_t   *dccp_generate_response(conn_t *, mblk_t *);
 289 extern mblk_t   *dccp_generate_request(conn_t *);
 290 extern mblk_t   *dccp_generate_reset(conn_t *);
 291 
 292 /*
 293  * Functions in dccp_opt_data.c
 294  */
 295 extern int      dccp_opt_get(conn_t *, int, int, uchar_t *);
 296 extern int      dccp_opt_set(conn_t *, uint_t, int, int, uint_t, uchar_t *,
 297                     uint_t *, uchar_t *, void *, cred_t *);
 298 
 299 /*
 300  * Functions in dccp_timers.c
 301  */
 302 extern timeout_id_t     dccp_timeout(conn_t *, void (*)(void *), hrtime_t);
 303 extern clock_t  dccp_timeout_cancel(conn_t *, timeout_id_t);
 304 extern mblk_t   *dccp_timermp_alloc(int);
 305 extern void     dccp_timermp_free(dccp_t *);
 306 extern void     dccp_timer(void *);
 307 
 308 /*
 309  * Functions in dccp_tpi.c
 310  */
 311 extern void     dccp_do_capability_ack(dccp_t *, struct T_capability_ack *,
 312                     t_uscalar_t);
 313 extern void     dccp_capability_req(dccp_t *, mblk_t *);
 314 extern void     dccp_err_ack(dccp_t *, mblk_t *, int, int);
 315 extern void     dccp_tpi_connect(dccp_t *, mblk_t *);
 316 extern int      dccp_tpi_close(queue_t *, int);
 317 extern int      dccp_tpi_close_accept(queue_t *);
 318 extern boolean_t        dccp_conn_con(dccp_t *, uchar_t *, mblk_t *, mblk_t **,
 319                             ip_recv_attr_t *);
 320 extern int      dccp_tpi_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
 321 extern int      dccp_tpi_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *,
 322                     uint_t *, uchar_t *, void *, cred_t *);
 323 extern void     dccp_tpi_accept(queue_t *, mblk_t *);
 324 
 325 #endif  /* _KERNEL */
 326 
 327 #ifdef  __cplusplus
 328 }
 329 #endif
 330 
 331 #endif  /* _INET_DCCP_IMPL_H */