diff options
Diffstat (limited to 'hicn-light/src')
42 files changed, 553 insertions, 535 deletions
diff --git a/hicn-light/src/hicn/base/bitmap.h b/hicn-light/src/hicn/base/bitmap.h index 1159806c8..46d473ff8 100644 --- a/hicn-light/src/hicn/base/bitmap.h +++ b/hicn-light/src/hicn/base/bitmap.h @@ -66,6 +66,13 @@ bitmap_ensure_pos(bitmap_t ** bitmap, off_t pos) } /** + * @brief Returns the allocated size of a bitmap. + * + * @see listener_table_get_by_id + */ +#define bitmap_get_alloc_size(bitmap) vector_get_alloc_size(bitmap) + +/** * @brief Retrieve the state of the i-th bit in the bitmap. * * @param[in] bitmap The bitmap to access. @@ -76,6 +83,7 @@ int bitmap_get(const bitmap_t * bitmap, off_t i) { size_t offset = i / BITMAP_WIDTH(bitmap); + assert(offset < bitmap_get_alloc_size(bitmap)); size_t pos = i % BITMAP_WIDTH(bitmap); size_t shift = BITMAP_WIDTH(bitmap) - pos - 1; return (bitmap[offset] >> shift) & 1; @@ -100,16 +108,27 @@ bitmap_get(const bitmap_t * bitmap, off_t i) * * @return bool */ +#define bitmap_set(bitmap, i) \ + _bitmap_set((bitmap_t**)&bitmap, i) + +/* + * @brief Returns whether the i-th bit is unset (equal to 0) in a bitmap (helper). + * + * @param[in] bitmap The bitmap to access. + * @param[in] i The bit position. + * + * @return bool + */ static inline int -bitmap_set(bitmap_t * bitmap, off_t i) +_bitmap_set(bitmap_t ** bitmap, off_t i) { - if (bitmap_ensure_pos(&bitmap, i) < 0) + if (bitmap_ensure_pos(bitmap, i) < 0) return -1; size_t offset = i / BITMAP_WIDTH(bitmap); size_t pos = i % BITMAP_WIDTH(bitmap); size_t shift = BITMAP_WIDTH(bitmap) - pos - 1; - bitmap[offset] |= 1ul << shift; + (*bitmap)[offset] |= 1ul << shift; return 0; } @@ -186,8 +205,4 @@ END: #define bitmap_free(bitmap) vector_free(bitmap) -#ifdef WITH_TESTS -#define bitmap_get_alloc_size(bitmap) vector_get_alloc_size(bitmap) -#endif /* WITH_TESTS */ - #endif /* UTIL_BITMAP_H */ diff --git a/hicn-light/src/hicn/base/loop.c b/hicn-light/src/hicn/base/loop.c index 8588b538d..d27e81f5b 100644 --- a/hicn-light/src/hicn/base/loop.c +++ b/hicn-light/src/hicn/base/loop.c @@ -97,12 +97,17 @@ void loop_free(loop_t *loop) { free(loop); } -int loop_dispatch(loop_t *loop) +int _loop_dispatch(loop_t *loop, int flags) { - event_base_loop(loop->event_base, EVLOOP_NO_EXIT_ON_EMPTY); + event_base_loop(loop->event_base, flags); return 0; } +int loop_dispatch(loop_t *loop) +{ + return _loop_dispatch(loop, EVLOOP_NO_EXIT_ON_EMPTY); +} + int loop_undispatch(loop_t *loop) { return 0; } void loop_break(loop_t *loop) { event_base_loopbreak(loop->event_base); } diff --git a/hicn-light/src/hicn/base/loop.h b/hicn-light/src/hicn/base/loop.h index 697021175..544d73cd7 100644 --- a/hicn-light/src/hicn/base/loop.h +++ b/hicn-light/src/hicn/base/loop.h @@ -52,7 +52,15 @@ loop_t *loop_create(); void loop_free(loop_t *loop); /** - * \brief Runs the loop instance to process events + * \brief Runs the loop instance to process events (helper). + * \param [in] loop - Pointer to the loop instance + * \param [in] flags - Loop mode: EVLOOP_ONCE, EVLOOP_NONBLOCK or EVLOOP_NO_EXIT_ON_EMPTY + * \return 0 if successful, -1 otherwise + */ +int _loop_dispatch(loop_t *loop, int flags); + +/** + * \brief Runs the loop instance to process events. * \param [in] loop - Pointer to the loop instance * \return 0 if successful, -1 otherwise */ diff --git a/hicn-light/src/hicn/base/pool.c b/hicn-light/src/hicn/base/pool.c index a7c50963d..662c1233c 100644 --- a/hicn-light/src/hicn/base/pool.c +++ b/hicn-light/src/hicn/base/pool.c @@ -154,7 +154,8 @@ _pool_put(void ** pool_ptr, void ** elt, size_t elt_size) pool_hdr_t * ph = pool_hdr(*pool_ptr); uint64_t l = vector_len(ph->free_indices); vector_ensure_pos(ph->free_indices, l); - ph->free_indices[l] = *elt - *pool_ptr; + off_t freed_id = (*elt - *pool_ptr) / elt_size; + ph->free_indices[l] = freed_id; vector_len(ph->free_indices)++; - bitmap_set(ph->free_bitmap, l); + bitmap_set(ph->free_bitmap, freed_id); } diff --git a/hicn-light/src/hicn/base/test/test-loop.cc b/hicn-light/src/hicn/base/test/test-loop.cc index c86ccd5e6..d50b2472a 100644 --- a/hicn-light/src/hicn/base/test/test-loop.cc +++ b/hicn-light/src/hicn/base/test/test-loop.cc @@ -229,7 +229,7 @@ TEST_F(LoopTest, TimerCreateAndCancel) ret = loop_timer_register(timer2, timer_tick_ / 2); EXPECT_TRUE(ret >= 0); - loop_dispatch(loop_); + _loop_dispatch(loop_, 0); loop_undispatch(loop_); @@ -266,7 +266,7 @@ TEST_F(LoopTest, LoopDispatch) EXPECT_TRUE(ret >= 0); // Start event dispatching - loop_dispatch(loop_); + _loop_dispatch(loop_, 0); // Stop dispatching loop_undispatch(loop_); diff --git a/hicn-light/src/hicn/base/test/test-pool.cc b/hicn-light/src/hicn/base/test/test-pool.cc index e5df191ea..fd0d5988b 100644 --- a/hicn-light/src/hicn/base/test/test-pool.cc +++ b/hicn-light/src/hicn/base/test/test-pool.cc @@ -140,7 +140,6 @@ TEST_F(PoolTest, PoolAllocation) pool_free(pool); } -// XXX todo : check state after several get and put TEST_F(PoolTest, PoolPut) { pool_init(pool, DEFAULT_SIZE, 0); @@ -148,9 +147,7 @@ TEST_F(PoolTest, PoolPut) int* elt; pool_get(pool, elt); *elt = 10; - printf("2\n"); pool_put(pool, elt); - printf("3\n"); pool_free(pool); } @@ -169,6 +166,43 @@ TEST_F(PoolTest, PoolGetForceBitmapRealloc) pool_free(pool); } +TEST_F(PoolTest, PoolGetAfterReleasing) +{ + int *elt1 = NULL, *elt2 = NULL, *tmp = NULL; + pool_init(pool, DEFAULT_SIZE, 0); + + // If two elements are requested... + off_t id1 = pool_get(pool, elt1); + pool_get(pool, tmp); + + // ...and the first one is released... + pool_put(pool, elt1); + + // ...requesting a new one should return + // the first one (that was freed) + off_t id2 = pool_get(pool, elt2); + EXPECT_EQ(id1, id2); + EXPECT_EQ(elt1, elt2); + + pool_free(pool); +} + +TEST_F(PoolTest, PoolGetMultipleElementsAfterReleasing) +{ + const int N = 2; + int *elts[N]; + pool_init(pool, N, 0); + + for (int i = 0; i < N; i++) + pool_get(pool, elts[i]); + for (int i = 0; i < N; i++) + pool_put(pool, elts[i]); + for (int i = 0; i < N; i++) + pool_get(pool, elts[i]); + + pool_free(pool); +} + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); diff --git a/hicn-light/src/hicn/base/vector.h b/hicn-light/src/hicn/base/vector.h index b369086fc..fd8401e6d 100644 --- a/hicn-light/src/hicn/base/vector.h +++ b/hicn-light/src/hicn/base/vector.h @@ -251,8 +251,9 @@ do { \ */ #define vector_len(vector) vector_hdr(vector)->cur_size -#ifdef WITH_TESTS +/** + * @brief Returns the allocated size of a vector. + */ #define vector_get_alloc_size(vector) vector_hdr(vector)->alloc_size -#endif /* WITH_TESTS */ #endif /* UTIL_VECTOR_H */ diff --git a/hicn-light/src/hicn/cli/color.c b/hicn-light/src/hicn/cli/color.c index 2fff2ead6..7fb25e6b2 100644 --- a/hicn-light/src/hicn/cli/color.c +++ b/hicn-light/src/hicn/cli/color.c @@ -32,6 +32,7 @@ vprintfc(color_t color, const char * fmt, va_list ap) case COLOR_UNDEFINED: case COLOR_N: + default: // XXX color_s = ""; break; } diff --git a/hicn-light/src/hicn/cli/hicnc.c b/hicn-light/src/hicn/cli/hicnc.c index 2c1c3500e..2445f258c 100644 --- a/hicn-light/src/hicn/cli/hicnc.c +++ b/hicn-light/src/hicn/cli/hicnc.c @@ -150,6 +150,11 @@ main(int argc, char * const * argv) fprintf(stderr, "Error running command"); goto ERR_CMD; } + } else if (command.action == ACTION_CREATE && command.object.type == OBJECT_ROUTE) { + if (hc_route_create(s, &command.object.route) < 0) { + fprintf(stderr, "Error running command"); + goto ERR_CMD; + } } exit(EXIT_SUCCESS); diff --git a/hicn-light/src/hicn/config/command.h b/hicn-light/src/hicn/config/command.h index c0e3e66e8..ddeb94b03 100644 --- a/hicn-light/src/hicn/config/command.h +++ b/hicn-light/src/hicn/config/command.h @@ -13,6 +13,7 @@ /* Update sscanf accordingly in parse_cmd.c */ #define MAX_PARAMETERS 10 +#define MAX_SCANF_PARAM_LEN 100 typedef int (*parser_hook_t)(void * arg); @@ -125,7 +126,7 @@ typedef struct { }, \ } /* We need to allocate room for the intermediate string */ -#define TYPE_FMT_ENUM "%ms" +#define TYPE_FMT_ENUM "%s" #define TYPE_POLICY_STATE(TAG) (parser_type_t) { \ .name = TYPENAME_POLICY_STATE, \ @@ -134,7 +135,7 @@ typedef struct { }, \ } /* We need to allocate room for the intermediate string */ -#define TYPE_FMT_POLICY_STATE "%ms" +#define TYPE_FMT_POLICY_STATE "%s" /** * \brief Register a protocol diff --git a/hicn-light/src/hicn/config/command_route.c b/hicn-light/src/hicn/config/command_route.c index b357cb036..2c20ad193 100644 --- a/hicn-light/src/hicn/config/command_route.c +++ b/hicn-light/src/hicn/config/command_route.c @@ -1,3 +1,4 @@ +#include <math.h> #include "command.h" /* Parameters */ @@ -5,7 +6,7 @@ static const command_parameter_t symbolic_or_id = { .name = "symbolic_or_id", .help = "The symbolic name for an egress, or the egress route id (see 'help list routes')", - .type = TYPE_SYMBOLIC_OR_ID, + .type = TYPE_INT(1, pow(2, 16) - 1), .offset = offsetof(hc_route_t, face_id), }; diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c index f5ed231b2..f56ce73ce 100644 --- a/hicn-light/src/hicn/config/configuration.c +++ b/hicn-light/src/hicn/config/configuration.c @@ -21,8 +21,6 @@ * @endcode */ -#include <hicn/ctrl/commands.h> - #ifndef _WIN32 #include <arpa/inet.h> #include <unistd.h> @@ -53,13 +51,13 @@ #define DEFAULT_COST 1 #define DEFAULT_PORT 1234 -#define make_ack(msg) ((msg_header_t *)msg)->header.messageType = ACK_LIGHT -#define make_nack(msg) ((msg_header_t *)msg)->header.messageType = NACK_LIGHT +#define make_ack(msg) ((msg_header_t *)msg)->header.message_type = ACK_LIGHT +#define make_nack(msg) ((msg_header_t *)msg)->header.message_type = NACK_LIGHT #define msg_malloc_list(msg, N) \ do { \ msg = malloc(sizeof((msg)->header) + N * sizeof((msg)->payload)); \ - (msg)->header.messageType = RESPONSE_LIGHT; \ + (msg)->header.message_type = RESPONSE_LIGHT; \ (msg)->header.length = (uint16_t)(N); \ } while(0); @@ -73,7 +71,7 @@ do { \ * * prefix_str -> strategy_type */ -KHASH_INIT(strategy_map, const char *, unsigned, 0, str_hash, str_hash_eq); +KHASH_MAP_INIT_STR(strategy_map, unsigned); struct configuration_s { forwarder_t * forwarder; @@ -200,23 +198,33 @@ configuration_on_listener_add(configuration_t * config, uint8_t * packet, /* Verify that the listener DOES NOT exist */ listener_t * listener = listener_table_get_by_name(table, control->symbolic); - if (listener) + if (listener) { + DEBUG("Listener %s already exists", control->symbolic); goto NACK; + } address_t address; if (address_from_ip_port(&address, control->family, &control->address, control->port) < 0) { WARN("Unsupported address type for HICN (ingress id %u): " "must be either IPV4 or IPV6", ingress_id); - return false; + goto NACK; } - // NOTE: interface_name is expected NULL for hICN listener - face_type_t face_type = get_face_type_from_listener_type((hc_connection_type_t) control->listenerType); + if (!face_type_is_defined(control->type)) { + WARN("[configuration_on_listener_add] Invalid listener type"); + goto NACK; + } + + // XXX validate that we use face_type everywhere, as we use the untyped + // uint8_t for the control protocol + face_type_t face_type = get_face_type_from_listener_type((hc_connection_type_t) control->type); if (!face_type_is_defined(face_type)) goto NACK; - listener = listener_create(face_type, &address, control->interfaceName, control->symbolic, forwarder); + // NOTE: interface_name is expected NULL for hICN listener + + listener = listener_create(face_type, &address, control->interface_name, control->symbolic, forwarder); if (!listener) goto NACK; @@ -378,10 +386,9 @@ configuration_on_connection_add(configuration_t * config, uint8_t * packet, const char *symbolic_name = control->symbolic; - face_type_t face_type; - if (!face_type_is_defined(control->type)) + face_type_t face_type = get_face_type_from_listener_type((hc_connection_type_t) control->type); + if (!face_type_is_defined(face_type)) goto NACK; - face_type = (face_type_t)control->type; connection_table_t * table = forwarder_get_connection_table(config->forwarder); if (connection_table_get_by_name(table, symbolic_name)) { @@ -1422,7 +1429,7 @@ configuration_receive_command(configuration_t * config, msgbuf_t * msgbuf) case COMMAND_TYPE_ROUTE_LIST: case COMMAND_TYPE_POLICY_LIST: /* Free replies that have been allocated (not NACK's) */ - if (((msg_header_t *)reply)->header.messageType != NACK_LIGHT) + if (((msg_header_t *)reply)->header.message_type != NACK_LIGHT) free(reply); break; default: @@ -1450,4 +1457,3 @@ face_type_t get_face_type_from_listener_type(hc_connection_type_t listener_type) } return face_type; } - diff --git a/hicn-light/src/hicn/config/configuration.h b/hicn-light/src/hicn/config/configuration.h index 1cf772b42..91f851a59 100644 --- a/hicn-light/src/hicn/config/configuration.h +++ b/hicn-light/src/hicn/config/configuration.h @@ -29,6 +29,7 @@ #include "../core/msgbuf.h" #include "../core/strategy.h" #include <hicn/ctrl/api.h> +#include <hicn/ctrl/commands.h> typedef struct configuration_s configuration_t; diff --git a/hicn-light/src/hicn/config/parse.c b/hicn-light/src/hicn/config/parse.c index 4959b7cde..b26227c1a 100644 --- a/hicn-light/src/hicn/config/parse.c +++ b/hicn-light/src/hicn/config/parse.c @@ -33,8 +33,6 @@ #include "command.h" -static void * sscanf_params[MAX_PARAMETERS]; - const char * action_str[] = { #define _(x) [ACTION_ ## x] = #x, foreach_action @@ -114,6 +112,11 @@ parser_type_fmt(const parser_type_t * type) int parser_type_func(const parser_type_t * type, void * src, void *dst, void * dst2, void * dst3) { + ip_address_t addr; + char *addr_str; + char *len_str; + int len; + switch(type->name) { case TYPENAME_INT: *(int*)dst = *(int*)src; @@ -133,19 +136,25 @@ parser_type_func(const parser_type_t * type, void * src, void *dst, void * dst2, case TYPENAME_SYMBOLIC_OR_ID: break; case TYPENAME_IP_ADDRESS: - *(ip_address_t*)dst = IP_ADDRESS_EMPTY; // XXX - *(int*)dst2 = AF_INET; + ip_address_pton((char *)src, &addr); + + *(ip_address_t*)dst = addr; + *(int*)dst2 = ip_address_get_family((char *)src); break; case TYPENAME_IP_PREFIX: - *(ip_address_t*)dst = IP_ADDRESS_EMPTY; // XXX - *(int*)dst2 = 128; - *(int*)dst3 = AF_INET; + addr_str = strtok((char *)src, "/"); + len_str = strtok(NULL, " "); + ip_address_pton((char *)src, &addr); + len = atoi(len_str); + + *(ip_address_t*)dst = addr; + *(int*)dst2 = len; + *(int*)dst3 = ip_address_get_family(addr_str); break; case TYPENAME_ENUM: /* Enum index from string */ assert(type->enum_.from_str); - const char * str = *(const char **)src; - *(int*)dst = type->enum_.from_str(str); + *(int*)dst = type->enum_.from_str((char *)src); break; case TYPENAME_POLICY_STATE: { @@ -172,10 +181,9 @@ parse_params(const command_parser_t * parser, const char * params_s, char fmt[1024]; int n; size_t size = 0; - char * pos = fmt; - - int must_free[MAX_PARAMETERS]; + /* Update MAX_PARAMETERS accordingly in command.h */ + char sscanf_params[MAX_PARAMETERS][MAX_SCANF_PARAM_LEN]; unsigned count = 0; for (unsigned i = 0; i < parser->nparams; i++) { @@ -185,8 +193,6 @@ parse_params(const command_parser_t * parser, const char * params_s, WARN("Ignored parameter %s with unknown type formatter", p->name); continue; } - must_free[count] = (strcmp(fmt, "%ms") == 0), - n = snprintf(pos, 1024 - size, "%s", fmt); pos += n; @@ -198,21 +204,17 @@ parse_params(const command_parser_t * parser, const char * params_s, } *pos = '\0'; - void ** sp = sscanf_params; - /* Update MAX_PARAMETERS accordingly in command.h */ - sscanf(params_s, fmt, &sp[0], &sp[1], &sp[2], &sp[3], &sp[4], &sp[5], - &sp[6], &sp[7], &sp[8], &sp[9]); + sscanf(params_s, fmt, sscanf_params[0], sscanf_params[1], sscanf_params[2], sscanf_params[3], sscanf_params[4], sscanf_params[5], + sscanf_params[6], sscanf_params[7], sscanf_params[8], sscanf_params[9]); for (unsigned i = 0; i < count; i++) { const command_parameter_t * p = &parser->parameters[i]; - if (parser_type_func(&p->type, &sp[i], &command->object.as_uint8 + p->offset, + if (parser_type_func(&p->type, sscanf_params[i], &command->object.as_uint8 + p->offset, &command->object.as_uint8 + p->offset2, &command->object.as_uint8 + p->offset3) < 0) { ERROR("Error during parsing of parameter '%s' value\n", p->name); goto ERR; } - if (must_free[i]) - free(sp[i]); } return 0; diff --git a/hicn-light/src/hicn/core/CMakeLists.txt b/hicn-light/src/hicn/core/CMakeLists.txt index 32b546400..277bcedb2 100644 --- a/hicn-light/src/hicn/core/CMakeLists.txt +++ b/hicn-light/src/hicn/core/CMakeLists.txt @@ -78,4 +78,4 @@ set(TO_INSTALL_HEADER_FILES if (BUILD_TESTS) add_subdirectory(test) -endif()
\ No newline at end of file +endif() diff --git a/hicn-light/src/hicn/core/address.c b/hicn-light/src/hicn/core/address.c index 07aa4a8bd..cde89c888 100644 --- a/hicn-light/src/hicn/core/address.c +++ b/hicn-light/src/hicn/core/address.c @@ -26,10 +26,10 @@ address_from_ip_port(address_t * address, int family, ip_address_t * addr, uint1 memset(address, 0, sizeof(address_t)); switch(family) { case AF_INET: - *address = ADDRESS4(addr->v4.as_inaddr.s_addr, port); + *address = ADDRESS4(ntohl(addr->v4.as_inaddr.s_addr), ntohs(port)); break; case AF_INET6: - *address = ADDRESS6(addr->v6.as_in6addr, port); + *address = ADDRESS6(ntohl(addr->v6.as_in6addr), ntohs(port)); break; default: return -1; @@ -41,3 +41,18 @@ const char * _address_family_str[] = { [AF_INET] = "AF_INET", [AF_INET6] = "AF_INET6", }; + +int address_to_string(const address_t *address, char *buffer) { + struct sockaddr_storage addr = *address; + socklen_t addr_len = sizeof(addr); + int err=getnameinfo((struct sockaddr*) &addr, addr_len, buffer, INET6_ADDRSTRLEN, 0, 0, NI_NUMERICHOST); + + if (err != 0) { + strncpy(buffer, "N/A", INET6_ADDRSTRLEN); + } + return err; +} + +address_t _ADDRESS4_LOCALHOST(uint16_t port) { + return ADDRESS4_LOCALHOST(port); +}
\ No newline at end of file diff --git a/hicn-light/src/hicn/core/address.h b/hicn-light/src/hicn/core/address.h index 35d0f63ea..f1f2ac1e0 100644 --- a/hicn-light/src/hicn/core/address.h +++ b/hicn-light/src/hicn/core/address.h @@ -61,6 +61,15 @@ int address_from_ip_port(address_t * address, int family, ip_address_t * addr, u })) #define ADDRESS4_LOCALHOST(port) ADDRESS4(INADDR_LOOPBACK, (port)) + +/** + * @brief Helper function to avoid macro expansion in c++ tests. Wrapper around 'ADDRESS4_LOCALHOST()'. + * + * @param port + * @return address_t + */ +address_t _ADDRESS4_LOCALHOST(uint16_t port); + #define ADDRESS4_ANY(port) ADDRESS4(INADDR_ANY, (port)) #define ADDRESS6(ip, port) (*(address_t*) &((struct sockaddr_in6) {\ @@ -84,5 +93,13 @@ extern const char * _address_family_str[]; #define address6_empty(address) (memcmp(address6_ip(address).s6_addr, &in6addr_any, sizeof(struct in6_addr)) == 0) #define address_empty(address) (address_family(address) == AF_INET ? address4_empty(address) : address6_empty(address)) -#endif /* HICNLIGHT_ADDRESS_H */ +/** + * @brief Return the string representation of the IP address provided. + * + * @param[in] address Address to obtain the string representation from. + * @param[in, out] buffer String to store the string representation of the address. It contains "N/A" in case of failure (see return value). + * @return int 0 if success, failure otherwise. + */ +int address_to_string(const address_t *address, char *buffer); +#endif /* HICNLIGHT_ADDRESS_H */ diff --git a/hicn-light/src/hicn/core/connection.c b/hicn-light/src/hicn/core/connection.c index 3921eb582..fcca364e9 100644 --- a/hicn-light/src/hicn/core/connection.c +++ b/hicn-light/src/hicn/core/connection.c @@ -286,13 +286,15 @@ connection_initialize(connection_t * connection, face_type_t type, const char * goto ERR_REGISTER_FD; #endif - // XXX TODO - //char *str = pair_ToString(udp->pair); + char addr_str[INET6_ADDRSTRLEN]; + if (local) + address_to_string(&(pair->local), addr_str); + else + address_to_string(&(pair->remote), addr_str); DEBUG("%s connection %p created for address %s (local=%s)", - face_type_str(connection->type), connection, "N/A", + face_type_str(connection->type), connection, addr_str, connection_is_local(connection) ? "true" : "false"); - //free(str); - // + return 0; #if 0 diff --git a/hicn-light/src/hicn/core/connection_table.h b/hicn-light/src/hicn/core/connection_table.h index 160867176..6814967c9 100644 --- a/hicn-light/src/hicn/core/connection_table.h +++ b/hicn-light/src/hicn/core/connection_table.h @@ -39,8 +39,8 @@ #define _ct_var(x) _ct_var_##x /* Hash functions for indices. */ -#define address_pair_hash(pair) (hash32(pair, sizeof(address_pair_t))) -#define address_pair_hash_eq(a, b) (address_pair_hash(b) - address_pair_hash(a)) +#define address_pair_hash(pair) (hash_struct(pair)) +#define address_pair_hash_eq(a, b) (address_pair_hash(b) == address_pair_hash(a)) /* Hash table types for indices. */ KHASH_INIT(ct_pair, const address_pair_t *, unsigned, 1, address_pair_hash, address_pair_hash_eq); diff --git a/hicn-light/src/hicn/core/content_store.h b/hicn-light/src/hicn/core/content_store.h index 95b0a1d0a..754796d31 100644 --- a/hicn-light/src/hicn/core/content_store.h +++ b/hicn-light/src/hicn/core/content_store.h @@ -42,9 +42,9 @@ typedef struct { // XXX TODO #define name_hash(name) (name_HashCode(name)) -#define name_hash_eq(a, b) (name_hash(b) - name_hash(a)) +#define name_hash_eq(a, b) (name_hash(b) == name_hash(a)) -KHASH_INIT(cs_name, const Name *, unsigned, 0, name_hash, name_hash_eq); +KHASH_INIT(cs_name, const Name *, unsigned, 1, name_hash, name_hash_eq); typedef struct { cs_type_t type; diff --git a/hicn-light/src/hicn/core/fib_entry.c b/hicn-light/src/hicn/core/fib_entry.c index 5c6e28d5b..59e5f7e7c 100644 --- a/hicn-light/src/hicn/core/fib_entry.c +++ b/hicn-light/src/hicn/core/fib_entry.c @@ -20,7 +20,6 @@ //#include <hicn/core/connectionState.h> #include <hicn/core/strategy_vft.h> #include <hicn/core/nameBitvector.h> -#include <hicn/utils/commands.h> #ifdef WITH_MAPME #include <hicn/core/ticks.h> @@ -122,7 +121,7 @@ fib_entry_filter_nexthops(fib_entry_t * entry, nexthops_t * nexthops, unsigned nexthop, i; uint_fast32_t flags; - policy_t policy = fib_entry_get_policy(entry); + hicn_policy_t policy = fib_entry_get_policy(entry); nexthops_enumerate(nexthops, i, nexthop, { conn = connection_table_at(table, nexthop); @@ -325,14 +324,14 @@ fib_entry_get_available_nexthops(fib_entry_t * entry, unsigned ingress_id, nexth return fib_entry_filter_nexthops(entry, fib_entry_get_nexthops(entry), ingress_id, true); } -policy_t +hicn_policy_t fib_entry_get_policy(const fib_entry_t * entry) { return entry->policy; } void -fib_entry_set_policy(fib_entry_t * entry, policy_t policy) +fib_entry_set_policy(fib_entry_t * entry, hicn_policy_t policy) { entry->policy = policy; @@ -406,7 +405,7 @@ fib_entry_get_nexthops_from_strategy(fib_entry_t * entry, * If multipath is disabled, we don't offer much choice to the forwarding * strategy, but still go through it for accounting purposes. */ - policy_t policy = fib_entry_get_policy(entry); + hicn_policy_t policy = fib_entry_get_policy(entry); if ((policy.tags[POLICY_TAG_MULTIPATH].state == POLICY_STATE_PROHIBIT) || (policy.tags[POLICY_TAG_MULTIPATH].state != POLICY_STATE_AVOID)) { nexthops_select_one(nexthops); diff --git a/hicn-light/src/hicn/core/fib_entry.h b/hicn-light/src/hicn/core/fib_entry.h index 5ec0f29de..3b249a8fe 100644 --- a/hicn-light/src/hicn/core/fib_entry.h +++ b/hicn-light/src/hicn/core/fib_entry.h @@ -42,7 +42,6 @@ #include "msgbuf.h" #include "nexthops.h" #include "prefix_stats.h" -//#include "../utils/commands.h" // strategy type typedef struct { Name *name; @@ -53,7 +52,7 @@ typedef struct { const void * forwarder; #ifdef WITH_POLICY - policy_t policy; + hicn_policy_t policy; #endif /* WITH_POLICY */ prefix_counters_t prefix_counters; @@ -114,9 +113,9 @@ void fib_entry_on_data(fib_entry_t * fib_entry, const nexthops_t * nexthops, Ticks data_reception); #ifdef WITH_POLICY -policy_t fib_entry_get_policy(const fib_entry_t *fib_entry); +hicn_policy_t fib_entry_get_policy(const fib_entry_t *fib_entry); void fib_entry_reconsider_policy(fib_entry_t *fib_entry); -void fib_entry_set_policy(fib_entry_t *fib_entry, policy_t policy); +void fib_entry_set_policy(fib_entry_t *fib_entry, hicn_policy_t policy); void fib_entry_update_stats(fib_entry_t *fib_entry, uint64_t now); #endif /* WITH_POLICY */ diff --git a/hicn-light/src/hicn/core/forwarder.c b/hicn-light/src/hicn/core/forwarder.c index 9954ecd0a..e1a7243ca 100644 --- a/hicn-light/src/hicn/core/forwarder.c +++ b/hicn-light/src/hicn/core/forwarder.c @@ -941,7 +941,7 @@ forwarder_remove_route(forwarder_t * forwarder, ip_prefix_t * prefix, bool forwarder_add_or_update_policy(forwarder_t * forwarder, ip_prefix_t * prefix, - policy_t * policy) + hicn_policy_t * policy) { assert(forwarder); assert(prefix); @@ -1188,7 +1188,7 @@ forwarder_receive(forwarder_t * forwarder, listener_t * listener, msgbuf->connection_id = listener_create_connection(listener, pair); msg_header_t * msg = (msg_header_t*) packet; - msgbuf->command.type = msg->header.commandID; + msgbuf->command.type = msg->header.command_id; if (msgbuf->command.type >= COMMAND_TYPE_N || msgbuf->command.type == COMMAND_TYPE_UNDEFINED) { ERROR("Invalid command"); return -msgbuf_get_len(msgbuf); diff --git a/hicn-light/src/hicn/core/forwarder.h b/hicn-light/src/hicn/core/forwarder.h index f5ac375da..17d8a1994 100644 --- a/hicn-light/src/hicn/core/forwarder.h +++ b/hicn-light/src/hicn/core/forwarder.h @@ -162,7 +162,7 @@ bool forwarder_remove_route(forwarder_t * forwarder, ip_prefix_t * prefix, * @brief Adds or updates a policy on the message processor */ bool forwarder_add_or_update_policy(forwarder_t * forwarder, - ip_prefix_t * prefix, policy_t * policy); + ip_prefix_t * prefix, hicn_policy_t * policy); /** * @brief Removes a policy from the message processor diff --git a/hicn-light/src/hicn/core/listener.c b/hicn-light/src/hicn/core/listener.c index 66b5c09ee..01f62bb39 100644 --- a/hicn-light/src/hicn/core/listener.c +++ b/hicn-light/src/hicn/core/listener.c @@ -39,7 +39,10 @@ listener_create(face_type_t type, const address_t * address, .type = type, .address = *address, }; - listener_table_allocate(table, listener, &key, name); + listener_table_allocate(table, listener, &key, strdup(name)); + WITH_DEBUG( + listener_table_print(table); + ) unsigned listener_id = listener_table_get_listener_id(table, listener); @@ -63,7 +66,7 @@ listener_initialize(listener_t * listener, face_type_t type, const char * name, .type = type, .interface_name = strdup(interface_name), //.interface_index = , - //.family = , + .family = address->ss_family, .fd = 0, .address = *address, .forwarder = forwarder, @@ -103,12 +106,10 @@ listener_initialize(listener_t * listener, face_type_t type, const char * name, goto ERR_REGISTER_FD; } - // XXX TODO - //char *str = addressToString(listener->local_addr); + char addr_str[INET6_ADDRSTRLEN]; + address_to_string(address, addr_str); DEBUG("%s UdpListener %p created for address %s", - face_type_str(listener->type), listener, "N/A"); - //free(str); - + face_type_str(listener->type), listener, addr_str); return 0; ERR_REGISTER_FD: @@ -282,6 +283,9 @@ listener_read_batch(listener_t * listener) total_size += processed_size; } + // TODO: free only if not used by cs or pit + for (unsigned i = 0; i < MAX_MSG; i++) + msgbuf_pool_put(msgbuf_pool, msgbuf[i]); } while(r == MAX_MSG); /* backpressure based on queue size ? */ /* @@ -375,13 +379,6 @@ listener_setup_all(const forwarder_t * forwarder, uint16_t port, const char *loc void listener_setup_local_ipv4(forwarder_t * forwarder, uint16_t port) { -#if 0 - // XXX memset - address_t address = ADDRESS4_LOCALHOST(port); - - _setupUdpListener(forwarder, "lo_udp", &address, "lo"); - _setupTcpListener(forwarder, "lo_tcp", &address, "lo"); -#endif address_t address; memset(&address, 0, sizeof(address_t)); address = ADDRESS4_LOCALHOST(port); diff --git a/hicn-light/src/hicn/core/listener.h b/hicn-light/src/hicn/core/listener.h index b55074967..d0658270b 100644 --- a/hicn-light/src/hicn/core/listener.h +++ b/hicn-light/src/hicn/core/listener.h @@ -69,6 +69,12 @@ typedef struct { listener_t * listener_create(face_type_t type, const address_t * address, const char * interface_name, const char * symbolic, struct forwarder_s * forwarder); +/** + * @brief Helper function used inside 'listener_create' to + * setup variables in listener struct. + * + * @see listener_create + */ int listener_initialize(listener_t * listener, face_type_t type, const char * name, unsigned listener_id, const address_t * address, const char * interface_name, struct forwarder_s * forwarder); diff --git a/hicn-light/src/hicn/core/listener_table.c b/hicn-light/src/hicn/core/listener_table.c index 9750fbbe8..560c23f20 100644 --- a/hicn-light/src/hicn/core/listener_table.c +++ b/hicn-light/src/hicn/core/listener_table.c @@ -104,3 +104,17 @@ listener_table_get_by_name(listener_table_t * table, const char * name) return NULL; return listener_table_at(table, kh_val(table->id_by_name, k)); } + +listener_t *_listener_table_get_by_id(listener_table_t *table, off_t id) { + return listener_table_get_by_id(table, id); +} + +void listener_table_print(const listener_table_t *table) { + const char *k; + unsigned v; + + printf("*** Listener table ***\n"); + kh_foreach(table->id_by_name, k, v, { + printf("%s:\t%u\n", k, v); + }) +}
\ No newline at end of file diff --git a/hicn-light/src/hicn/core/listener_table.h b/hicn-light/src/hicn/core/listener_table.h index 91b68ee94..91e985221 100644 --- a/hicn-light/src/hicn/core/listener_table.h +++ b/hicn-light/src/hicn/core/listener_table.h @@ -40,8 +40,8 @@ #define _lt_var(x) _lt_var_##x /* Hash functions for indices */ -#define key_hash(key) (hash(key, sizeof(listener_key_t))) -#define key_hash_eq(a, b) (key_hash(b) - key_hash(a)) +#define key_hash(key) (hash_struct(key)) +#define key_hash_eq(a, b) (key_hash(b) == key_hash(a)) /* Hash table types for indices */ KHASH_MAP_INIT_STR(lt_name, unsigned); @@ -72,7 +72,7 @@ typedef struct { */ #define listener_table_allocate(TABLE, LISTENER, KEY, NAME) \ do { \ - pool_get(table->listeners, (LISTENER)); \ + pool_get(TABLE->listeners, (LISTENER)); \ if (LISTENER) { \ off_t _lt_var(id) = (LISTENER) - (TABLE)->listeners; \ int _lt_var(res); \ @@ -176,6 +176,11 @@ do { ? listener_table_at(table, id) : NULL /** + * @brief Helper function to avoid macro expansion in c++ tests. Wrapper around 'listener_table_get_by_id'. + */ +listener_t *_listener_table_get_by_id(listener_table_t *table, off_t id); + +/** * @brief Returns the index of a given listener in the listener table. * * @param[in] table The listener table from which to retrieve the index. @@ -248,6 +253,9 @@ listener_t * listener_table_get_by_name(listener_table_t * table, */ void listener_table_remove_by_id(listener_table_t * table, off_t id); -unsigned listener_table_add(listener_table_t * table, listener_t * listener); +// TODO: not implemented yet +unsigned listener_table_add(const listener_table_t * table, listener_t * listener); + +void listener_table_print(const listener_table_t *table); #endif /* HICNLIGHT_LISTENER_TABLE_H */ diff --git a/hicn-light/src/hicn/core/mapme.h b/hicn-light/src/hicn/core/mapme.h index d1d21079f..29b59faf5 100644 --- a/hicn-light/src/hicn/core/mapme.h +++ b/hicn-light/src/hicn/core/mapme.h @@ -26,12 +26,12 @@ #include <stdbool.h> #include <stdint.h> +#include <hicn/ctrl/commands.h> #include <hicn/hicn.h> #include "connection.h" #include "fib_entry.h" #include "msgbuf.h" -#include "../utils/commands.h" typedef struct mapme_s mapme_t; diff --git a/hicn-light/src/hicn/core/messageHandler.h b/hicn-light/src/hicn/core/messageHandler.h index 1df511a5c..c6a03eee4 100644 --- a/hicn-light/src/hicn/core/messageHandler.h +++ b/hicn-light/src/hicn/core/messageHandler.h @@ -50,6 +50,8 @@ #define CONTROL_PORT 9695 #define HTTP_PORT 8080 +// XXX Hardcoded packet format HF_INET6_TCP + #define IPV6_DEFAULT_VERSION 6 #define IPV6_DEFAULT_TRAFFIC_CLASS 0 #define IPV6_DEFAULT_FLOW_LABEL 0 @@ -183,7 +185,7 @@ static inline bool messageHandler_IsInterest(const uint8_t *message) { if (!messageHandler_IsTCP(message)) return false; bool flag; - hicn_packet_test_ece((hicn_header_t *)message, + hicn_packet_test_ece(HF_INET6_TCP, (hicn_header_t *)message, &flag); // ECE flag is set to 0 in interest packets if (flag == false) return true; return false; @@ -193,7 +195,7 @@ static inline bool messageHandler_IsData(const uint8_t *message) { if (!messageHandler_IsTCP(message)) return false; bool flag; - hicn_packet_test_ece((hicn_header_t *)message, + hicn_packet_test_ece(HF_INET6_TCP, (hicn_header_t *)message, &flag); // ECE flag is set to 1 in data packets if (flag == true) return true; return false; @@ -354,13 +356,10 @@ static inline uint32_t messageHandler_GetPathLabel(const uint8_t *message) { } static inline void messageHandler_SetPathLabel(uint8_t *message, + uint32_t old_path_label, uint32_t new_path_label) { if (!messageHandler_IsTCP(message)) return; - uint32_t old_path_label; - int res = hicn_data_get_path_label((hicn_header_t *)message, &old_path_label); - if (res < 0) return; - hicn_data_set_path_label((hicn_header_t *)message, new_path_label); messageHandler_UpdateTCPCheckSum(message, (uint16_t *)&old_path_label, @@ -376,20 +375,12 @@ static inline void messageHandler_UpdatePathLabel(uint8_t *message, uint32_t pl_new_32bit = (uint32_t)((((pl_old_8bit << 1) | (pl_old_8bit >> 7)) ^ outFace) << 24UL); - hicn_data_set_path_label((hicn_header_t *)message, pl_new_32bit); - - messageHandler_UpdateTCPCheckSum(message, (uint16_t *)&pl_old_32bit, - (uint16_t *)&pl_new_32bit, 2); + // XXX path label should be 8 bits now ? + messageHandler_SetPathLabel(message, pl_old_32bit, pl_new_32bit); } static inline void messageHandler_ResetPathLabel(uint8_t *message) { - if (!messageHandler_IsTCP(message)) return; - - uint32_t pl_old_32bit = messageHandler_GetPathLabel(message); - uint32_t pl_new_32bit = 0; - hicn_data_set_path_label((hicn_header_t *)message, pl_new_32bit); - messageHandler_UpdateTCPCheckSum(message, (uint16_t *)&pl_old_32bit, - (uint16_t *)&pl_new_32bit, 2); + messageHandler_SetPathLabel(message, messageHandler_GetPathLabel(message), 0); } static inline uint16_t messageHandler_GetInterestLifetime( @@ -555,7 +546,7 @@ static inline uint8_t * messageHandler_CreateProbePacket(hicn_format_t format, hicn_packet_init_header(format, (hicn_header_t *) pkt); - hicn_packet_set_dst_port((hicn_header_t *) pkt, BFD_PORT); + hicn_packet_set_dst_port(format, (hicn_header_t *) pkt, BFD_PORT); hicn_interest_set_lifetime ((hicn_header_t *) pkt, probe_lifetime); return pkt; @@ -573,10 +564,10 @@ static inline void messageHandler_CreateProbeReply(uint8_t * probe, uint16_t src_prt; uint16_t dst_prt; - hicn_packet_get_src_port((const hicn_header_t *) probe, &src_prt); - hicn_packet_get_dst_port((const hicn_header_t *) probe, &dst_prt); - hicn_packet_set_src_port((hicn_header_t *) probe, dst_prt); - hicn_packet_set_dst_port((hicn_header_t *) probe, src_prt); + hicn_packet_get_src_port(format, (const hicn_header_t *) probe, &src_prt); + hicn_packet_get_dst_port(format, (const hicn_header_t *) probe, &dst_prt); + hicn_packet_set_src_port(format, (hicn_header_t *) probe, dst_prt); + hicn_packet_set_dst_port(format, (hicn_header_t *) probe, src_prt); hicn_data_set_name (format, (hicn_header_t *) probe, &probe_name); hicn_data_set_locator (format, (hicn_header_t *) probe, &probe_locator); @@ -598,8 +589,8 @@ static inline void messageHandler_SetProbeName(uint8_t * probe, hicn_format_t fo static inline bool messageHandler_IsAProbe(const uint8_t *packet){ uint16_t src_prt; uint16_t dst_prt; - hicn_packet_get_src_port ((const hicn_header_t *) packet, &src_prt); - hicn_packet_get_dst_port ((const hicn_header_t *) packet, &dst_prt); + hicn_packet_get_src_port (HF_INET6_TCP, (const hicn_header_t *) packet, &src_prt); + hicn_packet_get_dst_port (HF_INET6_TCP, (const hicn_header_t *) packet, &dst_prt); if(dst_prt == BFD_PORT){ //interest probe diff --git a/hicn-light/src/hicn/core/msgbuf.h b/hicn-light/src/hicn/core/msgbuf.h index a52e6b298..f3125a2e7 100644 --- a/hicn-light/src/hicn/core/msgbuf.h +++ b/hicn-light/src/hicn/core/msgbuf.h @@ -24,7 +24,7 @@ #include "name.h" #include "ticks.h" #include "messageHandler.h" -#include "../utils/commands.h" +#include <hicn/ctrl/commands.h> struct name_s; @@ -84,8 +84,8 @@ typedef struct { /* Path label */ #define msgbuf_get_pathlabel(M) (messageHandler_GetPathLabel((M)->packet)) -#define msgbuf_set_pathlabel(M, label) (messageHandler_SetPathLabel((M)->packet, label)) -#define msgbuf_update_pathlabel(M, outface) (messageHandler_SetPathLabel((M)->packet, outface)) +#define msgbuf_set_pathlabel(M, label) (messageHandler_SetPathLabel((M)->packet, msgbuf_get_pathlabel(M), label)) +#define msgbuf_update_pathlabel(M, outface) (messageHandler_UpdatePathLabel((M)->packet, outface)) #define msgbuf_reset_pathlabel(M) (messageHandler_ResetPathLabel((M)->packet)) /* WLDR */ diff --git a/hicn-light/src/hicn/core/nameBitvector.c b/hicn-light/src/hicn/core/nameBitvector.c index d3dc8c0ee..999f7a928 100644 --- a/hicn-light/src/hicn/core/nameBitvector.c +++ b/hicn-light/src/hicn/core/nameBitvector.c @@ -21,7 +21,7 @@ #include <hicn/core/nameBitvector.h> #include <hicn/common.h> // hash32 -#include <hicn/utils/commands.h> +#include <hicn/ctrl/commands.h> #define DEFAULT_PORT 1234 #define NAME_LEN 2 diff --git a/hicn-light/src/hicn/core/pit.h b/hicn-light/src/hicn/core/pit.h index 85958f88e..9164aab60 100644 --- a/hicn-light/src/hicn/core/pit.h +++ b/hicn-light/src/hicn/core/pit.h @@ -64,9 +64,9 @@ typedef enum { nexthops_add(pit_entry_get_egress(E), (NH)) #define name_hash(name) (name_HashCode(name)) -#define name_hash_eq(a, b) (name_hash(b) - name_hash(a)) +#define name_hash_eq(a, b) (name_hash(b) == name_hash(a)) -KHASH_INIT(pit_name, const Name *, unsigned, 0, name_hash, name_hash_eq); +KHASH_INIT(pit_name, const Name *, unsigned, 1, name_hash, name_hash_eq); typedef struct { size_t max_size; diff --git a/hicn-light/src/hicn/core/strategy.h b/hicn-light/src/hicn/core/strategy.h index 67630bbab..c684750f1 100644 --- a/hicn-light/src/hicn/core/strategy.h +++ b/hicn-light/src/hicn/core/strategy.h @@ -24,17 +24,6 @@ #include "../strategies/low_latency.h" #include "../strategies/random.h" -typedef enum { - STRATEGY_TYPE_UNDEFINED, - STRATEGY_TYPE_LOADBALANCER, - STRATEGY_TYPE_LOW_LATENCY, - STRATEGY_TYPE_RANDOM, - STRATEGY_TYPE_N -} strategy_type_t; - -#define STRATEGY_TYPE_VALID(type) \ - ((type != STRATEGY_TYPE_UNDEFINED) && (type != STRATEGY_TYPE_N)) - typedef union { strategy_load_balancer_options_t load_balancer; strategy_low_latency_options_t low_latency; diff --git a/hicn-light/src/hicn/core/test/CMakeLists.txt b/hicn-light/src/hicn/core/test/CMakeLists.txt index 1043ce580..95f64594e 100644 --- a/hicn-light/src/hicn/core/test/CMakeLists.txt +++ b/hicn-light/src/hicn/core/test/CMakeLists.txt @@ -4,6 +4,8 @@ include(BuildMacros) list(APPEND TESTS test-msgbuf_pool + test-connection_table + test-listener_table ) foreach(test ${TESTS}) diff --git a/hicn-light/src/hicn/core/test/test-connection_table.cc b/hicn-light/src/hicn/core/test/test-connection_table.cc new file mode 100644 index 000000000..b4dd53eef --- /dev/null +++ b/hicn-light/src/hicn/core/test/test-connection_table.cc @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020 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 <gtest/gtest.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" { +#define WITH_TESTS +#include <hicn/core/connection_table.h> +} + +class ConnectionTableTest : public ::testing::Test { +protected: + ConnectionTableTest() { + conn_table = connection_table_create(); + } + virtual ~ConnectionTableTest() { + connection_table_free(conn_table); + } + + connection_table_t *conn_table; +}; + +TEST_F(ConnectionTableTest, Create) +{ + /* Check connection_table allocation */ + EXPECT_NE(conn_table, nullptr); + + /* Check connection_table size */ + size_t conn_table_size = connection_table_len(conn_table); + EXPECT_EQ(conn_table_size, (size_t) 0); +} + +TEST_F(ConnectionTableTest, AddConnection) +{ + address_pair_t pair = { + .local = _ADDRESS4_LOCALHOST(1), + .remote = _ADDRESS4_LOCALHOST(2) + }; + connection_t * connection; + + connection_table_allocate(conn_table, connection, &pair, "listener_name_test"); + size_t conn_table_size = connection_table_len(conn_table); + EXPECT_EQ(conn_table_size, (size_t) 1); + EXPECT_NE(connection, nullptr); + + khiter_t k = kh_get_ct_name(conn_table->id_by_name, "listener_name_test"); + EXPECT_NE(k, kh_end(conn_table->id_by_name)); + k = kh_get_ct_pair(conn_table->id_by_pair, &pair); + EXPECT_NE(k, kh_end(conn_table->id_by_pair)); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/hicn-light/src/hicn/core/test/test-listener_table.cc b/hicn-light/src/hicn/core/test/test-listener_table.cc new file mode 100644 index 000000000..34db546fc --- /dev/null +++ b/hicn-light/src/hicn/core/test/test-listener_table.cc @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2020 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 <gtest/gtest.h> +#include <gmock/gmock.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <netinet/in.h> + +extern "C" { +#define WITH_TESTS +#include <hicn/core/listener_table.h> +} + +#define LISTENER_NAME "listener_name_test" +#define LISTENER_NAME_2 "listener_name_test_2" + +class ListenerTableTest : public ::testing::Test { +protected: + ListenerTableTest() { + listener_table = listener_table_create(); + } + virtual ~ListenerTableTest() { + listener_table_free(listener_table); + } + + listener_table_t *listener_table; + listener_t *listener; + listener_key_t key = { + .address = _ADDRESS4_LOCALHOST(1), + .type = FACE_TYPE_UDP + }; +}; + +TEST_F(ListenerTableTest, CreateTable) +{ + // Check listener_table allocation + EXPECT_NE(listener_table, nullptr); + + // Check listener_table size + size_t listener_table_size = listener_table_len(listener_table); + EXPECT_EQ(listener_table_size, (size_t) 0); +} + +TEST_F(ListenerTableTest, AddListener) +{ + // Add listener to listener table + listener_table_allocate(listener_table, listener, &key, LISTENER_NAME); + size_t listener_table_size = listener_table_len(listener_table); + EXPECT_EQ(listener_table_size, (size_t) 1); + EXPECT_NE(listener, nullptr); + + // Get listener by name and by key + khiter_t k_name = kh_get_lt_name(listener_table->id_by_name, LISTENER_NAME); + EXPECT_NE(k_name, kh_end(listener_table->id_by_name)); + khiter_t k_key = kh_get_lt_key(listener_table->id_by_key, &key); + EXPECT_NE(k_key, kh_end(listener_table->id_by_key)); +} + +TEST_F(ListenerTableTest, GetListener) +{ + // Add listener to listener table + listener_table_allocate(listener_table, listener, &key, LISTENER_NAME); + size_t listener_table_size = listener_table_len(listener_table); + EXPECT_EQ(listener_table_size, (size_t) 1); + ASSERT_NE(listener, nullptr); + + // Get listener by name + listener_t *listener_retrieved = listener_table_get_by_name(listener_table, LISTENER_NAME); + ASSERT_NE(listener_retrieved, nullptr); + EXPECT_EQ(listener_retrieved, listener); + + // Get listener by key + listener_retrieved = listener_table_get_by_address(listener_table, key.type, &key.address); + ASSERT_NE(listener_retrieved, nullptr); + EXPECT_EQ(listener_retrieved, listener); +} + +TEST_F(ListenerTableTest, GetListenerWithIdOutOfRange) +{ + // Try to retrieve a listener with an index + // bigger than the current listener table size + ASSERT_DEATH({ + _listener_table_get_by_id(listener_table, ~0); + }, ".*Assertion.*"); +} + +TEST_F(ListenerTableTest, GetListenerWithInvalidId) +{ + // First listener inserted has always id equal to 0 + int non_valid_id = 5; + + listener_table_allocate(listener_table, listener, &key, LISTENER_NAME); + listener_t *listener_not_found = listener_table_get_by_id(listener_table, non_valid_id); + ASSERT_EQ(listener_not_found, nullptr); +} + +TEST_F(ListenerTableTest, GetListenerWithValidId) +{ + listener_table_allocate(listener_table, listener, &key, LISTENER_NAME); + int id = listener_table_get_listener_id(listener_table, listener); + listener_t *listener_found = listener_table_get_by_id(listener_table, id); + ASSERT_EQ(listener_found, listener); +} + +TEST_F(ListenerTableTest, RemoveListener) +{ + // Add listener (listerner name and key must be set) + listener_table_allocate(listener_table, listener, &key, LISTENER_NAME); + listener->name = (char*) LISTENER_NAME; + listener->key = key; + + // Remove listener + int id = listener_table_get_listener_id(listener_table, listener); + listener_table_remove_by_id(listener_table, id); + + // Check listener table size + size_t listener_table_size = listener_table_len(listener_table); + EXPECT_EQ(listener_table_size, (size_t) 0); + + // Check that previous listener is not valid anymore + listener_t *listener_not_found = listener_table_get_by_id(listener_table, id); + EXPECT_EQ(listener_not_found, nullptr); + listener_not_found = listener_table_get_by_name(listener_table, LISTENER_NAME); + EXPECT_EQ(listener_not_found, nullptr); + listener_not_found = listener_table_get_by_address(listener_table, key.type, &key.address); + EXPECT_EQ(listener_not_found, nullptr); +} + +TEST_F(ListenerTableTest, PrintTable) +{ + listener_table_allocate(listener_table, listener, &key, LISTENER_NAME); + + listener_t *listener_2; + listener_key_t key_2 = { + .address = _ADDRESS4_LOCALHOST(2), + .type = FACE_TYPE_TCP + }; + listener_table_allocate(listener_table, listener_2, &key_2, LISTENER_NAME_2); + + testing::internal::CaptureStdout(); + listener_table_print(listener_table); + std::string std_out = testing::internal::GetCapturedStdout(); + + ASSERT_NE(std_out, ""); + EXPECT_THAT(std_out, testing::HasSubstr(LISTENER_NAME)); + EXPECT_THAT(std_out, testing::HasSubstr(LISTENER_NAME_2)); +} + +TEST_F(ListenerTableTest, AddMultipleListeners) +{ + listener_table_allocate(listener_table, listener, &key, LISTENER_NAME); + + listener_t *listener_2; + listener_key_t key_2 = { + .address = _ADDRESS4_LOCALHOST(2), + .type = FACE_TYPE_TCP + }; + listener_table_allocate(listener_table, listener_2, &key_2, "listener_name_test_2"); + + // Check listener table size + size_t listener_table_size = listener_table_len(listener_table); + EXPECT_EQ(listener_table_size, (size_t) 2); + + listener_t *l1 = listener_table_get_by_name(listener_table, LISTENER_NAME); + ASSERT_NE(l1, nullptr); + listener_t *l2 = listener_table_get_by_name(listener_table, LISTENER_NAME_2); + ASSERT_NE(l2, nullptr); + EXPECT_NE(l1, l2); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/hicn-light/src/hicn/io/tcp.c b/hicn-light/src/hicn/io/tcp.c index e4f5d196f..1e36f78ea 100644 --- a/hicn-light/src/hicn/io/tcp.c +++ b/hicn-light/src/hicn/io/tcp.c @@ -38,7 +38,6 @@ #include "../core/msgbuf.h" #include "../core/forwarder.h" #include "../core/messageHandler.h" -#include "../utils/commands.h" // 128 KB output queue #define OUTPUT_QUEUE_BYTES (128 * 1024) @@ -144,12 +143,14 @@ connection_tcp_accept(connection_t * connection, forwarder_t *forwarder, int fd, .closed = false, }; - // XXX this new connection needs to be registered - //char *str = pair_ToString(udp->pair); + char addr_str[INET6_ADDRSTRLEN]; + if (local) + address_to_string(&(pair->local), addr_str); + else + address_to_string(&(pair->remote), addr_str); INFO("%s connection %p created for address %s (local=%s)", - face_type_str(connection->type), connection, "N/A", + face_type_str(connection->type), connection, addr_str, connection_is_local(connection) ? "true" : "false"); - //free(str); return 0; } @@ -233,10 +234,12 @@ connection_tcp_initialize(connection_t * connection) return -1; } - //char *pair_str = address_pair_ToString(pair); - INFO("%s connection %p connect for address pair %s", - face_type_str(connection->type), connection, "N/A"); - //free(pair_str); + char local_addr_str[INET6_ADDRSTRLEN]; + address_to_string(&(connection->pair.local), local_addr_str); + char remote_addr_str[INET6_ADDRSTRLEN]; + address_to_string(&(connection->pair.remote), remote_addr_str); + INFO("%s connection %p connect for address pair %s - %s", + face_type_str(connection->type), connection,local_addr_str, remote_addr_str); return 0; } diff --git a/hicn-light/src/hicn/strategies/low_latency.h b/hicn-light/src/hicn/strategies/low_latency.h index ff8255eae..47e9a202b 100644 --- a/hicn-light/src/hicn/strategies/low_latency.h +++ b/hicn-light/src/hicn/strategies/low_latency.h @@ -20,10 +20,10 @@ #ifndef HICNLIGHT_STRATEGY_LOW_LATENCY_H #define HICNLIGHT_STRATEGY_LOW_LATENCY_H -#define MAX_FWD_STRATEGY_RELATED_PREFIXES 10 - struct name_s; +#include <hicn/strategy.h> + typedef struct { } strategy_low_latency_nexthop_state_t; diff --git a/hicn-light/src/hicn/utils/CMakeLists.txt b/hicn-light/src/hicn/utils/CMakeLists.txt index 99592b31d..1fdfdee9f 100644 --- a/hicn-light/src/hicn/utils/CMakeLists.txt +++ b/hicn-light/src/hicn/utils/CMakeLists.txt @@ -13,8 +13,9 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) +# XXX This is installed in hicn/utils... list(APPEND HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/commands.h +# ${CMAKE_CURRENT_SOURCE_DIR}/commands.h # ${CMAKE_CURRENT_SOURCE_DIR}/interface.h # ${CMAKE_CURRENT_SOURCE_DIR}/interfaceSet.h ${CMAKE_CURRENT_SOURCE_DIR}/punting.h diff --git a/hicn-light/src/hicn/utils/commands.h b/hicn-light/src/hicn/utils/commands.h deleted file mode 100644 index ede6177f4..000000000 --- a/hicn-light/src/hicn/utils/commands.h +++ /dev/null @@ -1,378 +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 commands.h - * @brief All hicn-light commands: 14 in total. - * - * Header and payload in binary format. - */ - -#ifndef commands_h -#define commands_h - -#ifndef _WIN32 -#include <netinet/in.h> -#include <sys/socket.h> -#endif - -#include <stdint.h> -#include <stdlib.h> - -#ifdef WITH_POLICY -#include <hicn/policy.h> -#endif /* WITH_POLICY */ -#include <hicn/util/ip_address.h> - -#include "../core/strategy.h" // to be moved in libhicn - -#define SYMBOLIC_NAME_LEN 16 - -typedef struct in6_addr ipv6_addr_t; -typedef uint32_t ipv4_addr_t; - -typedef enum { - MESSAGE_COMMAND_SUBTYPE_UNDEFINED, - REQUEST_LIGHT = 0xc0, // this is a command - RESPONSE_LIGHT, - ACK_LIGHT, - NACK_LIGHT, - MESSAGE_COMMAND_SUBTYPE_N -} message_command_subtype_t; - -#define message_type_is_valid(message_type) \ - ((message_type != MESSAGE_TYPE_UNDEFINED) && (message_type != MESSAGE_COMMAND_SUBTYPE_N)) - -#define message_type_from_uchar(x) \ - (((x) < REQUEST_LIGHT) || (((x) >= MESSAGE_COMMAND_SUBTYPE_N)) ? MESSAGE_COMMAND_SUBTYPE_N : (message_command_subtype_t)(x)) - -#define foreach_command_type \ - _(listener_add, LISTENER_ADD) \ - _(listener_remove, LISTENER_REMOVE) \ - _(listener_list, LISTENER_LIST) \ - _(connection_add, CONNECTION_ADD) \ - _(connection_remove, CONNECTION_REMOVE) \ - _(connection_list, CONNECTION_LIST) \ - _(connection_set_admin_state, CONNECTION_SET_ADMIN_STATE) \ - _(connection_update, CONNECTION_UPDATE) \ - _(connection_set_priority, CONNECTION_SET_PRIORITY) \ - _(connection_set_tags, CONNECTION_SET_TAGS) \ - _(route_add, ROUTE_ADD) \ - _(route_remove, ROUTE_REMOVE) \ - _(route_list, ROUTE_LIST) \ - _(cache_set_store, CACHE_SET_STORE) \ - _(cache_set_serve, CACHE_SET_SERVE) \ - _(cache_clear, CACHE_CLEAR) \ - _(strategy_set, STRATEGY_SET) \ - _(wldr_set, WLDR_SET) \ - _(punting_add, PUNTING_ADD) \ - _(mapme_enable, MAPME_ENABLE) \ - _(mapme_set_discovery, MAPME_SET_DISCOVERY) \ - _(mapme_set_timescale, MAPME_SET_TIMESCALE) \ - _(mapme_set_retx, MAPME_SET_RETX) \ - _(mapme_send_update, MAPME_SEND_UPDATE) \ - _(policy_add, POLICY_ADD) \ - _(policy_remove, POLICY_REMOVE) \ - _(policy_list, POLICY_LIST) \ - -typedef enum { - COMMAND_TYPE_UNDEFINED, -#define _(l, u) COMMAND_TYPE_ ## u, - foreach_command_type -#undef _ - COMMAND_TYPE_N, -} command_type_t; - -#define command_type_is_valid(command_type) \ - ((command_type != COMMAND_TYPE_UNDEFINED) && (command_type != COMMAND_TYPE_N)) - -#define command_type_from_uchar(x) \ - (((x) >= COMMAND_TYPE_N) ? COMMAND_TYPE_N : (command_type_t)(x)) - -/* Should be at least 8 bytes */ -typedef struct { - uint8_t messageType; - uint8_t commandID; - uint16_t length; /* Number of structures in the payload */ - uint32_t seqNum; -} cmd_header_t; - -typedef struct { - cmd_header_t header; -} msg_header_t; - -/* Listener */ - -typedef struct { - char symbolic[SYMBOLIC_NAME_LEN]; - char interface_name[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint16_t port; - uint8_t family; - uint8_t listener_type; -} cmd_listener_add_t; - -typedef struct { - char symbolicOrListenerid[SYMBOLIC_NAME_LEN]; -} cmd_listener_remove_t; - -typedef struct { -} cmd_listener_list_t; - -typedef struct { - ip_address_t address; - char name[SYMBOLIC_NAME_LEN]; - char interface_name[SYMBOLIC_NAME_LEN]; - uint32_t id; - uint16_t port; - uint8_t family; - uint8_t type; -} cmd_listener_list_item_t; - -/* Connection */ - -typedef struct { - char symbolic[SYMBOLIC_NAME_LEN]; - //char interface_name[SYMBOLIC_NAME_LEN]; - ip_address_t remote_ip; - ip_address_t local_ip; - uint16_t remote_port; - uint16_t local_port; - uint8_t family; - uint8_t type; - uint8_t admin_state; -#ifdef WITH_POLICY - uint32_t priority; - policy_tags_t tags; -#endif /* WITH_POLICY */ -} cmd_connection_add_t; - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; -} cmd_connection_remove_t; - -typedef struct { -} cmd_connection_list_t; - -typedef struct { - char symbolic[SYMBOLIC_NAME_LEN]; - //char interface_name[SYMBOLIC_NAME_LEN]; - ip_address_t remote_ip; - ip_address_t local_ip; - uint16_t remote_port; - uint16_t local_port; - uint8_t family; - uint8_t type; - uint8_t admin_state; -#ifdef WITH_POLICY - uint32_t priority; - policy_tags_t tags; -#endif /* WITH_POLICY */ - uint32_t id; - uint8_t state; - char interface_name[SYMBOLIC_NAME_LEN]; - char name[SYMBOLIC_NAME_LEN]; -} cmd_connection_list_item_t; - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - uint8_t admin_state; - uint8_t pad8[3]; -} cmd_connection_set_admin_state_t; - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - uint8_t admin_state; - uint32_t priority; - policy_tags_t tags; -} cmd_connection_update_t; - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - uint32_t priority; -} cmd_connection_set_priority_t; - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - policy_tags_t tags; -} cmd_connection_set_tags_t; - -/* Route */ - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint16_t cost; - uint8_t family; - uint8_t len; -} cmd_route_add_t; - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint8_t family; - uint8_t len; -} cmd_route_remove_t; - -typedef struct { -} cmd_route_list_t; - -typedef struct { - ip_address_t address; - uint32_t connection_id; - uint16_t cost; - uint8_t family; - uint8_t len; -} cmd_route_list_item_t; - -/* Cache */ - -typedef struct { - uint8_t activate; -} cmd_cache_set_store_t; - -typedef struct { - uint8_t activate; -} cmd_cache_set_serve_t; - -typedef struct { -} cmd_cache_clear_t; - -/* WLDR */ - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - uint8_t activate; -} cmd_wldr_set_t; - -/* Strategy */ - -typedef struct { - ip_address_t address; - uint8_t strategy_type; - uint8_t family; - uint8_t len; - uint8_t related_prefixes; - union { - struct { - ip_address_t addresses[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - uint8_t lens[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - uint8_t families[MAX_FWD_STRATEGY_RELATED_PREFIXES]; - } low_latency; - }; -} cmd_strategy_set_t; - -/* Punting */ - -typedef struct { - char symbolicOrConnid[SYMBOLIC_NAME_LEN]; - ip_address_t address; - uint8_t family; - uint8_t len; -} cmd_punting_add_t; - -/* MAP-Me */ - -typedef struct { - uint8_t activate; -} cmd_mapme_activator_t; - -typedef cmd_mapme_activator_t cmd_mapme_enable_t; -typedef cmd_mapme_activator_t cmd_mapme_set_discovery_t; - -typedef struct { - uint32_t timePeriod; -} cmd_mapme_timing_t; - -typedef cmd_mapme_timing_t cmd_mapme_set_timescale_t; -typedef cmd_mapme_timing_t cmd_mapme_set_retx_t; - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; -} cmd_mapme_send_update_t; - -/* Policy */ - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; - policy_t policy; -} cmd_policy_add_t; - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; -} cmd_policy_remove_t; - -typedef struct { -} cmd_policy_list_t; - -typedef struct { - ip_address_t address; - uint8_t family; - uint8_t len; - policy_t policy; -} cmd_policy_list_item_t; - -/* Full messages */ - -#define _(l, u) \ -typedef struct { \ - cmd_header_t header; \ - cmd_ ## l ## _t payload; \ -} msg_ ## l ## _t; - foreach_command_type -#undef _ - -typedef struct { - cmd_header_t header; - cmd_listener_list_item_t payload; -} msg_listener_list_reply_t; - -typedef struct { - cmd_header_t header; - cmd_connection_list_item_t payload; -} msg_connection_list_reply_t; - -typedef struct { - cmd_header_t header; - cmd_route_list_item_t payload; -} msg_route_list_reply_t; - -typedef struct { - cmd_header_t header; - cmd_policy_list_item_t payload; -} msg_policy_list_reply_t; - -//===== size of commands ====== -// REMINDER: when a new_command is added, the following switch has to be -// updated. -static inline int command_get_payload_len(command_type_t command_type) { - switch (command_type) { -#define _(l, u) \ - case COMMAND_TYPE_ ## u: \ - return sizeof(cmd_## l ## _t); - foreach_command_type -#undef _ - case COMMAND_TYPE_UNDEFINED: - case COMMAND_TYPE_N: - return 0; - } -} -#endif diff --git a/hicn-light/src/hicn/utils/utils.h b/hicn-light/src/hicn/utils/utils.h index 368a93f5a..ee94250bb 100644 --- a/hicn-light/src/hicn/utils/utils.h +++ b/hicn-light/src/hicn/utils/utils.h @@ -17,7 +17,8 @@ #define utils_h //#include <hicn/config/controlState.h> -#include <hicn/utils/commands.h> +//#include <hicn/utils/commands.h> +#include <hicn/util/ip_address.h> /** * Return true if string is purely an integer @@ -30,6 +31,8 @@ bool utils_IsNumber(const char *string); */ bool utils_ValidateSymbolicName(const char *symbolic); +// XXX cf IS_VALID_xxx in libhicntrl + /** *Convert IPv4/IPv6 address from binary to text string. `uint8_t *ipAddress` has *to be a `in_addr_t * or `a struct in6_addr *. |