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