Print this page
dccp: getting kernel segfaults, back out recent added features
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/inet/dccp/dccp_options.c
+++ new/usr/src/uts/common/inet/dccp/dccp_options.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
10 10 */
11 11
12 12 /*
13 13 * Copyright 2012 David Hoeppner. All rights reserved.
14 14 */
15 15
16 16 #include <sys/types.h>
17 17 #include <sys/stream.h>
18 18 #include <sys/debug.h>
19 19 #include <sys/cmn_err.h>
20 +
20 21 #include <inet/dccp_impl.h>
21 22 #include <inet/dccp_stack.h>
22 23
23 24 /*
24 25 * This file contains functions to parse and process DCCP options.
25 26 */
26 27
27 28
28 29 /*
29 30 * Parse the options in a DCCP header.
30 31 */
31 32 int
32 33 dccp_parse_options(dccp_t *dccp, dccpha_t *dccpha)
33 34 {
34 35 uchar_t *end;
35 36 uchar_t *up;
36 37 uint8_t dccp_type;
37 38 uint32_t option_value;
38 39 uint8_t option_type;
39 40 uint8_t option_length;
40 41 int len;
41 42 int i;
42 43 uchar_t *value;
43 44 boolean_t mandatory = B_FALSE;
44 45 int error;
45 46
46 47 cmn_err(CE_NOTE, "dccp_features.c: dccp_parse_options");
47 48
48 49 dccp_type = dccpha->dha_type;
49 50
50 51 up = (uchar_t *)dccpha;
51 52 end = up + DCCP_HDR_LENGTH(dccpha);
52 53 up += 20;
53 54
54 55 while (up != end) {
55 56 option_length = 0;
56 57 option_type = *up++;
57 58
58 59 if (option_type > 31) {
59 60 if (up == end) {
60 61 goto length_error;
61 62 }
62 63
63 64 option_length = *up++;
64 65 if (option_length < 2) {
65 66 goto length_error;
66 67 }
67 68
68 69 option_length -= 2;
69 70 value = up;
70 71
71 72 up += option_length;
72 73
73 74 /* Ignore options with greater length then header */
74 75 if (up > end) {
75 76 goto length_error;
76 77 }
77 78 }
78 79
79 80 switch (option_type) {
80 81 case DCCP_OPTION_PADDING:
81 82 cmn_err(CE_NOTE, "PADDING");
82 83 break;
83 84 case DCCP_OPTION_MANDATORY:
84 85 cmn_err(CE_NOTE, "MANDATORY");
85 86 if (mandatory)
86 87 goto option_error;
87 88
88 89 if (dccp_type != DCCP_PKT_DATA)
89 90 mandatory = B_TRUE;
90 91 break;
91 92 case DCCP_OPTION_SLOW_RECEIVER:
92 93 cmn_err(CE_NOTE, "SLOW RECEIVER");
93 94 break;
94 95 case DCCP_OPTION_CHANGE_L:
95 96 case DCCP_OPTION_CONFIRM_L:
96 97 case DCCP_OPTION_CHANGE_R:
97 98 case DCCP_OPTION_CONFIRM_R:
98 99 if (dccp_type == DCCP_PKT_DATA)
99 100 break;
100 101
101 102 if (option_length == 0)
102 103 goto option_error;
103 104
104 105 dccp_parse_feature(dccp, option_type, option_length,
105 106 value, mandatory);
106 107 break;
107 108 case DCCP_OPTION_INIT_COOKIE:
108 109 cmn_err(CE_NOTE, "INIT COOKIE");
109 110 break;
110 111 case DCCP_OPTION_NDP_COUNT:
111 112 cmn_err(CE_NOTE, "NDP COUNT");
112 113 if (option_length > 6)
113 114 goto option_error;
114 115 break;
115 116 case DCCP_OPTION_ACK_VECTOR_1:
116 117 cmn_err(CE_NOTE, "ACK VECTOR 1");
117 118 break;
118 119 case DCCP_OPTION_ACK_VECTOR_2:
119 120 cmn_err(CE_NOTE, "ACK VECTOR 2");
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
120 121 break;
121 122 case DCCP_OPTION_DATA_DROPPED:
122 123 cmn_err(CE_NOTE, "DATA DROPPED");
123 124 break;
124 125 case DCCP_OPTION_TIMESTAMP:
125 126 cmn_err(CE_NOTE, "TIMESTAMP");
126 127 if (option_length != 4)
127 128 goto option_error;
128 129
129 130 /* XXX read unaligned big endian */
130 - option_value = ((uint8_t)value[0] << 31);
131 + option_value = ((uint8_t)value[0] << 24);
132 + option_value += ((uint8_t)value[1] << 16);
133 + option_value += ((uint8_t)value[2] << 8);
134 + option_value += (uint8_t)value[3];
131 135 if (option_value) {
132 136 cmn_err(CE_NOTE, "Zero timestamp");
133 137 break;
134 138 }
135 139
136 140 dccp->dccp_timestamp_echo = ntohs(option_value);
137 - dccp->dccp_timestamp = gethrtime();
141 + dccp->dccp_timestamp = TICK_TO_MSEC(LBOLT_FASTPATH);
138 142 break;
139 143 case DCCP_OPTION_TIMESTAMP_ECHO:
140 144 cmn_err(CE_NOTE, "TIMESTAMP ECHO");
141 145 if (option_length != 4 &&
142 146 option_length != 6 &&
143 147 option_length != 8) {
144 148 goto option_error;
145 149 }
146 150
147 151 break;
148 152 case DCCP_OPTION_ELAPSED_TIME:
149 153 cmn_err(CE_NOTE, "ELAPSES TIME");
150 154 switch (option_length) {
151 155 case 2:
152 156 break;
153 157 case 4:
154 158 break;
155 159 default:
156 160 goto option_error;
157 161 }
158 162 break;
159 163 case DCCP_OPTION_DATA_CHECKSUM:
160 164 cmn_err(CE_NOTE, "DATA CHECKSUM");
161 165 break;
162 166
163 167 default:
164 168 cmn_err(CE_NOTE, "DEFAULT");
165 169 break;
166 170 }
167 171
168 172 if (option_type != DCCP_OPTION_MANDATORY) {
169 173 mandatory = B_FALSE;
170 174 }
171 175 }
172 176
173 177 if (mandatory)
174 178 goto option_error;
175 179
176 180 length_error:
177 181 return (0);
178 182
179 183 option_error:
180 184 error = DCCP_RESET_OPTION_ERROR;
181 185
182 186 cmn_err(CE_NOTE, "setting error code");
183 187
184 188 dccp->dccp_reset_code = error;
185 189 dccp->dccp_reset_data[0] = option_type;
186 190 dccp->dccp_reset_data[1] = option_length > 0 ? value[0] : 0;
187 191 dccp->dccp_reset_data[2] = option_length > 1 ? value[1] : 0;
188 192
189 193 return (-1);
190 194 }
191 195
192 196 void
193 197 dccp_process_options(dccp_t *dccp, dccpha_t *dccpha)
194 198 {
195 199 cmn_err(CE_NOTE, "dccp_features.c: dccp_process_features");
196 200
197 201 dccp_parse_options(dccp, dccpha);
198 202 }
199 203
200 204 int
201 205 dccp_generate_options(dccp_t *dccp, void **opt, size_t *opt_len)
202 206 {
203 207 dccp_feature_t *feature = NULL;
204 208 uint8_t buf[1024]; /* XXX */
205 209 uint8_t option_type;
206 210 uint_t len = 0;
207 211 uint_t total_len;
208 212 void *options;
209 213 int rest;
210 214
211 215 cmn_err(CE_NOTE, "dccp_features.c: dccp_generate_options");
212 216
213 217 for (feature = list_head(&dccp->dccp_features); feature;
214 218 feature = list_next(&dccp->dccp_features, feature)) {
215 219 if (feature->df_option == DCCP_OPTION_CHANGE_L) {
216 220 option_type = DCCP_OPTION_CONFIRM_R;
217 221 } else {
218 222 option_type = DCCP_OPTION_CONFIRM_L;
219 223 }
220 224 /*
221 225 if (feature->df_mandatory == B_TRUE) {
222 226 buf[len] = DCCP_OPTION_MANDATORY;
223 227 len++;
224 228 }
225 229 */
226 230 if (feature->df_type == DCCP_FEATURE_CCID) {
227 231 cmn_err(CE_NOTE, "FOUND DCCP_FEATURE_CCID");
228 232
229 233 buf[len] = option_type;
230 234 len++;
231 235 buf[len] = 4;
232 236 len++;
233 237 buf[len] = DCCP_FEATURE_CCID;
234 238 len++;
235 239 buf[len] = 2;
236 240 len++;
237 241 }
238 242
239 243 if (feature->df_type == DCCP_FEATURE_ALLOW_SHORT_SEQNOS) {
240 244 buf[len] = option_type;
241 245 len++;
242 246 buf[len] = 4;
243 247 len++;
244 248 buf[len] = feature->df_type;
245 249 len++;
246 250 buf[len] = 0;
247 251 len++;
248 252 }
249 253
250 254 if (feature->df_type == DCCP_FEATURE_ECN_INCAPABLE) {
251 255 buf[len] = option_type;
252 256 len++;
253 257 buf[len] = 4;
254 258 len++;
↓ open down ↓ |
107 lines elided |
↑ open up ↑ |
255 259 buf[len] = feature->df_type;
256 260 len++;
257 261 buf[len] = 1;
258 262 len++;
259 263 }
260 264 }
261 265
262 266 if (dccp->dccp_timestamp_echo != 0) {
263 267 uint32_t elapsed;
264 268 int elapsed_length;
269 + clock_t now;
265 270
266 271 buf[len] = DCCP_OPTION_TIMESTAMP_ECHO;
267 272 len++;
273 + buf[len] = 10;
274 + len++;
275 +
276 + now = TICK_TO_MSEC(LBOLT_FASTPATH);
277 + elapsed = now - dccp->dccp_timestamp;
268 278
269 - elapsed = gethrtime() - dccp->dccp_timestamp;
270 279
271 280 dccp->dccp_timestamp_echo = 0;
272 281 }
273 282
274 283 total_len = ((len + (4 - 1)) / 4) * 4;
275 284 options = kmem_zalloc(total_len, KM_SLEEP);
276 285 if (options == NULL) {
277 286 cmn_err(CE_NOTE, "kmem_zalloc failed");
278 287 return (ENOMEM);
279 288 }
280 289 memcpy(options, buf, len);
281 290
282 291 *opt = options;
283 292 *opt_len = len;
284 293
285 294 return (0);
286 295 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX