Merge branch 'maint-0.4.1' into release-0.4.1
[tor.git] / src / trunnel / circpad_negotiation.c
blob236be06adaab24db2547605641983d5fe8ba0713
1 /* circpad_negotiation.c -- generated by Trunnel v1.5.2.
2 * https://gitweb.torproject.org/trunnel.git
3 * You probably shouldn't edit this file.
4 */
5 #include <stdlib.h>
6 #include "trunnel-impl.h"
8 #include "circpad_negotiation.h"
10 #define TRUNNEL_SET_ERROR_CODE(obj) \
11 do { \
12 (obj)->trunnel_error_code_ = 1; \
13 } while (0)
15 #if defined(__COVERITY__) || defined(__clang_analyzer__)
16 /* If we're running a static analysis tool, we don't want it to complain
17 * that some of our remaining-bytes checks are dead-code. */
18 int circpadnegotiation_deadcode_dummy__ = 0;
19 #define OR_DEADCODE_DUMMY || circpadnegotiation_deadcode_dummy__
20 #else
21 #define OR_DEADCODE_DUMMY
22 #endif
24 #define CHECK_REMAINING(nbytes, label) \
25 do { \
26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \
27 goto label; \
28 } \
29 } while (0)
31 circpad_negotiate_t *
32 circpad_negotiate_new(void)
34 circpad_negotiate_t *val = trunnel_calloc(1, sizeof(circpad_negotiate_t));
35 if (NULL == val)
36 return NULL;
37 val->command = CIRCPAD_COMMAND_START;
38 return val;
41 /** Release all storage held inside 'obj', but do not free 'obj'.
43 static void
44 circpad_negotiate_clear(circpad_negotiate_t *obj)
46 (void) obj;
49 void
50 circpad_negotiate_free(circpad_negotiate_t *obj)
52 if (obj == NULL)
53 return;
54 circpad_negotiate_clear(obj);
55 trunnel_memwipe(obj, sizeof(circpad_negotiate_t));
56 trunnel_free_(obj);
59 uint8_t
60 circpad_negotiate_get_version(const circpad_negotiate_t *inp)
62 return inp->version;
64 int
65 circpad_negotiate_set_version(circpad_negotiate_t *inp, uint8_t val)
67 if (! ((val == 0))) {
68 TRUNNEL_SET_ERROR_CODE(inp);
69 return -1;
71 inp->version = val;
72 return 0;
74 uint8_t
75 circpad_negotiate_get_command(const circpad_negotiate_t *inp)
77 return inp->command;
79 int
80 circpad_negotiate_set_command(circpad_negotiate_t *inp, uint8_t val)
82 if (! ((val == CIRCPAD_COMMAND_START || val == CIRCPAD_COMMAND_STOP))) {
83 TRUNNEL_SET_ERROR_CODE(inp);
84 return -1;
86 inp->command = val;
87 return 0;
89 uint8_t
90 circpad_negotiate_get_machine_type(const circpad_negotiate_t *inp)
92 return inp->machine_type;
94 int
95 circpad_negotiate_set_machine_type(circpad_negotiate_t *inp, uint8_t val)
97 inp->machine_type = val;
98 return 0;
100 uint8_t
101 circpad_negotiate_get_echo_request(const circpad_negotiate_t *inp)
103 return inp->echo_request;
106 circpad_negotiate_set_echo_request(circpad_negotiate_t *inp, uint8_t val)
108 if (! ((val == 0 || val == 1))) {
109 TRUNNEL_SET_ERROR_CODE(inp);
110 return -1;
112 inp->echo_request = val;
113 return 0;
115 const char *
116 circpad_negotiate_check(const circpad_negotiate_t *obj)
118 if (obj == NULL)
119 return "Object was NULL";
120 if (obj->trunnel_error_code_)
121 return "A set function failed on this object";
122 if (! (obj->version == 0))
123 return "Integer out of bounds";
124 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
125 return "Integer out of bounds";
126 if (! (obj->echo_request == 0 || obj->echo_request == 1))
127 return "Integer out of bounds";
128 return NULL;
131 ssize_t
132 circpad_negotiate_encoded_len(const circpad_negotiate_t *obj)
134 ssize_t result = 0;
136 if (NULL != circpad_negotiate_check(obj))
137 return -1;
140 /* Length of u8 version IN [0] */
141 result += 1;
143 /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
144 result += 1;
146 /* Length of u8 machine_type */
147 result += 1;
149 /* Length of u8 echo_request IN [0, 1] */
150 result += 1;
151 return result;
154 circpad_negotiate_clear_errors(circpad_negotiate_t *obj)
156 int r = obj->trunnel_error_code_;
157 obj->trunnel_error_code_ = 0;
158 return r;
160 ssize_t
161 circpad_negotiate_encode(uint8_t *output, const size_t avail, const circpad_negotiate_t *obj)
163 ssize_t result = 0;
164 size_t written = 0;
165 uint8_t *ptr = output;
166 const char *msg;
167 #ifdef TRUNNEL_CHECK_ENCODED_LEN
168 const ssize_t encoded_len = circpad_negotiate_encoded_len(obj);
169 #endif
171 if (NULL != (msg = circpad_negotiate_check(obj)))
172 goto check_failed;
174 #ifdef TRUNNEL_CHECK_ENCODED_LEN
175 trunnel_assert(encoded_len >= 0);
176 #endif
178 /* Encode u8 version IN [0] */
179 trunnel_assert(written <= avail);
180 if (avail - written < 1)
181 goto truncated;
182 trunnel_set_uint8(ptr, (obj->version));
183 written += 1; ptr += 1;
185 /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
186 trunnel_assert(written <= avail);
187 if (avail - written < 1)
188 goto truncated;
189 trunnel_set_uint8(ptr, (obj->command));
190 written += 1; ptr += 1;
192 /* Encode u8 machine_type */
193 trunnel_assert(written <= avail);
194 if (avail - written < 1)
195 goto truncated;
196 trunnel_set_uint8(ptr, (obj->machine_type));
197 written += 1; ptr += 1;
199 /* Encode u8 echo_request IN [0, 1] */
200 trunnel_assert(written <= avail);
201 if (avail - written < 1)
202 goto truncated;
203 trunnel_set_uint8(ptr, (obj->echo_request));
204 written += 1; ptr += 1;
207 trunnel_assert(ptr == output + written);
208 #ifdef TRUNNEL_CHECK_ENCODED_LEN
210 trunnel_assert(encoded_len >= 0);
211 trunnel_assert((size_t)encoded_len == written);
214 #endif
216 return written;
218 truncated:
219 result = -2;
220 goto fail;
221 check_failed:
222 (void)msg;
223 result = -1;
224 goto fail;
225 fail:
226 trunnel_assert(result < 0);
227 return result;
230 /** As circpad_negotiate_parse(), but do not allocate the output
231 * object.
233 static ssize_t
234 circpad_negotiate_parse_into(circpad_negotiate_t *obj, const uint8_t *input, const size_t len_in)
236 const uint8_t *ptr = input;
237 size_t remaining = len_in;
238 ssize_t result = 0;
239 (void)result;
241 /* Parse u8 version IN [0] */
242 CHECK_REMAINING(1, truncated);
243 obj->version = (trunnel_get_uint8(ptr));
244 remaining -= 1; ptr += 1;
245 if (! (obj->version == 0))
246 goto fail;
248 /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
249 CHECK_REMAINING(1, truncated);
250 obj->command = (trunnel_get_uint8(ptr));
251 remaining -= 1; ptr += 1;
252 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
253 goto fail;
255 /* Parse u8 machine_type */
256 CHECK_REMAINING(1, truncated);
257 obj->machine_type = (trunnel_get_uint8(ptr));
258 remaining -= 1; ptr += 1;
260 /* Parse u8 echo_request IN [0, 1] */
261 CHECK_REMAINING(1, truncated);
262 obj->echo_request = (trunnel_get_uint8(ptr));
263 remaining -= 1; ptr += 1;
264 if (! (obj->echo_request == 0 || obj->echo_request == 1))
265 goto fail;
266 trunnel_assert(ptr + remaining == input + len_in);
267 return len_in - remaining;
269 truncated:
270 return -2;
271 fail:
272 result = -1;
273 return result;
276 ssize_t
277 circpad_negotiate_parse(circpad_negotiate_t **output, const uint8_t *input, const size_t len_in)
279 ssize_t result;
280 *output = circpad_negotiate_new();
281 if (NULL == *output)
282 return -1;
283 result = circpad_negotiate_parse_into(*output, input, len_in);
284 if (result < 0) {
285 circpad_negotiate_free(*output);
286 *output = NULL;
288 return result;
290 circpad_negotiated_t *
291 circpad_negotiated_new(void)
293 circpad_negotiated_t *val = trunnel_calloc(1, sizeof(circpad_negotiated_t));
294 if (NULL == val)
295 return NULL;
296 val->command = CIRCPAD_COMMAND_START;
297 val->response = CIRCPAD_RESPONSE_ERR;
298 return val;
301 /** Release all storage held inside 'obj', but do not free 'obj'.
303 static void
304 circpad_negotiated_clear(circpad_negotiated_t *obj)
306 (void) obj;
309 void
310 circpad_negotiated_free(circpad_negotiated_t *obj)
312 if (obj == NULL)
313 return;
314 circpad_negotiated_clear(obj);
315 trunnel_memwipe(obj, sizeof(circpad_negotiated_t));
316 trunnel_free_(obj);
319 uint8_t
320 circpad_negotiated_get_version(const circpad_negotiated_t *inp)
322 return inp->version;
325 circpad_negotiated_set_version(circpad_negotiated_t *inp, uint8_t val)
327 if (! ((val == 0))) {
328 TRUNNEL_SET_ERROR_CODE(inp);
329 return -1;
331 inp->version = val;
332 return 0;
334 uint8_t
335 circpad_negotiated_get_command(const circpad_negotiated_t *inp)
337 return inp->command;
340 circpad_negotiated_set_command(circpad_negotiated_t *inp, uint8_t val)
342 if (! ((val == CIRCPAD_COMMAND_START || val == CIRCPAD_COMMAND_STOP))) {
343 TRUNNEL_SET_ERROR_CODE(inp);
344 return -1;
346 inp->command = val;
347 return 0;
349 uint8_t
350 circpad_negotiated_get_response(const circpad_negotiated_t *inp)
352 return inp->response;
355 circpad_negotiated_set_response(circpad_negotiated_t *inp, uint8_t val)
357 if (! ((val == CIRCPAD_RESPONSE_ERR || val == CIRCPAD_RESPONSE_OK))) {
358 TRUNNEL_SET_ERROR_CODE(inp);
359 return -1;
361 inp->response = val;
362 return 0;
364 uint8_t
365 circpad_negotiated_get_machine_type(const circpad_negotiated_t *inp)
367 return inp->machine_type;
370 circpad_negotiated_set_machine_type(circpad_negotiated_t *inp, uint8_t val)
372 inp->machine_type = val;
373 return 0;
375 const char *
376 circpad_negotiated_check(const circpad_negotiated_t *obj)
378 if (obj == NULL)
379 return "Object was NULL";
380 if (obj->trunnel_error_code_)
381 return "A set function failed on this object";
382 if (! (obj->version == 0))
383 return "Integer out of bounds";
384 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
385 return "Integer out of bounds";
386 if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK))
387 return "Integer out of bounds";
388 return NULL;
391 ssize_t
392 circpad_negotiated_encoded_len(const circpad_negotiated_t *obj)
394 ssize_t result = 0;
396 if (NULL != circpad_negotiated_check(obj))
397 return -1;
400 /* Length of u8 version IN [0] */
401 result += 1;
403 /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
404 result += 1;
406 /* Length of u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
407 result += 1;
409 /* Length of u8 machine_type */
410 result += 1;
411 return result;
414 circpad_negotiated_clear_errors(circpad_negotiated_t *obj)
416 int r = obj->trunnel_error_code_;
417 obj->trunnel_error_code_ = 0;
418 return r;
420 ssize_t
421 circpad_negotiated_encode(uint8_t *output, const size_t avail, const circpad_negotiated_t *obj)
423 ssize_t result = 0;
424 size_t written = 0;
425 uint8_t *ptr = output;
426 const char *msg;
427 #ifdef TRUNNEL_CHECK_ENCODED_LEN
428 const ssize_t encoded_len = circpad_negotiated_encoded_len(obj);
429 #endif
431 if (NULL != (msg = circpad_negotiated_check(obj)))
432 goto check_failed;
434 #ifdef TRUNNEL_CHECK_ENCODED_LEN
435 trunnel_assert(encoded_len >= 0);
436 #endif
438 /* Encode u8 version IN [0] */
439 trunnel_assert(written <= avail);
440 if (avail - written < 1)
441 goto truncated;
442 trunnel_set_uint8(ptr, (obj->version));
443 written += 1; ptr += 1;
445 /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
446 trunnel_assert(written <= avail);
447 if (avail - written < 1)
448 goto truncated;
449 trunnel_set_uint8(ptr, (obj->command));
450 written += 1; ptr += 1;
452 /* Encode u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
453 trunnel_assert(written <= avail);
454 if (avail - written < 1)
455 goto truncated;
456 trunnel_set_uint8(ptr, (obj->response));
457 written += 1; ptr += 1;
459 /* Encode u8 machine_type */
460 trunnel_assert(written <= avail);
461 if (avail - written < 1)
462 goto truncated;
463 trunnel_set_uint8(ptr, (obj->machine_type));
464 written += 1; ptr += 1;
467 trunnel_assert(ptr == output + written);
468 #ifdef TRUNNEL_CHECK_ENCODED_LEN
470 trunnel_assert(encoded_len >= 0);
471 trunnel_assert((size_t)encoded_len == written);
474 #endif
476 return written;
478 truncated:
479 result = -2;
480 goto fail;
481 check_failed:
482 (void)msg;
483 result = -1;
484 goto fail;
485 fail:
486 trunnel_assert(result < 0);
487 return result;
490 /** As circpad_negotiated_parse(), but do not allocate the output
491 * object.
493 static ssize_t
494 circpad_negotiated_parse_into(circpad_negotiated_t *obj, const uint8_t *input, const size_t len_in)
496 const uint8_t *ptr = input;
497 size_t remaining = len_in;
498 ssize_t result = 0;
499 (void)result;
501 /* Parse u8 version IN [0] */
502 CHECK_REMAINING(1, truncated);
503 obj->version = (trunnel_get_uint8(ptr));
504 remaining -= 1; ptr += 1;
505 if (! (obj->version == 0))
506 goto fail;
508 /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
509 CHECK_REMAINING(1, truncated);
510 obj->command = (trunnel_get_uint8(ptr));
511 remaining -= 1; ptr += 1;
512 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
513 goto fail;
515 /* Parse u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
516 CHECK_REMAINING(1, truncated);
517 obj->response = (trunnel_get_uint8(ptr));
518 remaining -= 1; ptr += 1;
519 if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK))
520 goto fail;
522 /* Parse u8 machine_type */
523 CHECK_REMAINING(1, truncated);
524 obj->machine_type = (trunnel_get_uint8(ptr));
525 remaining -= 1; ptr += 1;
526 trunnel_assert(ptr + remaining == input + len_in);
527 return len_in - remaining;
529 truncated:
530 return -2;
531 fail:
532 result = -1;
533 return result;
536 ssize_t
537 circpad_negotiated_parse(circpad_negotiated_t **output, const uint8_t *input, const size_t len_in)
539 ssize_t result;
540 *output = circpad_negotiated_new();
541 if (NULL == *output)
542 return -1;
543 result = circpad_negotiated_parse_into(*output, input, len_in);
544 if (result < 0) {
545 circpad_negotiated_free(*output);
546 *output = NULL;
548 return result;