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/ip.h> 30 #include <inet/ip6.h> 31 #include <inet/optcom.h> 32 #include <inet/tunables.h> 33 34 #include "dccp_stack.h" 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #ifdef _KERNEL 41 42 #define DCCP_MOD_ID 5999 /* XXX */ 43 44 extern struct qinit dccp_sock_winit; 45 extern struct qinit dccp_winit; 46 47 extern sock_downcalls_t sock_dccp_downcalls; 48 49 #define DCCP_XMIT_LOWATER (4 * 1024) 50 #define DCCP_XMIT_HIWATER 49152 51 #define DCCP_RECV_LOWATER (2 * 1024) 52 #define DCCP_RECV_HIWATER 128000 53 54 #define TIDUSZ 4096 /* transport interface data unit size */ 55 56 /* 57 * Bind hash array size and hash function. 58 */ 59 #define DCCP_BIND_FANOUT_SIZE 128 60 #define DCCP_BIND_HASH(lport, size) ((ntohs((uint16_t)lport)) & (size - 1)) 61 62 /* 63 * Was this tcp created via socket() interface? 64 */ 65 #define DCCP_IS_SOCKET(dccp) ((dccp)->dccp_issocket) 66 67 #define DCCP_HDR_LENGTH(dccph) (((dccph_t *)dccph)->dh_offset * 4) /* XXX >> 2 */ 68 #define DCCP_MAX_HDR_LENGTH 1020 69 #define DCCP_MIN_HEADER_LENGTH 12 70 71 /* Packet types (RFC 4340, Section 5.1.) */ 72 #define DCCP_PKT_REQUEST 0 73 #define DCCP_PKT_RESPONSE 1 74 #define DCCP_PKT_DATA 2 75 #define DCCP_PKT_ACK 3 76 #define DCCP_PKT_DATAACK 4 77 #define DCCP_PKT_CLOSEREQ 5 78 #define DCCP_PKT_CLOSE 6 79 #define DCCP_PKT_RESET 7 80 #define DCCP_PKT_SYNC 8 81 #define DCCP_PKT_SYNCACK 9 82 83 /* 84 * DCCP options and features. 85 */ 86 87 /* Options types (RFC 4340, Section 5.8.) */ 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 /* Feature types (RFC 4340, Section 6.4.) */ 106 #define DCCP_FEATURE_CCID 1 107 #define DCCP_FEATURE_ALLOW_SHORT_SEQNOS 2 108 #define DCCP_FEATURE_SEQUENCE_WINDOW 3 109 #define DCCP_FEATURE_ECN_INCAPABLE 4 110 #define DCCP_FEATURE_ACK_RATIO 5 111 #define DCCP_FEATURE_SEND_ACK_VECTOR 6 112 #define DCCP_FEATURE_SEND_NDP_COUNT 7 113 #define DCCP_FEATURE_MIN_CHECKSUM_COVERAGE 8 114 #define DCCP_FEATURE_CHECK_DATA_CHECKSUM 9 115 116 /* Feature negotation states (RFC 4340, Section 6.6.2.) */ 117 #define DCCP_FEATURE_STATE_CHANGING 0 118 #define DCCP_FEATURE_STATE_UNSTABLE 1 119 #define DCCP_FEATURE_STATE_STABLE 2 120 121 typedef struct dccp_feature_s { 122 list_node_t df_next; 123 uint8_t df_option; 124 uint8_t df_type; 125 uint8_t df_state; 126 uint64_t df_value; 127 boolean_t df_mandatory; 128 } dccp_feature_t; 129 130 /* Options in DCCP header */ 131 typedef struct dccp_opt_s { 132 int type; 133 boolean_t mandatory; 134 } dccp_opt_t; 135 136 /* 137 * DCCP header structures. 138 */ 139 140 /* Generic protocol header (RFC 4340, Section 5.1.) */ 141 typedef struct dccphdr_s { 142 uint8_t dh_lport[2]; 143 uint8_t dh_fport[2]; 144 uint8_t dh_offset; 145 uint8_t dh_ccval:4, 146 dh_cscov:4; 147 uint8_t db_sum[2]; 148 uint8_t dh_reserved:3, 149 dh_type:4, 150 dh_x:1; 151 uint8_t dh_res_seq; 152 uint8_t dh_seq[2]; 153 } dccph_t; 154 155 156 /* Generic protocol header aligned (RFC 4340, Section 5.1.) */ 157 typedef struct dccphdra_s { 158 in_port_t dha_lport; /* Source port */ 159 in_port_t dha_fport; /* Destination port */ 160 uint8_t dha_offset; /* Data offset */ 161 uint8_t dha_ccval:4, /* */ 162 dha_cscov:4; /* */ 163 uint16_t dha_sum; /* Checksum */ 164 uint8_t dha_x:1, /* Reserved */ 165 dha_type:4, /* Packet type */ 166 dha_reserved:3; /* Header type */ 167 uint8_t dha_res_seq; 168 uint16_t dha_seq; /* Partial sequence number */ 169 } dccpha_t; 170 171 typedef struct dccphdra_ext_s { 172 uint32_t dha_ext_seq; 173 } dccpha_ext_t; 174 175 /* Acknowledgement number */ 176 typedef struct dccphdra_ack { 177 uint16_t dha_ack_reserved; 178 uint16_t dha_ack_high; 179 uint32_t dha_ack_low; 180 } dccpha_ack_t; 181 182 /* Service number */ 183 typedef struct dccphdra_srv { 184 uint32_t dha_srv_code; 185 } dccpha_srv_t; 186 187 /* Reset data */ 188 typedef struct dccphdra_reset { 189 uint8_t dha_reset_code; 190 uint8_t dha_reset_data[3]; 191 } dccpha_reset_t; 192 193 /* Internal DCCP structure */ 194 typedef struct dccp_s { 195 196 conn_t *dccp_connp; /* Backpointer to conn_t */ 197 dccp_stack_t *dccp_dccps; /* Backpointer to dccp_stack_t */ 198 199 int32_t dccp_state; 200 201 uint32_t 202 dccp_loopback: 1, /* Src and dst are the same machine */ 203 dccp_localnet: 1, /* Src and dst are on the same subnet */ 204 dccp_active_open: 1, /* This is a active open */ 205 dccp_dummy: 1; 206 207 /* Bind related */ 208 struct dccp_s *dccp_bind_hash; /* Bind hash chain */ 209 struct dccp_s *dccp_bind_hash_port; /* Bound to the same port */ 210 struct dccp_s **dccp_ptpbhn; 211 212 struct dccphdra_s *dccp_dccpha; /* Template header */ 213 214 mblk_t *dccp_xmit_head; 215 216 /* 217 * Pointers into the header template. 218 */ 219 ipha_t *dccp_ipha; 220 ip6_t *dccp_ip6h; 221 222 t_uscalar_t dccp_acceptor_id; /* ACCEPTOR_id */ 223 224 sock_connid_t dccp_connid; 225 226 /* Incrementing pending conn req ID */ 227 t_scalar_t dccp_conn_req_seqnum; 228 229 boolean_t dccp_issocket; /* This is a socket dccp */ 230 231 /* List of features being negotiated */ 232 list_t dccp_features; 233 234 /* 235 *Sequence numbers (Section 7.1.) 236 */ 237 uint64_t dccp_iss; /* Initial sequence number sent */ 238 uint64_t dccp_isr; /* Initial sequence number received */ 239 uint64_t dccp_gss; /* Greatest sequence number sent */ 240 uint64_t dccp_gsr; /* Greatest sequence */ 241 /* number received */ 242 uint64_t dccp_gar; /* Greatest acknowledgement */ 243 /* number received */ 244 } dccp_t; 245 246 #define dccps_smallest_nonpriv_port dccps_propinfo_tbl[0].prop_cur_uval 247 #define dccps_smallest_anon_port dccps_propinfo_tbl[1].prop_cur_uval 248 #define dccps_largest_anon_port dccps_propinfo_tbl[2].prop_cur_uval 249 250 #define dccps_dbg dccps_propinfo_tbl[4].prop_cur_uval 251 #define dccps_rst_sent_rate_enabled dccps_propinfo_tbl[5].prop_cur_uval 252 #define dccps_rst_sent_rate dccps_propinfo_tbl[6].prop_cur_uval 253 254 typedef struct dccp_df_s { 255 struct dccp_s *df_dccp; 256 kmutex_t df_lock; 257 uchar_t df_pad[TF_CACHEL_PAD - (sizeof (dccp_t *) + 258 sizeof (kmutex_t))]; 259 } dccp_df_t; 260 261 extern struct qinit dccp_rinitv4, dccp_rinitv6; 262 263 extern optdb_obj_t dccp_opt_obj; 264 extern uint_t dccp_max_optsize; 265 266 extern int dccp_squeue_flag; 267 268 /* 269 * Functions in dccp.c 270 */ 271 extern int dccp_build_hdrs(dccp_t *); 272 extern conn_t *dccp_create_common(cred_t *, boolean_t, boolean_t, int *); 273 extern void dccp_close_common(conn_t *, int); 274 extern int dccp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *, 275 boolean_t); 276 extern int dccp_do_unbind(conn_t *); 277 extern int dccp_do_listen(conn_t *, struct sockaddr *, socklen_t, int, 278 cred_t *, boolean_t); 279 extern int dccp_do_connect(conn_t *, const struct sockaddr *, socklen_t, 280 cred_t *, pid_t); 281 extern void dccp_init_values(dccp_t *, dccp_t *); 282 extern void *dccp_get_conn(void *, dccp_stack_t *); 283 extern int dccp_set_destination(dccp_t *dccp); 284 285 /* 286 * Functions in dccp_bind.c 287 */ 288 extern void dccp_bind_hash_insert(dccp_df_t *, dccp_t *, int); 289 extern void dccp_bind_hash_remove(dccp_t *); 290 extern int dccp_bind_check(conn_t *, struct sockaddr *, socklen_t, cred_t *cr, 291 boolean_t); 292 extern in_port_t dccp_bindi(dccp_t *, in_port_t, const in6_addr_t *, int, 293 boolean_t, boolean_t, boolean_t); 294 extern in_port_t dccp_update_next_port(in_port_t, const dccp_t *, boolean_t); 295 296 /* 297 * Functions in dccp_features.c 298 */ 299 extern void dccp_process_options(dccp_t *, dccpha_t *); 300 extern int dccp_generate_options(dccp_t *, void **, size_t *); 301 302 /* 303 * Functions in dccp_stats.c 304 */ 305 extern mblk_t *dccp_snmp_get(queue_t *, mblk_t *, boolean_t); 306 extern void *dccp_kstat_init(netstackid_t); 307 extern void dccp_kstat_fini(netstackid_t, kstat_t *); 308 309 /* 310 * Functions in dccp_socket.c 311 */ 312 extern sock_lower_handle_t dccp_create(int, int, int, sock_downcalls_t **, 313 uint_t *, int *, int, cred_t *); 314 extern int dccp_fallback(sock_lower_handle_t, queue_t *, boolean_t, 315 so_proto_quiesced_cb_t, sock_quiesce_arg_t *); 316 317 /* 318 * Functions in dccp_input.c 319 */ 320 extern void dccp_icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *); 321 extern void dccp_input_data(void *, mblk_t *, void *, ip_recv_attr_t *); 322 extern void dccp_rsrv(queue_t *); 323 extern void dccp_input_listener_unbound(void *, mblk_t *, void *, 324 ip_recv_attr_t *); 325 extern boolean_t dccp_verifyicmp(conn_t *, void *, icmph_t *, icmp6_t *, 326 ip_recv_attr_t *); 327 328 /* 329 * Functions in dccp_misc.c 330 */ 331 extern void dccp_stack_cpu_add(dccp_stack_t *, processorid_t); 332 333 /* 334 * Functions in dccp_output.c 335 */ 336 extern void dccp_wput(queue_t *, mblk_t *); 337 extern void dccp_wput_sock(queue_t *, mblk_t *); 338 extern void dccp_wput_fallback(queue_t *, mblk_t *); 339 extern void dccp_output_urgent(void *, mblk_t *, void *, ip_recv_attr_t *); 340 extern void dccp_output(void *, mblk_t *, void *, ip_recv_attr_t *); 341 extern void dccp_send_data(dccp_t *, mblk_t *); 342 extern void dccp_xmit_listeners_reset(mblk_t *, ip_recv_attr_t *, 343 ip_stack_t *, conn_t *); 344 extern void dccp_send_synack(void *, mblk_t *, void *, ip_recv_attr_t *); 345 extern mblk_t *dccp_xmit_mp(dccp_t *, mblk_t *, int32_t, int32_t *, 346 mblk_t **, uint32_t, boolean_t, uint32_t *, boolean_t); 347 /* XXX following functions should be redone */ 348 extern mblk_t *dccp_generate_packet(conn_t *, mblk_t *); 349 extern mblk_t *dccp_generate_request(conn_t *); 350 351 /* 352 * Functions in dccp_opt_data.c 353 */ 354 extern int dccp_opt_get(conn_t *, int, int, uchar_t *); 355 extern int dccp_opt_set(conn_t *, uint_t, int, int, uint_t, uchar_t *, 356 uint_t *, uchar_t *, void *, cred_t *); 357 358 /* 359 * Functions in dccp_tpi.c 360 */ 361 extern void dccp_do_capability_ack(dccp_t *, struct T_capability_ack *, 362 t_uscalar_t); 363 extern void dccp_capability_req(dccp_t *, mblk_t *); 364 extern void dccp_err_ack(dccp_t *, mblk_t *, int, int); 365 extern void dccp_tpi_connect(dccp_t *, mblk_t *); 366 extern int dccp_tpi_close(queue_t *, int); 367 extern int dccp_tpi_close_accept(queue_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 */