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