subproto_request.c (11709B)
1 /* subproto_request.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" 7 8 #include "subproto_request.h" 9 10 #define TRUNNEL_SET_ERROR_CODE(obj) \ 11 do { \ 12 (obj)->trunnel_error_code_ = 1; \ 13 } while (0) 14 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 subprotorequest_deadcode_dummy__ = 0; 19 #define OR_DEADCODE_DUMMY || subprotorequest_deadcode_dummy__ 20 #else 21 #define OR_DEADCODE_DUMMY 22 #endif 23 24 #define CHECK_REMAINING(nbytes, label) \ 25 do { \ 26 if (remaining < (nbytes) OR_DEADCODE_DUMMY) { \ 27 goto label; \ 28 } \ 29 } while (0) 30 31 trn_subproto_request_t * 32 trn_subproto_request_new(void) 33 { 34 trn_subproto_request_t *val = trunnel_calloc(1, sizeof(trn_subproto_request_t)); 35 if (NULL == val) 36 return NULL; 37 return val; 38 } 39 40 /** Release all storage held inside 'obj', but do not free 'obj'. 41 */ 42 static void 43 trn_subproto_request_clear(trn_subproto_request_t *obj) 44 { 45 (void) obj; 46 } 47 48 void 49 trn_subproto_request_free(trn_subproto_request_t *obj) 50 { 51 if (obj == NULL) 52 return; 53 trn_subproto_request_clear(obj); 54 trunnel_memwipe(obj, sizeof(trn_subproto_request_t)); 55 trunnel_free_(obj); 56 } 57 58 uint8_t 59 trn_subproto_request_get_protocol_id(const trn_subproto_request_t *inp) 60 { 61 return inp->protocol_id; 62 } 63 int 64 trn_subproto_request_set_protocol_id(trn_subproto_request_t *inp, uint8_t val) 65 { 66 inp->protocol_id = val; 67 return 0; 68 } 69 uint8_t 70 trn_subproto_request_get_proto_cap_number(const trn_subproto_request_t *inp) 71 { 72 return inp->proto_cap_number; 73 } 74 int 75 trn_subproto_request_set_proto_cap_number(trn_subproto_request_t *inp, uint8_t val) 76 { 77 inp->proto_cap_number = val; 78 return 0; 79 } 80 const char * 81 trn_subproto_request_check(const trn_subproto_request_t *obj) 82 { 83 if (obj == NULL) 84 return "Object was NULL"; 85 if (obj->trunnel_error_code_) 86 return "A set function failed on this object"; 87 return NULL; 88 } 89 90 ssize_t 91 trn_subproto_request_encoded_len(const trn_subproto_request_t *obj) 92 { 93 ssize_t result = 0; 94 95 if (NULL != trn_subproto_request_check(obj)) 96 return -1; 97 98 99 /* Length of u8 protocol_id */ 100 result += 1; 101 102 /* Length of u8 proto_cap_number */ 103 result += 1; 104 return result; 105 } 106 int 107 trn_subproto_request_clear_errors(trn_subproto_request_t *obj) 108 { 109 int r = obj->trunnel_error_code_; 110 obj->trunnel_error_code_ = 0; 111 return r; 112 } 113 ssize_t 114 trn_subproto_request_encode(uint8_t *output, const size_t avail, const trn_subproto_request_t *obj) 115 { 116 ssize_t result = 0; 117 size_t written = 0; 118 uint8_t *ptr = output; 119 const char *msg; 120 #ifdef TRUNNEL_CHECK_ENCODED_LEN 121 const ssize_t encoded_len = trn_subproto_request_encoded_len(obj); 122 #endif 123 124 if (NULL != (msg = trn_subproto_request_check(obj))) 125 goto check_failed; 126 127 #ifdef TRUNNEL_CHECK_ENCODED_LEN 128 trunnel_assert(encoded_len >= 0); 129 #endif 130 131 /* Encode u8 protocol_id */ 132 trunnel_assert(written <= avail); 133 if (avail - written < 1) 134 goto truncated; 135 trunnel_set_uint8(ptr, (obj->protocol_id)); 136 written += 1; ptr += 1; 137 138 /* Encode u8 proto_cap_number */ 139 trunnel_assert(written <= avail); 140 if (avail - written < 1) 141 goto truncated; 142 trunnel_set_uint8(ptr, (obj->proto_cap_number)); 143 written += 1; ptr += 1; 144 145 146 trunnel_assert(ptr == output + written); 147 #ifdef TRUNNEL_CHECK_ENCODED_LEN 148 { 149 trunnel_assert(encoded_len >= 0); 150 trunnel_assert((size_t)encoded_len == written); 151 } 152 153 #endif 154 155 return written; 156 157 truncated: 158 result = -2; 159 goto fail; 160 check_failed: 161 (void)msg; 162 result = -1; 163 goto fail; 164 fail: 165 trunnel_assert(result < 0); 166 return result; 167 } 168 169 /** As trn_subproto_request_parse(), but do not allocate the output 170 * object. 171 */ 172 static ssize_t 173 trn_subproto_request_parse_into(trn_subproto_request_t *obj, const uint8_t *input, const size_t len_in) 174 { 175 const uint8_t *ptr = input; 176 size_t remaining = len_in; 177 ssize_t result = 0; 178 (void)result; 179 180 /* Parse u8 protocol_id */ 181 CHECK_REMAINING(1, truncated); 182 obj->protocol_id = (trunnel_get_uint8(ptr)); 183 remaining -= 1; ptr += 1; 184 185 /* Parse u8 proto_cap_number */ 186 CHECK_REMAINING(1, truncated); 187 obj->proto_cap_number = (trunnel_get_uint8(ptr)); 188 remaining -= 1; ptr += 1; 189 trunnel_assert(ptr + remaining == input + len_in); 190 return len_in - remaining; 191 192 truncated: 193 return -2; 194 } 195 196 ssize_t 197 trn_subproto_request_parse(trn_subproto_request_t **output, const uint8_t *input, const size_t len_in) 198 { 199 ssize_t result; 200 *output = trn_subproto_request_new(); 201 if (NULL == *output) 202 return -1; 203 result = trn_subproto_request_parse_into(*output, input, len_in); 204 if (result < 0) { 205 trn_subproto_request_free(*output); 206 *output = NULL; 207 } 208 return result; 209 } 210 trn_subproto_request_ext_t * 211 trn_subproto_request_ext_new(void) 212 { 213 trn_subproto_request_ext_t *val = trunnel_calloc(1, sizeof(trn_subproto_request_ext_t)); 214 if (NULL == val) 215 return NULL; 216 return val; 217 } 218 219 /** Release all storage held inside 'obj', but do not free 'obj'. 220 */ 221 static void 222 trn_subproto_request_ext_clear(trn_subproto_request_ext_t *obj) 223 { 224 (void) obj; 225 { 226 227 unsigned idx; 228 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->reqs); ++idx) { 229 trn_subproto_request_free(TRUNNEL_DYNARRAY_GET(&obj->reqs, idx)); 230 } 231 } 232 TRUNNEL_DYNARRAY_WIPE(&obj->reqs); 233 TRUNNEL_DYNARRAY_CLEAR(&obj->reqs); 234 } 235 236 void 237 trn_subproto_request_ext_free(trn_subproto_request_ext_t *obj) 238 { 239 if (obj == NULL) 240 return; 241 trn_subproto_request_ext_clear(obj); 242 trunnel_memwipe(obj, sizeof(trn_subproto_request_ext_t)); 243 trunnel_free_(obj); 244 } 245 246 size_t 247 trn_subproto_request_ext_getlen_reqs(const trn_subproto_request_ext_t *inp) 248 { 249 return TRUNNEL_DYNARRAY_LEN(&inp->reqs); 250 } 251 252 struct trn_subproto_request_st * 253 trn_subproto_request_ext_get_reqs(trn_subproto_request_ext_t *inp, size_t idx) 254 { 255 return TRUNNEL_DYNARRAY_GET(&inp->reqs, idx); 256 } 257 258 const struct trn_subproto_request_st * 259 trn_subproto_request_ext_getconst_reqs(const trn_subproto_request_ext_t *inp, size_t idx) 260 { 261 return trn_subproto_request_ext_get_reqs((trn_subproto_request_ext_t*)inp, idx); 262 } 263 int 264 trn_subproto_request_ext_set_reqs(trn_subproto_request_ext_t *inp, size_t idx, struct trn_subproto_request_st * elt) 265 { 266 trn_subproto_request_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->reqs, idx); 267 if (oldval && oldval != elt) 268 trn_subproto_request_free(oldval); 269 return trn_subproto_request_ext_set0_reqs(inp, idx, elt); 270 } 271 int 272 trn_subproto_request_ext_set0_reqs(trn_subproto_request_ext_t *inp, size_t idx, struct trn_subproto_request_st * elt) 273 { 274 TRUNNEL_DYNARRAY_SET(&inp->reqs, idx, elt); 275 return 0; 276 } 277 int 278 trn_subproto_request_ext_add_reqs(trn_subproto_request_ext_t *inp, struct trn_subproto_request_st * elt) 279 { 280 TRUNNEL_DYNARRAY_ADD(struct trn_subproto_request_st *, &inp->reqs, elt, {}); 281 return 0; 282 trunnel_alloc_failed: 283 TRUNNEL_SET_ERROR_CODE(inp); 284 return -1; 285 } 286 287 struct trn_subproto_request_st * * 288 trn_subproto_request_ext_getarray_reqs(trn_subproto_request_ext_t *inp) 289 { 290 return inp->reqs.elts_; 291 } 292 const struct trn_subproto_request_st * const * 293 trn_subproto_request_ext_getconstarray_reqs(const trn_subproto_request_ext_t *inp) 294 { 295 return (const struct trn_subproto_request_st * const *)trn_subproto_request_ext_getarray_reqs((trn_subproto_request_ext_t*)inp); 296 } 297 int 298 trn_subproto_request_ext_setlen_reqs(trn_subproto_request_ext_t *inp, size_t newlen) 299 { 300 struct trn_subproto_request_st * *newptr; 301 newptr = trunnel_dynarray_setlen(&inp->reqs.allocated_, 302 &inp->reqs.n_, inp->reqs.elts_, newlen, 303 sizeof(inp->reqs.elts_[0]), (trunnel_free_fn_t) trn_subproto_request_free, 304 &inp->trunnel_error_code_); 305 if (newlen != 0 && newptr == NULL) 306 goto trunnel_alloc_failed; 307 inp->reqs.elts_ = newptr; 308 return 0; 309 trunnel_alloc_failed: 310 TRUNNEL_SET_ERROR_CODE(inp); 311 return -1; 312 } 313 const char * 314 trn_subproto_request_ext_check(const trn_subproto_request_ext_t *obj) 315 { 316 if (obj == NULL) 317 return "Object was NULL"; 318 if (obj->trunnel_error_code_) 319 return "A set function failed on this object"; 320 { 321 const char *msg; 322 323 unsigned idx; 324 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->reqs); ++idx) { 325 if (NULL != (msg = trn_subproto_request_check(TRUNNEL_DYNARRAY_GET(&obj->reqs, idx)))) 326 return msg; 327 } 328 } 329 return NULL; 330 } 331 332 ssize_t 333 trn_subproto_request_ext_encoded_len(const trn_subproto_request_ext_t *obj) 334 { 335 ssize_t result = 0; 336 337 if (NULL != trn_subproto_request_ext_check(obj)) 338 return -1; 339 340 341 /* Length of struct trn_subproto_request reqs[] */ 342 { 343 344 unsigned idx; 345 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->reqs); ++idx) { 346 result += trn_subproto_request_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->reqs, idx)); 347 } 348 } 349 return result; 350 } 351 int 352 trn_subproto_request_ext_clear_errors(trn_subproto_request_ext_t *obj) 353 { 354 int r = obj->trunnel_error_code_; 355 obj->trunnel_error_code_ = 0; 356 return r; 357 } 358 ssize_t 359 trn_subproto_request_ext_encode(uint8_t *output, const size_t avail, const trn_subproto_request_ext_t *obj) 360 { 361 ssize_t result = 0; 362 size_t written = 0; 363 uint8_t *ptr = output; 364 const char *msg; 365 #ifdef TRUNNEL_CHECK_ENCODED_LEN 366 const ssize_t encoded_len = trn_subproto_request_ext_encoded_len(obj); 367 #endif 368 369 if (NULL != (msg = trn_subproto_request_ext_check(obj))) 370 goto check_failed; 371 372 #ifdef TRUNNEL_CHECK_ENCODED_LEN 373 trunnel_assert(encoded_len >= 0); 374 #endif 375 376 /* Encode struct trn_subproto_request reqs[] */ 377 { 378 379 unsigned idx; 380 for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->reqs); ++idx) { 381 trunnel_assert(written <= avail); 382 result = trn_subproto_request_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->reqs, idx)); 383 if (result < 0) 384 goto fail; /* XXXXXXX !*/ 385 written += result; ptr += result; 386 } 387 } 388 389 390 trunnel_assert(ptr == output + written); 391 #ifdef TRUNNEL_CHECK_ENCODED_LEN 392 { 393 trunnel_assert(encoded_len >= 0); 394 trunnel_assert((size_t)encoded_len == written); 395 } 396 397 #endif 398 399 return written; 400 401 check_failed: 402 (void)msg; 403 result = -1; 404 goto fail; 405 fail: 406 trunnel_assert(result < 0); 407 return result; 408 } 409 410 /** As trn_subproto_request_ext_parse(), but do not allocate the 411 * output object. 412 */ 413 static ssize_t 414 trn_subproto_request_ext_parse_into(trn_subproto_request_ext_t *obj, const uint8_t *input, const size_t len_in) 415 { 416 const uint8_t *ptr = input; 417 size_t remaining = len_in; 418 ssize_t result = 0; 419 (void)result; 420 421 /* Parse struct trn_subproto_request reqs[] */ 422 { 423 trn_subproto_request_t * elt; 424 while (remaining > 0) { 425 result = trn_subproto_request_parse(&elt, ptr, remaining); 426 if (result < 0) 427 goto fail; 428 trunnel_assert((size_t)result <= remaining); 429 remaining -= result; ptr += result; 430 TRUNNEL_DYNARRAY_ADD(trn_subproto_request_t *, &obj->reqs, elt, {trn_subproto_request_free(elt);}); 431 } 432 } 433 trunnel_assert(ptr + remaining == input + len_in); 434 return len_in - remaining; 435 436 trunnel_alloc_failed: 437 return -1; 438 fail: 439 result = -1; 440 return result; 441 } 442 443 ssize_t 444 trn_subproto_request_ext_parse(trn_subproto_request_ext_t **output, const uint8_t *input, const size_t len_in) 445 { 446 ssize_t result; 447 *output = trn_subproto_request_ext_new(); 448 if (NULL == *output) 449 return -1; 450 result = trn_subproto_request_ext_parse_into(*output, input, len_in); 451 if (result < 0) { 452 trn_subproto_request_ext_free(*output); 453 *output = NULL; 454 } 455 return result; 456 }