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