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