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 */