Line data Source code
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 28 : trunnel_htonll(uint64_t a)
80 : {
81 : #ifdef IS_LITTLE_ENDIAN
82 28 : return trunnel_htonl((uint32_t)(a>>32))
83 28 : | (((uint64_t)trunnel_htonl((uint32_t)a))<<32);
84 : #else
85 : return a;
86 : #endif
87 : }
88 :
89 : uint64_t
90 14 : trunnel_ntohll(uint64_t a)
91 : {
92 14 : 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 30192 : trunnel_dynarray_expand(size_t *allocated_p, void *ptr,
104 : size_t howmanymore, size_t eltsize)
105 : {
106 30192 : size_t newsize = howmanymore + *allocated_p;
107 30192 : void *newarray = NULL;
108 30192 : if (newsize < 8)
109 : newsize = 8;
110 30192 : if (newsize < *allocated_p * 2)
111 : newsize = *allocated_p * 2;
112 30192 : if (newsize <= *allocated_p || newsize < howmanymore)
113 : return NULL;
114 30192 : newarray = trunnel_reallocarray(ptr, newsize, eltsize);
115 30192 : if (newarray == NULL)
116 : return NULL;
117 :
118 30192 : *allocated_p = newsize;
119 30192 : 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 0 : trunnel_string_getstr(trunnel_string_t *str)
140 : {
141 0 : trunnel_assert(str->allocated_ >= str->n_);
142 0 : if (str->allocated_ == str->n_) {
143 0 : TRUNNEL_DYNARRAY_EXPAND(char, str, 1, {});
144 : }
145 0 : str->elts_[str->n_] = 0;
146 0 : return str->elts_;
147 0 : trunnel_alloc_failed:
148 0 : return NULL;
149 : }
150 :
151 : int
152 284 : trunnel_string_setstr0(trunnel_string_t *str, const char *val, size_t len,
153 : uint8_t *errcode_ptr)
154 : {
155 284 : if (len == SIZE_MAX)
156 0 : goto trunnel_alloc_failed;
157 284 : if (str->allocated_ <= len) {
158 284 : TRUNNEL_DYNARRAY_EXPAND(char, str, len + 1 - str->allocated_, {});
159 : }
160 284 : memcpy(str->elts_, val, len);
161 284 : str->n_ = len;
162 284 : str->elts_[len] = 0;
163 284 : return 0;
164 0 : trunnel_alloc_failed:
165 0 : *errcode_ptr = 1;
166 0 : return -1;
167 : }
168 :
169 : int
170 0 : trunnel_string_setlen(trunnel_string_t *str, size_t newlen,
171 : uint8_t *errcode_ptr)
172 : {
173 0 : if (newlen == SIZE_MAX)
174 0 : goto trunnel_alloc_failed;
175 0 : if (str->allocated_ < newlen + 1) {
176 0 : TRUNNEL_DYNARRAY_EXPAND(char, str, newlen + 1 - str->allocated_, {});
177 : }
178 0 : if (str->n_ < newlen) {
179 0 : memset(& (str->elts_[str->n_]), 0, (newlen - str->n_));
180 : }
181 0 : str->n_ = newlen;
182 0 : str->elts_[newlen] = 0;
183 0 : return 0;
184 :
185 0 : trunnel_alloc_failed:
186 0 : *errcode_ptr = 1;
187 0 : return -1;
188 : }
189 :
190 : void *
191 530 : 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 530 : if (*allocated_p < newlen) {
197 379 : void *newptr = trunnel_dynarray_expand(allocated_p, ptr,
198 : newlen - *allocated_p, eltsize);
199 379 : if (newptr == NULL)
200 0 : goto trunnel_alloc_failed;
201 : ptr = newptr;
202 : }
203 530 : if (free_fn && *len_p > newlen) {
204 : size_t i;
205 : void **elts = (void **) ptr;
206 10 : for (i = newlen; i < *len_p; ++i) {
207 5 : free_fn(elts[i]);
208 5 : elts[i] = NULL;
209 : }
210 : }
211 530 : if (*len_p < newlen) {
212 381 : memset( ((char*)ptr) + (eltsize * *len_p), 0, (newlen - *len_p) * eltsize);
213 : }
214 530 : *len_p = newlen;
215 530 : return ptr;
216 0 : trunnel_alloc_failed:
217 0 : *errcode_ptr = 1;
218 0 : 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 : */
|