LCOV - code coverage report
Current view: top level - trunnel/hs - cell_establish_intro.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 363 568 63.9 %
Date: 2021-11-24 03:28:48 Functions: 60 89 67.4 %

          Line data    Source code
       1             : /* cell_establish_intro.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 "cell_establish_intro.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 cellestablishintro_deadcode_dummy__ = 0;
      19             : #define OR_DEADCODE_DUMMY || cellestablishintro_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             : typedef struct trn_cell_extension_st trn_cell_extension_t;
      32             : trn_cell_extension_t *trn_cell_extension_new(void);
      33             : void trn_cell_extension_free(trn_cell_extension_t *victim);
      34             : ssize_t trn_cell_extension_parse(trn_cell_extension_t **output, const uint8_t *input, const size_t len_in);
      35             : ssize_t trn_cell_extension_encoded_len(const trn_cell_extension_t *obj);
      36             : ssize_t trn_cell_extension_encode(uint8_t *output, size_t avail, const trn_cell_extension_t *input);
      37             : const char *trn_cell_extension_check(const trn_cell_extension_t *obj);
      38             : int trn_cell_extension_clear_errors(trn_cell_extension_t *obj);
      39             : trn_cell_extension_dos_param_t *
      40          28 : trn_cell_extension_dos_param_new(void)
      41             : {
      42          28 :   trn_cell_extension_dos_param_t *val = trunnel_calloc(1, sizeof(trn_cell_extension_dos_param_t));
      43          28 :   if (NULL == val)
      44           0 :     return NULL;
      45             :   return val;
      46             : }
      47             : 
      48             : /** Release all storage held inside 'obj', but do not free 'obj'.
      49             :  */
      50             : static void
      51             : trn_cell_extension_dos_param_clear(trn_cell_extension_dos_param_t *obj)
      52             : {
      53             :   (void) obj;
      54             : }
      55             : 
      56             : void
      57          28 : trn_cell_extension_dos_param_free(trn_cell_extension_dos_param_t *obj)
      58             : {
      59          28 :   if (obj == NULL)
      60             :     return;
      61          28 :   trn_cell_extension_dos_param_clear(obj);
      62          28 :   trunnel_memwipe(obj, sizeof(trn_cell_extension_dos_param_t));
      63          28 :   trunnel_free_(obj);
      64             : }
      65             : 
      66             : uint8_t
      67          14 : trn_cell_extension_dos_param_get_type(const trn_cell_extension_dos_param_t *inp)
      68             : {
      69          14 :   return inp->type;
      70             : }
      71             : int
      72          14 : trn_cell_extension_dos_param_set_type(trn_cell_extension_dos_param_t *inp, uint8_t val)
      73             : {
      74          14 :   inp->type = val;
      75          14 :   return 0;
      76             : }
      77             : uint64_t
      78          14 : trn_cell_extension_dos_param_get_value(const trn_cell_extension_dos_param_t *inp)
      79             : {
      80          14 :   return inp->value;
      81             : }
      82             : int
      83          14 : trn_cell_extension_dos_param_set_value(trn_cell_extension_dos_param_t *inp, uint64_t val)
      84             : {
      85          14 :   inp->value = val;
      86          14 :   return 0;
      87             : }
      88             : const char *
      89          56 : trn_cell_extension_dos_param_check(const trn_cell_extension_dos_param_t *obj)
      90             : {
      91          56 :   if (obj == NULL)
      92             :     return "Object was NULL";
      93          56 :   if (obj->trunnel_error_code_)
      94           0 :     return "A set function failed on this object";
      95             :   return NULL;
      96             : }
      97             : 
      98             : ssize_t
      99          14 : trn_cell_extension_dos_param_encoded_len(const trn_cell_extension_dos_param_t *obj)
     100             : {
     101          14 :   ssize_t result = 0;
     102             : 
     103          14 :   if (NULL != trn_cell_extension_dos_param_check(obj))
     104           0 :      return -1;
     105             : 
     106             : 
     107             :   /* Length of u8 type */
     108             :   result += 1;
     109             : 
     110             :   /* Length of u64 value */
     111          14 :   result += 8;
     112             :   return result;
     113             : }
     114             : int
     115           0 : trn_cell_extension_dos_param_clear_errors(trn_cell_extension_dos_param_t *obj)
     116             : {
     117           0 :   int r = obj->trunnel_error_code_;
     118           0 :   obj->trunnel_error_code_ = 0;
     119           0 :   return r;
     120             : }
     121             : ssize_t
     122          14 : trn_cell_extension_dos_param_encode(uint8_t *output, const size_t avail, const trn_cell_extension_dos_param_t *obj)
     123             : {
     124          14 :   ssize_t result = 0;
     125          14 :   size_t written = 0;
     126          14 :   uint8_t *ptr = output;
     127          14 :   const char *msg;
     128             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     129             :   const ssize_t encoded_len = trn_cell_extension_dos_param_encoded_len(obj);
     130             : #endif
     131             : 
     132          14 :   if (NULL != (msg = trn_cell_extension_dos_param_check(obj)))
     133           0 :     goto check_failed;
     134             : 
     135             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     136             :   trunnel_assert(encoded_len >= 0);
     137             : #endif
     138             : 
     139             :   /* Encode u8 type */
     140          14 :   trunnel_assert(written <= avail);
     141          14 :   if (avail - written < 1)
     142           0 :     goto truncated;
     143          14 :   trunnel_set_uint8(ptr, (obj->type));
     144          14 :   written += 1; ptr += 1;
     145             : 
     146             :   /* Encode u64 value */
     147          14 :   trunnel_assert(written <= avail);
     148          14 :   if (avail - written < 8)
     149           0 :     goto truncated;
     150          14 :   trunnel_set_uint64(ptr, trunnel_htonll(obj->value));
     151          14 :   written += 8; ptr += 8;
     152             : 
     153             : 
     154          14 :   trunnel_assert(ptr == output + written);
     155             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     156             :   {
     157             :     trunnel_assert(encoded_len >= 0);
     158             :     trunnel_assert((size_t)encoded_len == written);
     159             :   }
     160             : 
     161             : #endif
     162             : 
     163             :   return written;
     164             : 
     165           0 :  truncated:
     166           0 :   result = -2;
     167           0 :   goto fail;
     168           0 :  check_failed:
     169           0 :   (void)msg;
     170           0 :   result = -1;
     171           0 :   goto fail;
     172             :  fail:
     173             :   trunnel_assert(result < 0);
     174             :   return result;
     175             : }
     176             : 
     177             : /** As trn_cell_extension_dos_param_parse(), but do not allocate the
     178             :  * output object.
     179             :  */
     180             : static ssize_t
     181          14 : trn_cell_extension_dos_param_parse_into(trn_cell_extension_dos_param_t *obj, const uint8_t *input, const size_t len_in)
     182             : {
     183          14 :   const uint8_t *ptr = input;
     184          14 :   size_t remaining = len_in;
     185          14 :   ssize_t result = 0;
     186          14 :   (void)result;
     187             : 
     188             :   /* Parse u8 type */
     189          14 :   CHECK_REMAINING(1, truncated);
     190          14 :   obj->type = (trunnel_get_uint8(ptr));
     191          14 :   remaining -= 1; ptr += 1;
     192             : 
     193             :   /* Parse u64 value */
     194          14 :   CHECK_REMAINING(8, truncated);
     195          14 :   obj->value = trunnel_ntohll(trunnel_get_uint64(ptr));
     196          14 :   remaining -= 8; ptr += 8;
     197          14 :   trunnel_assert(ptr + remaining == input + len_in);
     198             :   return len_in - remaining;
     199             : 
     200             :  truncated:
     201             :   return -2;
     202             : }
     203             : 
     204             : ssize_t
     205          14 : trn_cell_extension_dos_param_parse(trn_cell_extension_dos_param_t **output, const uint8_t *input, const size_t len_in)
     206             : {
     207          14 :   ssize_t result;
     208          14 :   *output = trn_cell_extension_dos_param_new();
     209          14 :   if (NULL == *output)
     210             :     return -1;
     211          14 :   result = trn_cell_extension_dos_param_parse_into(*output, input, len_in);
     212          14 :   if (result < 0) {
     213           0 :     trn_cell_extension_dos_param_free(*output);
     214           0 :     *output = NULL;
     215             :   }
     216             :   return result;
     217             : }
     218             : trn_cell_establish_intro_t *
     219          31 : trn_cell_establish_intro_new(void)
     220             : {
     221          31 :   trn_cell_establish_intro_t *val = trunnel_calloc(1, sizeof(trn_cell_establish_intro_t));
     222          31 :   if (NULL == val)
     223           0 :     return NULL;
     224             :   return val;
     225             : }
     226             : 
     227             : /** Release all storage held inside 'obj', but do not free 'obj'.
     228             :  */
     229             : static void
     230          31 : trn_cell_establish_intro_clear(trn_cell_establish_intro_t *obj)
     231             : {
     232          31 :   (void) obj;
     233          31 :   TRUNNEL_DYNARRAY_WIPE(&obj->auth_key);
     234          31 :   TRUNNEL_DYNARRAY_CLEAR(&obj->auth_key);
     235          31 :   trn_cell_extension_free(obj->extensions);
     236          31 :   obj->extensions = NULL;
     237          31 :   TRUNNEL_DYNARRAY_WIPE(&obj->sig);
     238          31 :   TRUNNEL_DYNARRAY_CLEAR(&obj->sig);
     239          31 : }
     240             : 
     241             : void
     242          32 : trn_cell_establish_intro_free(trn_cell_establish_intro_t *obj)
     243             : {
     244          32 :   if (obj == NULL)
     245             :     return;
     246          31 :   trn_cell_establish_intro_clear(obj);
     247          31 :   trunnel_memwipe(obj, sizeof(trn_cell_establish_intro_t));
     248          31 :   trunnel_free_(obj);
     249             : }
     250             : 
     251             : const uint8_t *
     252           0 : trn_cell_establish_intro_get_start_cell(const trn_cell_establish_intro_t *inp)
     253             : {
     254           0 :   return inp->start_cell;
     255             : }
     256             : uint8_t
     257           0 : trn_cell_establish_intro_get_auth_key_type(const trn_cell_establish_intro_t *inp)
     258             : {
     259           0 :   return inp->auth_key_type;
     260             : }
     261             : int
     262          15 : trn_cell_establish_intro_set_auth_key_type(trn_cell_establish_intro_t *inp, uint8_t val)
     263             : {
     264          15 :   if (! ((val == 0 || val == 1 || val == 2))) {
     265           0 :      TRUNNEL_SET_ERROR_CODE(inp);
     266           0 :      return -1;
     267             :   }
     268          15 :   inp->auth_key_type = val;
     269          15 :   return 0;
     270             : }
     271             : uint16_t
     272          10 : trn_cell_establish_intro_get_auth_key_len(const trn_cell_establish_intro_t *inp)
     273             : {
     274          10 :   return inp->auth_key_len;
     275             : }
     276             : int
     277          16 : trn_cell_establish_intro_set_auth_key_len(trn_cell_establish_intro_t *inp, uint16_t val)
     278             : {
     279          16 :   inp->auth_key_len = val;
     280          16 :   return 0;
     281             : }
     282             : size_t
     283          27 : trn_cell_establish_intro_getlen_auth_key(const trn_cell_establish_intro_t *inp)
     284             : {
     285          27 :   return TRUNNEL_DYNARRAY_LEN(&inp->auth_key);
     286             : }
     287             : 
     288             : uint8_t
     289           0 : trn_cell_establish_intro_get_auth_key(trn_cell_establish_intro_t *inp, size_t idx)
     290             : {
     291           0 :   return TRUNNEL_DYNARRAY_GET(&inp->auth_key, idx);
     292             : }
     293             : 
     294             : uint8_t
     295           0 : trn_cell_establish_intro_getconst_auth_key(const trn_cell_establish_intro_t *inp, size_t idx)
     296             : {
     297           0 :   return trn_cell_establish_intro_get_auth_key((trn_cell_establish_intro_t*)inp, idx);
     298             : }
     299             : int
     300           0 : trn_cell_establish_intro_set_auth_key(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt)
     301             : {
     302           0 :   TRUNNEL_DYNARRAY_SET(&inp->auth_key, idx, elt);
     303           0 :   return 0;
     304             : }
     305             : int
     306           0 : trn_cell_establish_intro_add_auth_key(trn_cell_establish_intro_t *inp, uint8_t elt)
     307             : {
     308             : #if SIZE_MAX >= UINT16_MAX
     309           0 :   if (inp->auth_key.n_ == UINT16_MAX)
     310           0 :     goto trunnel_alloc_failed;
     311             : #endif
     312           0 :   TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->auth_key, elt, {});
     313           0 :   return 0;
     314           0 :  trunnel_alloc_failed:
     315           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     316           0 :   return -1;
     317             : }
     318             : 
     319             : uint8_t *
     320          32 : trn_cell_establish_intro_getarray_auth_key(trn_cell_establish_intro_t *inp)
     321             : {
     322          32 :   return inp->auth_key.elts_;
     323             : }
     324             : const uint8_t  *
     325          16 : trn_cell_establish_intro_getconstarray_auth_key(const trn_cell_establish_intro_t *inp)
     326             : {
     327          16 :   return (const uint8_t  *)trn_cell_establish_intro_getarray_auth_key((trn_cell_establish_intro_t*)inp);
     328             : }
     329             : int
     330          16 : trn_cell_establish_intro_setlen_auth_key(trn_cell_establish_intro_t *inp, size_t newlen)
     331             : {
     332          16 :   uint8_t *newptr;
     333             : #if UINT16_MAX < SIZE_MAX
     334          16 :   if (newlen > UINT16_MAX)
     335           0 :     goto trunnel_alloc_failed;
     336             : #endif
     337          32 :   newptr = trunnel_dynarray_setlen(&inp->auth_key.allocated_,
     338          16 :                  &inp->auth_key.n_, inp->auth_key.elts_, newlen,
     339             :                  sizeof(inp->auth_key.elts_[0]), (trunnel_free_fn_t) NULL,
     340             :                  &inp->trunnel_error_code_);
     341          16 :   if (newlen != 0 && newptr == NULL)
     342           0 :     goto trunnel_alloc_failed;
     343          16 :   inp->auth_key.elts_ = newptr;
     344          16 :   return 0;
     345           0 :  trunnel_alloc_failed:
     346           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     347           0 :   return -1;
     348             : }
     349             : struct trn_cell_extension_st *
     350           6 : trn_cell_establish_intro_get_extensions(trn_cell_establish_intro_t *inp)
     351             : {
     352           6 :   return inp->extensions;
     353             : }
     354             : const struct trn_cell_extension_st *
     355           6 : trn_cell_establish_intro_getconst_extensions(const trn_cell_establish_intro_t *inp)
     356             : {
     357           6 :   return trn_cell_establish_intro_get_extensions((trn_cell_establish_intro_t*) inp);
     358             : }
     359             : int
     360          15 : trn_cell_establish_intro_set_extensions(trn_cell_establish_intro_t *inp, struct trn_cell_extension_st *val)
     361             : {
     362          15 :   if (inp->extensions && inp->extensions != val)
     363           0 :     trn_cell_extension_free(inp->extensions);
     364          15 :   return trn_cell_establish_intro_set0_extensions(inp, val);
     365             : }
     366             : int
     367          15 : trn_cell_establish_intro_set0_extensions(trn_cell_establish_intro_t *inp, struct trn_cell_extension_st *val)
     368             : {
     369          15 :   inp->extensions = val;
     370          15 :   return 0;
     371             : }
     372             : const uint8_t *
     373           0 : trn_cell_establish_intro_get_end_mac_fields(const trn_cell_establish_intro_t *inp)
     374             : {
     375           0 :   return inp->end_mac_fields;
     376             : }
     377             : size_t
     378          15 : trn_cell_establish_intro_getlen_handshake_mac(const trn_cell_establish_intro_t *inp)
     379             : {
     380          15 :   (void)inp;  return TRUNNEL_SHA3_256_LEN;
     381             : }
     382             : 
     383             : uint8_t
     384           0 : trn_cell_establish_intro_get_handshake_mac(trn_cell_establish_intro_t *inp, size_t idx)
     385             : {
     386           0 :   trunnel_assert(idx < TRUNNEL_SHA3_256_LEN);
     387           0 :   return inp->handshake_mac[idx];
     388             : }
     389             : 
     390             : uint8_t
     391           0 : trn_cell_establish_intro_getconst_handshake_mac(const trn_cell_establish_intro_t *inp, size_t idx)
     392             : {
     393           0 :   return trn_cell_establish_intro_get_handshake_mac((trn_cell_establish_intro_t*)inp, idx);
     394             : }
     395             : int
     396           0 : trn_cell_establish_intro_set_handshake_mac(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt)
     397             : {
     398           0 :   trunnel_assert(idx < TRUNNEL_SHA3_256_LEN);
     399           0 :   inp->handshake_mac[idx] = elt;
     400           0 :   return 0;
     401             : }
     402             : 
     403             : uint8_t *
     404          16 : trn_cell_establish_intro_getarray_handshake_mac(trn_cell_establish_intro_t *inp)
     405             : {
     406          16 :   return inp->handshake_mac;
     407             : }
     408             : const uint8_t  *
     409           0 : trn_cell_establish_intro_getconstarray_handshake_mac(const trn_cell_establish_intro_t *inp)
     410             : {
     411           0 :   return (const uint8_t  *)trn_cell_establish_intro_getarray_handshake_mac((trn_cell_establish_intro_t*)inp);
     412             : }
     413             : const uint8_t *
     414           0 : trn_cell_establish_intro_get_end_sig_fields(const trn_cell_establish_intro_t *inp)
     415             : {
     416           0 :   return inp->end_sig_fields;
     417             : }
     418             : uint16_t
     419           9 : trn_cell_establish_intro_get_sig_len(const trn_cell_establish_intro_t *inp)
     420             : {
     421           9 :   return inp->sig_len;
     422             : }
     423             : int
     424          16 : trn_cell_establish_intro_set_sig_len(trn_cell_establish_intro_t *inp, uint16_t val)
     425             : {
     426          16 :   inp->sig_len = val;
     427          16 :   return 0;
     428             : }
     429             : size_t
     430          10 : trn_cell_establish_intro_getlen_sig(const trn_cell_establish_intro_t *inp)
     431             : {
     432          10 :   return TRUNNEL_DYNARRAY_LEN(&inp->sig);
     433             : }
     434             : 
     435             : uint8_t
     436           0 : trn_cell_establish_intro_get_sig(trn_cell_establish_intro_t *inp, size_t idx)
     437             : {
     438           0 :   return TRUNNEL_DYNARRAY_GET(&inp->sig, idx);
     439             : }
     440             : 
     441             : uint8_t
     442           0 : trn_cell_establish_intro_getconst_sig(const trn_cell_establish_intro_t *inp, size_t idx)
     443             : {
     444           0 :   return trn_cell_establish_intro_get_sig((trn_cell_establish_intro_t*)inp, idx);
     445             : }
     446             : int
     447           0 : trn_cell_establish_intro_set_sig(trn_cell_establish_intro_t *inp, size_t idx, uint8_t elt)
     448             : {
     449           0 :   TRUNNEL_DYNARRAY_SET(&inp->sig, idx, elt);
     450           0 :   return 0;
     451             : }
     452             : int
     453           0 : trn_cell_establish_intro_add_sig(trn_cell_establish_intro_t *inp, uint8_t elt)
     454             : {
     455             : #if SIZE_MAX >= UINT16_MAX
     456           0 :   if (inp->sig.n_ == UINT16_MAX)
     457           0 :     goto trunnel_alloc_failed;
     458             : #endif
     459           0 :   TRUNNEL_DYNARRAY_ADD(uint8_t, &inp->sig, elt, {});
     460           0 :   return 0;
     461           0 :  trunnel_alloc_failed:
     462           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     463           0 :   return -1;
     464             : }
     465             : 
     466             : uint8_t *
     467          25 : trn_cell_establish_intro_getarray_sig(trn_cell_establish_intro_t *inp)
     468             : {
     469          25 :   return inp->sig.elts_;
     470             : }
     471             : const uint8_t  *
     472          10 : trn_cell_establish_intro_getconstarray_sig(const trn_cell_establish_intro_t *inp)
     473             : {
     474          10 :   return (const uint8_t  *)trn_cell_establish_intro_getarray_sig((trn_cell_establish_intro_t*)inp);
     475             : }
     476             : int
     477          16 : trn_cell_establish_intro_setlen_sig(trn_cell_establish_intro_t *inp, size_t newlen)
     478             : {
     479          16 :   uint8_t *newptr;
     480             : #if UINT16_MAX < SIZE_MAX
     481          16 :   if (newlen > UINT16_MAX)
     482           0 :     goto trunnel_alloc_failed;
     483             : #endif
     484          32 :   newptr = trunnel_dynarray_setlen(&inp->sig.allocated_,
     485          16 :                  &inp->sig.n_, inp->sig.elts_, newlen,
     486             :                  sizeof(inp->sig.elts_[0]), (trunnel_free_fn_t) NULL,
     487             :                  &inp->trunnel_error_code_);
     488          16 :   if (newlen != 0 && newptr == NULL)
     489           0 :     goto trunnel_alloc_failed;
     490          16 :   inp->sig.elts_ = newptr;
     491          16 :   return 0;
     492           0 :  trunnel_alloc_failed:
     493           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     494           0 :   return -1;
     495             : }
     496             : const char *
     497          49 : trn_cell_establish_intro_check(const trn_cell_establish_intro_t *obj)
     498             : {
     499          49 :   if (obj == NULL)
     500             :     return "Object was NULL";
     501          49 :   if (obj->trunnel_error_code_)
     502             :     return "A set function failed on this object";
     503          49 :   if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2))
     504             :     return "Integer out of bounds";
     505          49 :   if (TRUNNEL_DYNARRAY_LEN(&obj->auth_key) != obj->auth_key_len)
     506             :     return "Length mismatch for auth_key";
     507             :   {
     508          49 :     const char *msg;
     509          49 :     if (NULL != (msg = trn_cell_extension_check(obj->extensions)))
     510             :       return msg;
     511             :   }
     512          49 :   if (TRUNNEL_DYNARRAY_LEN(&obj->sig) != obj->sig_len)
     513           0 :     return "Length mismatch for sig";
     514             :   return NULL;
     515             : }
     516             : 
     517             : ssize_t
     518           0 : trn_cell_establish_intro_encoded_len(const trn_cell_establish_intro_t *obj)
     519             : {
     520           0 :   ssize_t result = 0;
     521             : 
     522           0 :   if (NULL != trn_cell_establish_intro_check(obj))
     523             :      return -1;
     524             : 
     525             : 
     526             :   /* Length of u8 auth_key_type IN [0, 1, 2] */
     527           0 :   result += 1;
     528             : 
     529             :   /* Length of u16 auth_key_len */
     530           0 :   result += 2;
     531             : 
     532             :   /* Length of u8 auth_key[auth_key_len] */
     533           0 :   result += TRUNNEL_DYNARRAY_LEN(&obj->auth_key);
     534             : 
     535             :   /* Length of struct trn_cell_extension extensions */
     536           0 :   result += trn_cell_extension_encoded_len(obj->extensions);
     537             : 
     538             :   /* Length of u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */
     539           0 :   result += TRUNNEL_SHA3_256_LEN;
     540             : 
     541             :   /* Length of u16 sig_len */
     542           0 :   result += 2;
     543             : 
     544             :   /* Length of u8 sig[sig_len] */
     545           0 :   result += TRUNNEL_DYNARRAY_LEN(&obj->sig);
     546           0 :   return result;
     547             : }
     548             : int
     549           0 : trn_cell_establish_intro_clear_errors(trn_cell_establish_intro_t *obj)
     550             : {
     551           0 :   int r = obj->trunnel_error_code_;
     552           0 :   obj->trunnel_error_code_ = 0;
     553           0 :   return r;
     554             : }
     555             : ssize_t
     556          49 : trn_cell_establish_intro_encode(uint8_t *output, const size_t avail, const trn_cell_establish_intro_t *obj)
     557             : {
     558          49 :   ssize_t result = 0;
     559          49 :   size_t written = 0;
     560          49 :   uint8_t *ptr = output;
     561          49 :   const char *msg;
     562             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     563             :   const ssize_t encoded_len = trn_cell_establish_intro_encoded_len(obj);
     564             : #endif
     565             : 
     566          49 :   if (NULL != (msg = trn_cell_establish_intro_check(obj)))
     567           0 :     goto check_failed;
     568             : 
     569             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     570             :   trunnel_assert(encoded_len >= 0);
     571             : #endif
     572             : 
     573             :   /* Encode u8 auth_key_type IN [0, 1, 2] */
     574          49 :   trunnel_assert(written <= avail);
     575          49 :   if (avail - written < 1)
     576           0 :     goto truncated;
     577          49 :   trunnel_set_uint8(ptr, (obj->auth_key_type));
     578          49 :   written += 1; ptr += 1;
     579             : 
     580             :   /* Encode u16 auth_key_len */
     581          49 :   trunnel_assert(written <= avail);
     582          49 :   if (avail - written < 2)
     583           0 :     goto truncated;
     584          49 :   trunnel_set_uint16(ptr, trunnel_htons(obj->auth_key_len));
     585          49 :   written += 2; ptr += 2;
     586             : 
     587             :   /* Encode u8 auth_key[auth_key_len] */
     588             :   {
     589          49 :     size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->auth_key);
     590          49 :     trunnel_assert(obj->auth_key_len == elt_len);
     591          49 :     trunnel_assert(written <= avail);
     592          49 :     if (avail - written < elt_len)
     593           0 :       goto truncated;
     594          49 :     if (elt_len)
     595          49 :       memcpy(ptr, obj->auth_key.elts_, elt_len);
     596          49 :     written += elt_len; ptr += elt_len;
     597             :   }
     598             : 
     599             :   /* Encode struct trn_cell_extension extensions */
     600          49 :   trunnel_assert(written <= avail);
     601          49 :   result = trn_cell_extension_encode(ptr, avail - written, obj->extensions);
     602          49 :   if (result < 0)
     603           0 :     goto fail; /* XXXXXXX !*/
     604          49 :   written += result; ptr += result;
     605             : 
     606             :   /* Encode u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */
     607          49 :   trunnel_assert(written <= avail);
     608          49 :   if (avail - written < TRUNNEL_SHA3_256_LEN)
     609           0 :     goto truncated;
     610          49 :   memcpy(ptr, obj->handshake_mac, TRUNNEL_SHA3_256_LEN);
     611          49 :   written += TRUNNEL_SHA3_256_LEN; ptr += TRUNNEL_SHA3_256_LEN;
     612             : 
     613             :   /* Encode u16 sig_len */
     614          49 :   trunnel_assert(written <= avail);
     615          49 :   if (avail - written < 2)
     616           0 :     goto truncated;
     617          49 :   trunnel_set_uint16(ptr, trunnel_htons(obj->sig_len));
     618          49 :   written += 2; ptr += 2;
     619             : 
     620             :   /* Encode u8 sig[sig_len] */
     621             :   {
     622          49 :     size_t elt_len = TRUNNEL_DYNARRAY_LEN(&obj->sig);
     623          49 :     trunnel_assert(obj->sig_len == elt_len);
     624          49 :     trunnel_assert(written <= avail);
     625          49 :     if (avail - written < elt_len)
     626           0 :       goto truncated;
     627          49 :     if (elt_len)
     628          49 :       memcpy(ptr, obj->sig.elts_, elt_len);
     629          49 :     written += elt_len; ptr += elt_len;
     630             :   }
     631             : 
     632             : 
     633          49 :   trunnel_assert(ptr == output + written);
     634             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     635             :   {
     636             :     trunnel_assert(encoded_len >= 0);
     637             :     trunnel_assert((size_t)encoded_len == written);
     638             :   }
     639             : 
     640             : #endif
     641             : 
     642          49 :   return written;
     643             : 
     644           0 :  truncated:
     645           0 :   result = -2;
     646           0 :   goto fail;
     647           0 :  check_failed:
     648           0 :   (void)msg;
     649           0 :   result = -1;
     650           0 :   goto fail;
     651           0 :  fail:
     652           0 :   trunnel_assert(result < 0);
     653             :   return result;
     654             : }
     655             : 
     656             : /** As trn_cell_establish_intro_parse(), but do not allocate the
     657             :  * output object.
     658             :  */
     659             : static ssize_t
     660          15 : trn_cell_establish_intro_parse_into(trn_cell_establish_intro_t *obj, const uint8_t *input, const size_t len_in)
     661             : {
     662          15 :   const uint8_t *ptr = input;
     663          15 :   size_t remaining = len_in;
     664          15 :   ssize_t result = 0;
     665          15 :   (void)result;
     666          15 :   obj->start_cell = ptr;
     667             : 
     668             :   /* Parse u8 auth_key_type IN [0, 1, 2] */
     669          15 :   CHECK_REMAINING(1, truncated);
     670          15 :   obj->auth_key_type = (trunnel_get_uint8(ptr));
     671          15 :   remaining -= 1; ptr += 1;
     672          15 :   if (! (obj->auth_key_type == 0 || obj->auth_key_type == 1 || obj->auth_key_type == 2))
     673           0 :     goto fail;
     674             : 
     675             :   /* Parse u16 auth_key_len */
     676          15 :   CHECK_REMAINING(2, truncated);
     677          15 :   obj->auth_key_len = trunnel_ntohs(trunnel_get_uint16(ptr));
     678          15 :   remaining -= 2; ptr += 2;
     679             : 
     680             :   /* Parse u8 auth_key[auth_key_len] */
     681          15 :   CHECK_REMAINING(obj->auth_key_len, truncated);
     682          15 :   TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->auth_key, obj->auth_key_len, {});
     683          15 :   obj->auth_key.n_ = obj->auth_key_len;
     684          15 :   if (obj->auth_key_len)
     685          15 :     memcpy(obj->auth_key.elts_, ptr, obj->auth_key_len);
     686          15 :   ptr += obj->auth_key_len; remaining -= obj->auth_key_len;
     687             : 
     688             :   /* Parse struct trn_cell_extension extensions */
     689          15 :   result = trn_cell_extension_parse(&obj->extensions, ptr, remaining);
     690          15 :   if (result < 0)
     691           0 :     goto relay_fail;
     692          15 :   trunnel_assert((size_t)result <= remaining);
     693          15 :   remaining -= result; ptr += result;
     694          15 :   obj->end_mac_fields = ptr;
     695             : 
     696             :   /* Parse u8 handshake_mac[TRUNNEL_SHA3_256_LEN] */
     697          15 :   CHECK_REMAINING(TRUNNEL_SHA3_256_LEN, truncated);
     698          15 :   memcpy(obj->handshake_mac, ptr, TRUNNEL_SHA3_256_LEN);
     699          15 :   remaining -= TRUNNEL_SHA3_256_LEN; ptr += TRUNNEL_SHA3_256_LEN;
     700          15 :   obj->end_sig_fields = ptr;
     701             : 
     702             :   /* Parse u16 sig_len */
     703          15 :   CHECK_REMAINING(2, truncated);
     704          15 :   obj->sig_len = trunnel_ntohs(trunnel_get_uint16(ptr));
     705          15 :   remaining -= 2; ptr += 2;
     706             : 
     707             :   /* Parse u8 sig[sig_len] */
     708          15 :   CHECK_REMAINING(obj->sig_len, truncated);
     709          15 :   TRUNNEL_DYNARRAY_EXPAND(uint8_t, &obj->sig, obj->sig_len, {});
     710          15 :   obj->sig.n_ = obj->sig_len;
     711          15 :   if (obj->sig_len)
     712          15 :     memcpy(obj->sig.elts_, ptr, obj->sig_len);
     713          15 :   ptr += obj->sig_len; remaining -= obj->sig_len;
     714          15 :   trunnel_assert(ptr + remaining == input + len_in);
     715          15 :   return len_in - remaining;
     716             : 
     717             :  truncated:
     718             :   return -2;
     719           0 :  relay_fail:
     720           0 :   trunnel_assert(result < 0);
     721             :   return result;
     722             :  trunnel_alloc_failed:
     723             :   return -1;
     724           0 :  fail:
     725           0 :   result = -1;
     726           0 :   return result;
     727             : }
     728             : 
     729             : ssize_t
     730          15 : trn_cell_establish_intro_parse(trn_cell_establish_intro_t **output, const uint8_t *input, const size_t len_in)
     731             : {
     732          15 :   ssize_t result;
     733          15 :   *output = trn_cell_establish_intro_new();
     734          15 :   if (NULL == *output)
     735             :     return -1;
     736          15 :   result = trn_cell_establish_intro_parse_into(*output, input, len_in);
     737          15 :   if (result < 0) {
     738           0 :     trn_cell_establish_intro_free(*output);
     739           0 :     *output = NULL;
     740             :   }
     741             :   return result;
     742             : }
     743             : trn_cell_extension_dos_t *
     744          14 : trn_cell_extension_dos_new(void)
     745             : {
     746          14 :   trn_cell_extension_dos_t *val = trunnel_calloc(1, sizeof(trn_cell_extension_dos_t));
     747          14 :   if (NULL == val)
     748           0 :     return NULL;
     749             :   return val;
     750             : }
     751             : 
     752             : /** Release all storage held inside 'obj', but do not free 'obj'.
     753             :  */
     754             : static void
     755          14 : trn_cell_extension_dos_clear(trn_cell_extension_dos_t *obj)
     756             : {
     757          14 :   (void) obj;
     758             :   {
     759             : 
     760          14 :     unsigned idx;
     761          42 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) {
     762          28 :       trn_cell_extension_dos_param_free(TRUNNEL_DYNARRAY_GET(&obj->params, idx));
     763             :     }
     764             :   }
     765          14 :   TRUNNEL_DYNARRAY_WIPE(&obj->params);
     766          14 :   TRUNNEL_DYNARRAY_CLEAR(&obj->params);
     767          14 : }
     768             : 
     769             : void
     770          15 : trn_cell_extension_dos_free(trn_cell_extension_dos_t *obj)
     771             : {
     772          15 :   if (obj == NULL)
     773             :     return;
     774          14 :   trn_cell_extension_dos_clear(obj);
     775          14 :   trunnel_memwipe(obj, sizeof(trn_cell_extension_dos_t));
     776          14 :   trunnel_free_(obj);
     777             : }
     778             : 
     779             : uint8_t
     780          15 : trn_cell_extension_dos_get_n_params(const trn_cell_extension_dos_t *inp)
     781             : {
     782          15 :   return inp->n_params;
     783             : }
     784             : int
     785           7 : trn_cell_extension_dos_set_n_params(trn_cell_extension_dos_t *inp, uint8_t val)
     786             : {
     787           7 :   inp->n_params = val;
     788           7 :   return 0;
     789             : }
     790             : size_t
     791           0 : trn_cell_extension_dos_getlen_params(const trn_cell_extension_dos_t *inp)
     792             : {
     793           0 :   return TRUNNEL_DYNARRAY_LEN(&inp->params);
     794             : }
     795             : 
     796             : struct trn_cell_extension_dos_param_st *
     797          14 : trn_cell_extension_dos_get_params(trn_cell_extension_dos_t *inp, size_t idx)
     798             : {
     799          14 :   return TRUNNEL_DYNARRAY_GET(&inp->params, idx);
     800             : }
     801             : 
     802             :  const struct trn_cell_extension_dos_param_st *
     803          14 : trn_cell_extension_dos_getconst_params(const trn_cell_extension_dos_t *inp, size_t idx)
     804             : {
     805          14 :   return trn_cell_extension_dos_get_params((trn_cell_extension_dos_t*)inp, idx);
     806             : }
     807             : int
     808           0 : trn_cell_extension_dos_set_params(trn_cell_extension_dos_t *inp, size_t idx, struct trn_cell_extension_dos_param_st * elt)
     809             : {
     810           0 :   trn_cell_extension_dos_param_t *oldval = TRUNNEL_DYNARRAY_GET(&inp->params, idx);
     811           0 :   if (oldval && oldval != elt)
     812           0 :     trn_cell_extension_dos_param_free(oldval);
     813           0 :   return trn_cell_extension_dos_set0_params(inp, idx, elt);
     814             : }
     815             : int
     816           0 : trn_cell_extension_dos_set0_params(trn_cell_extension_dos_t *inp, size_t idx, struct trn_cell_extension_dos_param_st * elt)
     817             : {
     818           0 :   TRUNNEL_DYNARRAY_SET(&inp->params, idx, elt);
     819           0 :   return 0;
     820             : }
     821             : int
     822          14 : trn_cell_extension_dos_add_params(trn_cell_extension_dos_t *inp, struct trn_cell_extension_dos_param_st * elt)
     823             : {
     824             : #if SIZE_MAX >= UINT8_MAX
     825          14 :   if (inp->params.n_ == UINT8_MAX)
     826           0 :     goto trunnel_alloc_failed;
     827             : #endif
     828          14 :   TRUNNEL_DYNARRAY_ADD(struct trn_cell_extension_dos_param_st *, &inp->params, elt, {});
     829          14 :   return 0;
     830           0 :  trunnel_alloc_failed:
     831           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     832           0 :   return -1;
     833             : }
     834             : 
     835             : struct trn_cell_extension_dos_param_st * *
     836           0 : trn_cell_extension_dos_getarray_params(trn_cell_extension_dos_t *inp)
     837             : {
     838           0 :   return inp->params.elts_;
     839             : }
     840             : const struct trn_cell_extension_dos_param_st *  const  *
     841           0 : trn_cell_extension_dos_getconstarray_params(const trn_cell_extension_dos_t *inp)
     842             : {
     843           0 :   return (const struct trn_cell_extension_dos_param_st *  const  *)trn_cell_extension_dos_getarray_params((trn_cell_extension_dos_t*)inp);
     844             : }
     845             : int
     846           0 : trn_cell_extension_dos_setlen_params(trn_cell_extension_dos_t *inp, size_t newlen)
     847             : {
     848           0 :   struct trn_cell_extension_dos_param_st * *newptr;
     849             : #if UINT8_MAX < SIZE_MAX
     850           0 :   if (newlen > UINT8_MAX)
     851           0 :     goto trunnel_alloc_failed;
     852             : #endif
     853           0 :   newptr = trunnel_dynarray_setlen(&inp->params.allocated_,
     854           0 :                  &inp->params.n_, inp->params.elts_, newlen,
     855             :                  sizeof(inp->params.elts_[0]), (trunnel_free_fn_t) trn_cell_extension_dos_param_free,
     856             :                  &inp->trunnel_error_code_);
     857           0 :   if (newlen != 0 && newptr == NULL)
     858           0 :     goto trunnel_alloc_failed;
     859           0 :   inp->params.elts_ = newptr;
     860           0 :   return 0;
     861           0 :  trunnel_alloc_failed:
     862           0 :   TRUNNEL_SET_ERROR_CODE(inp);
     863           0 :   return -1;
     864             : }
     865             : const char *
     866          14 : trn_cell_extension_dos_check(const trn_cell_extension_dos_t *obj)
     867             : {
     868          14 :   if (obj == NULL)
     869             :     return "Object was NULL";
     870          14 :   if (obj->trunnel_error_code_)
     871             :     return "A set function failed on this object";
     872             :   {
     873             :     const char *msg;
     874             : 
     875             :     unsigned idx;
     876          42 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) {
     877          28 :       if (NULL != (msg = trn_cell_extension_dos_param_check(TRUNNEL_DYNARRAY_GET(&obj->params, idx))))
     878           0 :         return msg;
     879             :     }
     880             :   }
     881          14 :   if (TRUNNEL_DYNARRAY_LEN(&obj->params) != obj->n_params)
     882           0 :     return "Length mismatch for params";
     883             :   return NULL;
     884             : }
     885             : 
     886             : ssize_t
     887           7 : trn_cell_extension_dos_encoded_len(const trn_cell_extension_dos_t *obj)
     888             : {
     889           7 :   ssize_t result = 0;
     890             : 
     891           7 :   if (NULL != trn_cell_extension_dos_check(obj))
     892             :      return -1;
     893             : 
     894             : 
     895             :   /* Length of u8 n_params */
     896             :   result += 1;
     897             : 
     898             :   /* Length of struct trn_cell_extension_dos_param params[n_params] */
     899             :   {
     900             : 
     901             :     unsigned idx;
     902          21 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) {
     903          14 :       result += trn_cell_extension_dos_param_encoded_len(TRUNNEL_DYNARRAY_GET(&obj->params, idx));
     904             :     }
     905             :   }
     906             :   return result;
     907             : }
     908             : int
     909           0 : trn_cell_extension_dos_clear_errors(trn_cell_extension_dos_t *obj)
     910             : {
     911           0 :   int r = obj->trunnel_error_code_;
     912           0 :   obj->trunnel_error_code_ = 0;
     913           0 :   return r;
     914             : }
     915             : ssize_t
     916           7 : trn_cell_extension_dos_encode(uint8_t *output, const size_t avail, const trn_cell_extension_dos_t *obj)
     917             : {
     918           7 :   ssize_t result = 0;
     919           7 :   size_t written = 0;
     920           7 :   uint8_t *ptr = output;
     921           7 :   const char *msg;
     922             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     923             :   const ssize_t encoded_len = trn_cell_extension_dos_encoded_len(obj);
     924             : #endif
     925             : 
     926           7 :   if (NULL != (msg = trn_cell_extension_dos_check(obj)))
     927           0 :     goto check_failed;
     928             : 
     929             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     930             :   trunnel_assert(encoded_len >= 0);
     931             : #endif
     932             : 
     933             :   /* Encode u8 n_params */
     934           7 :   trunnel_assert(written <= avail);
     935           7 :   if (avail - written < 1)
     936           0 :     goto truncated;
     937           7 :   trunnel_set_uint8(ptr, (obj->n_params));
     938           7 :   written += 1; ptr += 1;
     939             : 
     940             :   /* Encode struct trn_cell_extension_dos_param params[n_params] */
     941             :   {
     942             : 
     943           7 :     unsigned idx;
     944          21 :     for (idx = 0; idx < TRUNNEL_DYNARRAY_LEN(&obj->params); ++idx) {
     945          14 :       trunnel_assert(written <= avail);
     946          14 :       result = trn_cell_extension_dos_param_encode(ptr, avail - written, TRUNNEL_DYNARRAY_GET(&obj->params, idx));
     947          14 :       if (result < 0)
     948           0 :         goto fail; /* XXXXXXX !*/
     949          14 :       written += result; ptr += result;
     950             :     }
     951             :   }
     952             : 
     953             : 
     954           7 :   trunnel_assert(ptr == output + written);
     955             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
     956             :   {
     957             :     trunnel_assert(encoded_len >= 0);
     958             :     trunnel_assert((size_t)encoded_len == written);
     959             :   }
     960             : 
     961             : #endif
     962             : 
     963           7 :   return written;
     964             : 
     965           0 :  truncated:
     966           0 :   result = -2;
     967           0 :   goto fail;
     968           0 :  check_failed:
     969           0 :   (void)msg;
     970           0 :   result = -1;
     971           0 :   goto fail;
     972           0 :  fail:
     973           0 :   trunnel_assert(result < 0);
     974             :   return result;
     975             : }
     976             : 
     977             : /** As trn_cell_extension_dos_parse(), but do not allocate the output
     978             :  * object.
     979             :  */
     980             : static ssize_t
     981           7 : trn_cell_extension_dos_parse_into(trn_cell_extension_dos_t *obj, const uint8_t *input, const size_t len_in)
     982             : {
     983           7 :   const uint8_t *ptr = input;
     984           7 :   size_t remaining = len_in;
     985           7 :   ssize_t result = 0;
     986           7 :   (void)result;
     987             : 
     988             :   /* Parse u8 n_params */
     989           7 :   CHECK_REMAINING(1, truncated);
     990           7 :   obj->n_params = (trunnel_get_uint8(ptr));
     991           7 :   remaining -= 1; ptr += 1;
     992             : 
     993             :   /* Parse struct trn_cell_extension_dos_param params[n_params] */
     994           7 :   TRUNNEL_DYNARRAY_EXPAND(trn_cell_extension_dos_param_t *, &obj->params, obj->n_params, {});
     995             :   {
     996           7 :     trn_cell_extension_dos_param_t * elt;
     997           7 :     unsigned idx;
     998          21 :     for (idx = 0; idx < obj->n_params; ++idx) {
     999          14 :       result = trn_cell_extension_dos_param_parse(&elt, ptr, remaining);
    1000          14 :       if (result < 0)
    1001           0 :         goto relay_fail;
    1002          14 :       trunnel_assert((size_t)result <= remaining);
    1003          14 :       remaining -= result; ptr += result;
    1004          14 :       TRUNNEL_DYNARRAY_ADD(trn_cell_extension_dos_param_t *, &obj->params, elt, {trn_cell_extension_dos_param_free(elt);});
    1005             :     }
    1006             :   }
    1007           7 :   trunnel_assert(ptr + remaining == input + len_in);
    1008           7 :   return len_in - remaining;
    1009             : 
    1010           0 :  truncated:
    1011           0 :   return -2;
    1012           0 :  relay_fail:
    1013           0 :   trunnel_assert(result < 0);
    1014             :   return result;
    1015             :  trunnel_alloc_failed:
    1016             :   return -1;
    1017             : }
    1018             : 
    1019             : ssize_t
    1020           7 : trn_cell_extension_dos_parse(trn_cell_extension_dos_t **output, const uint8_t *input, const size_t len_in)
    1021             : {
    1022           7 :   ssize_t result;
    1023           7 :   *output = trn_cell_extension_dos_new();
    1024           7 :   if (NULL == *output)
    1025             :     return -1;
    1026           7 :   result = trn_cell_extension_dos_parse_into(*output, input, len_in);
    1027           7 :   if (result < 0) {
    1028           0 :     trn_cell_extension_dos_free(*output);
    1029           0 :     *output = NULL;
    1030             :   }
    1031             :   return result;
    1032             : }
    1033             : trn_cell_intro_established_t *
    1034           6 : trn_cell_intro_established_new(void)
    1035             : {
    1036           6 :   trn_cell_intro_established_t *val = trunnel_calloc(1, sizeof(trn_cell_intro_established_t));
    1037           6 :   if (NULL == val)
    1038           0 :     return NULL;
    1039             :   return val;
    1040             : }
    1041             : 
    1042             : /** Release all storage held inside 'obj', but do not free 'obj'.
    1043             :  */
    1044             : static void
    1045           6 : trn_cell_intro_established_clear(trn_cell_intro_established_t *obj)
    1046             : {
    1047           6 :   (void) obj;
    1048           6 :   trn_cell_extension_free(obj->extensions);
    1049           6 :   obj->extensions = NULL;
    1050           6 : }
    1051             : 
    1052             : void
    1053           6 : trn_cell_intro_established_free(trn_cell_intro_established_t *obj)
    1054             : {
    1055           6 :   if (obj == NULL)
    1056             :     return;
    1057           6 :   trn_cell_intro_established_clear(obj);
    1058           6 :   trunnel_memwipe(obj, sizeof(trn_cell_intro_established_t));
    1059           6 :   trunnel_free_(obj);
    1060             : }
    1061             : 
    1062             : struct trn_cell_extension_st *
    1063           0 : trn_cell_intro_established_get_extensions(trn_cell_intro_established_t *inp)
    1064             : {
    1065           0 :   return inp->extensions;
    1066             : }
    1067             : const struct trn_cell_extension_st *
    1068           0 : trn_cell_intro_established_getconst_extensions(const trn_cell_intro_established_t *inp)
    1069             : {
    1070           0 :   return trn_cell_intro_established_get_extensions((trn_cell_intro_established_t*) inp);
    1071             : }
    1072             : int
    1073           5 : trn_cell_intro_established_set_extensions(trn_cell_intro_established_t *inp, struct trn_cell_extension_st *val)
    1074             : {
    1075           5 :   if (inp->extensions && inp->extensions != val)
    1076           0 :     trn_cell_extension_free(inp->extensions);
    1077           5 :   return trn_cell_intro_established_set0_extensions(inp, val);
    1078             : }
    1079             : int
    1080           5 : trn_cell_intro_established_set0_extensions(trn_cell_intro_established_t *inp, struct trn_cell_extension_st *val)
    1081             : {
    1082           5 :   inp->extensions = val;
    1083           5 :   return 0;
    1084             : }
    1085             : const char *
    1086          10 : trn_cell_intro_established_check(const trn_cell_intro_established_t *obj)
    1087             : {
    1088          10 :   if (obj == NULL)
    1089             :     return "Object was NULL";
    1090          10 :   if (obj->trunnel_error_code_)
    1091             :     return "A set function failed on this object";
    1092             :   {
    1093          10 :     const char *msg;
    1094          10 :     if (NULL != (msg = trn_cell_extension_check(obj->extensions)))
    1095           0 :       return msg;
    1096             :   }
    1097             :   return NULL;
    1098             : }
    1099             : 
    1100             : ssize_t
    1101           5 : trn_cell_intro_established_encoded_len(const trn_cell_intro_established_t *obj)
    1102             : {
    1103           5 :   ssize_t result = 0;
    1104             : 
    1105           5 :   if (NULL != trn_cell_intro_established_check(obj))
    1106             :      return -1;
    1107             : 
    1108             : 
    1109             :   /* Length of struct trn_cell_extension extensions */
    1110           5 :   result += trn_cell_extension_encoded_len(obj->extensions);
    1111           5 :   return result;
    1112             : }
    1113             : int
    1114           0 : trn_cell_intro_established_clear_errors(trn_cell_intro_established_t *obj)
    1115             : {
    1116           0 :   int r = obj->trunnel_error_code_;
    1117           0 :   obj->trunnel_error_code_ = 0;
    1118           0 :   return r;
    1119             : }
    1120             : ssize_t
    1121           5 : trn_cell_intro_established_encode(uint8_t *output, const size_t avail, const trn_cell_intro_established_t *obj)
    1122             : {
    1123           5 :   ssize_t result = 0;
    1124           5 :   size_t written = 0;
    1125           5 :   uint8_t *ptr = output;
    1126           5 :   const char *msg;
    1127             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1128             :   const ssize_t encoded_len = trn_cell_intro_established_encoded_len(obj);
    1129             : #endif
    1130             : 
    1131           5 :   if (NULL != (msg = trn_cell_intro_established_check(obj)))
    1132           0 :     goto check_failed;
    1133             : 
    1134             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1135             :   trunnel_assert(encoded_len >= 0);
    1136             : #endif
    1137             : 
    1138             :   /* Encode struct trn_cell_extension extensions */
    1139           5 :   trunnel_assert(written <= avail);
    1140           5 :   result = trn_cell_extension_encode(ptr, avail - written, obj->extensions);
    1141           5 :   if (result < 0)
    1142           0 :     goto fail; /* XXXXXXX !*/
    1143           5 :   written += result; ptr += result;
    1144             : 
    1145             : 
    1146             :   trunnel_assert(ptr == output + written);
    1147             : #ifdef TRUNNEL_CHECK_ENCODED_LEN
    1148             :   {
    1149             :     trunnel_assert(encoded_len >= 0);
    1150             :     trunnel_assert((size_t)encoded_len == written);
    1151             :   }
    1152             : 
    1153             : #endif
    1154             : 
    1155             :   return written;
    1156             : 
    1157           0 :  check_failed:
    1158           0 :   (void)msg;
    1159           0 :   result = -1;
    1160           0 :   goto fail;
    1161           0 :  fail:
    1162           0 :   trunnel_assert(result < 0);
    1163             :   return result;
    1164             : }
    1165             : 
    1166             : /** As trn_cell_intro_established_parse(), but do not allocate the
    1167             :  * output object.
    1168             :  */
    1169             : static ssize_t
    1170           1 : trn_cell_intro_established_parse_into(trn_cell_intro_established_t *obj, const uint8_t *input, const size_t len_in)
    1171             : {
    1172           1 :   const uint8_t *ptr = input;
    1173           1 :   size_t remaining = len_in;
    1174           1 :   ssize_t result = 0;
    1175           1 :   (void)result;
    1176             : 
    1177             :   /* Parse struct trn_cell_extension extensions */
    1178           1 :   result = trn_cell_extension_parse(&obj->extensions, ptr, remaining);
    1179           1 :   if (result < 0)
    1180           0 :     goto relay_fail;
    1181           1 :   trunnel_assert((size_t)result <= remaining);
    1182           1 :   remaining -= result; ptr += result;
    1183             :   trunnel_assert(ptr + remaining == input + len_in);
    1184             :   return len_in - remaining;
    1185             : 
    1186           0 :  relay_fail:
    1187           0 :   trunnel_assert(result < 0);
    1188             :   return result;
    1189             : }
    1190             : 
    1191             : ssize_t
    1192           1 : trn_cell_intro_established_parse(trn_cell_intro_established_t **output, const uint8_t *input, const size_t len_in)
    1193             : {
    1194           1 :   ssize_t result;
    1195           1 :   *output = trn_cell_intro_established_new();
    1196           1 :   if (NULL == *output)
    1197             :     return -1;
    1198           1 :   result = trn_cell_intro_established_parse_into(*output, input, len_in);
    1199           1 :   if (result < 0) {
    1200           0 :     trn_cell_intro_established_free(*output);
    1201           0 :     *output = NULL;
    1202             :   }
    1203             :   return result;
    1204             : }

Generated by: LCOV version 1.14