diff options
author | Jordan Augé <jordan.auge+fdio@cisco.com> | 2019-11-15 12:20:09 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@fd.io> | 2019-11-15 12:20:09 +0000 |
commit | 4f2b5bb4c0fb4083b4f2bb19296117c6e66e862e (patch) | |
tree | ce33d227b203121b98f6afda4179a1a3894c6f04 /ctrl | |
parent | 92bc1a46f8e33cc664a95819fde45b9b5b4ac321 (diff) | |
parent | fdb523a02680f5aa0727b862f0616ba5f8cb24cf (diff) |
Merge "[HICN-386] Improve API error management in libhicnctrl"
Diffstat (limited to 'ctrl')
28 files changed, 282 insertions, 1887 deletions
diff --git a/ctrl/facemgr/includes/CMakeLists.txt b/ctrl/facemgr/includes/CMakeLists.txt index eaf8b88a0..d2510c205 100644 --- a/ctrl/facemgr/includes/CMakeLists.txt +++ b/ctrl/facemgr/includes/CMakeLists.txt @@ -22,12 +22,10 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Android") set(TO_INSTALL_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/facemgr.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/facemgr/api.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/facemgr/cfg.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/facemgr/facelet.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/facemgr/loop.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/log.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/android_utility/android_utility.h PARENT_SCOPE ) @@ -40,7 +38,6 @@ else () ${CMAKE_CURRENT_SOURCE_DIR}/hicn/facemgr/cfg.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/facemgr/facelet.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn/facemgr/loop.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn/util/log.h PARENT_SCOPE ) diff --git a/ctrl/facemgr/includes/hicn/util/log.h b/ctrl/facemgr/includes/hicn/util/log.h deleted file mode 100644 index f1cafba47..000000000 --- a/ctrl/facemgr/includes/hicn/util/log.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UTIL_LOG_H -#define UTIL_LOG_H - -#include <stdarg.h> // va_* -#include <stdio.h> // FILE -#include <time.h> // time, localtime - -#define LOG_FATAL 0 -#define LOG_ERROR 1 -#define LOG_WARN 2 -#define LOG_INFO 3 -#define LOG_DEBUG 4 -#define LOG_TRACE 5 - -typedef struct { - int log_level; - int debug; - FILE * log_file; -} log_conf_t; - -#define DEFAULT_LOG_CONF { \ - .log_level = LOG_DEBUG, \ - .debug = 0, \ - .log_file = NULL, \ -}; - -extern log_conf_t log_conf; - -#define WITH_DEBUG(BLOCK) \ - if (log_conf.log_level >= LOG_DEBUG) \ - BLOCK - -#define FATAL(fmt, ...) (_log(LOG_FATAL, fmt, ##__VA_ARGS__ )) -#define ERROR(fmt, ...) (_log(LOG_ERROR, fmt, ##__VA_ARGS__ )) -#define WARN(fmt, ...) (_log(LOG_WARN, fmt, ##__VA_ARGS__ )) -#define INFO(fmt, ...) (_log(LOG_INFO, fmt, ##__VA_ARGS__ )) -#define DEBUG(fmt, ...) (_log(LOG_DEBUG, fmt, ##__VA_ARGS__ )) -#define TRACE(fmt, ...) (_log(LOG_TRACE, fmt, ##__VA_ARGS__ )) - -void _log_va(int level, const char *fmt, va_list ap); - -void _log(int level, const char *fmt, ...); - -void fatal(char *fmt, ...); - -#ifdef HAVE_BACKTRACE -#include <execinfo.h> -void print_trace(void); -#endif - -#endif // UTIL_LOG_H diff --git a/ctrl/facemgr/src/CMakeLists.txt b/ctrl/facemgr/src/CMakeLists.txt index 7069d1fdc..e675c7785 100644 --- a/ctrl/facemgr/src/CMakeLists.txt +++ b/ctrl/facemgr/src/CMakeLists.txt @@ -25,10 +25,6 @@ set(HEADER_FILES facelet_array.h interface.h loop.h - util/hash.h - util/array.h - util/map.h - util/set.h ) set(SOURCE_FILES @@ -39,7 +35,6 @@ set(SOURCE_FILES facelet.c facelet_array.c interface.c - util/log.c ) if(APPLE) diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c index 373e55422..23ca2f2ae 100644 --- a/ctrl/facemgr/src/api.c +++ b/ctrl/facemgr/src/api.c @@ -30,6 +30,8 @@ #include <hicn/facemgr/cfg.h> #include <hicn/facemgr/facelet.h> #include <hicn/util/log.h> +#include <hicn/util/map.h> +#include <hicn/util/set.h> #ifdef __APPLE__ #include "interfaces/network_framework/network_framework.h" @@ -48,8 +50,6 @@ #include "common.h" #include "facelet_array.h" #include "interface.h" -#include "util/map.h" -#include "util/set.h" #define RAND_NAME_LEN 5 diff --git a/ctrl/facemgr/src/cfg.c b/ctrl/facemgr/src/cfg.c index 20c8d8332..e324d04c3 100644 --- a/ctrl/facemgr/src/cfg.c +++ b/ctrl/facemgr/src/cfg.c @@ -9,7 +9,7 @@ #include <hicn/policy.h> #include <hicn/util/ip_address.h> #include "facelet_array.h" -#include "util/set.h" +#include <hicn/util/set.h> /* Overlay */ diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c index ccd8b54c9..7a34b18c8 100644 --- a/ctrl/facemgr/src/facelet.c +++ b/ctrl/facemgr/src/facelet.c @@ -25,8 +25,7 @@ #include <hicn/facemgr/cfg.h> #include <hicn/facemgr/facelet.h> #include <hicn/util/log.h> - -#include "util/set.h" +#include <hicn/util/set.h> #define FACELET_MAX_ROUTES 10 diff --git a/ctrl/facemgr/src/facelet_array.c b/ctrl/facemgr/src/facelet_array.c index 4d7f30862..3ee110b8e 100644 --- a/ctrl/facemgr/src/facelet_array.c +++ b/ctrl/facemgr/src/facelet_array.c @@ -19,8 +19,8 @@ */ #include <hicn/facemgr/facelet.h> +#include <hicn/util/array.h> #include "facelet_array.h" -#include "util/array.h" TYPEDEF_ARRAY(facelet_array, facelet_t *, facelet_equals, facelet_snprintf); diff --git a/ctrl/facemgr/src/facelet_array.h b/ctrl/facemgr/src/facelet_array.h index 8febe7885..099774691 100644 --- a/ctrl/facemgr/src/facelet_array.h +++ b/ctrl/facemgr/src/facelet_array.h @@ -22,7 +22,7 @@ #include <hicn/facemgr/facelet.h> -#include "util/array.h" +#include <hicn/util/array.h> TYPEDEF_ARRAY_H(facelet_array, facelet_t *); diff --git a/ctrl/facemgr/src/interface.c b/ctrl/facemgr/src/interface.c index d592bf04c..3d6328d6d 100644 --- a/ctrl/facemgr/src/interface.c +++ b/ctrl/facemgr/src/interface.c @@ -24,9 +24,9 @@ #include <hicn/facemgr/facelet.h> #include <hicn/facemgr/loop.h> /* *_callback_data_t */ +#include <hicn/util/map.h> #include "interface.h" -#include "util/map.h" TYPEDEF_MAP_H(interface_ops_map, const char *, const interface_ops_t *); TYPEDEF_MAP(interface_ops_map, const char *, const interface_ops_t *, strcmp, string_snprintf, generic_snprintf); diff --git a/ctrl/facemgr/src/interfaces/bonjour/bonjour.c b/ctrl/facemgr/src/interfaces/bonjour/bonjour.c index 87f1e1257..10e757245 100644 --- a/ctrl/facemgr/src/interfaces/bonjour/bonjour.c +++ b/ctrl/facemgr/src/interfaces/bonjour/bonjour.c @@ -24,10 +24,10 @@ #include <hicn/facemgr.h> #include <hicn/util/log.h> +#include <hicn/util/map.h> #include "../../common.h" #include "../../interface.h" -#include "../../util/map.h" #include "mdns/mdns.h" #include "bonjour.h" diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c index 756d85738..945b60af2 100644 --- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c +++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c @@ -26,9 +26,9 @@ #include <hicn/facemgr.h> #include <hicn/util/ip_address.h> #include <hicn/util/log.h> +#include <hicn/util/map.h> #include "../../interface.h" -#include "../../util/map.h" #define DEFAULT_ROUTE_COST 0 diff --git a/ctrl/facemgr/src/interfaces/network_framework/network_framework.c b/ctrl/facemgr/src/interfaces/network_framework/network_framework.c index 01c40c0b7..2c4bff513 100644 --- a/ctrl/facemgr/src/interfaces/network_framework/network_framework.c +++ b/ctrl/facemgr/src/interfaces/network_framework/network_framework.c @@ -29,11 +29,11 @@ #include <hicn/facemgr.h> #include <hicn/util/token.h> #include <hicn/util/log.h> +#include <hicn/util/map.h> #include "../../common.h" #include <hicn/ctrl/face.h> #include "../../interface.h" -#include "../../util/map.h" #include "network_framework.h" diff --git a/ctrl/facemgr/src/loop_libevent.c b/ctrl/facemgr/src/loop_libevent.c index 966129730..92d5eb5ef 100644 --- a/ctrl/facemgr/src/loop_libevent.c +++ b/ctrl/facemgr/src/loop_libevent.c @@ -37,7 +37,7 @@ #include <hicn/util/log.h> #include <hicn/facemgr/loop.h> -#include "util/map.h" +#include <hicn/util/map.h> /** * \brief Holds all callback parameters diff --git a/ctrl/facemgr/src/main.c b/ctrl/facemgr/src/main.c index eeb0a0259..da5e55943 100644 --- a/ctrl/facemgr/src/main.c +++ b/ctrl/facemgr/src/main.c @@ -27,16 +27,14 @@ #include <unistd.h> // sleep #include <hicn/facemgr.h> +#include <hicn/facemgr/cfg.h> +#include <hicn/facemgr/loop.h> #include <hicn/policy.h> - #include <hicn/util/ip_address.h> #include <hicn/util/log.h> - -#include <hicn/facemgr/cfg.h> -#include <hicn/facemgr/loop.h> +#include <hicn/util/map.h> #include "cfg_file.h" -#include "util/map.h" #define FACEMGR_TIMEOUT 3 diff --git a/ctrl/facemgr/src/util/array.h b/ctrl/facemgr/src/util/array.h deleted file mode 100644 index ab8852ed8..000000000 --- a/ctrl/facemgr/src/util/array.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * \file array.h - * \brief Generic array template - */ - -#ifndef UTIL_ARRAY_H -#define UTIL_ARRAY_H - -#include <assert.h> -#include <hicn/util/log.h> -#include <math.h> // log2 -#include <string.h> // memmove - -#define BUFSIZE 1024 - -typedef int(*cmp_t)(const void * x, const void * y); - -#define TYPEDEF_ARRAY_H(NAME, T) \ - \ -typedef struct { \ - size_t size; \ - size_t max_size_log; \ - T * elements; \ -} NAME ## _t; \ - \ -int NAME ## _initialize(NAME ## _t * array); \ - \ -int NAME ## _finalize(NAME ## _t * array); \ - \ -NAME ## _t * NAME ## _create(); \ - \ -void NAME ## _free(NAME ## _t * array); \ - \ -int NAME ## _add(NAME ## _t * array, T element); \ - \ -int NAME ## _remove_index(NAME ## _t * array, int index, T * element); \ - \ -int NAME ## _remove(NAME ## _t * array, const T search, T * element); \ - \ -int NAME ## _get(const NAME ## _t * array, const T search, T * element); \ - \ -int NAME ## _get_index(const NAME ## _t * array, int index, T * element); \ - \ -int NAME ## _get_elements(const NAME ## _t * array, T ** elements); \ - \ -size_t NAME ## _len(const NAME ## _t * array); - - -#define ARRAY_MAX_SIZE_LOG_INIT 0 - -#define TYPEDEF_ARRAY(NAME, T, CMP, SNPRINTF) \ -int \ -NAME ## _initialize(NAME ## _t * array) \ -{ \ - array->max_size_log = ARRAY_MAX_SIZE_LOG_INIT; \ - array->size = 0; \ - if (array->max_size_log == 0) { \ - array->elements = NULL; \ - return 0; \ - } \ - array->elements = malloc((1 << array->max_size_log) * sizeof(T)); \ - if (!array->elements) \ - return -1; \ - return 0; \ -} \ - \ -int \ -NAME ## _finalize(NAME ## _t * array) \ -{ \ - for (unsigned i = 0; i < array->size; i++) { \ - NAME ## _remove_index(array, i, NULL); \ - } \ - return 0; \ -} \ - \ -NAME ## _t * \ -NAME ## _create() \ -{ \ - NAME ## _t * array = malloc(sizeof(NAME ## _t)); \ - if (!array) \ - goto ERR_MALLOC; \ - \ - if (NAME ## _initialize(array) < 0) \ - goto ERR_INITIALIZE; \ - \ - return array; \ - \ -ERR_INITIALIZE: \ - free(array); \ -ERR_MALLOC: \ - return NULL; \ -} \ - \ -void \ -NAME ## _free(NAME ## _t * array) \ -{ \ - NAME ## _finalize(array); \ - free(array->elements); \ - free(array); \ -} \ - \ -int \ -NAME ## _add(NAME ## _t * array, T element) \ -{ \ - /* Ensure sufficient space for next addition */ \ - size_t new_size_log = (array->size > 0) ? log2(array->size)+1 : 1; \ - if (new_size_log > array->max_size_log) { \ - array->max_size_log = new_size_log; \ - array->elements = realloc(array->elements, \ - (1 << new_size_log) * sizeof(T)); \ - } \ - \ - if (!array->elements) \ - goto ERR_REALLOC; \ - \ - array->elements[array->size++] = element; \ - return 0; \ - \ -ERR_REALLOC: \ - return -1; \ -} \ - \ -int \ -NAME ## _remove_index(NAME ## _t * array, int index, T * element) \ -{ \ - if (index > NAME ## _len(array)) \ - return -1; \ - if (element) \ - *element = array->elements[index]; \ - if (index < array->size) \ - memmove(array->elements + index, array->elements + index + 1, \ - array->size - index); \ - array->size--; \ - return 0; \ -} \ - \ -int \ -NAME ## _remove(NAME ## _t * array, const T search, T * element) \ -{ \ - for (unsigned i = 0; i < array->size; i++) { \ - if (CMP(search, array->elements[i]) == 0) \ - return facelet_array_remove_index(array, i, element); \ - } \ - /* Not found */ \ - if (element) \ - *element = NULL; \ - return 0; \ -} \ - \ -int \ -NAME ## _get(const NAME ## _t * array, const T search, T * element) \ -{ \ - assert(element); \ - for (unsigned i = 0; i < array->size; i++) \ - if (CMP(search, array->elements[i]) == 0) \ - *element = array->elements[i]; \ - return 0; \ - /* Not found */ \ - *element = NULL; \ - return 0; \ -} \ - \ -int \ -NAME ## _get_index(const NAME ## _t * array, int index, T * element) \ -{ \ - assert(element); \ - *element = array->elements[index]; \ - return 0; \ -} \ - \ -int \ -NAME ## _get_elements(const NAME ## _t * array, T ** elements) \ -{ \ - *elements = array->elements; \ - return 0; \ -} \ - \ -size_t \ -NAME ## _len(const NAME ## _t * array) \ -{ \ - return array->size; \ -} - -#endif /* UTIL_ARRAY_H */ diff --git a/ctrl/facemgr/src/util/hash.h b/ctrl/facemgr/src/util/hash.h deleted file mode 100644 index 04b08eb54..000000000 --- a/ctrl/facemgr/src/util/hash.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * \file hash.h - * \brief Simple non-cryptographic hash implementation. - * - * Two helpers are provided : - * hash(buf, len) : hash a buffer <buf> of length <len> - * hash_struct(buf) : hash a buffer corresponding to an allocated struct - * - * This file consists in excerpts from Jenkins hash (public domain). - * http://www.burtleburtle.net/bob/c/lookup3.c - */ -#ifndef UTIL_HASH_H -#define UTIL_HASH_H - -#include "../common.h" - -#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ - __BYTE_ORDER == __LITTLE_ENDIAN) || \ - (defined(i386) || defined(__i386__) || defined(__i486__) || \ - defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 -#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ - __BYTE_ORDER == __BIG_ENDIAN) || \ - (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 -#else -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 0 -#endif - -#define hashsize(n) ((uint32_t)1<<(n)) -#define hashmask(n) (hashsize(n)-1) -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - -static inline -uint32_t hashlittle( const void *key, size_t length, uint32_t initval) -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : return c; - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - -/* Helpers */ - -#define HASH_INITVAL 1 -#define hash(buf, len) (hash_t)hashlittle(buf, len, HASH_INITVAL) -#define hash_struct(buf) hash(buf, sizeof(buf)) - -#endif /* UTIL_JENKINS_HASH_H */ diff --git a/ctrl/facemgr/src/util/log.c b/ctrl/facemgr/src/util/log.c deleted file mode 100644 index c1fc999ad..000000000 --- a/ctrl/facemgr/src/util/log.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <hicn/util/log.h> - -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> - -#ifdef __ANDROID__ -#include <android/log.h> -#endif - -log_conf_t log_conf = DEFAULT_LOG_CONF; - -#define FMT_DATETIME "%02d-%02d-%04d %02d:%02d:%02d" -#define FMT_DATETIME_LEN 20 -#define snprintf_nowarn(...) (snprintf(__VA_ARGS__) < 0 ? abort() : (void)0) - - -static char ts[FMT_DATETIME_LEN]; - -static char *timestamp(void) -{ - time_t tv; - struct tm *tm; - - time(&tv); - tm = localtime(&tv); - - snprintf_nowarn(ts, FMT_DATETIME_LEN, FMT_DATETIME, tm->tm_mday, - tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, - tm->tm_sec); - return ts; -} - -void _log_va(int level, const char *fmt, va_list ap) -{ - -#if 0 - if (!conf.log_system) - return; -#endif - - char *prefix; - -#ifdef __ANDROID__ - int prio = -1; - if (level > log_conf.log_level) - return; - - switch (level) { - case LOG_FATAL: - prio = ANDROID_LOG_FATAL; - prefix = "FATAL: "; - break; - case LOG_ERROR: - prio = ANDROID_LOG_ERROR; - prefix = "ERROR: "; - break; - case LOG_WARN: - prio = ANDROID_LOG_WARN; - prefix = "WARNING: "; - break; - case LOG_INFO: - prio = ANDROID_LOG_INFO; - prefix = ""; - break; - case LOG_DEBUG: - prio = ANDROID_LOG_DEBUG; - prefix = "DEBUG: "; - break; - case LOG_TRACE: - prio = ANDROID_LOG_DEBUG; - prefix = "TRACE: "; - break; - default: - prio = ANDROID_LOG_INFO; - prefix = ""; - break; - } - - if (log_conf.log_file) { - FILE *f = log_conf.log_file; - fprintf(f, "%s %s", timestamp(), prefix); - vfprintf(f, fmt, ap); - fprintf(f, "\n"); - } else { - __android_log_vprint(ANDROID_LOG_INFO, "HICN FACEMGR", fmt, ap); - } - -#else - - if (level > log_conf.log_level) - return; - - switch (level) { - case LOG_FATAL: - prefix = "FATAL: "; - break; - case LOG_ERROR: - prefix = "ERROR: "; - break; - case LOG_WARN: - prefix = "WARNING: "; - break; - case LOG_INFO: - prefix = ""; - break; - case LOG_DEBUG: - prefix = "DEBUG: "; - break; - case LOG_TRACE: - prefix = "TRACE: "; - break; - default: - prefix = ""; - break; - } - FILE *f = log_conf.log_file ? log_conf.log_file : stdout; - fprintf(f, "%s %s", timestamp(), prefix); - vfprintf(f, fmt, ap); - fprintf(f, "\n"); -#ifdef DEBUG - fflush(f); -#endif -#endif -} - -void _log(int level, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _log_va(level, fmt, ap); - va_end(ap); -} - -#ifdef HAVE_BACKTRACE -#include <execinfo.h> - -void print_trace(void) -{ - void *array[32]; - size_t size; - - size = backtrace(array, 32); - fflush(conf.log_file); - backtrace_symbols_fd(array, size, fileno(conf.log_file)); -} -#endif - -void fatal(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _log_va(LOG_FATAL, fmt, ap); - va_end(ap); - -#ifdef HAVE_BACKTRACE - print_trace(); -#endif - - exit(200); -} diff --git a/ctrl/facemgr/src/util/map.h b/ctrl/facemgr/src/util/map.h deleted file mode 100644 index adab8d758..000000000 --- a/ctrl/facemgr/src/util/map.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UTIL_MAP_H -#define UTIL_MAP_H - -#include <stdlib.h> - -#include "set.h" - -#define ERR_MAP_EXISTS -2 -#define ERR_MAP_NOT_FOUND -3 - -#define TYPEDEF_MAP_H(NAME, KEY_T, VAL_T) \ - \ -typedef struct { \ - KEY_T key; \ - VAL_T value; \ -} NAME ## _pair_t; \ - \ -NAME ## _pair_t * NAME ## _pair_create(KEY_T key, VAL_T value); \ - \ -void NAME ## _pair_free(NAME ## _pair_t * pair); \ - \ -int NAME ## _pair_cmp(const NAME ## _pair_t * p1, const NAME ## _pair_t * p2); \ - \ -TYPEDEF_SET_H(NAME ## _pair_set, NAME ## _pair_t *) \ - \ -typedef struct NAME ## _s { \ - NAME ## _pair_set_t pair_set; \ -} NAME ## _t; \ - \ -int NAME ## _initialize(NAME ## _t * map); \ - \ -int NAME ## _finalize(NAME ## _t * map); \ - \ -NAME ## _t * NAME ## _create(); \ - \ -void NAME ## _free(NAME ## _t * map); \ - \ -int NAME ## _add(NAME ## _t * map, KEY_T key, VAL_T value); \ - \ -int NAME ## _remove(NAME ## _t * map, KEY_T key, VAL_T * value); \ - \ -int NAME ## _get(NAME ## _t * map, KEY_T key, VAL_T * value); \ - \ -void NAME ## _dump(NAME ## _t * map); - - - - -#define TYPEDEF_MAP(NAME, KEY_T, VAL_T, CMP, KEY_SNPRINTF, VALUE_SNPRINTF) \ - \ -NAME ## _pair_t * NAME ## _pair_create(KEY_T key, VAL_T value) \ -{ \ - /* Create pair */ \ - NAME ## _pair_t * pair = malloc(sizeof(NAME ## _pair_t)); \ - if (!pair) \ - return NULL; \ - \ - pair->key = key; \ - pair->value = value; \ - \ - return pair; \ -} \ - \ -void NAME ## _pair_free(NAME ## _pair_t * pair) \ -{ \ - free(pair); \ -} \ - \ -int \ -NAME ## _pair_cmp(const NAME ## _pair_t * p1, const NAME ## _pair_t * p2) \ -{ \ - return (CMP(p1->key, p2->key)); \ -} \ - \ -int \ -NAME ## _pair_snprintf(char * buf, size_t size, const NAME ## _pair_t * pair) { \ - int rc; \ - rc = KEY_SNPRINTF(buf, BUFSIZE/2, (KEY_T)pair->key); \ - if (rc < 0) \ - return rc; \ - rc = VALUE_SNPRINTF(buf+rc, BUFSIZE/2, (VAL_T)pair->value); \ - return rc; \ -} \ - \ -TYPEDEF_SET(NAME ## _pair_set, NAME ## _pair_t *, NAME ## _pair_cmp, NAME ## _pair_snprintf); \ - \ -int \ -NAME ## _initialize(NAME ## _t * map) \ -{ \ - return NAME ## _pair_set_initialize(&map->pair_set); \ -} \ - \ -int \ -NAME ## _finalize(NAME ## _t * map) \ -{ \ - NAME ## _pair_t ** array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &array); \ - if (n < 0) \ - return -1; \ - for (unsigned i = 0; i < n; i++) { \ - NAME ## _pair_t * pair = array[i]; \ - NAME ## _pair_set_remove(&map->pair_set, pair, NULL); \ - NAME ## _pair_free(pair); \ - } \ - free(array); \ - return NAME ## _pair_set_finalize(&map->pair_set); \ -} \ - \ -NAME ## _t * \ -NAME ## _create() \ -{ \ - NAME ## _t * map = malloc(sizeof(NAME ## _t)); \ - if (!map) \ - goto ERR_MALLOC; \ - \ - if (NAME ## _initialize(map) < 0) \ - goto ERR_INITIALIZE; \ - \ - return map; \ - \ -ERR_INITIALIZE: \ - free(map); \ -ERR_MALLOC: \ - return NULL; \ -} \ - \ -void \ -NAME ## _free(NAME ## _t * map) \ -{ \ - NAME ## _finalize(map); \ - free(map); \ -} \ - \ -int \ -NAME ## _add(NAME ## _t * map, KEY_T key, VAL_T value) \ -{ \ - int rc; \ - NAME ## _pair_t * found = NULL; \ - \ - NAME ## _pair_t * pair = NAME ## _pair_create(key, value); \ - if (!pair) \ - return -1; \ - \ - rc = NAME ## _pair_set_get(&map->pair_set, pair, &found); \ - if (rc < 0) \ - return -1; \ - if (found) { \ - NAME ## _pair_free(pair); \ - return ERR_MAP_EXISTS; \ - } \ - \ - rc = NAME ## _pair_set_add(&map->pair_set, pair); \ - if (rc < 0) { \ - NAME ## _pair_free(pair); \ - return -1; \ - } \ - return 0; \ -} \ - \ -int \ -NAME ## _remove(NAME ## _t * map, KEY_T key, VAL_T * value) \ -{ \ - NAME ## _pair_t * found = NULL; \ - NAME ## _pair_t search = { .key = key }; \ - int rc = NAME ## _pair_set_remove(&map->pair_set, &search, &found); \ - if (rc < 0) \ - return ERR_MAP_NOT_FOUND; \ - if (value) \ - *value = found->value; \ - NAME ## _pair_free(found); \ - return 0; \ -} \ - \ -int \ -NAME ## _get(NAME ## _t * map, KEY_T key, VAL_T * value) \ -{ \ - NAME ## _pair_t * found = NULL, search = { .key = key }; \ - int rc = NAME ## _pair_set_get(&map->pair_set, &search, &found); \ - if (rc < 0) \ - return -1; \ - if (found) \ - *value = found->value; \ - return 0; \ -} \ - \ -void \ -NAME ## _dump(NAME ## _t * map) { \ - NAME ## _pair_set_dump(&map->pair_set); \ -} \ - \ -int \ -NAME ## _get_key_array(NAME ## _t * map, KEY_T **array) { \ - NAME ## _pair_t ** pair_array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &pair_array); \ - if (n < 0) \ - return -1; \ - /* Allocate result array */ \ - *array = malloc(n * sizeof(KEY_T)); \ - if (!array) { \ - free(pair_array); \ - return -1; \ - } \ - /* Copy keys */ \ - for (int i = 0; i < n; i++) \ - (*array)[i] = pair_array[i]->key; \ - free(pair_array); \ - return n; \ -} \ - \ -int \ -NAME ## _get_value_array(NAME ## _t * map, VAL_T **array) { \ - NAME ## _pair_t ** pair_array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &pair_array); \ - if (n < 0) \ - return -1; \ - /* Allocate result array */ \ - *array = malloc(n * sizeof(VAL_T)); \ - if (!array) { \ - free(pair_array); \ - return -1; \ - } \ - /* Copy values */ \ - for (int i = 0; i < n; i++) \ - (*array)[i] = pair_array[i]->value; \ - free(pair_array); \ - return n; \ -} - -#endif /* UTIL_MAP_H */ diff --git a/ctrl/facemgr/src/util/set.h b/ctrl/facemgr/src/util/set.h deleted file mode 100644 index b9d66c16e..000000000 --- a/ctrl/facemgr/src/util/set.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UTIL_SET_H -#define UTIL_SET_H - -#include <hicn/util/log.h> -#include <search.h> -#include <string.h> -//#if !defined(__ANDROID__) && !defined(__APPLE__) -//#include <threads.h> -//#else -#define thread_local _Thread_local -//#endif /* ! __ANDROID__ */ - -#define ERR_SET_EXISTS -2 -#define ERR_SET_NOT_FOUND -3 - -/* FIXME: buffer overflow when this is too small... investigate */ -#define BUFSIZE 1024 - -static inline -int -int_cmp(const int x, const int y) -{ - return x - y; -} - -static inline -int -int_snprintf(char * buf, size_t size, int value) { - return snprintf(buf, size, "%d", value); -} - -static inline -int -string_snprintf(char * buf, size_t size, const char * s) { - return snprintf(buf, size, "%s", s); -} - -static inline -int -generic_snprintf(char * buf, size_t size, const void * value) { - return snprintf(buf, BUFSIZE, "%p", value); -} - -typedef int(*cmp_t)(const void * x, const void * y); - -#define TYPEDEF_SET_H(NAME, T) \ - \ -typedef struct { \ - size_t size; \ - void * root; \ -} NAME ## _t; \ - \ -int NAME ## _initialize(NAME ## _t * set); \ - \ -int NAME ## _finalize(NAME ## _t * set); \ - \ -NAME ## _t * NAME ## _create(); \ - \ -void NAME ## _free(NAME ## _t * set); \ - \ -int NAME ## _add(NAME ## _t * set, const T element); \ - \ -int NAME ## _remove(NAME ## _t * set, const T search, T * element); \ - \ -int NAME ## _get(const NAME ## _t * set, const T search, T * element); \ - \ -int NAME ## _get_array(const NAME ## _t * set, T ** element); \ - \ -void NAME ## _dump(NAME ## _t * set); - - - - -#define TYPEDEF_SET(NAME, T, CMP, SNPRINTF) \ -int \ -NAME ## _initialize(NAME ## _t * set) \ -{ \ - set->root = NULL; \ - set->size = 0; \ - return 0; \ -} \ - \ -int \ -NAME ## _finalize(NAME ## _t * set) \ -{ \ - T * array; \ - int n = NAME ## _get_array(set, &array); \ - if (n < 0) \ - return -1; \ - for (unsigned i = 0; i < n; i++) { \ - T element = array[i]; \ - NAME ## _remove(set, element, NULL); \ - } \ - free(array); \ - return 0; \ -} \ - \ -NAME ## _t * \ -NAME ## _create() \ -{ \ - NAME ## _t * set = malloc(sizeof(NAME ## _t)); \ - if (!set) \ - goto ERR_MALLOC; \ - \ - if (NAME ## _initialize(set) < 0) \ - goto ERR_INITIALIZE; \ - \ - return set; \ - \ -ERR_INITIALIZE: \ - free(set); \ -ERR_MALLOC: \ - return NULL; \ -} \ - \ -void \ -NAME ## _free(NAME ## _t * set) \ -{ \ - NAME ## _finalize(set); \ - free(set); \ -} \ - \ -int \ -NAME ## _add(NAME ## _t * set, const T element) \ -{ \ - void * ptr = tsearch(element, &set->root, (cmp_t)CMP); \ - if (!ptr) \ - return -1; \ - set->size++; \ - return 0; \ -} \ - \ -int \ -NAME ## _remove(NAME ## _t * set, const T search, T * element) \ -{ \ - T * found = tfind(search, &set->root, (cmp_t)CMP); \ - if (!found) \ - return ERR_SET_NOT_FOUND; \ - if (element) \ - *element = *found; \ - tdelete(search, &set->root, (cmp_t)CMP); \ - set->size--; \ - return 0; \ -} \ - \ -int \ -NAME ## _get(const NAME ## _t * set, const T search, T * element) \ -{ \ - T * found = tfind(search, &set->root, (cmp_t)CMP); \ - if (element) \ - *element = found ? *found : NULL; \ - return 0; \ -} \ - \ -static void \ -NAME ## _dump_node(const void *nodep, const VISIT which, \ - const int depth) \ -{ \ - char buf[BUFSIZE]; \ - switch (which) { \ - case preorder: \ - case endorder: \ - break; \ - case postorder: \ - case leaf: \ - SNPRINTF(buf, BUFSIZE, *(T*)nodep); \ - INFO("%s", buf); \ - break; \ - } \ -} \ - \ -void \ -NAME ## _dump(NAME ## _t * set) { \ - twalk(set->root, NAME ## _dump_node); \ -} \ - \ -thread_local \ -T * NAME ## _array_pos = NULL; \ - \ -static void \ -NAME ## _add_node_to_array(const void *nodep, const VISIT which, \ - const int depth) \ -{ \ - if (!NAME ## _array_pos) \ - return; \ - switch (which) { \ - case preorder: \ - case endorder: \ - break; \ - case postorder: \ - case leaf: \ - *NAME ## _array_pos = *(T*)nodep; \ - NAME ## _array_pos++; \ - break; \ - } \ -} \ - \ -int \ -NAME ## _get_array(const NAME ## _t * set, T ** element) \ -{ \ - *element = malloc(set->size * sizeof(T)); \ - if (!*element) \ - return -1; \ - NAME ## _array_pos = *element; \ - twalk(set->root, NAME ## _add_node_to_array); \ - NAME ## _array_pos = NULL; \ - return set->size; \ -} - -#endif /* UTIL_SET_H */ diff --git a/ctrl/libhicnctrl/examples/Makefile b/ctrl/libhicnctrl/examples/Makefile index a6c6f0570..641936f4f 100644 --- a/ctrl/libhicnctrl/examples/Makefile +++ b/ctrl/libhicnctrl/examples/Makefile @@ -1,7 +1,7 @@ EXEC = $(shell basename $$(pwd)) CC = gcc -CFLAGS = -std=gnu11 -O3 -Wall -Wextra -Wpedantic -Wstrict-aliasing -DWITH_POLICY=1 +CFLAGS = -std=gnu11 -g -Wall -Wextra -Wpedantic -Wstrict-aliasing -DWITH_POLICY=1 LDFLAGS = -lhicn -lhicnctrl SRC = $(wildcard *.c) diff --git a/ctrl/libhicnctrl/examples/create_face.c b/ctrl/libhicnctrl/examples/create_face.c index 270ceeab9..dcacaeff1 100644 --- a/ctrl/libhicnctrl/examples/create_face.c +++ b/ctrl/libhicnctrl/examples/create_face.c @@ -52,12 +52,15 @@ int get_local_info(char * if_name, ip_address_t * local_ip) { snprintf(if_name, IFNAMSIZ, "%s", tmp->ifa_name); snprintf(ifr.ifr_name, IFNAMSIZ, "%s", tmp->ifa_name); - if (ioctl(fd, SIOCGIFADDR, &ifr) == 1) { - perror("ioctl"); + if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) { + //perror("ioctl"); continue; } + *local_ip = IP_ADDRESS_EMPTY; local_ip->v4.as_inaddr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; + if (ip_address_empty(local_ip)) + continue; ret = 0; break; @@ -79,7 +82,7 @@ int main() { if (get_local_info(if_name, &local_ip) < 0) { DEBUG("Error getting local information"); - return -1; + goto ERR_INIT; } char local_ip_str[MAXSZ_IP_ADDRESS]; @@ -90,22 +93,26 @@ int main() { if (ip_address_pton (remote_ip_str, &remote_ip) < 0){ DEBUG("Error parsing remote IP address"); - return -1; + goto ERR_INIT; } /* Filling face information */ hc_face_t face = { .face = { .type = FACE_TYPE_UDP, + .family = AF_INET, .local_addr = local_ip, .remote_addr = remote_ip, .local_port = 6000, .remote_port = 6000, + .admin_state = FACE_STATE_UNDEFINED, + .state = FACE_STATE_UNDEFINED, + .tags = POLICY_TAGS_EMPTY, }, }; if (netdevice_set_name(&face.face.netdevice, if_name) < 0) { DEBUG("Error setting face netdevice name"); - return -1; + goto ERR_INIT; } /* Connecting to socket and creating face */ @@ -113,22 +120,24 @@ int main() { hc_sock_t * socket = hc_sock_create(); if (!socket){ DEBUG("Error creating libhicnctrl socket"); - return -1; + goto ERR_SOCK; } if (hc_sock_connect(socket) < 0){ DEBUG("Error connecting to forwarder"); - return -1; + goto ERR; } if (hc_face_create(socket, &face) < 0){ DEBUG("Error creating face"); - return -1; + goto ERR; } DEBUG("Face created successfully"); +ERR: hc_sock_free(socket); - +ERR_SOCK: +ERR_INIT: return 0; } diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h index f522010cd..b3032d0f3 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h @@ -74,6 +74,8 @@ #define HICN_DEFAULT_PORT 9695 +#define HOTFIXMARGIN 0 + /* Helper for avoiding warnings about type-punning */ #define UNION_CAST(x, destType) \ (((union {__typeof__(x) a; destType b;})x).b) @@ -124,6 +126,7 @@ typedef struct hc_data_s { /* Callbacks */ data_callback_t complete_cb; // XXX int (*complete_cb)(struct hc_data_s * data); void * complete_cb_data; + int ret; } hc_data_t; /** @@ -412,7 +415,7 @@ foreach_connection_type } hc_connection_type_t; #define MAXSZ_HC_CONNECTION_TYPE_ 9 -#define MAXSZ_HC_CONNECTION_TYPE MAXSZ_HC_CONNECTION_TYPE_ + NULLTERM +#define MAXSZ_HC_CONNECTION_TYPE MAXSZ_HC_CONNECTION_TYPE_ + NULLTERM + HOTFIXMARGIN extern const char * connection_type_str[]; @@ -574,7 +577,7 @@ int hc_face_list_async(hc_sock_t * s); //, hc_data_t ** pdata); #define MAXSZ_FACE_NAME_ SYMBOLIC_NAME_LEN #define MAXSZ_FACE_NAME MAXSZ_FACE_NAME_ + NULLTERM -#define MAXSZ_HC_FACE_ MAXSZ_FACE_ID_ + MAXSZ_FACE_NAME_ + MAXSZ_FACE_ + 5 +#define MAXSZ_HC_FACE_ MAXSZ_FACE_ID_ + MAXSZ_FACE_NAME_ + MAXSZ_FACE_ + 5 + HOTFIXMARGIN #define MAXSZ_HC_FACE MAXSZ_HC_FACE_ + NULLTERM int hc_face_snprintf(char * s, size_t size, hc_face_t * face); diff --git a/ctrl/libhicnctrl/src/CMakeLists.txt b/ctrl/libhicnctrl/src/CMakeLists.txt index 670e79f05..b7c295ea7 100644 --- a/ctrl/libhicnctrl/src/CMakeLists.txt +++ b/ctrl/libhicnctrl/src/CMakeLists.txt @@ -23,15 +23,12 @@ set(HEADER_FILES set(UTIL_HEADER_FILES face.h - util/log.h - util/map.h ) set(SOURCE_FILES api.c face.c route.c - util/log.c ) set(LIBRARIES diff --git a/ctrl/libhicnctrl/src/api.c b/ctrl/libhicnctrl/src/api.c index e6fdb4120..7bfdda6c6 100644 --- a/ctrl/libhicnctrl/src/api.c +++ b/ctrl/libhicnctrl/src/api.c @@ -30,14 +30,14 @@ #include <hicn/ctrl/api.h> #include <hicn/ctrl/commands.h> #include <hicn/util/token.h> -#include "util/log.h" -#include "util/map.h" +#include <hicn/util/log.h> +#include <hicn/util/map.h> #include <strings.h> #define PORT 9695 #define INT_CMP(x, y) ((x > y) ? 1 : (x < y) ? -1 : 0) - +#define BOOLSTR(x) ((x) ? "true" : "false") /* * Internal state associated to a pending request */ @@ -323,6 +323,7 @@ hc_data_create(size_t in_element_size, size_t out_element_size) data->buffer = malloc((1 << data->max_size_log) * data->out_element_size); if (!data->buffer) goto ERR_BUFFER; + data->ret = 0; return data; @@ -399,6 +400,17 @@ int hc_data_set_complete(hc_data_t * data) { data->complete = true; + data->ret = 0; + if (data->complete_cb) + return data->complete_cb(data, data->complete_cb_data); + return 0; +} + +int +hc_data_set_error(hc_data_t * data) +{ + data->complete = true; + data->ret = -1; if (data->complete_cb) return data->complete_cb(data, data->complete_cb_data); return 0; @@ -631,12 +643,8 @@ hc_sock_process(hc_sock_t * s, hc_data_t ** data) if (available < sizeof(hc_msg_header_t)) break; - /* Sanity checks (might instead raise warnings) */ - assert((msg->hdr.messageType == RESPONSE_LIGHT) || - (msg->hdr.messageType == ACK_LIGHT) || - (msg->hdr.messageType == NACK_LIGHT)); - hc_sock_request_t * request = NULL; + printf("Received message with seq %d\n", msg->hdr.seqNum); if (hc_sock_map_get(s->map, msg->hdr.seqNum, &request) < 0) { ERROR("[hc_sock_process] Error searching for matching request"); return -1; @@ -645,15 +653,33 @@ hc_sock_process(hc_sock_t * s, hc_data_t ** data) ERROR("[hc_sock_process] No request matching received sequence number"); return -1; } + s->remaining = msg->hdr.length; - if (s->remaining == 0) { - hc_data_set_complete(request->data); - if (data) - *data = request->data; - hc_sock_request_free(request); - } else { - /* We only remember it if there is still data to parse */ - s->cur_request = request; + switch(msg->hdr.messageType) { + case ACK_LIGHT: + assert(s->remaining == 1); + assert(!data); + hc_data_set_complete(request->data); + break; + case NACK_LIGHT: + assert(s->remaining == 1); + assert(!data); + hc_data_set_error(request->data); + break; + case RESPONSE_LIGHT: + assert(data); + if (s->remaining == 0) { + hc_data_set_complete(request->data); + *data = request->data; + hc_sock_request_free(request); + } else { + /* We only remember it if there is still data to parse */ + s->cur_request = request; + } + break; + default: + ERROR("[hc_sock_process] Invalid response received"); + return -1; } available -= sizeof(hc_msg_header_t); @@ -691,6 +717,7 @@ hc_sock_process(hc_sock_t * s, hc_data_t ** data) available -= num_chunks * s->cur_request->data->in_element_size; s->roff += num_chunks * s->cur_request->data->in_element_size; if (s->remaining == 0) { + printf("done, sock map remove\n"); if (hc_sock_map_remove(s->map, s->cur_request->seq, NULL) < 0) { ERROR("[hc_sock_process] Error removing request from map"); return -1; @@ -830,6 +857,7 @@ hc_execute_command(hc_sock_t * s, hc_msg_t * msg, size_t msg_len, ERROR("[hc_execute_command] Could not get next sequence number"); goto ERR_SEQ; } + printf("Sending message with seq %d\n", seq); /* Create state used to process the request */ hc_sock_request_t * request = NULL; @@ -840,6 +868,7 @@ hc_execute_command(hc_sock_t * s, hc_msg_t * msg, size_t msg_len, } /* Add state to map */ + printf("sock map add\n"); if (hc_sock_map_add(s->map, seq, request) < 0) { ERROR("[hc_execute_command] Error adding request state to map"); goto ERR_MAP; @@ -870,7 +899,7 @@ hc_execute_command(hc_sock_t * s, hc_msg_t * msg, size_t msg_len, if (!pdata) hc_data_free(data); - return 0; + return data->ret; ERR_PROCESS: ERR_MAP: @@ -891,6 +920,13 @@ ERR_DATA: int _hc_listener_create(hc_sock_t * s, hc_listener_t * listener, bool async) { + char listener_s[MAXSZ_HC_LISTENER]; + int rc = hc_listener_snprintf(listener_s, MAXSZ_HC_LISTENER, listener); + if (rc >= MAXSZ_HC_LISTENER) + WARN("[_hc_listener_create] Unexpected truncation of listener string"); + DEBUG("[_hc_listener_create] listener=%s async=%s\n", listener_s, + BOOLSTR(async)); + if (!IS_VALID_FAMILY(listener->family)) return -1; @@ -916,8 +952,13 @@ _hc_listener_create(hc_sock_t * s, hc_listener_t * listener, bool async) } }; - snprintf(msg.payload.symbolic, SYMBOLIC_NAME_LEN, "%s", listener->name); - snprintf(msg.payload.interfaceName, INTERFACE_LEN, "%s", listener->interface_name); + rc = snprintf(msg.payload.symbolic, SYMBOLIC_NAME_LEN, "%s", listener->name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_listener_create] Unexpected truncation of symbolic name string"); + + rc = snprintf(msg.payload.interfaceName, INTERFACE_LEN, "%s", listener->interface_name); + if (rc >= INTERFACE_LEN) + WARN("[_hc_listener_create] Unexpected truncation of interface name string"); hc_command_params_t params = { .cmd = ACTION_CREATE, @@ -951,6 +992,12 @@ hc_listener_get(hc_sock_t * s, hc_listener_t * listener, hc_data_t * listeners; hc_listener_t * found; + char listener_s[MAXSZ_HC_LISTENER]; + int rc = hc_listener_snprintf(listener_s, MAXSZ_HC_LISTENER, listener); + if (rc >= MAXSZ_HC_LISTENER) + WARN("[hc_listener_get] Unexpected truncation of listener string"); + DEBUG("[hc_listener_get] listener=%s\n", listener_s); + if (hc_listener_list(s, &listeners) < 0) return -1; @@ -980,6 +1027,13 @@ hc_listener_get(hc_sock_t * s, hc_listener_t * listener, int _hc_listener_delete(hc_sock_t * s, hc_listener_t * listener, bool async) { + char listener_s[MAXSZ_HC_LISTENER]; + int rc = hc_listener_snprintf(listener_s, MAXSZ_HC_LISTENER, listener); + if (rc >= MAXSZ_HC_LISTENER) + WARN("[_hc_listener_delete] Unexpected truncation of listener string"); + DEBUG("[_hc_listener_delete] listener=%s async=%s\n", listener_s, + BOOLSTR(async)); + struct { header_control_message hdr; remove_listener_command payload; @@ -993,16 +1047,22 @@ _hc_listener_delete(hc_sock_t * s, hc_listener_t * listener, bool async) }; if (listener->id) { - snprintf(msg.payload.symbolicOrListenerid, SYMBOLIC_NAME_LEN, "%d", listener->id); + rc = snprintf(msg.payload.symbolicOrListenerid, SYMBOLIC_NAME_LEN, "%d", listener->id); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_listener_delete] Unexpected truncation of symbolic name string"); } else if (*listener->name) { - snprintf(msg.payload.symbolicOrListenerid, SYMBOLIC_NAME_LEN, "%s", listener->name); + rc = snprintf(msg.payload.symbolicOrListenerid, SYMBOLIC_NAME_LEN, "%s", listener->name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_listener_delete] Unexpected truncation of symbolic name string"); } else { hc_listener_t * listener_found; if (hc_listener_get(s, listener, &listener_found) < 0) return -1; if (!listener_found) return -1; - snprintf(msg.payload.symbolicOrListenerid, SYMBOLIC_NAME_LEN, "%d", listener_found->id); + rc = snprintf(msg.payload.symbolicOrListenerid, SYMBOLIC_NAME_LEN, "%d", listener_found->id); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_listener_delete] Unexpected truncation of symbolic name string"); free(listener_found); } @@ -1035,6 +1095,8 @@ hc_listener_delete_async(hc_sock_t * s, hc_listener_t * listener) int _hc_listener_list(hc_sock_t * s, hc_data_t ** pdata, bool async) { + DEBUG("[hc_listener_list] async=%s\n", BOOLSTR(async)); + struct { header_control_message hdr; } msg = { @@ -1118,6 +1180,8 @@ hc_listener_cmp(const hc_listener_t * l1, const hc_listener_t * l2) int hc_listener_parse(void * in, hc_listener_t * listener) { + int rc; + list_listeners_command * cmd = (list_listeners_command *)in; if (!IS_VALID_LIST_LISTENERS_TYPE(cmd->encapType)) @@ -1141,8 +1205,12 @@ hc_listener_parse(void * in, hc_listener_t * listener) .local_addr = UNION_CAST(cmd->address, ip_address_t), .local_port = ntohs(cmd->port), }; - snprintf(listener->name, SYMBOLIC_NAME_LEN, "%s", cmd->listenerName); - snprintf(listener->interface_name, INTERFACE_LEN, "%s", cmd->interfaceName); + rc = snprintf(listener->name, SYMBOLIC_NAME_LEN, "%s", cmd->listenerName); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[hc_listener_parse] Unexpected truncation of symbolic name string"); + rc = snprintf(listener->interface_name, INTERFACE_LEN, "%s", cmd->interfaceName); + if (rc >= INTERFACE_LEN) + WARN("[hc_listener_parse] Unexpected truncation of interface name string"); return 0; } @@ -1158,12 +1226,12 @@ hc_listener_snprintf(char * s, size_t size, hc_listener_t * listener) int rc; rc = url_snprintf(local, MAXSZ_URL, listener->family, &listener->local_addr, listener->local_port); + if (rc >= MAXSZ_URL) + WARN("[hc_listener_snprintf] Unexpected truncation of URL string"); if (rc < 0) return rc; - return snprintf(s, size+17, "%s %s %s", - listener->interface_name, - local, + return snprintf(s, size, "%s %s %s", listener->interface_name, local, connection_type_str[listener->type]); } @@ -1176,6 +1244,12 @@ hc_listener_snprintf(char * s, size_t size, hc_listener_t * listener) int _hc_connection_create(hc_sock_t * s, hc_connection_t * connection, bool async) { + char connection_s[MAXSZ_HC_CONNECTION]; + int rc = hc_connection_snprintf(connection_s, MAXSZ_HC_CONNECTION, connection); + if (rc >= MAXSZ_HC_CONNECTION) + WARN("[_hc_connection_create] Unexpected truncation of connection string"); + DEBUG("[_hc_connection_create] connection=%s async=%s\n", connection_s, BOOLSTR(async)); + if (hc_connection_validate(connection) < 0) return -1; @@ -1195,14 +1269,17 @@ _hc_connection_create(hc_sock_t * s, hc_connection_t * connection, bool async) .remotePort = htons(connection->remote_port), .localPort = htons(connection->local_port), .ipType = (u8)map_to_addr_type[connection->family], + .connectionType = (u8)map_to_connection_type[connection->type], .admin_state = connection->admin_state, #ifdef WITH_POLICY .tags = connection->tags, #endif /* WITH_POLICY */ - .connectionType = (u8)map_to_connection_type[connection->type], } }; - snprintf(msg.payload.symbolic, SYMBOLIC_NAME_LEN, "%s", connection->name); + rc = snprintf(msg.payload.symbolic, SYMBOLIC_NAME_LEN, "%s", connection->name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_connection_create] Unexpected truncation of symbolic name string"); + //snprintf(msg.payload.interfaceName, INTERFACE_NAME_LEN, "%s", connection->interface_name); hc_command_params_t params = { .cmd = ACTION_CREATE, @@ -1236,6 +1313,12 @@ hc_connection_get(hc_sock_t * s, hc_connection_t * connection, hc_data_t * connections; hc_connection_t * found; + char connection_s[MAXSZ_HC_CONNECTION]; + int rc = hc_connection_snprintf(connection_s, MAXSZ_HC_CONNECTION, connection); + if (rc >= MAXSZ_HC_CONNECTION) + WARN("[hc_connection_get] Unexpected truncation of connection string"); + DEBUG("[hc_connection_get] connection=%s\n", connection_s); + if (hc_connection_list(s, &connections) < 0) return -1; @@ -1265,6 +1348,12 @@ hc_connection_get(hc_sock_t * s, hc_connection_t * connection, int _hc_connection_delete(hc_sock_t * s, hc_connection_t * connection, bool async) { + char connection_s[MAXSZ_HC_CONNECTION]; + int rc = hc_connection_snprintf(connection_s, MAXSZ_HC_CONNECTION, connection); + if (rc >= MAXSZ_HC_CONNECTION) + WARN("[_hc_connection_delete] Unexpected truncation of connection string"); + DEBUG("[_hc_connection_delete] connection=%s async=%s\n", connection_s, BOOLSTR(async)); + struct { header_control_message hdr; remove_connection_command payload; @@ -1278,16 +1367,22 @@ _hc_connection_delete(hc_sock_t * s, hc_connection_t * connection, bool async) }; if (connection->id) { - snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", connection->id); + rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", connection->id); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_connection_delete] Unexpected truncation of symbolic name string"); } else if (*connection->name) { - snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%s", connection->name); + rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%s", connection->name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_connection_delete] Unexpected truncation of symbolic name string"); } else { hc_connection_t * connection_found; if (hc_connection_get(s, connection, &connection_found) < 0) return -1; if (!connection_found) return -1; - snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", connection_found->id); + rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", connection_found->id); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_connection_delete] Unexpected truncation of symbolic name string"); free(connection_found); } @@ -1319,6 +1414,8 @@ hc_connection_delete_async(hc_sock_t * s, hc_connection_t * connection) int _hc_connection_list(hc_sock_t * s, hc_data_t ** pdata, bool async) { + DEBUG("[hc_connection_list] async=%s\n", BOOLSTR(async)); + struct { header_control_message hdr; } msg = { @@ -1416,6 +1513,7 @@ int hc_connection_cmp(const hc_connection_t * c1, const hc_connection_t * c2) int hc_connection_parse(void * in, hc_connection_t * connection) { + int rc; list_connections_command * cmd = (list_connections_command *)in; if (!IS_VALID_LIST_CONNECTIONS_TYPE(cmd->connectionData.connectionType)) @@ -1455,8 +1553,12 @@ hc_connection_parse(void * in, hc_connection_t * connection) #endif /* WITH_POLICY */ .state = state, }; - snprintf(connection->name, SYMBOLIC_NAME_LEN, "%s", cmd->connectionData.symbolic); - snprintf(connection->interface_name, INTERFACE_LEN, "%s", cmd->interfaceName); + rc = snprintf(connection->name, SYMBOLIC_NAME_LEN, "%s", cmd->connectionData.symbolic); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[hc_connection_parse] Unexpected truncation of symbolic name string"); + rc = snprintf(connection->interface_name, INTERFACE_LEN, "%s", cmd->interfaceName); + if (rc >= INTERFACE_LEN) + WARN("[hc_connection_parse] Unexpected truncation of interface name string"); return 0; } @@ -1476,10 +1578,14 @@ hc_connection_snprintf(char * s, size_t size, const hc_connection_t * connection rc = url_snprintf(local, MAXSZ_URL, connection->family, &connection->local_addr, connection->local_port); + if (rc >= MAXSZ_URL) + WARN("[hc_connection_snprintf] Unexpected truncation of URL string"); if (rc < 0) return rc; rc = url_snprintf(remote, MAXSZ_URL, connection->family, &connection->remote_addr, connection->remote_port); + if (rc >= MAXSZ_URL) + WARN("[hc_connection_snprintf] Unexpected truncation of URL string"); if (rc < 0) return rc; @@ -1497,6 +1603,9 @@ int _hc_connection_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, face_state_t state, bool async) { + int rc; + DEBUG("[hc_connection_set_admin_state] connection_id/name=%s admin_state=%s async=%s\n", + conn_id_or_name, face_state_str[state], BOOLSTR(async)); struct { header_control_message hdr; connection_set_admin_state_command payload; @@ -1511,7 +1620,9 @@ _hc_connection_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, .admin_state = state, }, }; - snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%s", conn_id_or_name); + rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%s", conn_id_or_name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_connection_set_admin_state] Unexpected truncation of symbolic name string"); hc_command_params_t params = { .cmd = ACTION_SET, @@ -1547,6 +1658,12 @@ hc_connection_set_admin_state_async(hc_sock_t * s, const char * conn_id_or_name, int _hc_route_create(hc_sock_t * s, hc_route_t * route, bool async) { + char route_s[MAXSZ_HC_ROUTE]; + int rc = hc_route_snprintf(route_s, MAXSZ_HC_ROUTE, route); + if (rc >= MAXSZ_HC_ROUTE) + WARN("[_hc_route_create] Unexpected truncation of route string"); + DEBUG("[hc_route_create] route=%s async=%s\n", route_s, BOOLSTR(async)); + if (!IS_VALID_FAMILY(route->family)) return -1; @@ -1572,7 +1689,9 @@ _hc_route_create(hc_sock_t * s, hc_route_t * route, bool async) * The route commands expects the ID (or name that we don't use) as part of * the symbolicOrConnid attribute. */ - snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", route->face_id); + rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", route->face_id); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_route_create] Unexpected truncation of symbolic name string"); hc_command_params_t params = { .cmd = ACTION_CREATE, @@ -1602,6 +1721,12 @@ hc_route_create_async(hc_sock_t * s, hc_route_t * route) int _hc_route_delete(hc_sock_t * s, hc_route_t * route, bool async) { + char route_s[MAXSZ_HC_ROUTE]; + int rc = hc_route_snprintf(route_s, MAXSZ_HC_ROUTE, route); + if (rc >= MAXSZ_HC_ROUTE) + WARN("[_hc_route_delete] Unexpected truncation of route string"); + DEBUG("[hc_route_delete] route=%s async=%s\n", route_s, BOOLSTR(async)); + if (!IS_VALID_FAMILY(route->family)) return -1; @@ -1622,6 +1747,12 @@ _hc_route_delete(hc_sock_t * s, hc_route_t * route, bool async) } }; + /* + * The route commands expects the ID (or name that we don't use) as part of + * the symbolicOrConnid attribute. + */ + snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", route->face_id); + hc_command_params_t params = { .cmd = ACTION_DELETE, .cmd_id = REMOVE_ROUTE, @@ -1650,6 +1781,8 @@ hc_route_delete_async(hc_sock_t * s, hc_route_t * route) int _hc_route_list(hc_sock_t * s, hc_data_t ** pdata, bool async) { + DEBUG("[hc_route_list] async=%s\n", BOOLSTR(async)); + struct { header_control_message hdr; } msg = { @@ -1721,17 +1854,13 @@ hc_route_snprintf(char * s, size_t size, hc_route_t * route) rc = ip_address_snprintf(prefix, MAXSZ_IP_ADDRESS, &route->remote_addr, route->family); + if (rc >= MAXSZ_IP_ADDRESS) + ; if (rc < 0) return rc; - return snprintf(s, size, "%*d %*d %s %*d", - MAXSZ_FACE_ID, - route->face_id, - MAXSZ_COST, - route->cost, - prefix, - MAXSZ_LEN, - route->len); + return snprintf(s, size, "%*d %*d %s %*d", MAXSZ_FACE_ID, route->face_id, + MAXSZ_COST, route->cost, prefix, MAXSZ_LEN, route->len); } /*----------------------------------------------------------------------------* @@ -1780,6 +1909,7 @@ hc_listener_to_face(const hc_listener_t * listener, hc_face_t * face) int hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool generate_name) { + int rc; const face_t * f = &face->face; switch(f->type) { @@ -1797,10 +1927,10 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool .tags = f->tags, #endif /* WITH_POLICY */ }; - snprintf(connection->name, SYMBOLIC_NAME_LEN, "%s", - f->netdevice.name); - snprintf(connection->interface_name, INTERFACE_LEN, "%s", + rc = snprintf(connection->name, SYMBOLIC_NAME_LEN, "%s", f->netdevice.name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[hc_face_to_connection] Unexpected truncation of symbolic name string"); break; case FACE_TYPE_TCP: *connection = (hc_connection_t) { @@ -1817,12 +1947,12 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool #endif /* WITH_POLICY */ }; if (generate_name) { - snprintf(connection->name, SYMBOLIC_NAME_LEN, "tcp%u", RANDBYTE()); + rc = snprintf(connection->name, SYMBOLIC_NAME_LEN, "tcp%u", RANDBYTE()); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[hc_face_to_connection] Unexpected truncation of symbolic name string"); } else { memset(connection->name, 0, SYMBOLIC_NAME_LEN); } - snprintf(connection->interface_name, INTERFACE_LEN, "%s", - f->netdevice.name); break; case FACE_TYPE_UDP: *connection = (hc_connection_t) { @@ -1839,19 +1969,21 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool #endif /* WITH_POLICY */ }; if (generate_name) { - snprintf(connection->name, SYMBOLIC_NAME_LEN, "udp%u", RANDBYTE()); + rc = snprintf(connection->name, SYMBOLIC_NAME_LEN, "udp%u", RANDBYTE()); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[hc_face_to_connection] Unexpected truncation of symbolic name string"); } else { memset(connection->name, 0, SYMBOLIC_NAME_LEN); } - snprintf(connection->interface_name, INTERFACE_LEN, "%s", - f->netdevice.name); break; default: return -1; } - snprintf(connection->interface_name, INTERFACE_LEN, "%s", + rc = snprintf(connection->interface_name, INTERFACE_LEN, "%s", f->netdevice.name); + if (rc >= INTERFACE_LEN) + WARN("hc_face_to_connection] Unexpected truncation of interface name string"); return 0; } @@ -1861,6 +1993,7 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool int hc_connection_to_face(const hc_connection_t * connection, hc_face_t * face) { + int rc; switch (connection->type) { case CONNECTION_TYPE_TCP: *face = (hc_face_t) { @@ -1920,8 +2053,12 @@ hc_connection_to_face(const hc_connection_t * connection, hc_face_t * face) } face->face.netdevice.name[0] = '\0'; face->face.netdevice.index = 0; - snprintf(face->name, SYMBOLIC_NAME_LEN, "%s", connection->name); - snprintf(face->face.netdevice.name, INTERFACE_LEN, "%s", connection->interface_name); + rc = snprintf(face->name, SYMBOLIC_NAME_LEN, "%s", connection->name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[hc_connection_to_face] Unexpected truncation of symbolic name string"); + rc = snprintf(face->face.netdevice.name, INTERFACE_LEN, "%s", connection->interface_name); + if (rc >= INTERFACE_LEN) + WARN("[hc_connection_to_face] Unexpected truncation of interface name string"); netdevice_update_index(&face->face.netdevice); return 0; } @@ -1931,6 +2068,7 @@ hc_connection_to_face(const hc_connection_t * connection, hc_face_t * face) int hc_connection_to_local_listener(const hc_connection_t * connection, hc_listener_t * listener) { + int rc; *listener = (hc_listener_t) { .id = ~0, .type = connection->type, @@ -1938,8 +2076,13 @@ hc_connection_to_local_listener(const hc_connection_t * connection, hc_listener_ .local_addr = connection->local_addr, .local_port = connection->local_port, }; - snprintf(listener->name, SYMBOLIC_NAME_LEN, "lst%u", RANDBYTE()); // generate name - snprintf(listener->interface_name, INTERFACE_LEN, "%s", connection->interface_name); + rc = snprintf(listener->name, SYMBOLIC_NAME_LEN, "lst%u", RANDBYTE()); // generate name + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[hc_connection_to_local_listener] Unexpected truncation of symbolic name string"); + rc = snprintf(listener->interface_name, INTERFACE_LEN, "%s", connection->interface_name); + if (rc >= INTERFACE_LEN) + WARN("[hc_connection_to_local_listener] Unexpected truncation of interface name string"); + return 0; } @@ -1954,6 +2097,12 @@ hc_face_create(hc_sock_t * s, hc_face_t * face) hc_connection_t connection; hc_connection_t * connection_found; + char face_s[MAXSZ_HC_FACE]; + int rc = hc_face_snprintf(face_s, MAXSZ_HC_FACE, face); + if (rc >= MAXSZ_HC_FACE) + WARN("[hc_face_create] Unexpected truncation of face string"); + DEBUG("[hc_face_create] face=%s\n", face_s); + switch(face->face.type) { case FACE_TYPE_HICN: @@ -2042,6 +2191,12 @@ hc_face_get(hc_sock_t * s, hc_face_t * face, hc_face_t ** face_found) hc_connection_t connection; hc_connection_t * connection_found; + char face_s[MAXSZ_HC_FACE]; + int rc = hc_face_snprintf(face_s, MAXSZ_HC_FACE, face); + if (rc >= MAXSZ_HC_FACE) + WARN("[hc_face_get] Unexpected truncation of face string"); + DEBUG("[hc_face_get] face=%s\n"); + switch(face->face.type) { case FACE_TYPE_HICN: @@ -2089,6 +2244,12 @@ hc_face_get(hc_sock_t * s, hc_face_t * face, hc_face_t ** face_found) int hc_face_delete(hc_sock_t * s, hc_face_t * face) { + char face_s[MAXSZ_HC_FACE]; + int rc = hc_face_snprintf(face_s, MAXSZ_HC_FACE, face); + if (rc >= MAXSZ_HC_FACE) + WARN("[hc_face_delete] Unexpected truncation of face string"); + DEBUG("[hc_face_delete] face=%s\n"); + hc_connection_t connection; if (hc_face_to_connection(face, &connection, false) < 0) { ERROR("[hc_face_delete] Could not convert face to connection."); @@ -2157,6 +2318,8 @@ hc_face_list(hc_sock_t * s, hc_data_t ** pdata) hc_data_t * connection_data; hc_face_t face; + DEBUG("[hc_face_list]\n"); + if (hc_connection_list(s, &connection_data) < 0) { ERROR("[hc_face_list] Could not list connections."); return -1; @@ -2242,11 +2405,15 @@ hc_face_snprintf(char * s, size_t size, hc_face_t * face) rc = ip_address_snprintf(local, MAXSZ_URL, &face->face.local_addr, face->face.family); + if (rc >= MAXSZ_URL) + WARN("[hc_face_snprintf] Unexpected truncation of URL string"); if (rc < 0) return rc; rc = ip_address_snprintf(remote, MAXSZ_URL, &face->face.remote_addr, face->face.family); + if (rc >= MAXSZ_URL) + WARN("[hc_face_snprintf] Unexpected truncation of URL string"); if (rc < 0) return rc; break; @@ -2256,11 +2423,16 @@ hc_face_snprintf(char * s, size_t size, hc_face_t * face) case FACE_TYPE_UDP_LISTENER: rc = url_snprintf(local, MAXSZ_URL, face->face.family, &face->face.local_addr, - face->face.local_port); if (rc < 0) + face->face.local_port); + if (rc >= MAXSZ_URL) + WARN("[hc_face_snprintf] Unexpected truncation of URL string"); + if (rc < 0) return rc; rc = url_snprintf(remote, MAXSZ_URL, face->face.family, &face->face.remote_addr, - face->face.remote_port); if (rc < 0) + face->face.remote_port); + if (rc >= MAXSZ_URL) + WARN("[hc_face_snprintf] Unexpected truncation of URL string"); if (rc < 0) return rc; break; @@ -2271,6 +2443,8 @@ hc_face_snprintf(char * s, size_t size, hc_face_t * face) // [#ID NAME] TYPE LOCAL_URL REMOTE_URL STATE/ADMIN_STATE (TAGS) #ifdef WITH_POLICY rc = policy_tags_snprintf(tags, MAXSZ_POLICY_TAGS, face->face.tags); + if (rc >= MAXSZ_POLICY_TAGS) + WARN("[hc_face_snprintf] Unexpected truncation of policy tags string"); if (rc < 0) return rc; @@ -2293,7 +2467,6 @@ hc_face_snprintf(char * s, size_t size, hc_face_t * face) face_state_str[face->face.state], face_state_str[face->face.admin_state]); #endif /* WITH_POLICY */ - return 0; } int @@ -2310,6 +2483,8 @@ hc_face_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, // XXX wron int _hc_punting_create(hc_sock_t * s, hc_punting_t * punting, bool async) { + int rc; + if (hc_punting_validate(punting) < 0) return -1; @@ -2329,7 +2504,9 @@ _hc_punting_create(hc_sock_t * s, hc_punting_t * punting, bool async) .len = punting->prefix_len, } }; - snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", punting->face_id); + rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%d", punting->face_id); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_punting_create] Unexpected truncation of symbolic name string"); hc_command_params_t params = { .cmd = ACTION_CREATE, @@ -2533,13 +2710,17 @@ static const char * strategies[] = { int hc_strategy_list(hc_sock_t * s, hc_data_t ** data) { + int rc; + *data = hc_data_create(0, sizeof(hc_strategy_t)); for (unsigned i = 0; i < ARRAY_SIZE(strategies); i++) { hc_strategy_t * strategy = (hc_strategy_t*)hc_data_get_next(*data); if (!strategy) return -1; - snprintf(strategy->name, MAXSZ_HC_STRATEGY, "%s", strategies[i]); + rc = snprintf(strategy->name, MAXSZ_HC_STRATEGY, "%s", strategies[i]); + if (rc >= MAXSZ_HC_STRATEGY) + WARN("[hc_strategy_list] Unexpected truncation of strategy name string"); (*data)->size++; } diff --git a/ctrl/libhicnctrl/src/util/log.c b/ctrl/libhicnctrl/src/util/log.c deleted file mode 100644 index 54943cf45..000000000 --- a/ctrl/libhicnctrl/src/util/log.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "log.h" - -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> - -log_conf_t log_conf = DEFAULT_LOG_CONF; - -#define FMT_DATETIME "%02d-%02d-%04d %02d:%02d:%02d" -#define FMT_DATETIME_LEN 20 -#define snprintf_nowarn(...) (snprintf(__VA_ARGS__) < 0 ? abort() : (void)0) - - -static char ts[FMT_DATETIME_LEN]; - -static char *timestamp(void) -{ - time_t tv; - struct tm *tm; - - time(&tv); - tm = localtime(&tv); - - snprintf_nowarn(ts, FMT_DATETIME_LEN, FMT_DATETIME, tm->tm_mday, - tm->tm_mon + 1, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, - tm->tm_sec); - return ts; -} - -void _log_va(int level, const char *fmt, va_list ap) -{ - char *prefix; - FILE *f = log_conf.log_file ? log_conf.log_file : stdout; - -#if 0 - if (!conf.log_system) - return; -#endif - - if (level > log_conf.log_level) - return; - - switch (level) { - case LOG_FATAL: - prefix = "FATAL: "; - break; - case LOG_ERROR: - prefix = "ERROR: "; - break; - case LOG_WARN: - prefix = "WARNING: "; - break; - case LOG_INFO: - prefix = ""; - break; - case LOG_DEBUG: - prefix = "DEBUG: "; - break; - case LOG_TRACE: - prefix = "TRACE: "; - break; - default: - prefix = ""; - break; - } - - fprintf(f, "%s %s", timestamp(), prefix); - vfprintf(f, fmt, ap); - fprintf(f, "\n"); -#ifdef DEBUG - fflush(f); -#endif -} - -void _log(int level, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _log_va(level, fmt, ap); - va_end(ap); -} - -#ifdef HAVE_BACKTRACE -#include <execinfo.h> - -void print_trace(void) -{ - void *array[32]; - size_t size; - - size = backtrace(array, 32); - fflush(conf.log_file); - backtrace_symbols_fd(array, size, fileno(conf.log_file)); -} -#endif - -void fatal(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - _log_va(LOG_FATAL, fmt, ap); - va_end(ap); - -#ifdef HAVE_BACKTRACE - print_trace(); -#endif - - exit(200); -} diff --git a/ctrl/libhicnctrl/src/util/log.h b/ctrl/libhicnctrl/src/util/log.h deleted file mode 100644 index f1cafba47..000000000 --- a/ctrl/libhicnctrl/src/util/log.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UTIL_LOG_H -#define UTIL_LOG_H - -#include <stdarg.h> // va_* -#include <stdio.h> // FILE -#include <time.h> // time, localtime - -#define LOG_FATAL 0 -#define LOG_ERROR 1 -#define LOG_WARN 2 -#define LOG_INFO 3 -#define LOG_DEBUG 4 -#define LOG_TRACE 5 - -typedef struct { - int log_level; - int debug; - FILE * log_file; -} log_conf_t; - -#define DEFAULT_LOG_CONF { \ - .log_level = LOG_DEBUG, \ - .debug = 0, \ - .log_file = NULL, \ -}; - -extern log_conf_t log_conf; - -#define WITH_DEBUG(BLOCK) \ - if (log_conf.log_level >= LOG_DEBUG) \ - BLOCK - -#define FATAL(fmt, ...) (_log(LOG_FATAL, fmt, ##__VA_ARGS__ )) -#define ERROR(fmt, ...) (_log(LOG_ERROR, fmt, ##__VA_ARGS__ )) -#define WARN(fmt, ...) (_log(LOG_WARN, fmt, ##__VA_ARGS__ )) -#define INFO(fmt, ...) (_log(LOG_INFO, fmt, ##__VA_ARGS__ )) -#define DEBUG(fmt, ...) (_log(LOG_DEBUG, fmt, ##__VA_ARGS__ )) -#define TRACE(fmt, ...) (_log(LOG_TRACE, fmt, ##__VA_ARGS__ )) - -void _log_va(int level, const char *fmt, va_list ap); - -void _log(int level, const char *fmt, ...); - -void fatal(char *fmt, ...); - -#ifdef HAVE_BACKTRACE -#include <execinfo.h> -void print_trace(void); -#endif - -#endif // UTIL_LOG_H diff --git a/ctrl/libhicnctrl/src/util/map.h b/ctrl/libhicnctrl/src/util/map.h deleted file mode 100644 index 334f12cc1..000000000 --- a/ctrl/libhicnctrl/src/util/map.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UTIL_MAP_H -#define UTIL_MAP_H - -#include <stdlib.h> - -#include "set.h" - -#define ERR_MAP_EXISTS -2 -#define ERR_MAP_NOT_FOUND -3 - -#define TYPEDEF_MAP_H(NAME, KEY_T, VAL_T) \ - \ -typedef struct { \ - KEY_T key; \ - VAL_T value; \ -} NAME ## _pair_t; \ - \ -NAME ## _pair_t * NAME ## _pair_create(KEY_T key, VAL_T value); \ - \ -void NAME ## _pair_free(NAME ## _pair_t * pair); \ - \ -int NAME ## _pair_cmp(const NAME ## _pair_t * p1, const NAME ## _pair_t * p2); \ - \ -TYPEDEF_SET_H(NAME ## _pair_set, NAME ## _pair_t *) \ - \ -typedef struct NAME ## _s { \ - NAME ## _pair_set_t pair_set; \ -} NAME ## _t; \ - \ -int NAME ## _initialize(NAME ## _t * map); \ - \ -int NAME ## _finalize(NAME ## _t * map); \ - \ -NAME ## _t * NAME ## _create(); \ - \ -void NAME ## _free(NAME ## _t * map); \ - \ -int NAME ## _add(NAME ## _t * map, KEY_T key, VAL_T value); \ - \ -int NAME ## _remove(NAME ## _t * map, KEY_T key, VAL_T * value); \ - \ -int NAME ## _get(NAME ## _t * map, KEY_T key, VAL_T * value); \ - \ -void NAME ## _dump(NAME ## _t * map); - - - - -#define TYPEDEF_MAP(NAME, KEY_T, VAL_T, CMP, KEY_SNPRINTF, VALUE_SNPRINTF) \ - \ -NAME ## _pair_t * NAME ## _pair_create(KEY_T key, VAL_T value) \ -{ \ - /* Create pair */ \ - NAME ## _pair_t * pair = malloc(sizeof(NAME ## _pair_t)); \ - if (!pair) \ - return NULL; \ - \ - pair->key = key; \ - pair->value = value; \ - \ - return pair; \ -} \ - \ -void NAME ## _pair_free(NAME ## _pair_t * pair) \ -{ \ - free(pair); \ -} \ - \ -int \ -NAME ## _pair_cmp(const NAME ## _pair_t * p1, const NAME ## _pair_t * p2) \ -{ \ - return (CMP(p1->key, p2->key)); \ -} \ - \ -int \ -NAME ## _pair_snprintf(char * buf, size_t size, const NAME ## _pair_t * pair) { \ - int rc; \ - rc = KEY_SNPRINTF(buf, BUFSIZE/2, (KEY_T)pair->key); \ - if (rc < 0) \ - return rc; \ - rc = VALUE_SNPRINTF(buf+rc, BUFSIZE/2, (VAL_T)pair->value); \ - return rc; \ -} \ - \ -TYPEDEF_SET(NAME ## _pair_set, NAME ## _pair_t *, NAME ## _pair_cmp, NAME ## _pair_snprintf); \ - \ -int \ -NAME ## _initialize(NAME ## _t * map) \ -{ \ - return NAME ## _pair_set_initialize(&map->pair_set); \ -} \ - \ -int \ -NAME ## _finalize(NAME ## _t * map) \ -{ \ - return NAME ## _pair_set_finalize(&map->pair_set); \ -} \ - \ -NAME ## _t * \ -NAME ## _create() \ -{ \ - NAME ## _t * map = malloc(sizeof(NAME ## _t)); \ - if (!map) \ - goto ERR_MALLOC; \ - \ - if (NAME ## _initialize(map) < 0) \ - goto ERR_INITIALIZE; \ - \ - return map; \ - \ -ERR_INITIALIZE: \ - free(map); \ -ERR_MALLOC: \ - return NULL; \ -} \ - \ -void \ -NAME ## _free(NAME ## _t * map) \ -{ \ - NAME ## _finalize(map); \ - free(map); \ -} \ - \ -int \ -NAME ## _add(NAME ## _t * map, KEY_T key, VAL_T value) \ -{ \ - int rc; \ - NAME ## _pair_t * found = NULL; \ - \ - NAME ## _pair_t * pair = NAME ## _pair_create(key, value); \ - if (!pair) \ - return -1; \ - \ - rc = NAME ## _pair_set_get(&map->pair_set, pair, &found); \ - if (rc < 0) \ - return -1; \ - if (found) { \ - NAME ## _pair_free(pair); \ - return ERR_MAP_EXISTS; \ - } \ - \ - rc = NAME ## _pair_set_add(&map->pair_set, pair); \ - if (rc < 0) { \ - NAME ## _pair_free(pair); \ - return -1; \ - } \ - return 0; \ -} \ - \ -int \ -NAME ## _remove(NAME ## _t * map, KEY_T key, VAL_T * value) \ -{ \ - NAME ## _pair_t * found = NULL; \ - NAME ## _pair_t search = { .key = key }; \ - int rc = NAME ## _pair_set_remove(&map->pair_set, &search, &found); \ - if (rc < 0) \ - return ERR_MAP_NOT_FOUND; \ - if (value) \ - *value = found->value; \ - NAME ## _pair_free(found); \ - return 0; \ -} \ - \ -int \ -NAME ## _get(NAME ## _t * map, KEY_T key, VAL_T * value) \ -{ \ - NAME ## _pair_t * found = NULL, search = { .key = key }; \ - int rc = NAME ## _pair_set_get(&map->pair_set, &search, &found); \ - if (rc < 0) \ - return -1; \ - if (found) \ - *value = found->value; \ - return 0; \ -} \ - \ -void \ -NAME ## _dump(NAME ## _t * map) { \ - NAME ## _pair_set_dump(&map->pair_set); \ -} \ - \ -int \ -NAME ## _get_key_array(NAME ## _t * map, KEY_T **array) { \ - NAME ## _pair_t ** pair_array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &pair_array); \ - if (n < 0) \ - return -1; \ - /* Allocate result array */ \ - *array = malloc(n * sizeof(KEY_T)); \ - if (!array) { \ - free(pair_array); \ - return -1; \ - } \ - /* Copy keys */ \ - for (int i = 0; i < n; i++) \ - (*array)[i] = pair_array[i]->key; \ - free(pair_array); \ - return 0; \ -} \ - \ -int \ -NAME ## _get_value_array(NAME ## _t * map, VAL_T **array) { \ - NAME ## _pair_t ** pair_array; \ - int n = NAME ## _pair_set_get_array(&map->pair_set, &pair_array); \ - if (n < 0) \ - return -1; \ - /* Allocate result array */ \ - *array = malloc(n * sizeof(VAL_T)); \ - if (!*array) { \ - free(pair_array); \ - return -1; \ - } \ - /* Copy values */ \ - for (int i = 0; i < n; i++) \ - (*array)[i] = pair_array[i]->value; \ - free(pair_array); \ - return 0; \ -} - -#endif /* UTIL_MAP_H */ diff --git a/ctrl/libhicnctrl/src/util/set.h b/ctrl/libhicnctrl/src/util/set.h deleted file mode 100644 index 3706e36f4..000000000 --- a/ctrl/libhicnctrl/src/util/set.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef UTIL_SET_H -#define UTIL_SET_H - -#include <search.h> -#include <string.h> -//#if !defined(__ANDROID__) && !defined(__APPLE__) -//#include <threads.h> -//#else -#define thread_local _Thread_local -//#endif /* ! __ANDROID__ */ -#include "util/log.h" - -#define ERR_SET_EXISTS -2 -#define ERR_SET_NOT_FOUND -3 - -/* FIXME: buffer overflow when this is too small... investigate */ -#define BUFSIZE 1024 - -static inline -int -int_cmp(const int x, const int y) -{ - return x - y; -} - -static inline -int -int_snprintf(char * buf, size_t size, int value) { - return snprintf(buf, size, "%d", value); -} - -static inline -int -string_snprintf(char * buf, size_t size, const char * s) { - return snprintf(buf, size, "%s", s); -} - -static inline -int -generic_snprintf(char * buf, size_t size, const void * value) { - return snprintf(buf, BUFSIZE, "%p", value); -} - -typedef int(*cmp_t)(const void * x, const void * y); - -#define TYPEDEF_SET_H(NAME, T) \ - \ -typedef struct { \ - size_t size; \ - void * root; \ -} NAME ## _t; \ - \ -int NAME ## _initialize(NAME ## _t * set); \ - \ -int NAME ## _finalize(NAME ## _t * set); \ - \ -NAME ## _t * NAME ## _create(); \ - \ -void NAME ## _free(NAME ## _t * set); \ - \ -int NAME ## _add(NAME ## _t * set, const T element); \ - \ -int NAME ## _remove(NAME ## _t * set, const T search, T * element); \ - \ -int NAME ## _get(const NAME ## _t * set, const T search, T * element); \ - \ -int NAME ## _get_array(const NAME ## _t * set, T ** element); \ - \ -void NAME ## _dump(NAME ## _t * set); - - - - -#define TYPEDEF_SET(NAME, T, CMP, SNPRINTF) \ -int \ -NAME ## _initialize(NAME ## _t * set) \ -{ \ - set->root = NULL; \ - set->size = 0; \ - return 0; \ -} \ - \ -int \ -NAME ## _finalize(NAME ## _t * set) { return 0; } \ - \ -NAME ## _t * \ -NAME ## _create() \ -{ \ - NAME ## _t * set = malloc(sizeof(NAME ## _t)); \ - if (!set) \ - goto ERR_MALLOC; \ - \ - if (NAME ## _initialize(set) < 0) \ - goto ERR_INITIALIZE; \ - \ - return set; \ - \ -ERR_INITIALIZE: \ - free(set); \ -ERR_MALLOC: \ - return NULL; \ -} \ - \ -void \ -NAME ## _free(NAME ## _t * set) \ -{ \ - NAME ## _finalize(set); \ - free(set); \ -} \ - \ -int \ -NAME ## _add(NAME ## _t * set, const T element) \ -{ \ - void * ptr = tsearch(element, &set->root, (cmp_t)CMP); \ - if (!ptr) \ - return -1; \ - set->size++; \ - return 0; \ -} \ - \ -int \ -NAME ## _remove(NAME ## _t * set, const T search, T * element) \ -{ \ - T * found = tfind(search, &set->root, (cmp_t)CMP); \ - if (!found) \ - return ERR_SET_NOT_FOUND; \ - if (element) \ - *element = *found; \ - tdelete(search, &set->root, (cmp_t)CMP); \ - set->size--; \ - return 0; \ -} \ - \ -int \ -NAME ## _get(const NAME ## _t * set, const T search, T * element) \ -{ \ - T * found = tfind(search, &set->root, (cmp_t)CMP); \ - if (element) \ - *element = found ? *found : NULL; \ - return 0; \ -} \ - \ -static void \ -NAME ## _dump_node(const void *nodep, const VISIT which, \ - const int depth) \ -{ \ - char buf[BUFSIZE]; \ - switch (which) { \ - case preorder: \ - case endorder: \ - break; \ - case postorder: \ - case leaf: \ - SNPRINTF(buf, BUFSIZE, *(T*)nodep); \ - INFO("%s", buf); \ - break; \ - } \ -} \ - \ -void \ -NAME ## _dump(NAME ## _t * set) { \ - twalk(set->root, NAME ## _dump_node); \ -} \ - \ -thread_local \ -T * NAME ## _array_pos = NULL; \ - \ -static void \ -NAME ## _add_node_to_array(const void *nodep, const VISIT which, \ - const int depth) \ -{ \ - if (!NAME ## _array_pos) \ - return; \ - switch (which) { \ - case preorder: \ - case endorder: \ - break; \ - case postorder: \ - case leaf: \ - *NAME ## _array_pos = *(T*)nodep; \ - NAME ## _array_pos++; \ - break; \ - } \ -} \ - \ -int \ -NAME ## _get_array(const NAME ## _t * set, T ** element) \ -{ \ - *element = malloc(set->size * sizeof(T)); \ - if (!*element) \ - return -1; \ - NAME ## _array_pos = *element; \ - twalk(set->root, NAME ## _add_node_to_array); \ - NAME ## _array_pos = NULL; \ - return set->size; \ -} - -#endif /* UTIL_SET_H */ |