commit 821423c0ac52ff438e1f8f81bc41e8d7c69f6b67 Author: Nick Mathewson <ni...@torproject.org> Date: Thu Sep 25 13:14:18 2014 -0400
Teach trunnel to emit its C files, and store them as data. --- .gitignore | 2 + MANIFEST.in | 3 - c/trunnel.c | 242 ------------------------------- include/trunnel-impl.h | 306 --------------------------------------- include/trunnel.h | 60 -------- lib/trunnel/Boilerplate.py | 63 ++++++++ lib/trunnel/CodeGen.py | 4 +- lib/trunnel/__main__.py | 25 +++- lib/trunnel/data/trunnel-impl.h | 306 +++++++++++++++++++++++++++++++++++++++ lib/trunnel/data/trunnel.c | 242 +++++++++++++++++++++++++++++++ lib/trunnel/data/trunnel.h | 60 ++++++++ setup.py | 3 +- test/Makefile | 15 +- test/run_tests.sh | 11 +- 14 files changed, 716 insertions(+), 626 deletions(-) diff --git a/.gitignore b/.gitignore index f944487..0efb950 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ tests.log /test/valid/*.[ch] /test/ctest +/test/include + /doc/*.[ch] /doc/trunnel.html /doc/trunnel.txt diff --git a/MANIFEST.in b/MANIFEST.in index e9ebebe..4d96c8f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,9 +2,6 @@ include README include LICENSE include test.sh -include c/*.c -include include/*.h - include examples/*.trunnel include doc/*.md diff --git a/c/trunnel.c b/c/trunnel.c deleted file mode 100644 index 4bc28e3..0000000 --- a/c/trunnel.c +++ /dev/null @@ -1,242 +0,0 @@ -/* trunnel.c -- Helper functions to implement trunnel. - * - * Copyright 2014, The Tor Project, Inc. - * See license at the end of this file for copying information. - * - * See trunnel-impl.h for documentation of these functions. - */ - -#include <stdlib.h> -#include <string.h> -#include "trunnel-impl.h" - -#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ - __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define IS_LITTLE_ENDIAN 1 -#elif defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) && \ - BYTE_ORDER == __ORDER_LITTLE_ENDIAN -# define IS_LITTLE_ENDIAN 1 -#elif defined(_WIN32) -# define IS_LITTLE_ENDIAN 1 -#elif defined(__APPLE__) -# include <libkern/OSByteOrder.h> -# define BSWAP64(x) OSSwapLittleToHostInt64(x) -#elif defined(sun) || defined(__sun) -# include <sys/byteorder.h> -# ifndef _BIG_ENDIAN -# define IS_LITTLE_ENDIAN -# endif -#else -# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -# include <sys/endian.h> -# else -# include <endian.h> -# endif -# if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ - __BYTE_ORDER == __LITTLE_ENDIAN -# define IS_LITTLE_ENDIAN -# endif -#endif - -#ifdef _WIN32 -uint16_t -trunnel_htons(uint16_t s) -{ - return (s << 8) | (s >> 8); -} -uint16_t -trunnel_ntohs(uint16_t s) -{ - return (s << 8) | (s >> 8); -} -uint32_t -trunnel_htonl(uint32_t s) -{ - return (s << 24) | - ((s << 8)&0xff0000) | - ((s >> 8)&0xff00) | - (s >> 24); -} -uint32_t -trunnel_ntohl(uint32_t s) -{ - return (s << 24) | - ((s << 8)&0xff0000) | - ((s >> 8)&0xff00) | - (s >> 24); -} -#endif - -uint64_t -trunnel_htonll(uint64_t a) -{ -#ifdef IS_LITTLE_ENDIAN - return trunnel_htonl(a>>32) | (((uint64_t)trunnel_htonl(a))<<32); -#else - return a; -#endif -} - -uint64_t -trunnel_ntohll(uint64_t a) -{ - return trunnel_htonll(a); -} - -#ifdef TRUNNEL_DEBUG_FAILING_ALLOC -/** Used for debugging and running tricky test cases: Makes the nth - * memoryation allocation call from now fail. - */ -int trunnel_provoke_alloc_failure = 0; -#endif - -void * -trunnel_dynarray_expand(size_t *allocated_p, void *ptr, - size_t howmanymore, size_t eltsize) -{ - size_t newsize = howmanymore + *allocated_p; - void *newarray = NULL; - if (newsize < 8) - newsize = 8; - if (newsize < *allocated_p * 2) - newsize = *allocated_p * 2; - if (newsize <= *allocated_p || newsize < howmanymore) - return NULL; - newarray = trunnel_reallocarray(ptr, newsize, eltsize); - if (newarray == NULL) - return NULL; - - *allocated_p = newsize; - return newarray; -} - -#ifndef trunnel_reallocarray -void * -trunnel_reallocarray(void *a, size_t x, size_t y) -{ -#ifdef TRUNNEL_DEBUG_FAILING_ALLOC - if (trunnel_provoke_alloc_failure) { - if (--trunnel_provoke_alloc_failure == 0) - return NULL; - } -#endif - if (x > SIZE_MAX / y) - return NULL; - return trunnel_realloc(a, x * y); -} -#endif - -const char * -trunnel_string_getstr(trunnel_string_t *str) -{ - trunnel_assert(str->allocated_ >= str->n_); - if (str->allocated_ == str->n_) { - TRUNNEL_DYNARRAY_EXPAND(char, str, 1, {}); - } - str->elts_[str->n_] = 0; - return str->elts_; -trunnel_alloc_failed: - return NULL; -} - -int -trunnel_string_setstr0(trunnel_string_t *str, const char *val, size_t len, - uint8_t *errcode_ptr) -{ - if (len == SIZE_MAX) - goto trunnel_alloc_failed; - if (str->allocated_ <= len) { - TRUNNEL_DYNARRAY_EXPAND(char, str, len + 1 - str->allocated_, {}); - } - memcpy(str->elts_, val, len); - str->n_ = len; - str->elts_[len] = 0; - return 0; -trunnel_alloc_failed: - *errcode_ptr = 1; - return -1; -} - -int -trunnel_string_setlen(trunnel_string_t *str, size_t newlen, - uint8_t *errcode_ptr) -{ - if (newlen == SIZE_MAX) - goto trunnel_alloc_failed; - if (str->allocated_ < newlen + 1) { - TRUNNEL_DYNARRAY_EXPAND(char, str, newlen + 1 - str->allocated_, {}); - } - if (str->n_ < newlen) { - memset(& (str->elts_[str->n_]), 0, (newlen - str->n_)); - } - str->n_ = newlen; - str->elts_[newlen] = 0; - return 0; - - trunnel_alloc_failed: - *errcode_ptr = 1; - return -1; -} - -void * -trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p, - void *ptr, size_t newlen, - size_t eltsize, trunnel_free_fn_t free_fn, - uint8_t *errcode_ptr) -{ - if (*allocated_p < newlen) { - void *newptr = trunnel_dynarray_expand(allocated_p, ptr, - newlen - *allocated_p, eltsize); - if (newptr == NULL) - goto trunnel_alloc_failed; - ptr = newptr; - } - if (free_fn && *len_p > newlen) { - size_t i; - void **elts = (void **) ptr; - for (i = newlen; i < *len_p; ++i) { - free_fn(elts[i]); - elts[i] = NULL; - } - } - if (*len_p < newlen) { - memset( ((char*)ptr) + (eltsize * *len_p), 0, (newlen - *len_p) * eltsize); - } - *len_p = newlen; - return ptr; - trunnel_alloc_failed: - *errcode_ptr = 1; - return NULL; -} - -/* -Copyright 2014 The Tor Project, Inc. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - - * Neither the names of the copyright owners nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ diff --git a/include/trunnel-impl.h b/include/trunnel-impl.h deleted file mode 100644 index 4dd710f..0000000 --- a/include/trunnel-impl.h +++ /dev/null @@ -1,306 +0,0 @@ -/* trunnel-impl.h -- Implementation helpers for trunnel, included by - * generated trunnel files - * - * Copyright 2014, The Tor Project, Inc. - * See license at the end of this file for copying information. - */ - -#ifndef TRUNNEL_IMPL_H_INCLUDED_ -#define TRUNNEL_IMPL_H_INCLUDED_ -#include "trunnel.h" -#include <assert.h> -#include <string.h> -#ifdef TRUNNEL_LOCAL_H -#include "trunnel-local.h" -#endif - -#ifdef _MSC_VER -#define uint8_t unsigned char -#define uint16_t unsigned short -#define uint32_t unsigned int -#define uint64_t unsigned __int64 -#define inline __inline -#else -#include <stdint.h> -#endif - -#ifdef _WIN32 -uint32_t trunnel_htonl(uint32_t a); -uint32_t trunnel_ntohl(uint32_t a); -uint16_t trunnel_htons(uint16_t a); -uint16_t trunnel_ntohs(uint16_t a); -#else -#include <arpa/inet.h> -#define trunnel_htonl(x) htonl(x) -#define trunnel_htons(x) htons(x) -#define trunnel_ntohl(x) ntohl(x) -#define trunnel_ntohs(x) ntohs(x) -#endif -uint64_t trunnel_htonll(uint64_t a); -uint64_t trunnel_ntohll(uint64_t a); - -#ifndef trunnel_assert -#define trunnel_assert(x) assert(x) -#endif - -static inline void -trunnel_set_uint64(void *p, uint64_t v) { - memcpy(p, &v, 8); -} -static inline void -trunnel_set_uint32(void *p, uint32_t v) { - memcpy(p, &v, 4); -} -static inline void -trunnel_set_uint16(void *p, uint16_t v) { - memcpy(p, &v, 2); -} -static inline void -trunnel_set_uint8(void *p, uint8_t v) { - memcpy(p, &v, 1); -} - -static inline uint64_t -trunnel_get_uint64(const void *p) { - uint64_t x; - memcpy(&x, p, 8); - return x; -} -static inline uint32_t -trunnel_get_uint32(const void *p) { - uint32_t x; - memcpy(&x, p, 4); - return x; -} -static inline uint16_t -trunnel_get_uint16(const void *p) { - uint16_t x; - memcpy(&x, p, 2); - return x; -} -static inline uint8_t -trunnel_get_uint8(const void *p) { - return *(const uint8_t*)p; -} - - -#ifdef TRUNNEL_DEBUG_FAILING_ALLOC -extern int trunnel_provoke_alloc_failure; - -static inline void * -trunnel_malloc(size_t n) -{ - if (trunnel_provoke_alloc_failure) { - if (--trunnel_provoke_alloc_failure == 0) - return NULL; - } - return malloc(n); -} -static inline void * -trunnel_calloc(size_t a, size_t b) -{ - if (trunnel_provoke_alloc_failure) { - if (--trunnel_provoke_alloc_failure == 0) - return NULL; - } - return calloc(a,b); -} -static inline char * -trunnel_strdup(const char *s) -{ - if (trunnel_provoke_alloc_failure) { - if (--trunnel_provoke_alloc_failure == 0) - return NULL; - } - return strdup(s); -} -#else -#ifndef trunnel_malloc -#define trunnel_malloc(x) (malloc((x))) -#endif -#ifndef trunnel_calloc -#define trunnel_calloc(a,b) (calloc((a),(b))) -#endif -#ifndef trunnel_strdup -#define trunnel_strdup(s) (strdup((s))) -#endif -#endif - -#ifndef trunnel_realloc -#define trunnel_realloc(a,b) realloc((a),(b)) -#endif - -#ifndef trunnel_free_ -#define trunnel_free_(x) (free(x)) -#endif -#define trunnel_free(x) ((x) ? (trunnel_free_(x),0) : (0)) - -#ifndef trunnel_abort -#define trunnel_abort() abort() -#endif - -#ifndef trunnel_memwipe -#define trunnel_memwipe(mem, len) ((void)0) -#define trunnel_wipestr(s) ((void)0) -#else -#define trunnel_wipestr(s) do { \ - if (s) \ - trunnel_memwipe(s, strlen(s)); \ - } while (0) -#endif - -/* ====== dynamic arrays ======== */ - -#ifdef NDEBUG -#define TRUNNEL_DYNARRAY_GET(da, n) \ - ((da)->elts_[(n)]) -#else -/** Return the 'n'th element of 'da'. */ -#define TRUNNEL_DYNARRAY_GET(da, n) \ - (((n) >= (da)->n_ ? (trunnel_abort(),0) : 0), (da)->elts_[(n)]) -#endif - -/** Change the 'n'th element of 'da' to 'v'. */ -#define TRUNNEL_DYNARRAY_SET(da, n, v) do { \ - trunnel_assert((n) < (da)->n_); \ - (da)->elts_[(n)] = (v); \ - } while (0) - -/** Expand the dynamic array 'da' of 'elttype' so that it can hold at least - * 'howmanymore' elements than its current capacity. Always tries to increase - * the length of the array. On failure, run the code in 'on_fail' and goto - * trunnel_alloc_failed. */ -#define TRUNNEL_DYNARRAY_EXPAND(elttype, da, howmanymore, on_fail) do { \ - elttype *newarray; \ - newarray = trunnel_dynarray_expand(&(da)->allocated_, \ - (da)->elts_, (howmanymore), \ - sizeof(elttype)); \ - if (newarray == NULL) { \ - on_fail; \ - goto trunnel_alloc_failed; \ - } \ - (da)->elts_ = newarray; \ - } while (0) - -/** Add 'v' to the end of the dynamic array 'da' of 'elttype', expanding it if - * necessary. code in 'on_fail' and goto trunnel_alloc_failed. */ -#define TRUNNEL_DYNARRAY_ADD(elttype, da, v, on_fail) do { \ - if ((da)->n_ == (da)->allocated_) { \ - TRUNNEL_DYNARRAY_EXPAND(elttype, da, 1, on_fail); \ - } \ - (da)->elts_[(da)->n_++] = (v); \ - } while (0) - -/** Return the number of elements in 'da'. */ -#define TRUNNEL_DYNARRAY_LEN(da) ((da)->n_) - -/** Remove all storage held by 'da' and set it to be empty. Does not free - * storage held by the elements themselves. */ -#define TRUNNEL_DYNARRAY_CLEAR(da) do { \ - trunnel_free((da)->elts_); \ - (da)->elts_ = NULL; \ - (da)->n_ = (da)->allocated_ = 0; \ - } while (0) - -/** Remove all storage held by 'da' and set it to be empty. Does not free - * storage held by the elements themselves. */ -#define TRUNNEL_DYNARRAY_WIPE(da) do { \ - trunnel_memwipe((da)->elts_, (da)->allocated_ * sizeof((da)->elts_[0])); \ - } while (0) - -/** Helper: wraps or implements an OpenBSD-style reallocarray. Behaves - * as realloc(a, x*y), but verifies that no overflow will occur in the - * multiplication. Returns NULL on failure. */ -#ifndef trunnel_reallocarray -void *trunnel_reallocarray(void *a, size_t x, size_t y); -#endif - -/** Helper to expand a dynamic array. Behaves as TRUNNEL_DYNARRAY_EXPAND(), - * taking the array of elements in 'ptr', a pointer to thethe current number - * of allocated elements in allocated_p, the minimum numbeer of elements to - * add in 'howmanymore', and the size of a single element in 'eltsize'. - * - * On success, adjust *allocated_p, and return the new value for the array of - * elements. On failure, adjust nothing and return NULL. - */ -void *trunnel_dynarray_expand(size_t *allocated_p, void *ptr, - size_t howmanymore, size_t eltsize); - -/** Type for a function to free members of a dynarray of pointers. */ -typedef void (*trunnel_free_fn_t)(void *); - -/** - * Helper to change the length of a dynamic array. Takes pointers to the - * current allocated and n fields of the array in 'allocated_p' and 'len_p', - * and the current array of elements in 'ptr'; takes the length of a single - * element in 'eltsize'. Changes the length to 'newlen'. If 'newlen' is - * greater than the current length, pads the new elements with 0. If newlen - * is less than the current length, and free_fn is non-NULL, treat the - * array as an array of void *, and invoke free_fn() on each removed element. - * - * On success, adjust *allocated_p and *len_p, and return the new value for - * the array of elements. On failure, adjust nothing, set *errcode_ptr to 1, - * and return NULL. - */ -void *trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p, - void *ptr, size_t newlen, - size_t eltsize, trunnel_free_fn_t free_fn, - uint8_t *errcode_ptr); - -/** - * Helper: return a pointer to the value of 'str' as a NUL-terminated string. - * Might have to reallocate the storage for 'str' in order to fit in the final - * NUL character. On allocation failure, return NULL. - */ -const char *trunnel_string_getstr(trunnel_string_t *str); - -/** - * Helper: change the contents of 'str' to hold the 'len'-byte string in - * 'inp'. Adjusts the storage to have a terminating NUL that doesn't count - * towards the length of the string. On success, return 0. On failure, set - * *errcode_ptr to 1 and return -1. - */ -int trunnel_string_setstr0(trunnel_string_t *str, const char *inp, size_t len, - uint8_t *errcode_ptr); - -/** - * As trunnel_dynarray_setlen, but adjusts a string rather than a dynamic - * array, and ensures that the new string is NUL-terminated. - */ -int trunnel_string_setlen(trunnel_string_t *str, size_t newlen, - uint8_t *errcode_ptr); - -#endif - - -/* -Copyright 2014 The Tor Project, Inc. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - - * Neither the names of the copyright owners nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ diff --git a/include/trunnel.h b/include/trunnel.h deleted file mode 100644 index 0a78e6c..0000000 --- a/include/trunnel.h +++ /dev/null @@ -1,60 +0,0 @@ -/* trunnel.h -- Public declarations for trunnel, to be included - * in trunnel header files. - - * Copyright 2014, The Tor Project, Inc. - * See license at the end of this file for copying information. - */ - -#ifndef TRUNNEL_H_INCLUDED_ -#define TRUNNEL_H_INCLUDED_ - -#include <sys/types.h> - -/** Macro to declare a variable-length dynamically allocated array. Trunnel - * uses these to store all variable-length arrays. */ -#define TRUNNEL_DYNARRAY_HEAD(name, elttype) \ - struct name { \ - size_t n_; \ - size_t allocated_; \ - elttype *elts_; \ - } - -/** Initializer for a dynamic array of a given element type. */ -#define TRUNNEL_DYNARRAY_INIT(elttype) { 0, 0, (elttype*)NULL } - -/** Typedef used for storing variable-length arrays of char. */ -typedef TRUNNEL_DYNARRAY_HEAD(trunnel_string_st, char) trunnel_string_t; - -#endif - -/* -Copyright 2014 The Tor Project, Inc. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - - * Neither the names of the copyright owners nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ diff --git a/lib/trunnel/Boilerplate.py b/lib/trunnel/Boilerplate.py new file mode 100644 index 0000000..221d09e --- /dev/null +++ b/lib/trunnel/Boilerplate.py @@ -0,0 +1,63 @@ +# CodeGen.py -- code generator for trunnel. +# +# Copyright 2014, The Tor Project, Inc. +# See license at the end of this file for copying information. + +import os +import trunnel + +FILES = [ "trunnel.c", "trunnel.h", "trunnel-impl.h" ] + +def emit(target_dir=None): + if target_dir == None: + target_dir = '.' + directory = os.path.split(__file__)[0] + if not os.path.exists(target_dir): + os.makedirs(target_dir) + for f in FILES: + emitfile(f, + os.path.join(directory, "data", f), + os.path.join(target_dir, f)) + +def emitfile(fname, in_fname, out_fname): + settings = { + 'fname' : 'fname', + 'version' : trunnel.__version__ + } + with open(in_fname, 'r') as inp, open(out_fname, 'w') as out: + out.write("/* %(fname)s -- copied from Trunnel v%(version)s\n" + " * https://gitweb.torproject.org/trunnel.git\n" + " */\n") + out.write(inp.read()) + +__license__ = """ +Copyright 2014 The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" diff --git a/lib/trunnel/CodeGen.py b/lib/trunnel/CodeGen.py index 90178fc..cb779c9 100644 --- a/lib/trunnel/CodeGen.py +++ b/lib/trunnel/CodeGen.py @@ -2749,7 +2749,7 @@ MODULE_BOILERPLATE = """\ """ -def generate_code(input_fname, extra_options=[]): +def generate_code(input_fname, extra_options=[], target_dir=None): """Read a trunnel file from 'input_fname' and write the result to appropriate output files. If 'extra_options' is set, add those options as though they had been specified in the file with @@ -2758,6 +2758,8 @@ def generate_code(input_fname, extra_options=[]): basename = input_fname if basename.endswith(".trunnel"): basename = basename[:-len(".trunnel")] + if target_dir != None: + basename = os.path.join(target_dir, os.path.split(basename)[1]) c_fname = basename + ".c" h_fname = basename + ".h" diff --git a/lib/trunnel/__main__.py b/lib/trunnel/__main__.py index 68ed405..99b7fd4 100644 --- a/lib/trunnel/__main__.py +++ b/lib/trunnel/__main__.py @@ -5,23 +5,36 @@ if __name__ == '__main__': import sys + import trunnel.Boilerplate import trunnel.CodeGen import getopt - opts, args = getopt.gnu_getopt(sys.argv[1:], "O:", ["option="]) - - if len(args) < 1: - sys.stderr.write("Syntax: python -m trunnel.Main <fname>\n") - sys.exit(1) + opts, args = getopt.gnu_getopt(sys.argv[1:], "O:", + ["option=","write-c-files","target-dir="]) more_options = [] + target_dir = None + write_c_files = None for (k, v) in opts: if k in ('-O', '--option'): more_options.append(v) + elif k == '--write-c-files': + write_c_files = True + elif k == '--target-dir': + target_dir = v + + if len(args) < 1 and not write_c_files: + sys.stderr.write("Syntax: python -m trunnel <fname>\n") + sys.exit(1) for filename in args: - trunnel.CodeGen.generate_code(filename, more_options) + trunnel.CodeGen.generate_code(filename, more_options, + target_dir=target_dir) + + if write_c_files: + trunnel.Boilerplate.emit(target_dir=target_dir) + __license__ = """ Copyright 2014 The Tor Project, Inc. diff --git a/lib/trunnel/data/trunnel-impl.h b/lib/trunnel/data/trunnel-impl.h new file mode 100644 index 0000000..4dd710f --- /dev/null +++ b/lib/trunnel/data/trunnel-impl.h @@ -0,0 +1,306 @@ +/* trunnel-impl.h -- Implementation helpers for trunnel, included by + * generated trunnel files + * + * Copyright 2014, The Tor Project, Inc. + * See license at the end of this file for copying information. + */ + +#ifndef TRUNNEL_IMPL_H_INCLUDED_ +#define TRUNNEL_IMPL_H_INCLUDED_ +#include "trunnel.h" +#include <assert.h> +#include <string.h> +#ifdef TRUNNEL_LOCAL_H +#include "trunnel-local.h" +#endif + +#ifdef _MSC_VER +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned int +#define uint64_t unsigned __int64 +#define inline __inline +#else +#include <stdint.h> +#endif + +#ifdef _WIN32 +uint32_t trunnel_htonl(uint32_t a); +uint32_t trunnel_ntohl(uint32_t a); +uint16_t trunnel_htons(uint16_t a); +uint16_t trunnel_ntohs(uint16_t a); +#else +#include <arpa/inet.h> +#define trunnel_htonl(x) htonl(x) +#define trunnel_htons(x) htons(x) +#define trunnel_ntohl(x) ntohl(x) +#define trunnel_ntohs(x) ntohs(x) +#endif +uint64_t trunnel_htonll(uint64_t a); +uint64_t trunnel_ntohll(uint64_t a); + +#ifndef trunnel_assert +#define trunnel_assert(x) assert(x) +#endif + +static inline void +trunnel_set_uint64(void *p, uint64_t v) { + memcpy(p, &v, 8); +} +static inline void +trunnel_set_uint32(void *p, uint32_t v) { + memcpy(p, &v, 4); +} +static inline void +trunnel_set_uint16(void *p, uint16_t v) { + memcpy(p, &v, 2); +} +static inline void +trunnel_set_uint8(void *p, uint8_t v) { + memcpy(p, &v, 1); +} + +static inline uint64_t +trunnel_get_uint64(const void *p) { + uint64_t x; + memcpy(&x, p, 8); + return x; +} +static inline uint32_t +trunnel_get_uint32(const void *p) { + uint32_t x; + memcpy(&x, p, 4); + return x; +} +static inline uint16_t +trunnel_get_uint16(const void *p) { + uint16_t x; + memcpy(&x, p, 2); + return x; +} +static inline uint8_t +trunnel_get_uint8(const void *p) { + return *(const uint8_t*)p; +} + + +#ifdef TRUNNEL_DEBUG_FAILING_ALLOC +extern int trunnel_provoke_alloc_failure; + +static inline void * +trunnel_malloc(size_t n) +{ + if (trunnel_provoke_alloc_failure) { + if (--trunnel_provoke_alloc_failure == 0) + return NULL; + } + return malloc(n); +} +static inline void * +trunnel_calloc(size_t a, size_t b) +{ + if (trunnel_provoke_alloc_failure) { + if (--trunnel_provoke_alloc_failure == 0) + return NULL; + } + return calloc(a,b); +} +static inline char * +trunnel_strdup(const char *s) +{ + if (trunnel_provoke_alloc_failure) { + if (--trunnel_provoke_alloc_failure == 0) + return NULL; + } + return strdup(s); +} +#else +#ifndef trunnel_malloc +#define trunnel_malloc(x) (malloc((x))) +#endif +#ifndef trunnel_calloc +#define trunnel_calloc(a,b) (calloc((a),(b))) +#endif +#ifndef trunnel_strdup +#define trunnel_strdup(s) (strdup((s))) +#endif +#endif + +#ifndef trunnel_realloc +#define trunnel_realloc(a,b) realloc((a),(b)) +#endif + +#ifndef trunnel_free_ +#define trunnel_free_(x) (free(x)) +#endif +#define trunnel_free(x) ((x) ? (trunnel_free_(x),0) : (0)) + +#ifndef trunnel_abort +#define trunnel_abort() abort() +#endif + +#ifndef trunnel_memwipe +#define trunnel_memwipe(mem, len) ((void)0) +#define trunnel_wipestr(s) ((void)0) +#else +#define trunnel_wipestr(s) do { \ + if (s) \ + trunnel_memwipe(s, strlen(s)); \ + } while (0) +#endif + +/* ====== dynamic arrays ======== */ + +#ifdef NDEBUG +#define TRUNNEL_DYNARRAY_GET(da, n) \ + ((da)->elts_[(n)]) +#else +/** Return the 'n'th element of 'da'. */ +#define TRUNNEL_DYNARRAY_GET(da, n) \ + (((n) >= (da)->n_ ? (trunnel_abort(),0) : 0), (da)->elts_[(n)]) +#endif + +/** Change the 'n'th element of 'da' to 'v'. */ +#define TRUNNEL_DYNARRAY_SET(da, n, v) do { \ + trunnel_assert((n) < (da)->n_); \ + (da)->elts_[(n)] = (v); \ + } while (0) + +/** Expand the dynamic array 'da' of 'elttype' so that it can hold at least + * 'howmanymore' elements than its current capacity. Always tries to increase + * the length of the array. On failure, run the code in 'on_fail' and goto + * trunnel_alloc_failed. */ +#define TRUNNEL_DYNARRAY_EXPAND(elttype, da, howmanymore, on_fail) do { \ + elttype *newarray; \ + newarray = trunnel_dynarray_expand(&(da)->allocated_, \ + (da)->elts_, (howmanymore), \ + sizeof(elttype)); \ + if (newarray == NULL) { \ + on_fail; \ + goto trunnel_alloc_failed; \ + } \ + (da)->elts_ = newarray; \ + } while (0) + +/** Add 'v' to the end of the dynamic array 'da' of 'elttype', expanding it if + * necessary. code in 'on_fail' and goto trunnel_alloc_failed. */ +#define TRUNNEL_DYNARRAY_ADD(elttype, da, v, on_fail) do { \ + if ((da)->n_ == (da)->allocated_) { \ + TRUNNEL_DYNARRAY_EXPAND(elttype, da, 1, on_fail); \ + } \ + (da)->elts_[(da)->n_++] = (v); \ + } while (0) + +/** Return the number of elements in 'da'. */ +#define TRUNNEL_DYNARRAY_LEN(da) ((da)->n_) + +/** Remove all storage held by 'da' and set it to be empty. Does not free + * storage held by the elements themselves. */ +#define TRUNNEL_DYNARRAY_CLEAR(da) do { \ + trunnel_free((da)->elts_); \ + (da)->elts_ = NULL; \ + (da)->n_ = (da)->allocated_ = 0; \ + } while (0) + +/** Remove all storage held by 'da' and set it to be empty. Does not free + * storage held by the elements themselves. */ +#define TRUNNEL_DYNARRAY_WIPE(da) do { \ + trunnel_memwipe((da)->elts_, (da)->allocated_ * sizeof((da)->elts_[0])); \ + } while (0) + +/** Helper: wraps or implements an OpenBSD-style reallocarray. Behaves + * as realloc(a, x*y), but verifies that no overflow will occur in the + * multiplication. Returns NULL on failure. */ +#ifndef trunnel_reallocarray +void *trunnel_reallocarray(void *a, size_t x, size_t y); +#endif + +/** Helper to expand a dynamic array. Behaves as TRUNNEL_DYNARRAY_EXPAND(), + * taking the array of elements in 'ptr', a pointer to thethe current number + * of allocated elements in allocated_p, the minimum numbeer of elements to + * add in 'howmanymore', and the size of a single element in 'eltsize'. + * + * On success, adjust *allocated_p, and return the new value for the array of + * elements. On failure, adjust nothing and return NULL. + */ +void *trunnel_dynarray_expand(size_t *allocated_p, void *ptr, + size_t howmanymore, size_t eltsize); + +/** Type for a function to free members of a dynarray of pointers. */ +typedef void (*trunnel_free_fn_t)(void *); + +/** + * Helper to change the length of a dynamic array. Takes pointers to the + * current allocated and n fields of the array in 'allocated_p' and 'len_p', + * and the current array of elements in 'ptr'; takes the length of a single + * element in 'eltsize'. Changes the length to 'newlen'. If 'newlen' is + * greater than the current length, pads the new elements with 0. If newlen + * is less than the current length, and free_fn is non-NULL, treat the + * array as an array of void *, and invoke free_fn() on each removed element. + * + * On success, adjust *allocated_p and *len_p, and return the new value for + * the array of elements. On failure, adjust nothing, set *errcode_ptr to 1, + * and return NULL. + */ +void *trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p, + void *ptr, size_t newlen, + size_t eltsize, trunnel_free_fn_t free_fn, + uint8_t *errcode_ptr); + +/** + * Helper: return a pointer to the value of 'str' as a NUL-terminated string. + * Might have to reallocate the storage for 'str' in order to fit in the final + * NUL character. On allocation failure, return NULL. + */ +const char *trunnel_string_getstr(trunnel_string_t *str); + +/** + * Helper: change the contents of 'str' to hold the 'len'-byte string in + * 'inp'. Adjusts the storage to have a terminating NUL that doesn't count + * towards the length of the string. On success, return 0. On failure, set + * *errcode_ptr to 1 and return -1. + */ +int trunnel_string_setstr0(trunnel_string_t *str, const char *inp, size_t len, + uint8_t *errcode_ptr); + +/** + * As trunnel_dynarray_setlen, but adjusts a string rather than a dynamic + * array, and ensures that the new string is NUL-terminated. + */ +int trunnel_string_setlen(trunnel_string_t *str, size_t newlen, + uint8_t *errcode_ptr); + +#endif + + +/* +Copyright 2014 The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ diff --git a/lib/trunnel/data/trunnel.c b/lib/trunnel/data/trunnel.c new file mode 100644 index 0000000..4bc28e3 --- /dev/null +++ b/lib/trunnel/data/trunnel.c @@ -0,0 +1,242 @@ +/* trunnel.c -- Helper functions to implement trunnel. + * + * Copyright 2014, The Tor Project, Inc. + * See license at the end of this file for copying information. + * + * See trunnel-impl.h for documentation of these functions. + */ + +#include <stdlib.h> +#include <string.h> +#include "trunnel-impl.h" + +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define IS_LITTLE_ENDIAN 1 +#elif defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) && \ + BYTE_ORDER == __ORDER_LITTLE_ENDIAN +# define IS_LITTLE_ENDIAN 1 +#elif defined(_WIN32) +# define IS_LITTLE_ENDIAN 1 +#elif defined(__APPLE__) +# include <libkern/OSByteOrder.h> +# define BSWAP64(x) OSSwapLittleToHostInt64(x) +#elif defined(sun) || defined(__sun) +# include <sys/byteorder.h> +# ifndef _BIG_ENDIAN +# define IS_LITTLE_ENDIAN +# endif +#else +# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +# include <sys/endian.h> +# else +# include <endian.h> +# endif +# if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ + __BYTE_ORDER == __LITTLE_ENDIAN +# define IS_LITTLE_ENDIAN +# endif +#endif + +#ifdef _WIN32 +uint16_t +trunnel_htons(uint16_t s) +{ + return (s << 8) | (s >> 8); +} +uint16_t +trunnel_ntohs(uint16_t s) +{ + return (s << 8) | (s >> 8); +} +uint32_t +trunnel_htonl(uint32_t s) +{ + return (s << 24) | + ((s << 8)&0xff0000) | + ((s >> 8)&0xff00) | + (s >> 24); +} +uint32_t +trunnel_ntohl(uint32_t s) +{ + return (s << 24) | + ((s << 8)&0xff0000) | + ((s >> 8)&0xff00) | + (s >> 24); +} +#endif + +uint64_t +trunnel_htonll(uint64_t a) +{ +#ifdef IS_LITTLE_ENDIAN + return trunnel_htonl(a>>32) | (((uint64_t)trunnel_htonl(a))<<32); +#else + return a; +#endif +} + +uint64_t +trunnel_ntohll(uint64_t a) +{ + return trunnel_htonll(a); +} + +#ifdef TRUNNEL_DEBUG_FAILING_ALLOC +/** Used for debugging and running tricky test cases: Makes the nth + * memoryation allocation call from now fail. + */ +int trunnel_provoke_alloc_failure = 0; +#endif + +void * +trunnel_dynarray_expand(size_t *allocated_p, void *ptr, + size_t howmanymore, size_t eltsize) +{ + size_t newsize = howmanymore + *allocated_p; + void *newarray = NULL; + if (newsize < 8) + newsize = 8; + if (newsize < *allocated_p * 2) + newsize = *allocated_p * 2; + if (newsize <= *allocated_p || newsize < howmanymore) + return NULL; + newarray = trunnel_reallocarray(ptr, newsize, eltsize); + if (newarray == NULL) + return NULL; + + *allocated_p = newsize; + return newarray; +} + +#ifndef trunnel_reallocarray +void * +trunnel_reallocarray(void *a, size_t x, size_t y) +{ +#ifdef TRUNNEL_DEBUG_FAILING_ALLOC + if (trunnel_provoke_alloc_failure) { + if (--trunnel_provoke_alloc_failure == 0) + return NULL; + } +#endif + if (x > SIZE_MAX / y) + return NULL; + return trunnel_realloc(a, x * y); +} +#endif + +const char * +trunnel_string_getstr(trunnel_string_t *str) +{ + trunnel_assert(str->allocated_ >= str->n_); + if (str->allocated_ == str->n_) { + TRUNNEL_DYNARRAY_EXPAND(char, str, 1, {}); + } + str->elts_[str->n_] = 0; + return str->elts_; +trunnel_alloc_failed: + return NULL; +} + +int +trunnel_string_setstr0(trunnel_string_t *str, const char *val, size_t len, + uint8_t *errcode_ptr) +{ + if (len == SIZE_MAX) + goto trunnel_alloc_failed; + if (str->allocated_ <= len) { + TRUNNEL_DYNARRAY_EXPAND(char, str, len + 1 - str->allocated_, {}); + } + memcpy(str->elts_, val, len); + str->n_ = len; + str->elts_[len] = 0; + return 0; +trunnel_alloc_failed: + *errcode_ptr = 1; + return -1; +} + +int +trunnel_string_setlen(trunnel_string_t *str, size_t newlen, + uint8_t *errcode_ptr) +{ + if (newlen == SIZE_MAX) + goto trunnel_alloc_failed; + if (str->allocated_ < newlen + 1) { + TRUNNEL_DYNARRAY_EXPAND(char, str, newlen + 1 - str->allocated_, {}); + } + if (str->n_ < newlen) { + memset(& (str->elts_[str->n_]), 0, (newlen - str->n_)); + } + str->n_ = newlen; + str->elts_[newlen] = 0; + return 0; + + trunnel_alloc_failed: + *errcode_ptr = 1; + return -1; +} + +void * +trunnel_dynarray_setlen(size_t *allocated_p, size_t *len_p, + void *ptr, size_t newlen, + size_t eltsize, trunnel_free_fn_t free_fn, + uint8_t *errcode_ptr) +{ + if (*allocated_p < newlen) { + void *newptr = trunnel_dynarray_expand(allocated_p, ptr, + newlen - *allocated_p, eltsize); + if (newptr == NULL) + goto trunnel_alloc_failed; + ptr = newptr; + } + if (free_fn && *len_p > newlen) { + size_t i; + void **elts = (void **) ptr; + for (i = newlen; i < *len_p; ++i) { + free_fn(elts[i]); + elts[i] = NULL; + } + } + if (*len_p < newlen) { + memset( ((char*)ptr) + (eltsize * *len_p), 0, (newlen - *len_p) * eltsize); + } + *len_p = newlen; + return ptr; + trunnel_alloc_failed: + *errcode_ptr = 1; + return NULL; +} + +/* +Copyright 2014 The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ diff --git a/lib/trunnel/data/trunnel.h b/lib/trunnel/data/trunnel.h new file mode 100644 index 0000000..0a78e6c --- /dev/null +++ b/lib/trunnel/data/trunnel.h @@ -0,0 +1,60 @@ +/* trunnel.h -- Public declarations for trunnel, to be included + * in trunnel header files. + + * Copyright 2014, The Tor Project, Inc. + * See license at the end of this file for copying information. + */ + +#ifndef TRUNNEL_H_INCLUDED_ +#define TRUNNEL_H_INCLUDED_ + +#include <sys/types.h> + +/** Macro to declare a variable-length dynamically allocated array. Trunnel + * uses these to store all variable-length arrays. */ +#define TRUNNEL_DYNARRAY_HEAD(name, elttype) \ + struct name { \ + size_t n_; \ + size_t allocated_; \ + elttype *elts_; \ + } + +/** Initializer for a dynamic array of a given element type. */ +#define TRUNNEL_DYNARRAY_INIT(elttype) { 0, 0, (elttype*)NULL } + +/** Typedef used for storing variable-length arrays of char. */ +typedef TRUNNEL_DYNARRAY_HEAD(trunnel_string_st, char) trunnel_string_t; + +#endif + +/* +Copyright 2014 The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ diff --git a/setup.py b/setup.py index 6d10939..99012c6 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,8 @@ setup(name='Trunnel', author='Nick Mathewson', author_email='ni...@torproject.org', url='https://gitweb.torproject.org/trunnel.git/', - package_dir={'': 'lib'}, packages=['trunnel'], + package_dir={'': 'lib'}, + package_data={'trunnel' : ['data/*.c', 'data/*.h']}, license='3-clause BSD' ) diff --git a/test/Makefile b/test/Makefile index 8bca859..ba70e8d 100644 --- a/test/Makefile +++ b/test/Makefile @@ -7,7 +7,7 @@ MORE_CFLAGS=-fno-inline --coverage CC=gcc -CFLAGS=-g -O0 -fstack-protector-all -Wstack-protector -fwrapv --param ssp-buffer-size=1 -fPIE -fasynchronous-unwind-tables -Wall -fno-strict-aliasing -Wno-deprecated-declarations -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat=2 -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch-enum -Werror -Winit-self -Wmissing-field-initializers -Wdeclaration-after-statement -Wold-style-definition -Waddress -Wmissing-noreturn -Wstrict-overflow=1 -I . -I ../include -DTRUNNEL_DEBUG_FAILING_ALLOC -DTRUNNEL_CHECK_ENCODED_LEN $(MORE_CFLAGS) +CFLAGS=-g -O0 -fstack-protector-all -Wstack-protector -fwrapv --param ssp-buffer-size=1 -fPIE -fasynchronous-unwind-tables -Wall -fno-strict-aliasing -Wno-deprecated-declarations -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat=2 -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch-enum -Werror -Winit-self -Wmissing-field-initializers -Wdeclaration-after-statement -Wold-style-definition -Waddress -Wmissing-noreturn -Wstrict-overflow=1 -I . -I ./include -DTRUNNEL_DEBUG_FAILING_ALLOC -DTRUNNEL_CHECK_ENCODED_LEN $(MORE_CFLAGS) #OTHER_FLAGS= -Qunused-arguments -Wshorten-64-to-32 TEST_OBJS = \ @@ -33,13 +33,18 @@ TEST_OBJS = \ c/test_remainder_repeats.o \ c/test_util.o +BOILERPLATE_FILES=\ + ./include/trunnel.c \ + ./include/trunnel.h \ + ./include/trunnel-impl.h \ + OBJS=tinytest/tinytest.o \ valid/simple.o \ valid/derived.o \ valid/opaque.o \ valid/leftover.o \ valid/contexts.o \ - ../c/trunnel.o \ + ./include/trunnel.o \ $(TEST_OBJS) all: ctest @@ -54,7 +59,7 @@ reset-gcov: rm -f */*.gcda ../*/*.gcda distclean: clean - rm -f valid/*.[ch] + rm -f valid/*.[ch] include/*.[ch] test: ctest ./ctest @@ -65,6 +70,7 @@ valid/opaque.o: valid/opaque.h valid/opaque.h valid/leftover.o: valid/leftover.h valid/leftover.c valid/contexts.o: valid/contexts.h $(TEST_OBJS) : tinytest/tinytest.h tinytest/tinytest_macros.h valid/simple.h valid/derived.h +$(OBJS) : include/trunnel.h include/trunnel-impl.h tinytest/tinytest.o: tinytest/tinytest.h tinytest/tinytest_macros.h valid/simple.c valid/simple.h: valid/simple.trunnel ../lib/trunnel/*py @@ -82,4 +88,5 @@ valid/leftover.c valid/leftover.h: valid/leftover.trunnel ../lib/trunnel/*py valid/contexts.c valid/contexts.h: valid/contexts.trunnel ../lib/trunnel/*py PYTHONPATH=../lib:${PYTHONPATH} python -m trunnel valid/contexts.trunnel - +$(BOILERPLATE_FILES): ../lib/trunnel/*py ../lib/trunnel/data/*.[ch] + PYTHONPATH=../lib:${PYTHONPATH} python -m trunnel --target-dir=./include --write-c-files diff --git a/test/run_tests.sh b/test/run_tests.sh index 176cfa7..c66b604 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -8,12 +8,13 @@ # Copyright 2014 The Tor Project, Inc. # See LICENSE file for copying information. -export PYTHONPATH=../lib:${PYTHONPATH} +export PYTHONPATH=`dirname $0`/../lib:${PYTHONPATH} GRAMMAR=`dirname $0`/../lib/trunnel/Grammar.py CODEGEN=`dirname $0`/../lib/trunnel/CodeGen.py TRUNNEL=`dirname $0`/../lib/trunnel/__main__.py +BOILERPLATE=`dirname $0`/../lib/trunnel/Boilerplate.py CC=gcc -CFLAGS="-g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector -fwrapv --param ssp-buffer-size=1 -fPIE -fasynchronous-unwind-tables -Wall -fno-strict-aliasing -Wno-deprecated-declarations -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat=2 -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch-enum -Werror -Winit-self -Wmissing-field-initializers -Wdeclaration-after-statement -Wold-style-definition -Waddress -Wmissing-noreturn -Wstrict-overflow=1 -I `dirname $0`/../include" +CFLAGS="-g -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-all -Wstack-protector -fwrapv --param ssp-buffer-size=1 -fPIE -fasynchronous-unwind-tables -Wall -fno-strict-aliasing -Wno-deprecated-declarations -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat=2 -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch-enum -Werror -Winit-self -Wmissing-field-initializers -Wdeclaration-after-statement -Wold-style-definition -Waddress -Wmissing-noreturn -Wstrict-overflow=1 -I `dirname $0`/include/" X=" -Wshorten-64-to-32 -Qunused-arguments" PYTHON=python @@ -37,6 +38,8 @@ for fn in `dirname $0`/failing/*.trunnel; do $RUN $TRUNNEL $fn 2>>tests.log && echo "SHOULD HAVE FAILED: $fn" done +$RUN $TRUNNEL --target-dir=`dirname $0`/include --write-c-files + # Try valid tests. for fn in `dirname $0`/valid/*.trunnel; do echo >>tests.log "==== $fn" @@ -49,7 +52,9 @@ echo >>tests.log "==== MakeGrammar" $RUN $GRAMMAR > grammar.tmp 2>>tests.log || echo "FAILED: grammar" rm -f grammar.tmp -$COVERAGE report $TRUNNEL $GRAMMAR $CODEGEN +$COVERAGE report $TRUNNEL $GRAMMAR $CODEGEN $BOILERPLATE $COVERAGE annotate $TRUNNEL $COVERAGE annotate $GRAMMAR $COVERAGE annotate $CODEGEN +$COVERAGE annotate $BOILERPLATE + _______________________________________________ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits