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