Merge remote-tracking branch 'mbeth-private/ticket40821_mr'
[tor.git] / src / trunnel / circpad_negotiation.c
blob4e3ee3d5bdfe037883782d2e637a67738d5b1b90
1 /* circpad_negotiation.c -- generated by Trunnel v1.5.3.
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 uint32_t
116 circpad_negotiate_get_machine_ctr(const circpad_negotiate_t *inp)
118 return inp->machine_ctr;
121 circpad_negotiate_set_machine_ctr(circpad_negotiate_t *inp, uint32_t val)
123 inp->machine_ctr = val;
124 return 0;
126 const char *
127 circpad_negotiate_check(const circpad_negotiate_t *obj)
129 if (obj == NULL)
130 return "Object was NULL";
131 if (obj->trunnel_error_code_)
132 return "A set function failed on this object";
133 if (! (obj->version == 0))
134 return "Integer out of bounds";
135 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
136 return "Integer out of bounds";
137 if (! (obj->echo_request == 0 || obj->echo_request == 1))
138 return "Integer out of bounds";
139 return NULL;
142 ssize_t
143 circpad_negotiate_encoded_len(const circpad_negotiate_t *obj)
145 ssize_t result = 0;
147 if (NULL != circpad_negotiate_check(obj))
148 return -1;
151 /* Length of u8 version IN [0] */
152 result += 1;
154 /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
155 result += 1;
157 /* Length of u8 machine_type */
158 result += 1;
160 /* Length of u8 echo_request IN [0, 1] */
161 result += 1;
163 /* Length of u32 machine_ctr */
164 result += 4;
165 return result;
168 circpad_negotiate_clear_errors(circpad_negotiate_t *obj)
170 int r = obj->trunnel_error_code_;
171 obj->trunnel_error_code_ = 0;
172 return r;
174 ssize_t
175 circpad_negotiate_encode(uint8_t *output, const size_t avail, const circpad_negotiate_t *obj)
177 ssize_t result = 0;
178 size_t written = 0;
179 uint8_t *ptr = output;
180 const char *msg;
181 #ifdef TRUNNEL_CHECK_ENCODED_LEN
182 const ssize_t encoded_len = circpad_negotiate_encoded_len(obj);
183 #endif
185 if (NULL != (msg = circpad_negotiate_check(obj)))
186 goto check_failed;
188 #ifdef TRUNNEL_CHECK_ENCODED_LEN
189 trunnel_assert(encoded_len >= 0);
190 #endif
192 /* Encode u8 version IN [0] */
193 trunnel_assert(written <= avail);
194 if (avail - written < 1)
195 goto truncated;
196 trunnel_set_uint8(ptr, (obj->version));
197 written += 1; ptr += 1;
199 /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
200 trunnel_assert(written <= avail);
201 if (avail - written < 1)
202 goto truncated;
203 trunnel_set_uint8(ptr, (obj->command));
204 written += 1; ptr += 1;
206 /* Encode u8 machine_type */
207 trunnel_assert(written <= avail);
208 if (avail - written < 1)
209 goto truncated;
210 trunnel_set_uint8(ptr, (obj->machine_type));
211 written += 1; ptr += 1;
213 /* Encode u8 echo_request IN [0, 1] */
214 trunnel_assert(written <= avail);
215 if (avail - written < 1)
216 goto truncated;
217 trunnel_set_uint8(ptr, (obj->echo_request));
218 written += 1; ptr += 1;
220 /* Encode u32 machine_ctr */
221 trunnel_assert(written <= avail);
222 if (avail - written < 4)
223 goto truncated;
224 trunnel_set_uint32(ptr, trunnel_htonl(obj->machine_ctr));
225 written += 4; ptr += 4;
228 trunnel_assert(ptr == output + written);
229 #ifdef TRUNNEL_CHECK_ENCODED_LEN
231 trunnel_assert(encoded_len >= 0);
232 trunnel_assert((size_t)encoded_len == written);
235 #endif
237 return written;
239 truncated:
240 result = -2;
241 goto fail;
242 check_failed:
243 (void)msg;
244 result = -1;
245 goto fail;
246 fail:
247 trunnel_assert(result < 0);
248 return result;
251 /** As circpad_negotiate_parse(), but do not allocate the output
252 * object.
254 static ssize_t
255 circpad_negotiate_parse_into(circpad_negotiate_t *obj, const uint8_t *input, const size_t len_in)
257 const uint8_t *ptr = input;
258 size_t remaining = len_in;
259 ssize_t result = 0;
260 (void)result;
262 /* Parse u8 version IN [0] */
263 CHECK_REMAINING(1, truncated);
264 obj->version = (trunnel_get_uint8(ptr));
265 remaining -= 1; ptr += 1;
266 if (! (obj->version == 0))
267 goto fail;
269 /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
270 CHECK_REMAINING(1, truncated);
271 obj->command = (trunnel_get_uint8(ptr));
272 remaining -= 1; ptr += 1;
273 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
274 goto fail;
276 /* Parse u8 machine_type */
277 CHECK_REMAINING(1, truncated);
278 obj->machine_type = (trunnel_get_uint8(ptr));
279 remaining -= 1; ptr += 1;
281 /* Parse u8 echo_request IN [0, 1] */
282 CHECK_REMAINING(1, truncated);
283 obj->echo_request = (trunnel_get_uint8(ptr));
284 remaining -= 1; ptr += 1;
285 if (! (obj->echo_request == 0 || obj->echo_request == 1))
286 goto fail;
288 /* Parse u32 machine_ctr */
289 CHECK_REMAINING(4, truncated);
290 obj->machine_ctr = trunnel_ntohl(trunnel_get_uint32(ptr));
291 remaining -= 4; ptr += 4;
292 trunnel_assert(ptr + remaining == input + len_in);
293 return len_in - remaining;
295 truncated:
296 return -2;
297 fail:
298 result = -1;
299 return result;
302 ssize_t
303 circpad_negotiate_parse(circpad_negotiate_t **output, const uint8_t *input, const size_t len_in)
305 ssize_t result;
306 *output = circpad_negotiate_new();
307 if (NULL == *output)
308 return -1;
309 result = circpad_negotiate_parse_into(*output, input, len_in);
310 if (result < 0) {
311 circpad_negotiate_free(*output);
312 *output = NULL;
314 return result;
316 circpad_negotiated_t *
317 circpad_negotiated_new(void)
319 circpad_negotiated_t *val = trunnel_calloc(1, sizeof(circpad_negotiated_t));
320 if (NULL == val)
321 return NULL;
322 val->command = CIRCPAD_COMMAND_START;
323 val->response = CIRCPAD_RESPONSE_ERR;
324 return val;
327 /** Release all storage held inside 'obj', but do not free 'obj'.
329 static void
330 circpad_negotiated_clear(circpad_negotiated_t *obj)
332 (void) obj;
335 void
336 circpad_negotiated_free(circpad_negotiated_t *obj)
338 if (obj == NULL)
339 return;
340 circpad_negotiated_clear(obj);
341 trunnel_memwipe(obj, sizeof(circpad_negotiated_t));
342 trunnel_free_(obj);
345 uint8_t
346 circpad_negotiated_get_version(const circpad_negotiated_t *inp)
348 return inp->version;
351 circpad_negotiated_set_version(circpad_negotiated_t *inp, uint8_t val)
353 if (! ((val == 0))) {
354 TRUNNEL_SET_ERROR_CODE(inp);
355 return -1;
357 inp->version = val;
358 return 0;
360 uint8_t
361 circpad_negotiated_get_command(const circpad_negotiated_t *inp)
363 return inp->command;
366 circpad_negotiated_set_command(circpad_negotiated_t *inp, uint8_t val)
368 if (! ((val == CIRCPAD_COMMAND_START || val == CIRCPAD_COMMAND_STOP))) {
369 TRUNNEL_SET_ERROR_CODE(inp);
370 return -1;
372 inp->command = val;
373 return 0;
375 uint8_t
376 circpad_negotiated_get_response(const circpad_negotiated_t *inp)
378 return inp->response;
381 circpad_negotiated_set_response(circpad_negotiated_t *inp, uint8_t val)
383 if (! ((val == CIRCPAD_RESPONSE_ERR || val == CIRCPAD_RESPONSE_OK))) {
384 TRUNNEL_SET_ERROR_CODE(inp);
385 return -1;
387 inp->response = val;
388 return 0;
390 uint8_t
391 circpad_negotiated_get_machine_type(const circpad_negotiated_t *inp)
393 return inp->machine_type;
396 circpad_negotiated_set_machine_type(circpad_negotiated_t *inp, uint8_t val)
398 inp->machine_type = val;
399 return 0;
401 uint32_t
402 circpad_negotiated_get_machine_ctr(const circpad_negotiated_t *inp)
404 return inp->machine_ctr;
407 circpad_negotiated_set_machine_ctr(circpad_negotiated_t *inp, uint32_t val)
409 inp->machine_ctr = val;
410 return 0;
412 const char *
413 circpad_negotiated_check(const circpad_negotiated_t *obj)
415 if (obj == NULL)
416 return "Object was NULL";
417 if (obj->trunnel_error_code_)
418 return "A set function failed on this object";
419 if (! (obj->version == 0))
420 return "Integer out of bounds";
421 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
422 return "Integer out of bounds";
423 if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK))
424 return "Integer out of bounds";
425 return NULL;
428 ssize_t
429 circpad_negotiated_encoded_len(const circpad_negotiated_t *obj)
431 ssize_t result = 0;
433 if (NULL != circpad_negotiated_check(obj))
434 return -1;
437 /* Length of u8 version IN [0] */
438 result += 1;
440 /* Length of u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
441 result += 1;
443 /* Length of u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
444 result += 1;
446 /* Length of u8 machine_type */
447 result += 1;
449 /* Length of u32 machine_ctr */
450 result += 4;
451 return result;
454 circpad_negotiated_clear_errors(circpad_negotiated_t *obj)
456 int r = obj->trunnel_error_code_;
457 obj->trunnel_error_code_ = 0;
458 return r;
460 ssize_t
461 circpad_negotiated_encode(uint8_t *output, const size_t avail, const circpad_negotiated_t *obj)
463 ssize_t result = 0;
464 size_t written = 0;
465 uint8_t *ptr = output;
466 const char *msg;
467 #ifdef TRUNNEL_CHECK_ENCODED_LEN
468 const ssize_t encoded_len = circpad_negotiated_encoded_len(obj);
469 #endif
471 if (NULL != (msg = circpad_negotiated_check(obj)))
472 goto check_failed;
474 #ifdef TRUNNEL_CHECK_ENCODED_LEN
475 trunnel_assert(encoded_len >= 0);
476 #endif
478 /* Encode u8 version IN [0] */
479 trunnel_assert(written <= avail);
480 if (avail - written < 1)
481 goto truncated;
482 trunnel_set_uint8(ptr, (obj->version));
483 written += 1; ptr += 1;
485 /* Encode u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
486 trunnel_assert(written <= avail);
487 if (avail - written < 1)
488 goto truncated;
489 trunnel_set_uint8(ptr, (obj->command));
490 written += 1; ptr += 1;
492 /* Encode u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
493 trunnel_assert(written <= avail);
494 if (avail - written < 1)
495 goto truncated;
496 trunnel_set_uint8(ptr, (obj->response));
497 written += 1; ptr += 1;
499 /* Encode u8 machine_type */
500 trunnel_assert(written <= avail);
501 if (avail - written < 1)
502 goto truncated;
503 trunnel_set_uint8(ptr, (obj->machine_type));
504 written += 1; ptr += 1;
506 /* Encode u32 machine_ctr */
507 trunnel_assert(written <= avail);
508 if (avail - written < 4)
509 goto truncated;
510 trunnel_set_uint32(ptr, trunnel_htonl(obj->machine_ctr));
511 written += 4; ptr += 4;
514 trunnel_assert(ptr == output + written);
515 #ifdef TRUNNEL_CHECK_ENCODED_LEN
517 trunnel_assert(encoded_len >= 0);
518 trunnel_assert((size_t)encoded_len == written);
521 #endif
523 return written;
525 truncated:
526 result = -2;
527 goto fail;
528 check_failed:
529 (void)msg;
530 result = -1;
531 goto fail;
532 fail:
533 trunnel_assert(result < 0);
534 return result;
537 /** As circpad_negotiated_parse(), but do not allocate the output
538 * object.
540 static ssize_t
541 circpad_negotiated_parse_into(circpad_negotiated_t *obj, const uint8_t *input, const size_t len_in)
543 const uint8_t *ptr = input;
544 size_t remaining = len_in;
545 ssize_t result = 0;
546 (void)result;
548 /* Parse u8 version IN [0] */
549 CHECK_REMAINING(1, truncated);
550 obj->version = (trunnel_get_uint8(ptr));
551 remaining -= 1; ptr += 1;
552 if (! (obj->version == 0))
553 goto fail;
555 /* Parse u8 command IN [CIRCPAD_COMMAND_START, CIRCPAD_COMMAND_STOP] */
556 CHECK_REMAINING(1, truncated);
557 obj->command = (trunnel_get_uint8(ptr));
558 remaining -= 1; ptr += 1;
559 if (! (obj->command == CIRCPAD_COMMAND_START || obj->command == CIRCPAD_COMMAND_STOP))
560 goto fail;
562 /* Parse u8 response IN [CIRCPAD_RESPONSE_ERR, CIRCPAD_RESPONSE_OK] */
563 CHECK_REMAINING(1, truncated);
564 obj->response = (trunnel_get_uint8(ptr));
565 remaining -= 1; ptr += 1;
566 if (! (obj->response == CIRCPAD_RESPONSE_ERR || obj->response == CIRCPAD_RESPONSE_OK))
567 goto fail;
569 /* Parse u8 machine_type */
570 CHECK_REMAINING(1, truncated);
571 obj->machine_type = (trunnel_get_uint8(ptr));
572 remaining -= 1; ptr += 1;
574 /* Parse u32 machine_ctr */
575 CHECK_REMAINING(4, truncated);
576 obj->machine_ctr = trunnel_ntohl(trunnel_get_uint32(ptr));
577 remaining -= 4; ptr += 4;
578 trunnel_assert(ptr + remaining == input + len_in);
579 return len_in - remaining;
581 truncated:
582 return -2;
583 fail:
584 result = -1;
585 return result;
588 ssize_t
589 circpad_negotiated_parse(circpad_negotiated_t **output, const uint8_t *input, const size_t len_in)
591 ssize_t result;
592 *output = circpad_negotiated_new();
593 if (NULL == *output)
594 return -1;
595 result = circpad_negotiated_parse_into(*output, input, len_in);
596 if (result < 0) {
597 circpad_negotiated_free(*output);
598 *output = NULL;
600 return result;