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 }