tor

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

flow_control_cells.c (7962B)


      1 /* flow_control_cells.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 "flow_control_cells.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 flowcontrolcells_deadcode_dummy__ = 0;
     19 #define OR_DEADCODE_DUMMY || flowcontrolcells_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 xoff_cell_t *
     32 xoff_cell_new(void)
     33 {
     34  xoff_cell_t *val = trunnel_calloc(1, sizeof(xoff_cell_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 xoff_cell_clear(xoff_cell_t *obj)
     44 {
     45  (void) obj;
     46 }
     47 
     48 void
     49 xoff_cell_free(xoff_cell_t *obj)
     50 {
     51  if (obj == NULL)
     52    return;
     53  xoff_cell_clear(obj);
     54  trunnel_memwipe(obj, sizeof(xoff_cell_t));
     55  trunnel_free_(obj);
     56 }
     57 
     58 uint8_t
     59 xoff_cell_get_version(const xoff_cell_t *inp)
     60 {
     61  return inp->version;
     62 }
     63 int
     64 xoff_cell_set_version(xoff_cell_t *inp, uint8_t val)
     65 {
     66  if (! ((val == 0))) {
     67     TRUNNEL_SET_ERROR_CODE(inp);
     68     return -1;
     69  }
     70  inp->version = val;
     71  return 0;
     72 }
     73 const char *
     74 xoff_cell_check(const xoff_cell_t *obj)
     75 {
     76  if (obj == NULL)
     77    return "Object was NULL";
     78  if (obj->trunnel_error_code_)
     79    return "A set function failed on this object";
     80  if (! (obj->version == 0))
     81    return "Integer out of bounds";
     82  return NULL;
     83 }
     84 
     85 ssize_t
     86 xoff_cell_encoded_len(const xoff_cell_t *obj)
     87 {
     88  ssize_t result = 0;
     89 
     90  if (NULL != xoff_cell_check(obj))
     91     return -1;
     92 
     93 
     94  /* Length of u8 version IN [0] */
     95  result += 1;
     96  return result;
     97 }
     98 int
     99 xoff_cell_clear_errors(xoff_cell_t *obj)
    100 {
    101  int r = obj->trunnel_error_code_;
    102  obj->trunnel_error_code_ = 0;
    103  return r;
    104 }
    105 ssize_t
    106 xoff_cell_encode(uint8_t *output, const size_t avail, const xoff_cell_t *obj)
    107 {
    108  ssize_t result = 0;
    109  size_t written = 0;
    110  uint8_t *ptr = output;
    111  const char *msg;
    112 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    113  const ssize_t encoded_len = xoff_cell_encoded_len(obj);
    114 #endif
    115 
    116  if (NULL != (msg = xoff_cell_check(obj)))
    117    goto check_failed;
    118 
    119 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    120  trunnel_assert(encoded_len >= 0);
    121 #endif
    122 
    123  /* Encode u8 version IN [0] */
    124  trunnel_assert(written <= avail);
    125  if (avail - written < 1)
    126    goto truncated;
    127  trunnel_set_uint8(ptr, (obj->version));
    128  written += 1; ptr += 1;
    129 
    130 
    131  trunnel_assert(ptr == output + written);
    132 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    133  {
    134    trunnel_assert(encoded_len >= 0);
    135    trunnel_assert((size_t)encoded_len == written);
    136  }
    137 
    138 #endif
    139 
    140  return written;
    141 
    142 truncated:
    143  result = -2;
    144  goto fail;
    145 check_failed:
    146  (void)msg;
    147  result = -1;
    148  goto fail;
    149 fail:
    150  trunnel_assert(result < 0);
    151  return result;
    152 }
    153 
    154 /** As xoff_cell_parse(), but do not allocate the output object.
    155 */
    156 static ssize_t
    157 xoff_cell_parse_into(xoff_cell_t *obj, const uint8_t *input, const size_t len_in)
    158 {
    159  const uint8_t *ptr = input;
    160  size_t remaining = len_in;
    161  ssize_t result = 0;
    162  (void)result;
    163 
    164  /* Parse u8 version IN [0] */
    165  CHECK_REMAINING(1, truncated);
    166  obj->version = (trunnel_get_uint8(ptr));
    167  remaining -= 1; ptr += 1;
    168  if (! (obj->version == 0))
    169    goto fail;
    170  trunnel_assert(ptr + remaining == input + len_in);
    171  return len_in - remaining;
    172 
    173 truncated:
    174  return -2;
    175 fail:
    176  result = -1;
    177  return result;
    178 }
    179 
    180 ssize_t
    181 xoff_cell_parse(xoff_cell_t **output, const uint8_t *input, const size_t len_in)
    182 {
    183  ssize_t result;
    184  *output = xoff_cell_new();
    185  if (NULL == *output)
    186    return -1;
    187  result = xoff_cell_parse_into(*output, input, len_in);
    188  if (result < 0) {
    189    xoff_cell_free(*output);
    190    *output = NULL;
    191  }
    192  return result;
    193 }
    194 xon_cell_t *
    195 xon_cell_new(void)
    196 {
    197  xon_cell_t *val = trunnel_calloc(1, sizeof(xon_cell_t));
    198  if (NULL == val)
    199    return NULL;
    200  return val;
    201 }
    202 
    203 /** Release all storage held inside 'obj', but do not free 'obj'.
    204 */
    205 static void
    206 xon_cell_clear(xon_cell_t *obj)
    207 {
    208  (void) obj;
    209 }
    210 
    211 void
    212 xon_cell_free(xon_cell_t *obj)
    213 {
    214  if (obj == NULL)
    215    return;
    216  xon_cell_clear(obj);
    217  trunnel_memwipe(obj, sizeof(xon_cell_t));
    218  trunnel_free_(obj);
    219 }
    220 
    221 uint8_t
    222 xon_cell_get_version(const xon_cell_t *inp)
    223 {
    224  return inp->version;
    225 }
    226 int
    227 xon_cell_set_version(xon_cell_t *inp, uint8_t val)
    228 {
    229  if (! ((val == 0))) {
    230     TRUNNEL_SET_ERROR_CODE(inp);
    231     return -1;
    232  }
    233  inp->version = val;
    234  return 0;
    235 }
    236 uint32_t
    237 xon_cell_get_kbps_ewma(const xon_cell_t *inp)
    238 {
    239  return inp->kbps_ewma;
    240 }
    241 int
    242 xon_cell_set_kbps_ewma(xon_cell_t *inp, uint32_t val)
    243 {
    244  inp->kbps_ewma = val;
    245  return 0;
    246 }
    247 const char *
    248 xon_cell_check(const xon_cell_t *obj)
    249 {
    250  if (obj == NULL)
    251    return "Object was NULL";
    252  if (obj->trunnel_error_code_)
    253    return "A set function failed on this object";
    254  if (! (obj->version == 0))
    255    return "Integer out of bounds";
    256  return NULL;
    257 }
    258 
    259 ssize_t
    260 xon_cell_encoded_len(const xon_cell_t *obj)
    261 {
    262  ssize_t result = 0;
    263 
    264  if (NULL != xon_cell_check(obj))
    265     return -1;
    266 
    267 
    268  /* Length of u8 version IN [0] */
    269  result += 1;
    270 
    271  /* Length of u32 kbps_ewma */
    272  result += 4;
    273  return result;
    274 }
    275 int
    276 xon_cell_clear_errors(xon_cell_t *obj)
    277 {
    278  int r = obj->trunnel_error_code_;
    279  obj->trunnel_error_code_ = 0;
    280  return r;
    281 }
    282 ssize_t
    283 xon_cell_encode(uint8_t *output, const size_t avail, const xon_cell_t *obj)
    284 {
    285  ssize_t result = 0;
    286  size_t written = 0;
    287  uint8_t *ptr = output;
    288  const char *msg;
    289 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    290  const ssize_t encoded_len = xon_cell_encoded_len(obj);
    291 #endif
    292 
    293  if (NULL != (msg = xon_cell_check(obj)))
    294    goto check_failed;
    295 
    296 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    297  trunnel_assert(encoded_len >= 0);
    298 #endif
    299 
    300  /* Encode u8 version IN [0] */
    301  trunnel_assert(written <= avail);
    302  if (avail - written < 1)
    303    goto truncated;
    304  trunnel_set_uint8(ptr, (obj->version));
    305  written += 1; ptr += 1;
    306 
    307  /* Encode u32 kbps_ewma */
    308  trunnel_assert(written <= avail);
    309  if (avail - written < 4)
    310    goto truncated;
    311  trunnel_set_uint32(ptr, trunnel_htonl(obj->kbps_ewma));
    312  written += 4; ptr += 4;
    313 
    314 
    315  trunnel_assert(ptr == output + written);
    316 #ifdef TRUNNEL_CHECK_ENCODED_LEN
    317  {
    318    trunnel_assert(encoded_len >= 0);
    319    trunnel_assert((size_t)encoded_len == written);
    320  }
    321 
    322 #endif
    323 
    324  return written;
    325 
    326 truncated:
    327  result = -2;
    328  goto fail;
    329 check_failed:
    330  (void)msg;
    331  result = -1;
    332  goto fail;
    333 fail:
    334  trunnel_assert(result < 0);
    335  return result;
    336 }
    337 
    338 /** As xon_cell_parse(), but do not allocate the output object.
    339 */
    340 static ssize_t
    341 xon_cell_parse_into(xon_cell_t *obj, const uint8_t *input, const size_t len_in)
    342 {
    343  const uint8_t *ptr = input;
    344  size_t remaining = len_in;
    345  ssize_t result = 0;
    346  (void)result;
    347 
    348  /* Parse u8 version IN [0] */
    349  CHECK_REMAINING(1, truncated);
    350  obj->version = (trunnel_get_uint8(ptr));
    351  remaining -= 1; ptr += 1;
    352  if (! (obj->version == 0))
    353    goto fail;
    354 
    355  /* Parse u32 kbps_ewma */
    356  CHECK_REMAINING(4, truncated);
    357  obj->kbps_ewma = trunnel_ntohl(trunnel_get_uint32(ptr));
    358  remaining -= 4; ptr += 4;
    359  trunnel_assert(ptr + remaining == input + len_in);
    360  return len_in - remaining;
    361 
    362 truncated:
    363  return -2;
    364 fail:
    365  result = -1;
    366  return result;
    367 }
    368 
    369 ssize_t
    370 xon_cell_parse(xon_cell_t **output, const uint8_t *input, const size_t len_in)
    371 {
    372  ssize_t result;
    373  *output = xon_cell_new();
    374  if (NULL == *output)
    375    return -1;
    376  result = xon_cell_parse_into(*output, input, len_in);
    377  if (result < 0) {
    378    xon_cell_free(*output);
    379    *output = NULL;
    380  }
    381  return result;
    382 }