tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }