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