tor

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

trunnel.c (6618B)


      1 /* trunnel.c -- copied from Trunnel v1.5.3
      2 * https://gitweb.torproject.org/trunnel.git
      3 * You probably shouldn't edit this file.
      4 */
      5 /* trunnel.c -- Helper functions to implement trunnel.
      6 *
      7 * Copyright 2014-2019, The Tor Project, Inc.
      8 * See license at the end of this file for copying information.
      9 *
     10 * See trunnel-impl.h for documentation of these functions.
     11 */
     12 
     13 #include "trunnel-impl.h"
     14 #include <stdlib.h>
     15 #include <string.h>
     16 
     17 #ifdef HAVE_SYS_PARAM_H
     18 #include <sys/param.h>
     19 #endif
     20 
     21 #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
     22 __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     23 #  define IS_LITTLE_ENDIAN 1
     24 #elif defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) &&     \
     25 BYTE_ORDER == __ORDER_LITTLE_ENDIAN
     26 #  define IS_LITTLE_ENDIAN 1
     27 #elif defined(_WIN32)
     28 #  define IS_LITTLE_ENDIAN 1
     29 #elif defined(__APPLE__)
     30 #  include <libkern/OSByteOrder.h>
     31 #  define BSWAP64(x) OSSwapLittleToHostInt64(x)
     32 #elif defined(sun) || defined(__sun)
     33 #  include <sys/byteorder.h>
     34 #  ifndef _BIG_ENDIAN
     35 #    define IS_LITTLE_ENDIAN
     36 #  endif
     37 #else
     38 # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(OpenBSD)
     39 #  include <sys/endian.h>
     40 # else
     41 #  include <endian.h>
     42 # endif
     43 #  if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
     44 __BYTE_ORDER == __LITTLE_ENDIAN
     45 #    define IS_LITTLE_ENDIAN
     46 #  endif
     47 #endif
     48 
     49 #ifdef _WIN32
     50 uint16_t
     51 trunnel_htons(uint16_t s)
     52 {
     53  return (s << 8) | (s >> 8);
     54 }
     55 uint16_t
     56 trunnel_ntohs(uint16_t s)
     57 {
     58  return (s << 8) | (s >> 8);
     59 }
     60 uint32_t
     61 trunnel_htonl(uint32_t s)
     62 {
     63  return (s << 24) |
     64         ((s << 8)&0xff0000) |
     65         ((s >> 8)&0xff00) |
     66         (s >> 24);
     67 }
     68 uint32_t
     69 trunnel_ntohl(uint32_t s)
     70 {
     71  return (s << 24) |
     72         ((s << 8)&0xff0000) |
     73         ((s >> 8)&0xff00) |
     74         (s >> 24);
     75 }
     76 #endif
     77 
     78 uint64_t
     79 trunnel_htonll(uint64_t a)
     80 {
     81 #ifdef IS_LITTLE_ENDIAN
     82  return trunnel_htonl((uint32_t)(a>>32))
     83    | (((uint64_t)trunnel_htonl((uint32_t)a))<<32);
     84 #else
     85  return a;
     86 #endif
     87 }
     88 
     89 uint64_t
     90 trunnel_ntohll(uint64_t a)
     91 {
     92  return trunnel_htonll(a);
     93 }
     94 
     95 #ifdef TRUNNEL_DEBUG_FAILING_ALLOC
     96 /** Used for debugging and running tricky test cases: Makes the nth
     97 * memoryation allocation call from now fail.
     98 */
     99 int trunnel_provoke_alloc_failure = 0;
    100 #endif
    101 
    102 void *
    103 trunnel_dynarray_expand(size_t *allocated_p, void *ptr,
    104                        size_t howmanymore, size_t eltsize)
    105 {
    106  size_t newsize = howmanymore + *allocated_p;
    107  void *newarray = NULL;
    108  if (newsize < 8)
    109    newsize = 8;
    110  if (newsize < *allocated_p * 2)
    111    newsize = *allocated_p * 2;
    112  if (newsize <= *allocated_p || newsize < howmanymore)
    113    return NULL;
    114  newarray = trunnel_reallocarray(ptr, newsize, eltsize);
    115  if (newarray == NULL)
    116    return NULL;
    117 
    118  *allocated_p = newsize;
    119  return newarray;
    120 }
    121 
    122 #ifndef trunnel_reallocarray
    123 void *
    124 trunnel_reallocarray(void *a, size_t x, size_t y)
    125 {
    126 #ifdef TRUNNEL_DEBUG_FAILING_ALLOC
    127   if (trunnel_provoke_alloc_failure) {
    128     if (--trunnel_provoke_alloc_failure == 0)
    129       return NULL;
    130   }
    131 #endif
    132   if (x > SIZE_MAX / y)
    133     return NULL;
    134   return trunnel_realloc(a, x * y);
    135 }
    136 #endif
    137 
    138 const char *
    139 trunnel_string_getstr(trunnel_string_t *str)
    140 {
    141  trunnel_assert(str->allocated_ >= str->n_);
    142  if (str->allocated_ == str->n_) {
    143    TRUNNEL_DYNARRAY_EXPAND(char, str, 1, {});
    144  }
    145  str->elts_[str->n_] = 0;
    146  return str->elts_;
    147 trunnel_alloc_failed:
    148  return NULL;
    149 }
    150 
    151 int
    152 trunnel_string_setstr0(trunnel_string_t *str, const char *val, size_t len,
    153                       uint8_t *errcode_ptr)
    154 {
    155  if (len == SIZE_MAX)
    156    goto trunnel_alloc_failed;
    157  if (str->allocated_ <= len) {
    158    TRUNNEL_DYNARRAY_EXPAND(char, str, len + 1 - str->allocated_, {});
    159  }
    160  memcpy(str->elts_, val, len);
    161  str->n_ = len;
    162  str->elts_[len] = 0;
    163  return 0;
    164 trunnel_alloc_failed:
    165  *errcode_ptr = 1;
    166  return -1;
    167 }
    168 
    169 int
    170 trunnel_string_setlen(trunnel_string_t *str, size_t newlen,
    171                      uint8_t *errcode_ptr)
    172 {
    173  if (newlen == SIZE_MAX)
    174    goto trunnel_alloc_failed;
    175  if (str->allocated_ < newlen + 1) {
    176    TRUNNEL_DYNARRAY_EXPAND(char, str, newlen + 1 - str->allocated_, {});
    177  }
    178  if (str->n_ < newlen) {
    179    memset(& (str->elts_[str->n_]), 0, (newlen - str->n_));
    180  }
    181  str->n_ = newlen;
    182  str->elts_[newlen] = 0;
    183  return 0;
    184 
    185 trunnel_alloc_failed:
    186  *errcode_ptr = 1;
    187  return -1;
    188 }
    189 
    190 void *
    191 trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p,
    192                        void *ptr, size_t newlen,
    193                        size_t eltsize, trunnel_free_fn_t free_fn,
    194                        uint8_t *errcode_ptr)
    195 {
    196  if (*allocated_p < newlen) {
    197    void *newptr = trunnel_dynarray_expand(allocated_p, ptr,
    198                                           newlen - *allocated_p, eltsize);
    199    if (newptr == NULL)
    200      goto trunnel_alloc_failed;
    201    ptr = newptr;
    202  }
    203  if (free_fn && *len_p > newlen) {
    204    size_t i;
    205    void **elts = (void **) ptr;
    206    for (i = newlen; i < *len_p; ++i) {
    207      free_fn(elts[i]);
    208      elts[i] = NULL;
    209    }
    210  }
    211  if (*len_p < newlen) {
    212    memset( ((char*)ptr) + (eltsize * *len_p), 0, (newlen - *len_p) * eltsize);
    213  }
    214  *len_p = newlen;
    215  return ptr;
    216 trunnel_alloc_failed:
    217  *errcode_ptr = 1;
    218  return NULL;
    219 }
    220 
    221 /*
    222 Copyright 2014  The Tor Project, Inc.
    223 
    224 Redistribution and use in source and binary forms, with or without
    225 modification, are permitted provided that the following conditions are
    226 met:
    227 
    228    * Redistributions of source code must retain the above copyright
    229 notice, this list of conditions and the following disclaimer.
    230 
    231    * Redistributions in binary form must reproduce the above
    232 copyright notice, this list of conditions and the following disclaimer
    233 in the documentation and/or other materials provided with the
    234 distribution.
    235 
    236    * Neither the names of the copyright owners nor the names of its
    237 contributors may be used to endorse or promote products derived from
    238 this software without specific prior written permission.
    239 
    240 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    241 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    242 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    243 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    244 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    245 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    246 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    247 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    248 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    249 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    250 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    251 */