From 1b6994811bb8b94793e1086b0a49e2940621d863 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Fri, 14 May 2021 17:57:01 +0900 Subject: [PATCH 01/16] VineQueue: modify pop() to operate like std::queue Change-Id: I92f75a430848b630d9cc280d7d336749c26d122d --- plugins/libwebsockets/libwebsockets-plugin.cpp | 15 ++++++++++----- src/include/vine-queue.h | 13 ++----------- src/vine-dp.cpp | 2 +- src/vine-event-loop.cpp | 19 ++++++++++++------- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/plugins/libwebsockets/libwebsockets-plugin.cpp b/plugins/libwebsockets/libwebsockets-plugin.cpp index a9918a4..fed2d1b 100755 --- a/plugins/libwebsockets/libwebsockets-plugin.cpp +++ b/plugins/libwebsockets/libwebsockets-plugin.cpp @@ -231,7 +231,10 @@ static void _del_websocket_op_request(websocket_op_s *op) static void _process_websocket_op_request(void) { - websocket_op_s *op = op_queue.pop(); + RET_IF(op_queue.empty(), "operation queue is NULL"); + + websocket_op_s *op = op_queue.front(); + op_queue.pop(); RET_IF(op == NULL, "op is NULL"); if (!op->ws) { @@ -764,10 +767,12 @@ static int _write_data(websocket_s *ws) websocket_data_s *wd = NULL; int bytes = 0; - if (!ws->write_buffer) + if (!ws->write_buffer || ws->write_buffer->empty()) return bytes; - if ((wd = ws->write_buffer->pop())) { + wd = ws->write_buffer->front(); + ws->write_buffer->pop(); + if (wd) { unsigned char *out = (unsigned char *)calloc(LWS_PRE + wd->len, sizeof(unsigned char)); memcpy(out + LWS_PRE, wd->buf, wd->len); @@ -810,7 +815,7 @@ static int websocket_read(vine_dp_plugin_h handle, unsigned char *buf, size_t le while (!ws->recv_buffer->empty() && len > 0) { wd = ws->recv_buffer->front(); if (wd == nullptr) { - ws->recv_buffer->erase(); + ws->recv_buffer->pop(); return bytes; } @@ -821,7 +826,7 @@ static int websocket_read(vine_dp_plugin_h handle, unsigned char *buf, size_t le bytes += read_len; if (read_len >= wd->len) { - ws->recv_buffer->erase(); + ws->recv_buffer->pop(); bool last = wd->last; __destroy_websocket_data(wd); wd = NULL; diff --git a/src/include/vine-queue.h b/src/include/vine-queue.h index 4996394..5b805e8 100755 --- a/src/include/vine-queue.h +++ b/src/include/vine-queue.h @@ -40,20 +40,11 @@ public: _queue.push(element); } - T pop() + void pop() { std::lock_guard lock_guard(_q_mutex); if (_queue.empty()) - return NULL; - - T element = _queue.front(); - _queue.pop(); - return element; - } - - void erase() // void pop - { - std::lock_guard lock_guard(_q_mutex); + return; _queue.pop(); } diff --git a/src/vine-dp.cpp b/src/vine-dp.cpp index 52c94db..f6f4f68 100644 --- a/src/vine-dp.cpp +++ b/src/vine-dp.cpp @@ -1038,7 +1038,7 @@ int DPPubSub::recv(unsigned char *buf, size_t buf_len, size_t *read_len) *read_len = bytes; if (dp_info.second == 0) - mRecvDataPathList.erase(); + mRecvDataPathList.pop(); return VINE_ERROR_NONE; } diff --git a/src/vine-event-loop.cpp b/src/vine-event-loop.cpp index d4af0c7..f069db0 100644 --- a/src/vine-event-loop.cpp +++ b/src/vine-event-loop.cpp @@ -154,11 +154,15 @@ void vine_event_queue_destroy(vine_event_queue_h event_fd) { vine_event_queue_s *event_fd_handle = (vine_event_queue_s *)event_fd; - vine_event *event; - while ( (event = event_fd_handle->event_queue.pop()) != NULL) { - if (event->free_func) + vine_event *event = NULL; + while(!event_fd_handle->event_queue.empty()) { + event = event_fd_handle->event_queue.front(); + if (event && event->free_func) event->free_func(event->event_data); + event_fd_handle->event_queue.pop(); + free(event); } + if (event_fd_handle->fd >= 0) close(event_fd_handle->fd); delete event_fd_handle; @@ -286,17 +290,18 @@ int vine_event_loop_process(vine_event_queue_h event_fd) VINE_LOGD("eventfd counter: %lld", u); - while (u--) { - vine_event *event = event_fd_handle->event_queue.pop(); + while (u-- && !event_fd_handle->event_queue.empty()) { + vine_event *event = event_fd_handle->event_queue.front(); + event_fd_handle->event_queue.pop(); if (event == NULL) { VINE_LOGE("vine event queue is empty"); - return VINE_ERROR_INVALID_OPERATION; + continue; } VINE_LOGD("Vine event[%p]", event); if (event->handler == NULL) { VINE_LOGI("No event handler"); - return VINE_ERROR_NONE; + continue; } event->handler(event->event_data, event->user_data); -- 2.7.4 From 1e9bdc0c3e3d2b94e2a3d6cde5df36011c114d5a Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Thu, 20 May 2021 16:03:53 +0900 Subject: [PATCH 02/16] tool: Use a different timerfd per each dp Change-Id: Ic0d922609c98bd430f557b525198b609f0b0ccfa --- tool/tool_run.cpp | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/tool/tool_run.cpp b/tool/tool_run.cpp index ab7632b..83c25a5 100644 --- a/tool/tool_run.cpp +++ b/tool/tool_run.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #define RESET_COLOR "\e[m" #define MAKE_RED "\e[31m" @@ -23,7 +24,6 @@ extern int interrupt_flag; static int epollfd = 0; -static int timerfd = 0; static FILE *log_file = NULL; static struct { @@ -60,8 +60,9 @@ static struct { .is_sec = false, }; +static std::map timerfds; static int send_message(vine_dp_h dp); -static void _stop_message_timer(); +static void _stop_message_timer(vine_dp_h dp); static void __print_received_data(unsigned char *buf, size_t len) { @@ -86,7 +87,7 @@ static void __received_cb(vine_dp_h dp, size_t received_len, void *user_data) static void __terminated_cb(vine_dp_h dp, void *user_data) { printf("peer is terminated.\n"); - _stop_message_timer(); + _stop_message_timer(dp); } static void __opened_cb(vine_dp_h dp, vine_error_e result, void *user_data) @@ -221,7 +222,7 @@ static void _start_message_timer(vine_dp_h dp, int sec) if (sec <= 0) return; - timerfd = timerfd_create(CLOCK_MONOTONIC, 0); + int timerfd = timerfd_create(CLOCK_MONOTONIC, 0); if (timerfd == -1) return; @@ -235,26 +236,44 @@ static void _start_message_timer(vine_dp_h dp, int sec) return; } + timerfds.insert(std::make_pair(dp, timerfd)); struct epoll_event ev; ev.events = EPOLLIN; ev.data.ptr = (void *)dp; epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &ev); } -static void _stop_message_timer() +static void _stop_message_timer(vine_dp_h dp) { - if (timerfd <= 0) + auto it = timerfds.find(dp); + if (it == timerfds.end()) return; + int timerfd = it->second; + if (timerfd <= 0) { + timerfds.erase(it); + return; + } + epoll_ctl(epollfd, EPOLL_CTL_DEL, timerfd, NULL); close(timerfd); - timerfd = 0; + timerfds.erase(it); +} + +static void _stop_message_timer_all() +{ + for (auto &it : timerfds) { + if (it.second <= 0) + continue; + close(it.second); + } + timerfds.clear(); } static void _message_timer_handler(void *user_data) { - vine_dp_h dp = (vine_dp_h)user_data; - _stop_message_timer(); + vine_dp_h dp = (vine_dp_h) user_data; + _stop_message_timer(dp); send_message(dp); } @@ -307,7 +326,6 @@ static int _send_message(vine_dp_h dp) int ret = vine_dp_send(dp, buf, len); printf("%s to send a message.\n", ret == VINE_ERROR_NONE ? "Succeeded" : "Failed"); - _start_message_timer(dp, vine_configs.interval); return ret; } @@ -340,8 +358,7 @@ static void deinit() { tool_config_deinit(); - if (timerfd) - _stop_message_timer(); + _stop_message_timer_all(); if (log_file) { fclose(log_file); -- 2.7.4 From 1cc28b6317fcc182d89f90a0fd8405bb089aef48 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Fri, 21 May 2021 14:02:40 +0900 Subject: [PATCH 03/16] tests: Expose print functions Change-Id: Ibbe00dd27d6b60f3010818f5356c8f3922b8134d --- tests/vine-test/CMakeLists.txt | 5 +- tests/vine-test/vine-multi-thread-test.cpp | 105 +++---------------------- tests/vine-test/vine-test-utils.cpp | 78 +++++++++++++++++++ tests/vine-test/vine-test-utils.h | 18 +++++ tests/vine-test/vine-test.cpp | 118 +++++++---------------------- 5 files changed, 139 insertions(+), 185 deletions(-) create mode 100644 tests/vine-test/vine-test-utils.cpp create mode 100644 tests/vine-test/vine-test-utils.h diff --git a/tests/vine-test/CMakeLists.txt b/tests/vine-test/CMakeLists.txt index 691d9ee..b8f0953 100755 --- a/tests/vine-test/CMakeLists.txt +++ b/tests/vine-test/CMakeLists.txt @@ -26,9 +26,12 @@ INCLUDE_DIRECTORIES( ) FILE(GLOB VINE_TEST_SRCS *.cpp) +FILE(GLOB VINE_TEST_UTILS_SRC *utils*.cpp) +LIST(REMOVE_ITEM VINE_TEST_SRCS ${VINE_TEST_UTILS_SRC}) + foreach(file ${VINE_TEST_SRCS}) GET_FILENAME_COMPONENT(name ${file} NAME_WE) - ADD_EXECUTABLE(${name} ${file}) + ADD_EXECUTABLE(${name} ${file} ${VINE_TEST_UTILS_SRC}) TARGET_LINK_LIBRARIES(${name} ${TARGET_VINE} ${VINE_LOGGER} diff --git a/tests/vine-test/vine-multi-thread-test.cpp b/tests/vine-test/vine-multi-thread-test.cpp index 86de01a..7030b76 100644 --- a/tests/vine-test/vine-multi-thread-test.cpp +++ b/tests/vine-test/vine-multi-thread-test.cpp @@ -16,7 +16,6 @@ #include -#include #include #include #include @@ -27,19 +26,7 @@ #include #include -#define KGRN "\033[0;32;32m" -//#define KCYN "\033[0;36m" -#define KRED "\033[0;32;31m" -#define KYEL "\033[1;33m" -//#define KMAG "\033[0;35m" -//#define KBLU "\033[0;32;34m" -#define KCYN_L "\033[1;36m" -#define RESET "\033[0m" - - -#define PRINT_IF_ERROR(ret, func) __print_result(ret, func, false) -#define PRINT_RESULT(ret, func) __print_result(ret, func, true) -#define PRINT_LOG(format, args...) __print_log("[TID:%u] " format, (unsigned int)syscall(__NR_gettid), ##args) +#include "vine-test-utils.h" #define MAX_EVENTS 10 @@ -47,76 +34,6 @@ #define MAX_SERVICE_NAME_LEN 63 #define MAX_IP_LEN 39 // for IPv6 -static const char *__error_to_str(vine_error_e error) -{ - switch (error) { - case VINE_ERROR_NONE: - return "NO ERROR"; - case VINE_ERROR_NOT_PERMITTED: - return "NOT PERMITTED"; - case VINE_ERROR_OUT_OF_MEMORY: - return "OUT OF MEMORY"; - case VINE_ERROR_PERMISSION_DENIED: - return "PERMISSION DENIED"; - case VINE_ERROR_INVALID_PARAMETER: - return "INVALID PARAMETER"; - case VINE_ERROR_INVALID_OPERATION: - return "INVALID OPERATION"; - case VINE_ERROR_CONNECTION_TIME_OUT: - return "CONNECTION TIME OUT"; - case VINE_ERROR_NOW_IN_PROGRESS: - return "NOW IN PROGRESS"; - case VINE_ERROR_NOT_SUPPORTED: - return "NOT SUPPORTED"; - case VINE_ERROR_NOT_INITIALIZED: - return "NOT INITIALIZED"; - case VINE_ERROR_ALREADY_INITIALIZED: - return "ALREADY INITIALIZED"; - case VINE_ERROR_ALREADY_ENABLED: - return "ALREADY ENABLED"; - case VINE_ERROR_OPERATION_FAILED: - return "OPERATION FAILED"; - default: - return "UNKNOWN"; - } -} - -static void __print_error(const char *format, ...) -{ - va_list args; - va_start(args, format); - - printf(KRED); - vprintf(format, args); - printf(RESET"\n"); - - va_end(args); -} - -static void __print_log(const char *format, ...) -{ - va_list args; - va_start(args, format); - - printf(KGRN); - vprintf(format, args); - printf(RESET"\n"); - - va_end(args); -} - -static void __print_result(int ret, const char *function_name, bool print_if_no_error) -{ - unsigned int tid = (unsigned int)syscall(__NR_gettid); - if (ret == VINE_ERROR_NONE) { - if (print_if_no_error) - printf(KGRN "[TID:%u] %s" RESET "\n", tid, function_name); - } else { - __print_error("[TID:%u] %s: %s(%d) ", tid, function_name, - __error_to_str((vine_error_e)ret), ret); - } -} - static bool __print_attr(const char *key, const char *value, void *user_data) { PRINT_LOG("\t > Attributes: %s=%s\n", key, value); @@ -163,7 +80,7 @@ static void __get_current_time(char *buf) time(&now); if (localtime_r(&now, &local) == NULL) { - __print_error("localtime_r() fails"); + print_error("localtime_r() fails"); return; } @@ -186,11 +103,11 @@ void __logger(int log_level, const char *log) unsigned int ctid = (unsigned int)syscall(__NR_gettid); if (ctid == g_main_tid) { - printf("%s" KGRN "[T%5u]", timestamp, g_main_tid); + printf("%s" COLOR_GRN "[T%5u]", timestamp, g_main_tid); } else if (ctid == g_main_tid + 1) { - printf("%s" KCYN_L "[T%5u]", timestamp, ctid); + printf("%s" COLOR_CYN "[T%5u]", timestamp, ctid); } else if (ctid == g_main_tid + 2) { - printf("%s" KYEL "[T%5u]", timestamp, ctid); + printf("%s" COLOR_YEL "[T%5u]", timestamp, ctid); } else { printf("%s[T%5u] ", timestamp, ctid); } @@ -203,10 +120,10 @@ void __logger(int log_level, const char *log) printf("I/"); break; case VINE_LOG_ERROR: - printf(KRED "E/"); + printf(COLOR_RED "E/"); break; } - printf("%s" RESET "\n", log); + printf("%s" COLOR_RESET "\n", log); } static void __event_handler(vine_session_h session) @@ -226,7 +143,7 @@ static void __start_event_loop(vine_session_h session) int epollfd = epoll_create1(0); if (epollfd == -1) { - __print_error("Fail to create epoll fd %d", errno); + print_error("Fail to create epoll fd %d", errno); exit(1); } @@ -234,14 +151,14 @@ static void __start_event_loop(vine_session_h session) ev.events = EPOLLIN; ev.data.fd = fd; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { - __print_error("Fail to add an epoll event for fd %d: %d", fd, errno); + print_error("Fail to add an epoll event for fd %d: %d", fd, errno); exit(1); } while (true) { int n = epoll_wait(epollfd, events, MAX_EVENTS, 0); if (n == -1) { - __print_error("epoll_wait %d", errno); + print_error("epoll_wait %d", errno); exit(1); } @@ -264,7 +181,7 @@ static void start_vine() "vine_session_set_discovered_cb"); PRINT_LOG("Session Created"); - PRINT_IF_ERROR(vine_session_start_discovery(session, "", NULL), + PRINT_IF_ERROR(vine_session_start_discovery(session, "vine", NULL), "vine_session_start_discovery"); PRINT_LOG("Subscribed"); diff --git a/tests/vine-test/vine-test-utils.cpp b/tests/vine-test/vine-test-utils.cpp new file mode 100644 index 0000000..5260b6f --- /dev/null +++ b/tests/vine-test/vine-test-utils.cpp @@ -0,0 +1,78 @@ +#include "vine-test-utils.h" + +#include +#include +#include +#include +//#include + +const char *convert_error_to_str(vine_error_e error) +{ + switch (error) { + case VINE_ERROR_NONE: + return "NO ERROR"; + case VINE_ERROR_NOT_PERMITTED: + return "NOT PERMITTED"; + case VINE_ERROR_OUT_OF_MEMORY: + return "OUT OF MEMORY"; + case VINE_ERROR_PERMISSION_DENIED: + return "PERMISSION DENIED"; + case VINE_ERROR_INVALID_PARAMETER: + return "INVALID PARAMETER"; + case VINE_ERROR_INVALID_OPERATION: + return "INVALID OPERATION"; + case VINE_ERROR_CONNECTION_TIME_OUT: + return "CONNECTION TIME OUT"; + case VINE_ERROR_NOW_IN_PROGRESS: + return "NOW IN PROGRESS"; + case VINE_ERROR_NOT_SUPPORTED: + return "NOT SUPPORTED"; + case VINE_ERROR_NOT_INITIALIZED: + return "NOT INITIALIZED"; + case VINE_ERROR_ALREADY_INITIALIZED: + return "ALREADY INITIALIZED"; + case VINE_ERROR_ALREADY_ENABLED: + return "ALREADY ENABLED"; + case VINE_ERROR_OPERATION_FAILED: + return "OPERATION FAILED"; + default: + return "UNKNOWN"; + } +} + +void print_log(const char *format, ...) +{ + va_list args; + + printf(COLOR_GRN "[TID: %u] ", (unsigned int)syscall(__NR_gettid)); + + va_start(args, format); + vprintf(format, args); + printf(COLOR_RESET"\n"); + + va_end(args); +} + +void print_error(const char *format, ...) +{ + va_list args; + va_start(args, format); + + printf(COLOR_RED); + vprintf(format, args); + printf(COLOR_RESET"\n"); + + va_end(args); +} + +void print_result(int ret, const char *function_name, bool print_if_no_error) +{ + unsigned int tid = (unsigned int)syscall(__NR_gettid); + if (ret == VINE_ERROR_NONE) { + if (print_if_no_error) + printf(COLOR_GRN "[TID:%u] %s" COLOR_RESET "\n", tid, function_name); + } else { + print_error("[TID:%u] %s: %s(%d) ", tid, function_name, + convert_error_to_str((vine_error_e)ret), ret); + } +} diff --git a/tests/vine-test/vine-test-utils.h b/tests/vine-test/vine-test-utils.h new file mode 100644 index 0000000..60255e9 --- /dev/null +++ b/tests/vine-test/vine-test-utils.h @@ -0,0 +1,18 @@ +#include + +#define COLOR_RESET "\e[m" +#define COLOR_RED "\e[31m" +#define COLOR_GRN "\e[32m" +#define COLOR_YEL "\e[33m" +#define COLOR_BLU "\e[34m" +#define COLOR_CYN "\e[36m" + +#define PRINT_IF_ERROR(ret, func) print_result(ret, func, false) +#define PRINT_RESULT(ret, func) print_result(ret, func, true) +#define PRINT_LOG(format, args...) print_log(format, ##args) + +const char *convert_error_to_str(vine_error_e error); + +void print_log(const char *format, ...); +void print_error(const char *format, ...); +void print_result(int ret, const char *function_name, bool print_if_no_error); diff --git a/tests/vine-test/vine-test.cpp b/tests/vine-test/vine-test.cpp index fde6a78..4a692c5 100644 --- a/tests/vine-test/vine-test.cpp +++ b/tests/vine-test/vine-test.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -27,20 +26,15 @@ #include #include -#define MAX_EVENTS 16 +#include "vine-test-utils.h" +#define MAX_EVENTS 16 #define TEST_DEBUG -#define RESET_COLOR "\e[m" -#define MAKE_RED "\e[31m" -#define MAKE_GREEN "\e[32m" - -#define PRINT_IF_ERROR(ret, func) __print_result(ret, func, false) -#define PRINT_RESULT(ret, func) __print_result(ret, func, true) #define CHECK_SESSION \ do { \ if (!g_session) { \ - __print_error("No Session"); \ + print_error("No Session"); \ return; \ } \ } while (0) @@ -62,62 +56,6 @@ static vine_dp_h g_pubsub_dp = NULL; static std::list g_datapath_list; static std::list g_service_list; -static const char *__error_to_str(vine_error_e error) -{ - switch (error) { - case VINE_ERROR_NONE: - return "NO ERROR"; - case VINE_ERROR_NOT_PERMITTED: - return "NOT PERMITTED"; - case VINE_ERROR_OUT_OF_MEMORY: - return "OUT OF MEMORY"; - case VINE_ERROR_PERMISSION_DENIED: - return "PERMISSION DENIED"; - case VINE_ERROR_INVALID_PARAMETER: - return "INVALID PARAMETER"; - case VINE_ERROR_INVALID_OPERATION: - return "INVALID OPERATION"; - case VINE_ERROR_CONNECTION_TIME_OUT: - return "CONNECTION TIME OUT"; - case VINE_ERROR_NOW_IN_PROGRESS: - return "NOW IN PROGRESS"; - case VINE_ERROR_NOT_SUPPORTED: - return "NOT SUPPORTED"; - case VINE_ERROR_NOT_INITIALIZED: - return "NOT INITIALIZED"; - case VINE_ERROR_ALREADY_INITIALIZED: - return "ALREADY INITIALIZED"; - case VINE_ERROR_ALREADY_ENABLED: - return "ALREADY ENABLED"; - case VINE_ERROR_OPERATION_FAILED: - return "OPERATION FAILED"; - default: - return "UNKNOWN"; - } -} - -static void __print_error(const char *format, ...) -{ - va_list args; - va_start(args, format); - - printf(MAKE_RED); - vprintf(format, args); - printf(RESET_COLOR"\n"); - - va_end(args); -} - -static void __print_result(int ret, const char *function_name, bool print_if_no_error) -{ - if (ret == VINE_ERROR_NONE) { - if (print_if_no_error) - printf(MAKE_GREEN "%s" RESET_COLOR "\n", function_name); - } else { - __print_error("%s: %s(%d) ", function_name, __error_to_str((vine_error_e)ret), ret); - } -} - static bool test_get_user_string(const char *msg, char *buf, int buf_size) { if (msg == NULL || buf == NULL || buf_size < 2) @@ -164,7 +102,7 @@ static void __start_event_loop() ev.events = EPOLLIN; ev.data.ptr = g_session; if (epoll_ctl(g_epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { - __print_error("Fail to add an epoll event for fd %d: %d", fd, errno); + print_error("Fail to add an epoll event for fd %d: %d", fd, errno); exit(1); } } @@ -270,7 +208,7 @@ static void __received_cb(vine_dp_h dp, size_t received_len, void *user_data) unsigned char buf[20] = {0, }; size_t bytes = 0; - printf(MAKE_GREEN "[RECV_CB] %p received %zd bytes." RESET_COLOR "\n", dp, received_len); + printf(COLOR_GRN "[RECV_CB] %p received %zd bytes." COLOR_RESET "\n", dp, received_len); do { vine_dp_recv(dp, buf, 20, &bytes); __print_received_data(buf, bytes); @@ -280,7 +218,7 @@ static void __received_cb(vine_dp_h dp, size_t received_len, void *user_data) static void __terminated_cb(vine_dp_h dp, void *user_data) { - printf(MAKE_GREEN "[TERMINATED_CB] %p is terminated." RESET_COLOR "\n", dp); + printf(COLOR_GRN "[TERMINATED_CB] %p is terminated." COLOR_RESET "\n", dp); g_datapath_list.remove(dp); vine_dp_destroy(dp); } @@ -297,7 +235,7 @@ static void __opened_cb(vine_dp_h dp, vine_error_e result, void *user_data) int port; vine_dp_get_port(dp, &port); - printf(MAKE_GREEN "[OPENED_CB] %p is %s. port[%d]" RESET_COLOR "\n", + printf(COLOR_GRN "[OPENED_CB] %p is %s. port[%d]" COLOR_RESET "\n", dp, (result == VINE_ERROR_NONE) ? "opened" : "not opened", port); if (dp == g_client_dp || dp == g_pubsub_dp) __add_new_dp(dp); @@ -339,7 +277,7 @@ static void __set_service_type() char type[64]; printf(" >> Service Type: "); if (scanf(" %63s", type) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } PRINT_RESULT(vine_service_set_type(g_service, type), @@ -352,7 +290,7 @@ static void __set_service_name() char name[64]; printf(" >> Service Name (Max length 64): "); if (scanf(" %63s", name) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } PRINT_RESULT(vine_service_set_name(g_service, name), @@ -365,7 +303,7 @@ static void __set_port() int port; printf(" >> Port Number (0 ~ 65535): "); if (scanf(" %d", &port) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } PRINT_RESULT(vine_service_set_port(g_service, port), "vine_session_set_port"); @@ -429,7 +367,7 @@ static void __start_discovery() char type[20]; printf(" >> Service Type: "); if (scanf(" %19s", type) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } @@ -530,10 +468,10 @@ void __logger(int log_level, const char *log) printf("I/"); break; case VINE_LOG_ERROR: - printf(MAKE_RED "E/"); + printf(COLOR_RED "E/"); break; } - printf("%s" RESET_COLOR "\n", log); + printf("%s" COLOR_RESET "\n", log); } #endif @@ -587,12 +525,12 @@ static vine_security_h __create_security_handle(int type, bool is_server) static void __accepted_cb(vine_dp_h dp, vine_dp_h accepted_dp, void *user_data) { - printf(MAKE_GREEN "[ACCEPTED_CB] %p is accepted." RESET_COLOR "\n", accepted_dp); + printf(COLOR_GRN "[ACCEPTED_CB] %p is accepted." COLOR_RESET "\n", accepted_dp); vine_address_family_e addr_family; char *ip; int ret = vine_dp_get_remote_ip(accepted_dp, &addr_family, &ip); PRINT_IF_ERROR(ret, "vine_dp_get_remote_ip"); - printf(MAKE_GREEN " Client IP[%s] Family[%d]" RESET_COLOR "\n", ip, (int)addr_family); + printf(COLOR_GRN " Client IP[%s] Family[%d]" COLOR_RESET "\n", ip, (int)addr_family); free(ip); __add_new_dp(accepted_dp); } @@ -606,19 +544,19 @@ static void __open_server() printf(" >> Address type(0-default, 1-IPv4, 2-IPv6): "); if (scanf(" %d", &addr_family) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } printf(" >> listen port: "); if (scanf(" %d", &port) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } printf("Set security type(0.NONE, 1.TLS, 2.PSK): "); if (scanf("%d", &security_type) < 0) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } @@ -644,24 +582,24 @@ static void __connect_server() printf(" >> Address Family(0-IPv4, 1-IPv6): "); if (scanf(" %d", &addr_type) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } printf(" >> Peer IP: "); if (scanf(" %39s", ip) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } printf(" >> Peer port: "); if (scanf(" %d", &port) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } printf("Set security type(0.NONE, 1.TLS, 2.PSK): "); if (scanf("%d", &security_type) < 0) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } @@ -684,19 +622,19 @@ static void __join_service() printf(" >> Address type(0-default, 1-IPv4, 2-IPv6): "); if (scanf(" %d", &addr_family) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } printf(" >> Listen port: "); if (scanf(" %d", &port) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } printf(" >> Set topic: "); if (scanf(" %63s", topic) < 1) { - __print_error("Scan failed"); + print_error("Scan failed"); return; } @@ -890,7 +828,7 @@ int main() g_epollfd = epoll_create1(0); if (g_epollfd == -1) { - __print_error("Fail to create epoll fd %d", errno); + print_error("Fail to create epoll fd %d", errno); return -1; } @@ -898,14 +836,14 @@ int main() ev.events = EPOLLIN; ev.data.fd = STDIN_FILENO; if (epoll_ctl(g_epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1) { - __print_error("Fail to add an epoll event for stdin: %d", errno); + print_error("Fail to add an epoll event for stdin: %d", errno); return -1; } while (true) { int n = epoll_wait(g_epollfd, events, MAX_EVENTS, 0); if (n == -1) { - __print_error("epoll_wait %d", errno); + print_error("epoll_wait %d", errno); return -1; } -- 2.7.4 From 1eaa71a7260b2fbc03399dde9edb01f42cc6f8d8 Mon Sep 17 00:00:00 2001 From: Cheoleun Moon Date: Mon, 24 May 2021 19:44:19 +0900 Subject: [PATCH 04/16] vine-verifier: fix wrong parameter Change-Id: I54d7f595860f9ab43304b136ad2c309e784d1e9c Signed-off-by: Cheoleun Moon --- tests/verifier/vine-verifier.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/verifier/vine-verifier.cpp b/tests/verifier/vine-verifier.cpp index 67c99a5..6ce82b4 100644 --- a/tests/verifier/vine-verifier.cpp +++ b/tests/verifier/vine-verifier.cpp @@ -337,6 +337,7 @@ static void __ip_resolved_cb(vine_session_h session, vine_service_h service, const char *ip, vine_address_family_e address_family, /* availability */ void *user_data) { + printf("IP: %s\n", ip); // NOTE: Ignore a link-local address temporary. // This should be handled by dns-sd-plugin. if (!is_dp_running && strncmp(ip, "fe80:", 5) != 0) { @@ -387,7 +388,8 @@ static void __discovered_cb(vine_session_h session, vine_service_h service, fflush(stdout); vine_service_h s; - vine_service_clone(service, &s); + ret = vine_service_clone(service, &s); + PRINT_IF_ERROR(ret, "vine_service_clone"); ret = vine_session_set_ip_resolved_cb(session, s, __ip_resolved_cb, user_data); PRINT_IF_ERROR(ret, "vine_session_set_ip_resolved_cb"); } @@ -457,9 +459,9 @@ static void __start_pubsub(bool use_tls, bool use_psk) vine_dp_h dp; vine_dp_create(session, VINE_DP_TYPE_PUBSUB, &dp); - vine_dp_set_address_family(session, VINE_ADDRESS_FAMILY_IPV4); - vine_dp_set_security(session, security); - vine_dp_set_topic(session, TOPIC); + vine_dp_set_address_family(dp, VINE_ADDRESS_FAMILY_IPV4); + vine_dp_set_security(dp, security); + vine_dp_set_topic(dp, TOPIC); vine_dp_set_received_cb(dp, __pubsub_received_cb, NULL); PRINT_RESULT(vine_dp_open(dp, __pubsub_opened_cb, session), "vine_dp_open"); vine_security_destroy(security); -- 2.7.4 From 44a278479c7632bf00d258f1f6c36cd4f9e190c7 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Fri, 21 May 2021 16:27:27 +0900 Subject: [PATCH 05/16] tests: add test for pubsub repetition Change-Id: I73dc4a0290facc54ee423584a5d4e998fbb8bb92 --- tests/vine-test/vine-pubsub-open-close-test.cpp | 250 ++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 tests/vine-test/vine-pubsub-open-close-test.cpp diff --git a/tests/vine-test/vine-pubsub-open-close-test.cpp b/tests/vine-test/vine-pubsub-open-close-test.cpp new file mode 100644 index 0000000..a64a63c --- /dev/null +++ b/tests/vine-test/vine-pubsub-open-close-test.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/* + * Test: vine-pubsub-open-close-test + * Description: + * a PubSub DP opens and closes repeatedly in one session. + * The interval is 100ms. (DP_LIFETIME) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vine-test-utils.h" + +#define MAX_EVENTS 50 +#define DEFAULT_REPETITION_TIME 100 +#define DP_LIFETIME 100000000 // nanoseconds +#define TOPIC "pubsub-test" + +static int epollfd = 0; +static vine_session_h session = NULL; +static int count = DEFAULT_REPETITION_TIME; + +enum { + EPOLL_EVENT_TYPE_SESSION = 0, + EPOLL_EVENT_TYPE_TIMEOUT +}; + +typedef struct { + int type; + int timerfd; + void *ptr; +} epoll_data_s; + +static void open_dp(vine_session_h session); + +void _logger(int log_level, const char *log) +{ + switch (log_level) { + case VINE_LOG_DEBUG: + printf("D/"); + break; + case VINE_LOG_INFO: + printf("I/"); + break; + case VINE_LOG_ERROR: + printf(COLOR_RED "E/"); + break; + } + printf("%s" COLOR_RESET "\n", log); +} + +static void add_event_fd(int fd, void *user_data) +{ + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = fd; + ev.data.ptr = user_data; + if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { + print_error("Fail to add an epoll event for fd %d: %d", fd, errno); + exit(1); + } +} + +static void del_event_fd(int fd) +{ + epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL); +} + +static void _start_timer(vine_dp_h dp, int nsec) +{ + if (nsec <= 0) + return; + + int timerfd = timerfd_create(CLOCK_MONOTONIC, 0); + if (timerfd == -1) + return; + + struct itimerspec value; + value.it_interval.tv_sec = 0; + value.it_interval.tv_nsec = 0; + value.it_value.tv_sec = 0; + value.it_value.tv_nsec = nsec; + if (timerfd_settime(timerfd, 0, &value, NULL) != 0) { + close(timerfd); + return; + } + + epoll_data_s *data = (epoll_data_s *)calloc(1, sizeof(epoll_data_s)); + data->type = EPOLL_EVENT_TYPE_TIMEOUT; + data->timerfd = timerfd; + data->ptr = (void *)dp; + + add_event_fd(timerfd, (void *)data); +} + +static void _stop_timer(int fd) +{ + del_event_fd(fd); + close(fd); + --count; +} + +static void _handle_timer_event(epoll_data_s *data) +{ + int fd = data->timerfd; + vine_dp_h dp = (vine_dp_h)data->ptr; + + PRINT_LOG("Close dp[%p]", dp); + _stop_timer(fd); + vine_dp_close(dp); + vine_dp_destroy(dp); + + open_dp(session); +} + +static void _event_handler(void *user_data) +{ + epoll_data_s *data = (epoll_data_s *)user_data; + + if (!data || !data->ptr) + return; + + if (data->type == EPOLL_EVENT_TYPE_SESSION) { + PRINT_IF_ERROR(vine_session_process_event(data->ptr), "vine_process_event"); + } else if (data->type == EPOLL_EVENT_TYPE_TIMEOUT) { + _handle_timer_event(data); + free(data); + } +} + +static void run_event_loop(vine_session_h session) +{ + struct epoll_event events[MAX_EVENTS]; + + epollfd = epoll_create1(0); + if (epollfd == -1) { + print_error("Fail to create epoll fd %d", errno); + return; + } + + int fd = 0; + PRINT_IF_ERROR(vine_session_get_event_fd(session, &fd), "vine_session_get_event_fd"); + if (fd <= 0) + return; + + epoll_data_s *data = (epoll_data_s *)calloc(1, sizeof(epoll_data_s)); + data->type = EPOLL_EVENT_TYPE_SESSION; + data->ptr = session; + add_event_fd(fd, (void *)data); + + while (count) { + int n = epoll_wait(epollfd, events, MAX_EVENTS, 0); + if (n == -1) { + print_error("epoll_wait %d", errno); + break; + } + + for (int i = 0; i < n; ++i) { + if (events[i].data.ptr) + _event_handler(events[i].data.ptr); + } + } + free(data); + close(epollfd); +} + +static void open_dp(vine_session_h session) +{ + vine_dp_h dp = NULL; + + PRINT_IF_ERROR(vine_dp_create(session, VINE_DP_TYPE_PUBSUB, &dp), "vine_dp_create"); + PRINT_IF_ERROR(vine_dp_set_topic(dp, TOPIC), "vine_dp_set_topic"); + PRINT_IF_ERROR(vine_dp_set_terminated_cb(dp, + [](vine_dp_h dp, void *user_data) { + PRINT_LOG("dp[%p] is closed."); + }, NULL), "vine_dp_set_terminated_cb"); + PRINT_IF_ERROR(vine_dp_set_peer_joined_cb(dp, + [](vine_dp_h dp, const char *ip, int port, void *user_data) { + PRINT_LOG("dp[%p]'s peer[%s:%d] is joined.", dp, ip, port); + }, NULL), "vine_dp_set_peer_joined_cb"); + PRINT_IF_ERROR(vine_dp_set_peer_left_cb(dp, + [](vine_dp_h dp, const char *ip, int port, void *user_data) { + PRINT_LOG("dp[%p]'s peer[%s:%d] is left.", dp, ip, port); + }, NULL), "vine_dp_set_peer_left_cb"); + PRINT_IF_ERROR(vine_dp_open(dp, + [](vine_dp_h dp, vine_error_e result, void *user_data) { + if (result != VINE_ERROR_NONE) + return; + PRINT_LOG("dp[%p] is opened.", dp); + _start_timer(dp, DP_LIFETIME); + }, NULL), "vine_dp_open"); +} + +static void _parse_options(int argc, char **argv) +{ + int opt = 0; + + while ((opt = getopt(argc, argv, "dhn:")) != -1) { + switch(opt) { + case 'd': + vine_set_logger(_logger); + vine_set_log_level(VINE_LOG_DEBUG | VINE_LOG_INFO | VINE_LOG_ERROR); + break; + case 'n': + count = atoi(optarg); + break; + case 'h': + default: + printf(COLOR_CYN "[HELP] -n: number of times, -d: debug, -h: help\n" COLOR_RESET); + exit(1); + } + } +} + +int main(int argc, char **argv) +{ + _parse_options(argc, argv); + + PRINT_IF_ERROR(vine_initialize(), "vine_initialize()"); + PRINT_IF_ERROR(vine_session_create(&session), "vine_session_create"); + + open_dp(session); + run_event_loop(session); + + PRINT_IF_ERROR(vine_session_destroy(session), "vine_session_destroy"); + PRINT_IF_ERROR(vine_deinitialize(), "vine_deinitialize()"); + + return 0; +} -- 2.7.4 From 6c9d4410b22565cea11ab1d98a0b966b315fb62a Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Tue, 25 May 2021 19:50:19 +0900 Subject: [PATCH 06/16] DP: Add set/get remote port, get local ip - Fix vine_dp_[set/get]_port - Add new API vine_dp_[set/get]_remote_port - Add new API vine_dp_get_ip Change-Id: Ib1e1e4a5cfd72fcf3a33392921a5366225fc0275 --- include/vine.h | 62 ++++++++++- packaging/capi-network-vine.spec | 2 +- plugins/libwebsockets/libwebsockets-plugin.cpp | 103 ++++++++++++++---- src/include/vine-data-path-plugin.h | 3 + src/include/vine-data-path.h | 2 + src/include/vine-dp.h | 26 ++++- src/vine-data-path.cpp | 26 +++++ src/vine-dp.cpp | 139 ++++++++++++++++++++++++- src/vine.cpp | 24 +++++ tests/unittest/vine-unittest-dp.cpp | 70 ++++++++++++- tests/verifier/vine-verifier.cpp | 2 +- tests/vine-test/vine-test.cpp | 2 +- tool/tool_run.cpp | 32 +++++- 13 files changed, 451 insertions(+), 42 deletions(-) diff --git a/include/vine.h b/include/vine.h index e8e87dd..2fbca0a 100755 --- a/include/vine.h +++ b/include/vine.h @@ -879,16 +879,66 @@ int vine_dp_set_remote_ip(vine_dp_h dp, vine_address_family_e addr_family, const int vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip); /** - * @brief Sets the port. - * @remarks @a port is a remote server port if @a dp's type is VINE_DP_TYPE_CLIENT. \ - * Otherwise, @a port is a listen port. \ - * If it is a listen port, you can set it to 0 so that a random port is picked by the kernel. + * @brief Sets the port of a remote server. + * @remarks @a dp's type can be VINE_DP_TYPE_CLIENT only. * @since_tizen 6.5 * @param[in] dp The data path handle * @param[in] port The port * @return 0 on success, otherwise a negative error value * @retval #VINE_ERROR_NONE Successful * @retval #VINE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VINE_ERROR_INVALID_OPERATION Invalid operation + * @retval #VINE_ERROR_NOT_SUPPORTED Not supported + * @see vine_dp_create() + * @see vine_dp_get_remote_port() + */ +int vine_dp_set_remote_port(vine_dp_h dp, int port); + +/** + * @brief Gets the port of a remote server. + * @remarks @a dp's type can be VINE_DP_TYPE_CLIENT only. + * @since_tizen 6.5 + * @param[in] dp The data path handle + * @param[out] port The port + * @return 0 on success, otherwise a negative error value + * @retval #VINE_ERROR_NONE Successful + * @retval #VINE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VINE_ERROR_INVALID_OPERATION Invalid operation + * @retval #VINE_ERROR_NOT_SUPPORTED Not supported + * @see vine_dp_create() + * @see vine_dp_set_remote_port() + */ +int vine_dp_get_remote_port(vine_dp_h dp, int *port); + +/** + * @brief Gets the local IP address. + * @remarks @a ip must be released using free(). + * If VINE_DP_TYPE_SERVER are listening to multiple interfaces, + * @a ip would be returned empty without error. + * For the same reason, VINE_DP_TYPE_PUBSUB doesn't support this API. + * @since_tizen 6.5 + * @param[in] dp The data path handle + * @param[out] addr_family The address family + * @param[out] ip The local IP address + * @return 0 on success, otherwise a negative error value + * @retval #VINE_ERROR_NONE Successful + * @retval #VINE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VINE_ERROR_NOT_SUPPORTED Not supported + * @see vine_dp_create() + */ +int vine_dp_get_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip); + +/** + * @brief Sets the listen port. + * @remarks @a dp's type can be VINE_DP_TYPE_SERVER or VINE_DP_TYPE_PUBSUB. \ + * You can set it to 0 so that a random port is picked by the kernel. + * @since_tizen 6.5 + * @param[in] dp The data path handle + * @param[in] port The listen port + * @return 0 on success, otherwise a negative error value + * @retval #VINE_ERROR_NONE Successful + * @retval #VINE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VINE_ERROR_INVALID_OPERATION Invalid operation * @retval #VINE_ERROR_NOT_SUPPORTED Not supported * @see vine_dp_create() */ @@ -896,6 +946,9 @@ int vine_dp_set_port(vine_dp_h dp, int port); /** * @brief Gets the port. + * @remarks @a port is the local port number used for the connection. \ + * If dp is VINE_DP_TYPE_SERVER or VINE_DP_TYPE_PUBSUB, \ + * @a port is the same with a listen port. * @since_tizen 6.5 * @param[in] dp The data path handle * @param[out] port The port @@ -904,6 +957,7 @@ int vine_dp_set_port(vine_dp_h dp, int port); * @retval #VINE_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VINE_ERROR_NOT_SUPPORTED Not supported * @see vine_dp_create() + * @see vine_dp_set_port() */ int vine_dp_get_port(vine_dp_h dp, int *port); diff --git a/packaging/capi-network-vine.spec b/packaging/capi-network-vine.spec index 3336ebe..5260543 100755 --- a/packaging/capi-network-vine.spec +++ b/packaging/capi-network-vine.spec @@ -2,7 +2,7 @@ %bcond_without lws_static_prebuilt Name: capi-network-vine Summary: An service discovery framework -Version: 1.0.1 +Version: 1.0.2 Release: 0 Group: Network & Connectivity/API License: Apache-2.0 diff --git a/plugins/libwebsockets/libwebsockets-plugin.cpp b/plugins/libwebsockets/libwebsockets-plugin.cpp index fed2d1b..a16c942 100755 --- a/plugins/libwebsockets/libwebsockets-plugin.cpp +++ b/plugins/libwebsockets/libwebsockets-plugin.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -131,33 +132,19 @@ static bool __is_ipv4_mapped(const char *ip) return strncmp(IPV4_MAPPED_IPV6_PREFIX, ip, IPV4_MAPPED_IPv6_PREFIX_LEN) == 0; } -static void _get_peer_network_info(struct lws *wsi, - vine_dp_addr_family_e *family, char ip[], int *port) +static void __get_network_info(struct sockaddr_storage *addr, + vine_dp_addr_family_e *family, char ip[], int *port) { - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - int fd; - int ret; - - fd = lws_get_socket_fd(wsi); - if (fd < 0) { - VINE_LOGE("lws_get_socket_fd fails[%d]", fd); - return; - } - - ret = getpeername(fd, (struct sockaddr*)&addr, &len); - if (ret < 0) { - VINE_LOGE("Cannot get name of connected peer. errno[%d]", errno); + if (!addr) return; - } - if (addr.ss_family == AF_INET) { - struct sockaddr_in *s = (struct sockaddr_in*)&addr; + if (addr->ss_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in*)addr; *port = ntohs(s->sin_port); *family = VINE_DP_IPV4; inet_ntop(AF_INET, &s->sin_addr, ip, INET6_ADDRSTRLEN); } else { - struct sockaddr_in6 *s = (struct sockaddr_in6*)&addr; + struct sockaddr_in6 *s = (struct sockaddr_in6*)addr; *port = ntohs(s->sin6_port); inet_ntop(AF_INET6, &s->sin6_addr, ip, INET6_ADDRSTRLEN); if (__is_ipv4_mapped(ip)) { @@ -173,7 +160,53 @@ static void _get_peer_network_info(struct lws *wsi, *family = VINE_DP_IPV6; } } +} + +static int _get_local_network_info(struct lws *wsi, + vine_dp_addr_family_e *family, char ip[], int *port) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(struct sockaddr_storage); + int fd, ret; + + fd = lws_get_socket_fd(wsi); + if (fd < 0) { + VINE_LOGE("lws_get_socket_fd fails[%d]", fd); + return VINE_DATA_PATH_ERROR_OPERATION_FAILED; + } + + ret = getsockname(fd, (struct sockaddr *)&addr, &len); + if (ret < 0) { + VINE_LOGE("Cannot get sockname. errno[%d]", errno); + return VINE_DATA_PATH_ERROR_OPERATION_FAILED; + } + + __get_network_info(&addr, family, ip, port); + VINE_LOGD("address family[%d] ip[%s], port[%d]\n", addr.ss_family, ip, *port); + return VINE_DATA_PATH_ERROR_NONE; +} + +static void _get_peer_network_info(struct lws *wsi, + vine_dp_addr_family_e *family, char ip[], int *port) +{ + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + int fd; + int ret; + + fd = lws_get_socket_fd(wsi); + if (fd < 0) { + VINE_LOGE("lws_get_socket_fd fails[%d]", fd); + return; + } + + ret = getpeername(fd, (struct sockaddr*)&addr, &len); + if (ret < 0) { + VINE_LOGE("Cannot get name of connected peer. errno[%d]", errno); + return; + } + __get_network_info(&addr, family, ip, port); VINE_LOGD("address family[%d] peer ip[%s], peer port[%d]\n", addr.ss_family, ip, *port); } @@ -332,6 +365,16 @@ static void _change_websocket_poll_fd(struct lws_pollargs *args) g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_MOD, pollfd->fd, pollfd->events); } +static void _invoke_connected_cb(struct lws *wsi, bool connected, void *user_data) +{ + if (!connected) { + g_callbacks.connected_cb(-1, user_data); + return; + } + + g_callbacks.connected_cb(0, user_data); +} + static int _websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { @@ -422,7 +465,6 @@ static int _websocket_protocol_cb(struct lws *wsi, case LWS_CALLBACK_ESTABLISHED: { VINE_LOGI("Websocket connection is established."); - websocket_s *client_ws = (websocket_s *)lws_wsi_user(wsi); vhd->curr_conn++; if (g_callbacks.accepted_cb) { @@ -484,7 +526,7 @@ static int _websocket_protocol_cb(struct lws *wsi, case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: VINE_LOGI("Failed connection request to server."); if (ws && g_callbacks.connected_cb) - g_callbacks.connected_cb(-1, ws->user); + _invoke_connected_cb(wsi, false, ws->user); break; case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER: { @@ -505,7 +547,7 @@ static int _websocket_protocol_cb(struct lws *wsi, case LWS_CALLBACK_CLIENT_ESTABLISHED: VINE_LOGI("Connected with server."); if (ws && g_callbacks.connected_cb) - g_callbacks.connected_cb(0, ws->user); + _invoke_connected_cb(wsi, true, ws->user); break; case LWS_CALLBACK_CLIENT_RECEIVE: @@ -974,6 +1016,19 @@ static void websocket_register_callbacks(vine_dp_plugin_callbacks callbacks) g_callbacks = callbacks; } +static int websocket_get_local_address_info(vine_dp_plugin_h handle, + int *address_family, char local_ip[], int *port) +{ + RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL"); + RET_VAL_IF(address_family == NULL, + VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "address_family is NULL"); + RET_VAL_IF(local_ip == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "local_ip is NULL"); + RET_VAL_IF(port == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "port is NULL"); + + websocket_s *ws = (websocket_s *)handle; + return _get_local_network_info(ws->wsi, (vine_dp_addr_family_e *)address_family, local_ip, port); +} + static int websocket_set_token(vine_dp_plugin_h handle, const char *token) { RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL"); @@ -1019,6 +1074,8 @@ void vine_data_path_plugin_init(vine_dp_plugin_fn *fn) fn->write = websocket_write; fn->close = websocket_close; + fn->get_local_address_info = websocket_get_local_address_info; + fn->set_token = websocket_set_token; fn->get_token = websocket_get_token; } diff --git a/src/include/vine-data-path-plugin.h b/src/include/vine-data-path-plugin.h index a71bc8b..3f8a4c9 100755 --- a/src/include/vine-data-path-plugin.h +++ b/src/include/vine-data-path-plugin.h @@ -101,6 +101,9 @@ typedef struct { int (*write)(vine_dp_plugin_h handle, unsigned char *buf, size_t len); int (*close)(vine_dp_plugin_h handle); + int (*get_local_address_info)(vine_dp_plugin_h handle, + int *addr_family, char local_ip[], int *port); + // The token means an additional information which is used during connection establishing. // The way to send it can be different based on a plugin. // In case of libwebsockets, send it through a HTTP custom header. diff --git a/src/include/vine-data-path.h b/src/include/vine-data-path.h index 0cd2c97..15421ff 100755 --- a/src/include/vine-data-path.h +++ b/src/include/vine-data-path.h @@ -52,6 +52,8 @@ const char *vine_data_path_get_ip(vine_data_path_h datapath); vine_address_family_e vine_data_path_get_addr_family(vine_data_path_h datapath); int vine_data_path_get_port(vine_data_path_h datapath); vine_security_h vine_data_path_get_security(vine_data_path_h datapath); +int vine_data_path_get_local_address_info(vine_data_path_h datapath, int *address_family, + char **ip, int *port); int vine_data_path_set_received_cb(vine_data_path_h datapath, vine_data_path_received_cb callback, void *user_data); diff --git a/src/include/vine-dp.h b/src/include/vine-dp.h index 778534d..f070950 100644 --- a/src/include/vine-dp.h +++ b/src/include/vine-dp.h @@ -50,8 +50,12 @@ public: virtual int set_addr_family(vine_address_family_e addr_family) = 0; virtual int set_remote_ip(vine_address_family_e, const std::string &ip) = 0; virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip) = 0; + virtual int set_remote_port(int port) = 0; + virtual int get_remote_port() = 0; + virtual int get_ip(vine_address_family_e *addr_family, char **ip) = 0; virtual int set_port(int port) = 0; virtual int get_port() = 0; + virtual int update_local_address_info() = 0; virtual int set_topic(std::string topic) = 0; virtual int set_max_connections(int max_conn) = 0; virtual int set_accepted_cb(vine_dp_accepted_cb callback, void *user_data) = 0; @@ -103,8 +107,12 @@ public: virtual int set_addr_family(vine_address_family_e addr_family); virtual int set_remote_ip(vine_address_family_e, const std::string &ip); virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip); + virtual int set_remote_port(int port); + virtual int get_remote_port(); + virtual int get_ip(vine_address_family_e *addr_family, char **ip); virtual int set_port(int port); virtual int get_port(){ return mListenPort; }; + virtual int update_local_address_info(); virtual int set_topic(std::string topic); virtual int set_max_connections(int max_conn); virtual int set_accepted_cb(vine_dp_accepted_cb callback, void *user_data); @@ -121,6 +129,7 @@ private: vine_data_path_h mDataPath; vine_address_family_e mAddrFamily; int mListenPort; + std::string mLocalIp; int mMaxConnNum; vine_dp_accepted_cb mAcceptedCb; void *mAcceptedCbData; @@ -141,8 +150,12 @@ public: virtual int set_addr_family(vine_address_family_e addr_family); virtual int set_remote_ip(vine_address_family_e, const std::string &ip); virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip); + virtual int set_remote_port(int port); + virtual int get_remote_port(){ return mPeerPort; }; + virtual int get_ip(vine_address_family_e *addr_family, char **ip); virtual int set_port(int port); - virtual int get_port(){ return mPeerPort; }; + virtual int get_port(){ return mPort; }; + virtual int update_local_address_info(); virtual int set_topic(std::string topic); virtual int set_max_connections(int max_conn){ return VINE_ERROR_NONE; }; virtual int set_accepted_cb(vine_dp_accepted_cb callback, void *user_data); @@ -157,6 +170,8 @@ private: vine_address_family_e mAddrFamily; std::string mPeerIp; int mPeerPort; + std::string mLocalIp; + int mPort; bool isCreatedByServerDp; }; @@ -188,9 +203,12 @@ public: virtual int set_addr_family(vine_address_family_e addr_family); virtual int set_remote_ip(vine_address_family_e, const std::string &ip); virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip); + virtual int set_remote_port(int port); + virtual int get_remote_port(); + virtual int get_ip(vine_address_family_e *addr_family, char **ip); virtual int set_port(int port); virtual int get_port(){ return mListenPort; }; - + virtual int update_local_address_info(); virtual int set_topic(std::string topic); virtual int set_max_connections(int max_conn); virtual int set_accepted_cb(vine_dp_accepted_cb callback, void *user_data); @@ -231,6 +249,7 @@ private: vine_address_family_e mAddrFamily; std::set mIpList; int mListenPort; + std::string mLocalIp; int mMaxConnNum; vine_dp_peer_joined_cb mPeerJoinedCb; @@ -255,6 +274,9 @@ int _vine_dp_set_iface_name(vine_dp_h dp, const char *iface_name); int _vine_dp_set_addr_family(vine_dp_h dp, vine_address_family_e addr_family); int _vine_dp_set_remote_ip(vine_dp_h dp, vine_address_family_e addr_family, const char *ip); int _vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip); +int _vine_dp_set_remote_port(vine_dp_h dp, int port); +int _vine_dp_get_remote_port(vine_dp_h dp, int *port); +int _vine_dp_get_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip); int _vine_dp_set_port(vine_dp_h dp, int port); int _vine_dp_get_port(vine_dp_h dp, int *port); int _vine_dp_set_topic(vine_dp_h dp, const char *topic); diff --git a/src/vine-data-path.cpp b/src/vine-data-path.cpp index c51137b..d20890f 100755 --- a/src/vine-data-path.cpp +++ b/src/vine-data-path.cpp @@ -782,3 +782,29 @@ vine_security_h vine_data_path_get_security(vine_data_path_h datapath) vine_data_path_s *dp = (vine_data_path_s *)datapath; return dp->security; } + +int vine_data_path_get_local_address_info(vine_data_path_h datapath, int *address_family, + char **ip, int *port) +{ + RET_VAL_IF(datapath == NULL, VINE_ERROR_INVALID_PARAMETER, "datapath is NULL"); + RET_VAL_IF(address_family == NULL, VINE_ERROR_INVALID_PARAMETER, "address_family is NULL"); + RET_VAL_IF(ip == NULL, VINE_ERROR_INVALID_PARAMETER, "ip is NULL"); + RET_VAL_IF(port == NULL, VINE_ERROR_INVALID_PARAMETER, "port is NULL"); + + vine_data_path_s *dp = (vine_data_path_s *)datapath; + vine_error_e error; + int addr_family, local_port; + char local_ip[VINE_MAX_IP_LEN + 1] = {0, }; + int ret = g_dp_plugin_fn.get_local_address_info(dp->plugin_handle, + &addr_family, local_ip, &local_port); + + error = __convert_data_path_error_to_vine_error((vine_data_path_error)ret); + if (error != VINE_ERROR_NONE) + return error; + + *address_family = addr_family; + *port = local_port; + *ip = STRDUP(local_ip); + + return VINE_ERROR_NONE; +} diff --git a/src/vine-dp.cpp b/src/vine-dp.cpp index f6f4f68..014bc95 100644 --- a/src/vine-dp.cpp +++ b/src/vine-dp.cpp @@ -90,6 +90,7 @@ static void _opened_cb(vine_data_path_h datapath, int result, int port, void *us { DataPath *dp = static_cast(userdata); dp->set_port(port); + dp->update_local_address_info(); VINE_LOGI("port[%d] result[%d]", port, result); dp->invoke_opened_cb((vine_error_e)result); @@ -109,14 +110,21 @@ static void _accepted_cb(vine_data_path_h datapath, void *user_data) _received_cb, static_cast(connected_client_dp)); vine_data_path_set_terminated_cb(datapath, _terminated_cb, static_cast(connected_client_dp)); + + connected_client_dp->update_local_address_info(); static_cast(user_data)->invoke_accepted_cb(connected_client_dp); } static void _connected_cb(vine_data_path_h datapath, int result, void *user_data) { - vine_data_path_set_received_cb(datapath, _received_cb, user_data); - vine_data_path_set_terminated_cb(datapath, _terminated_cb, user_data); - static_cast(user_data)->invoke_opened_cb(result); + if (result == 0) { + vine_data_path_set_received_cb(datapath, _received_cb, user_data); + vine_data_path_set_terminated_cb(datapath, _terminated_cb, user_data); + } + + DataPath *dp = static_cast(user_data); + dp->update_local_address_info(); + dp->invoke_opened_cb(result); } static void _pubsub_received_cb(vine_data_path_h datapath, size_t received_len, void *user_data) @@ -485,6 +493,16 @@ int DPServer::get_remote_ip(vine_address_family_e *addr_family, char **ip) return VINE_ERROR_INVALID_OPERATION; } +int DPServer::set_remote_port(int port) +{ + return VINE_ERROR_INVALID_OPERATION; +} + +int DPServer::get_remote_port() +{ + return -1; +} + int DPServer::set_port(int port) { if (port < 0 || port > 65535) @@ -495,6 +513,28 @@ int DPServer::set_port(int port) return VINE_ERROR_NONE; } +int DPServer::get_ip(vine_address_family_e *addr_family, char **ip) +{ + *addr_family = mAddrFamily; + *ip = STRDUP(mLocalIp.c_str()); + return VINE_ERROR_NONE; +} + +int DPServer::update_local_address_info() +{ + char *ip; + int addr_family; + int port; + int ret = vine_data_path_get_local_address_info(mDataPath, &addr_family, &ip, &port); + if (ret != VINE_ERROR_NONE) + return ret; + + mLocalIp = string(ip); + free(ip); + + return VINE_ERROR_NONE; +} + int DPServer::set_topic(std::string topic) { return VINE_ERROR_INVALID_OPERATION; @@ -595,6 +635,7 @@ DPClient::DPClient(void *event_fd) mDataPath = NULL; mPeerIp = ""; mPeerPort = 0; + mPort = 0; mReceivedCb = NULL; mReceivedCbData = NULL; mOpenedCb = NULL; @@ -615,6 +656,7 @@ DPClient::DPClient(void *event_fd, void *datapath) mAddrFamily = vine_data_path_get_addr_family(mDataPath); mPeerIp = vine_data_path_get_ip(mDataPath); mPeerPort = vine_data_path_get_port(mDataPath); + mPort = 0; mReceivedCb = NULL; mReceivedCbData = NULL; mOpenedCb = NULL; @@ -656,7 +698,7 @@ int DPClient::get_remote_ip(vine_address_family_e *addr_family, char **ip) return VINE_ERROR_NONE; } -int DPClient::set_port(int port) +int DPClient::set_remote_port(int port) { RET_VAL_IF(isCreatedByServerDp, VINE_ERROR_INVALID_OPERATION, "cannot set port"); if (port <= 0 || port > 65535) // Do not allow 0 @@ -667,6 +709,35 @@ int DPClient::set_port(int port) return VINE_ERROR_NONE; } +int DPClient::set_port(int port) +{ + return VINE_ERROR_INVALID_OPERATION; +} + +int DPClient::get_ip(vine_address_family_e *addr_family, char **ip) +{ + *addr_family = mAddrFamily; + *ip = STRDUP(mLocalIp.c_str()); + return VINE_ERROR_NONE; +} + +int DPClient::update_local_address_info() +{ + char *ip; + int addr_family; + int port; + int ret = vine_data_path_get_local_address_info(mDataPath, &addr_family, &ip, &port); + if (ret != VINE_ERROR_NONE) + return ret; + + mLocalIp = string(ip); + mPort = port; + + free(ip); + + return VINE_ERROR_NONE; +} + int DPClient::set_topic(std::string topic) { return VINE_ERROR_INVALID_OPERATION; @@ -791,6 +862,16 @@ int DPPubSub::get_remote_ip(vine_address_family_e *addr_family, char **ip) return VINE_ERROR_INVALID_OPERATION; } +int DPPubSub::set_remote_port(int port) +{ + return VINE_ERROR_INVALID_OPERATION; +} + +int DPPubSub::get_remote_port() +{ + return -1; +} + int DPPubSub::set_port(int port) { if (port < 0 || port > 65535) @@ -801,6 +882,26 @@ int DPPubSub::set_port(int port) return VINE_ERROR_NONE; } +int DPPubSub::get_ip(vine_address_family_e *addr_family, char **ip) +{ + return VINE_ERROR_INVALID_OPERATION; +} + +int DPPubSub::update_local_address_info() +{ + char *ip; + int addr_family; + int port; + int ret = vine_data_path_get_local_address_info(mServerDataPath, &addr_family, &ip, &port); + if (ret != VINE_ERROR_NONE) + return ret; + + mLocalIp = string(ip); + free(ip); + + return VINE_ERROR_NONE; +} + int DPPubSub::set_topic(std::string topic) { mTopic = topic; @@ -1264,6 +1365,36 @@ int _vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, cha return _dp->get_remote_ip(addr_family, ip); } +int _vine_dp_set_remote_port(vine_dp_h dp, int port) +{ + RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null."); + + DataPath *_dp = static_cast(dp); + return _dp->set_remote_port(port); +} + +int _vine_dp_get_remote_port(vine_dp_h dp, int *port) +{ + RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null."); + RET_VAL_IF(port == NULL, VINE_ERROR_INVALID_PARAMETER, "port is null."); + + DataPath *_dp = static_cast(dp); + int remote_port = _dp->get_remote_port(); + if (remote_port < 0) + return VINE_ERROR_INVALID_OPERATION; + *port = remote_port; + return VINE_ERROR_NONE; +} +int _vine_dp_get_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip) +{ + RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null."); + RET_VAL_IF(addr_family == NULL, VINE_ERROR_INVALID_PARAMETER, "addr_family is null."); + RET_VAL_IF(ip == NULL, VINE_ERROR_INVALID_PARAMETER, "ip is null."); + + DataPath *_dp = static_cast(dp); + return _dp->get_ip(addr_family, ip); +} + int _vine_dp_set_port(vine_dp_h dp, int port) { RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null."); diff --git a/src/vine.cpp b/src/vine.cpp index 8ddfd82..bd16968 100755 --- a/src/vine.cpp +++ b/src/vine.cpp @@ -357,6 +357,30 @@ API int vine_dp_get_remote_ip(vine_dp_h dp, vine_address_family_e *addr_family, return _vine_dp_get_remote_ip(dp, addr_family, ip); } +API int vine_dp_set_remote_port(vine_dp_h dp, int port) +{ + __VINE_FUNC_ENTER__; + CHECK_FEATURE_SUPPORTED; + + return _vine_dp_set_remote_port(dp, port); +} + +API int vine_dp_get_remote_port(vine_dp_h dp, int *port) +{ + __VINE_FUNC_ENTER__; + CHECK_FEATURE_SUPPORTED; + + return _vine_dp_get_remote_port(dp, port); +} + +API int vine_dp_get_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip) +{ + __VINE_FUNC_ENTER__; + CHECK_FEATURE_SUPPORTED; + + return _vine_dp_get_ip(dp, addr_family, ip); +} + API int vine_dp_set_port(vine_dp_h dp, int port) { __VINE_FUNC_ENTER__; diff --git a/tests/unittest/vine-unittest-dp.cpp b/tests/unittest/vine-unittest-dp.cpp index 10fd0b8..209bbad 100755 --- a/tests/unittest/vine-unittest-dp.cpp +++ b/tests/unittest/vine-unittest-dp.cpp @@ -122,7 +122,7 @@ TEST_F(VineDpTest, SetRemoteIpN) vine_dp_set_remote_ip(server_dp, VINE_ADDRESS_FAMILY_IPV4, TEST_IP)); } -TEST_F(VineDpTest, GetRemoteN) +TEST_F(VineDpTest, GetRemoteIpN) { vine_address_family_e family; char *ip; @@ -151,18 +151,80 @@ TEST_F(VineDpTest, SetGetRemoteIpP) free(ip); } -TEST_F(VineDpTest, SetPortN) +TEST_F(VineDpTest, SetRemotePortN) { EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, - vine_dp_set_port(client_dp, -1)); + vine_dp_set_remote_port(client_dp, -1)); + EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, + vine_dp_set_remote_port(NULL, 12345)); + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, + vine_dp_set_remote_port(server_dp, 12345)); + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, + vine_dp_set_remote_port(pubsub_dp, 12345)); +} + +TEST_F(VineDpTest, SetRemotePortP) +{ + EXPECT_EQ(VINE_ERROR_NONE, + vine_dp_set_remote_port(client_dp, 12345)); +} + +TEST_F(VineDpTest, GetRemotePortN) +{ + int port; + EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, + vine_dp_get_remote_port(client_dp, NULL)); + EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, + vine_dp_get_remote_port(NULL, &port)); + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, + vine_dp_get_remote_port(server_dp, &port)); + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, + vine_dp_get_remote_port(pubsub_dp, &port)); +} + +TEST_F(VineDpTest, GetRemotePortP) +{ + int port; + EXPECT_EQ(VINE_ERROR_NONE, + vine_dp_get_remote_port(client_dp, &port)); +} + +TEST_F(VineDpTest, GetIpN) +{ + vine_address_family_e family; + char *ip; + EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, + vine_dp_get_ip(client_dp, NULL, &ip)); + EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, + vine_dp_get_ip(client_dp, &family, NULL)); + + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, + vine_dp_get_ip(pubsub_dp, &family, &ip)); +} + +TEST_F(VineDpTest, GetIpP) +{ + vine_address_family_e family; + char *ip; + EXPECT_EQ(VINE_ERROR_NONE, + vine_dp_get_ip(client_dp, &family, &ip)); + free(ip); +} + +TEST_F(VineDpTest, SetPortN) +{ EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, vine_dp_set_port(NULL, 12345)); + EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, + vine_dp_set_port(server_dp, -1)); + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, + vine_dp_set_port(client_dp, 12345)); } TEST_F(VineDpTest, SetPortP) { EXPECT_EQ(VINE_ERROR_NONE, - vine_dp_set_port(client_dp, 12345)); + vine_dp_set_port(server_dp, 12345)); } TEST_F(VineDpTest, GetPortN) diff --git a/tests/verifier/vine-verifier.cpp b/tests/verifier/vine-verifier.cpp index 6ce82b4..92d2c94 100644 --- a/tests/verifier/vine-verifier.cpp +++ b/tests/verifier/vine-verifier.cpp @@ -320,7 +320,7 @@ static void __connect_to_server(vine_session_h session, bool use_tls, bool use_p vine_dp_h dp; vine_dp_create(session, VINE_DP_TYPE_CLIENT, &dp); vine_dp_set_remote_ip(dp, address_family, ip); - vine_dp_set_port(dp, port); + vine_dp_set_remote_port(dp, port); vine_dp_set_security(dp, security); vine_dp_set_received_cb(dp, __client_received_cb, NULL); diff --git a/tests/vine-test/vine-test.cpp b/tests/vine-test/vine-test.cpp index 4a692c5..c9aa697 100644 --- a/tests/vine-test/vine-test.cpp +++ b/tests/vine-test/vine-test.cpp @@ -606,7 +606,7 @@ static void __connect_server() vine_dp_create(g_session, VINE_DP_TYPE_CLIENT, &g_client_dp); vine_dp_set_remote_ip(g_client_dp, addr_type ? VINE_ADDRESS_FAMILY_IPV6 : VINE_ADDRESS_FAMILY_IPV4, ip); - PRINT_RESULT(vine_dp_set_port(g_client_dp, port), "vine_dp_set_port"); + PRINT_RESULT(vine_dp_set_remote_port(g_client_dp, port), "vine_dp_set_remote_port"); vine_security_h security = __create_security_handle(security_type, true); vine_dp_set_security(g_client_dp, security); vine_security_destroy(security); diff --git a/tool/tool_run.cpp b/tool/tool_run.cpp index 83c25a5..4bb1635 100644 --- a/tool/tool_run.cpp +++ b/tool/tool_run.cpp @@ -93,6 +93,22 @@ static void __terminated_cb(vine_dp_h dp, void *user_data) static void __opened_cb(vine_dp_h dp, vine_error_e result, void *user_data) { printf("DP %s.\n", result == VINE_ERROR_NONE ? "is opened" : "open failure"); + if (result != VINE_ERROR_NONE) + return; + + vine_address_family_e addr_family; + char *ip = NULL; + int port = 0; + + vine_dp_get_port(dp, &port); + printf("\t> %s port: %d\n", + vine_configs.dp_type == VINE_DP_TYPE_CLIENT ? "connected" : "listen", + port); + + vine_dp_get_ip(dp, &addr_family, &ip); + printf("\t> local IP: %s, address family: %d \n", ip, addr_family); + free(ip); + vine_dp_set_received_cb(dp, __received_cb, NULL); vine_dp_set_terminated_cb(dp, __terminated_cb, NULL); @@ -104,7 +120,18 @@ static void __opened_cb(vine_dp_h dp, vine_error_e result, void *user_data) static void __accepted_cb(vine_dp_h dp, vine_dp_h accepted_dp, void *user_data) { + vine_address_family_e addr_family; + int port = 0; + char *ip = NULL; + + vine_dp_get_remote_port(accepted_dp, &port); printf("client is accepted.\n"); + printf("\t> client port: %d\n", port); + + vine_dp_get_ip(accepted_dp, &addr_family, &ip); + printf("\t> used local IP: %s, address family: %d\n", ip, addr_family); + free(ip); + vine_dp_set_received_cb(accepted_dp, __received_cb, NULL); vine_dp_set_terminated_cb(accepted_dp, __terminated_cb, NULL); @@ -451,16 +478,17 @@ static void _set_discovery_info() static void _set_dp_info(vine_dp_type_e type) { vine_dp_create(vine_configs.session, type, &vine_configs.dp); - vine_dp_set_port(vine_configs.dp, tool_config_get_port()); - vine_address_family_e addr_family = _convert_addr_family(tool_config_get_address_family()); vine_dp_set_address_family(vine_configs.dp, addr_family); vine_dp_set_max_connections(vine_configs.dp, tool_config_get_max_conn()); if (type == VINE_DP_TYPE_CLIENT) { + vine_dp_set_remote_port(vine_configs.dp, tool_config_get_port()); vine_dp_set_remote_ip(vine_configs.dp, addr_family, tool_config_get_remote_address()); vine_dp_set_received_cb(vine_configs.dp, __received_cb, NULL); + } else { + vine_dp_set_port(vine_configs.dp, tool_config_get_port()); } if (type == VINE_DP_TYPE_SERVER) -- 2.7.4 From d580fb7dc60d2cb81c549a90f391870b142f7d97 Mon Sep 17 00:00:00 2001 From: Cheoleun Moon Date: Mon, 31 May 2021 15:59:25 +0900 Subject: [PATCH 07/16] Change print_error to _test_print_error Change-Id: I797c6fb3dcb8890e2cf99efd2787e7a6c546ca19 Signed-off-by: Cheoleun Moon --- tests/vine-test/vine-multi-thread-test.cpp | 8 +++--- tests/vine-test/vine-pubsub-open-close-test.cpp | 8 +++--- tests/vine-test/vine-test-utils.cpp | 8 +++--- tests/vine-test/vine-test-utils.h | 12 ++++---- tests/vine-test/vine-test.cpp | 38 ++++++++++++------------- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/tests/vine-test/vine-multi-thread-test.cpp b/tests/vine-test/vine-multi-thread-test.cpp index 7030b76..32b5377 100644 --- a/tests/vine-test/vine-multi-thread-test.cpp +++ b/tests/vine-test/vine-multi-thread-test.cpp @@ -80,7 +80,7 @@ static void __get_current_time(char *buf) time(&now); if (localtime_r(&now, &local) == NULL) { - print_error("localtime_r() fails"); + _test_print_error("localtime_r() fails"); return; } @@ -143,7 +143,7 @@ static void __start_event_loop(vine_session_h session) int epollfd = epoll_create1(0); if (epollfd == -1) { - print_error("Fail to create epoll fd %d", errno); + _test_print_error("Fail to create epoll fd %d", errno); exit(1); } @@ -151,14 +151,14 @@ static void __start_event_loop(vine_session_h session) ev.events = EPOLLIN; ev.data.fd = fd; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { - print_error("Fail to add an epoll event for fd %d: %d", fd, errno); + _test_print_error("Fail to add an epoll event for fd %d: %d", fd, errno); exit(1); } while (true) { int n = epoll_wait(epollfd, events, MAX_EVENTS, 0); if (n == -1) { - print_error("epoll_wait %d", errno); + _test_print_error("epoll_wait %d", errno); exit(1); } diff --git a/tests/vine-test/vine-pubsub-open-close-test.cpp b/tests/vine-test/vine-pubsub-open-close-test.cpp index a64a63c..104028d 100644 --- a/tests/vine-test/vine-pubsub-open-close-test.cpp +++ b/tests/vine-test/vine-pubsub-open-close-test.cpp @@ -77,7 +77,7 @@ static void add_event_fd(int fd, void *user_data) ev.data.fd = fd; ev.data.ptr = user_data; if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { - print_error("Fail to add an epoll event for fd %d: %d", fd, errno); + _test_print_error("Fail to add an epoll event for fd %d: %d", fd, errno); exit(1); } } @@ -155,7 +155,7 @@ static void run_event_loop(vine_session_h session) epollfd = epoll_create1(0); if (epollfd == -1) { - print_error("Fail to create epoll fd %d", errno); + _test_print_error("Fail to create epoll fd %d", errno); return; } @@ -172,7 +172,7 @@ static void run_event_loop(vine_session_h session) while (count) { int n = epoll_wait(epollfd, events, MAX_EVENTS, 0); if (n == -1) { - print_error("epoll_wait %d", errno); + _test_print_error("epoll_wait %d", errno); break; } @@ -193,7 +193,7 @@ static void open_dp(vine_session_h session) PRINT_IF_ERROR(vine_dp_set_topic(dp, TOPIC), "vine_dp_set_topic"); PRINT_IF_ERROR(vine_dp_set_terminated_cb(dp, [](vine_dp_h dp, void *user_data) { - PRINT_LOG("dp[%p] is closed."); + PRINT_LOG("dp[%p] is closed.", dp); }, NULL), "vine_dp_set_terminated_cb"); PRINT_IF_ERROR(vine_dp_set_peer_joined_cb(dp, [](vine_dp_h dp, const char *ip, int port, void *user_data) { diff --git a/tests/vine-test/vine-test-utils.cpp b/tests/vine-test/vine-test-utils.cpp index 5260b6f..81b0548 100644 --- a/tests/vine-test/vine-test-utils.cpp +++ b/tests/vine-test/vine-test-utils.cpp @@ -40,7 +40,7 @@ const char *convert_error_to_str(vine_error_e error) } } -void print_log(const char *format, ...) +void _test_print_log(const char *format, ...) { va_list args; @@ -53,7 +53,7 @@ void print_log(const char *format, ...) va_end(args); } -void print_error(const char *format, ...) +void _test_print_error(const char *format, ...) { va_list args; va_start(args, format); @@ -65,14 +65,14 @@ void print_error(const char *format, ...) va_end(args); } -void print_result(int ret, const char *function_name, bool print_if_no_error) +void _test_print_result(int ret, const char *function_name, bool print_if_no_error) { unsigned int tid = (unsigned int)syscall(__NR_gettid); if (ret == VINE_ERROR_NONE) { if (print_if_no_error) printf(COLOR_GRN "[TID:%u] %s" COLOR_RESET "\n", tid, function_name); } else { - print_error("[TID:%u] %s: %s(%d) ", tid, function_name, + _test_print_error("[TID:%u] %s: %s(%d) ", tid, function_name, convert_error_to_str((vine_error_e)ret), ret); } } diff --git a/tests/vine-test/vine-test-utils.h b/tests/vine-test/vine-test-utils.h index 60255e9..515bcd5 100644 --- a/tests/vine-test/vine-test-utils.h +++ b/tests/vine-test/vine-test-utils.h @@ -7,12 +7,12 @@ #define COLOR_BLU "\e[34m" #define COLOR_CYN "\e[36m" -#define PRINT_IF_ERROR(ret, func) print_result(ret, func, false) -#define PRINT_RESULT(ret, func) print_result(ret, func, true) -#define PRINT_LOG(format, args...) print_log(format, ##args) +#define PRINT_IF_ERROR(ret, func) _test_print_result(ret, func, false) +#define PRINT_RESULT(ret, func) _test_print_result(ret, func, true) +#define PRINT_LOG(format, args...) _test_print_log(format, ##args) const char *convert_error_to_str(vine_error_e error); -void print_log(const char *format, ...); -void print_error(const char *format, ...); -void print_result(int ret, const char *function_name, bool print_if_no_error); +void _test_print_log(const char *format, ...); +void _test_print_error(const char *format, ...); +void _test_print_result(int ret, const char *function_name, bool print_if_no_error); diff --git a/tests/vine-test/vine-test.cpp b/tests/vine-test/vine-test.cpp index c9aa697..b954140 100644 --- a/tests/vine-test/vine-test.cpp +++ b/tests/vine-test/vine-test.cpp @@ -34,7 +34,7 @@ #define CHECK_SESSION \ do { \ if (!g_session) { \ - print_error("No Session"); \ + _test_print_error("No Session"); \ return; \ } \ } while (0) @@ -102,7 +102,7 @@ static void __start_event_loop() ev.events = EPOLLIN; ev.data.ptr = g_session; if (epoll_ctl(g_epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { - print_error("Fail to add an epoll event for fd %d: %d", fd, errno); + _test_print_error("Fail to add an epoll event for fd %d: %d", fd, errno); exit(1); } } @@ -277,7 +277,7 @@ static void __set_service_type() char type[64]; printf(" >> Service Type: "); if (scanf(" %63s", type) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } PRINT_RESULT(vine_service_set_type(g_service, type), @@ -290,7 +290,7 @@ static void __set_service_name() char name[64]; printf(" >> Service Name (Max length 64): "); if (scanf(" %63s", name) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } PRINT_RESULT(vine_service_set_name(g_service, name), @@ -303,7 +303,7 @@ static void __set_port() int port; printf(" >> Port Number (0 ~ 65535): "); if (scanf(" %d", &port) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } PRINT_RESULT(vine_service_set_port(g_service, port), "vine_session_set_port"); @@ -367,7 +367,7 @@ static void __start_discovery() char type[20]; printf(" >> Service Type: "); if (scanf(" %19s", type) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } @@ -544,19 +544,19 @@ static void __open_server() printf(" >> Address type(0-default, 1-IPv4, 2-IPv6): "); if (scanf(" %d", &addr_family) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } printf(" >> listen port: "); if (scanf(" %d", &port) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } printf("Set security type(0.NONE, 1.TLS, 2.PSK): "); if (scanf("%d", &security_type) < 0) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } @@ -582,24 +582,24 @@ static void __connect_server() printf(" >> Address Family(0-IPv4, 1-IPv6): "); if (scanf(" %d", &addr_type) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } printf(" >> Peer IP: "); if (scanf(" %39s", ip) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } printf(" >> Peer port: "); if (scanf(" %d", &port) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } printf("Set security type(0.NONE, 1.TLS, 2.PSK): "); if (scanf("%d", &security_type) < 0) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } @@ -622,19 +622,19 @@ static void __join_service() printf(" >> Address type(0-default, 1-IPv4, 2-IPv6): "); if (scanf(" %d", &addr_family) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } printf(" >> Listen port: "); if (scanf(" %d", &port) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } printf(" >> Set topic: "); if (scanf(" %63s", topic) < 1) { - print_error("Scan failed"); + _test_print_error("Scan failed"); return; } @@ -828,7 +828,7 @@ int main() g_epollfd = epoll_create1(0); if (g_epollfd == -1) { - print_error("Fail to create epoll fd %d", errno); + _test_print_error("Fail to create epoll fd %d", errno); return -1; } @@ -836,14 +836,14 @@ int main() ev.events = EPOLLIN; ev.data.fd = STDIN_FILENO; if (epoll_ctl(g_epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1) { - print_error("Fail to add an epoll event for stdin: %d", errno); + _test_print_error("Fail to add an epoll event for stdin: %d", errno); return -1; } while (true) { int n = epoll_wait(g_epollfd, events, MAX_EVENTS, 0); if (n == -1) { - print_error("epoll_wait %d", errno); + _test_print_error("epoll_wait %d", errno); return -1; } -- 2.7.4 From 6b132613f9d6d0025b927f43430135f30543234d Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Tue, 1 Jun 2021 11:15:26 +0900 Subject: [PATCH 08/16] Add vine_dp_get_id() - Add vine_dp_get_id() - Pass a peer Id to joined/left callback instead of IP/port Change-Id: I2c0f9db4fdbf9e37b0746a2f30f580ae3ac13488 --- include/vine.h | 25 +++++++-- packaging/capi-network-vine.spec | 2 +- src/include/vine-dp.h | 11 ++-- src/vine-dp.cpp | 75 +++++++++++++++++-------- tests/unittest/vine-unittest-dp.cpp | 4 +- tests/vine-test/vine-pubsub-open-close-test.cpp | 8 +-- tool/tool_run.cpp | 8 +-- 7 files changed, 90 insertions(+), 43 deletions(-) diff --git a/include/vine.h b/include/vine.h index 2fbca0a..4972a6a 100755 --- a/include/vine.h +++ b/include/vine.h @@ -822,6 +822,21 @@ int vine_dp_create(vine_session_h session, vine_dp_type_e type, vine_dp_h *dp); int vine_dp_destroy(vine_dp_h dp); /** + * @brief Gets the Id for DP_TYPE_PUBSUB. + * @remarks This should be called after completing vine_dp_open() + * @since_tizen 6.5 + * @param[in] dp The data path handle + * @param[out] id The PubSub Id + * @return 0 on success, otherwise a negative error value + * @retval #VINE_ERROR_NONE Successful + * @retval #VINE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VINE_ERROR_INVALID_OPERATION Invalid operation + * @retval #VINE_ERROR_NOT_SUPPORTED Not supported + * @see vine_dp_create() + */ +int vine_dp_get_id(vine_dp_h dp, char **id); + +/** * @brief Sets the interface name to use for datapath. * @remarks If the interface has multiple IP addresses, please set an IP address as @a iface_name. * @since_tizen 6.5 @@ -1202,13 +1217,12 @@ int vine_dp_unset_received_cb(vine_dp_h dp); * @brief Called when a pubsub peer is joined. * @since_tizen 6.5 * @param[in] dp The datapath handle - * @param[in] ip The peer's IP address - * @param[in] port The peer's port + * @param[in] peer_id The peer's Id * @param[in] user_data The user data passed from the callback registration function * @see vine_dp_set_peer_joined_cb() * @see vine_dp_unset_peer_joined_cb() */ -typedef void(*vine_dp_peer_joined_cb)(vine_dp_h dp, const char *ip, int port, void *user_data); +typedef void(*vine_dp_peer_joined_cb)(vine_dp_h dp, const char *peer_id, void *user_data); /** * @brief Registers the callback called when a pubsub peer is joined. @@ -1242,13 +1256,12 @@ int vine_dp_unset_peer_joined_cb(vine_dp_h dp); * @brief Called when a pubsub peer is left. * @since_tizen 6.5 * @param[in] dp The datapath handle. VINE_DP_TYPE_PUBSUB only - * @param[in] ip The peer's IP address - * @param[in] port The peer's port + * @param[in] peer_id The peer's Id * @param[in] user_data The user data passed from the callback registration function * @see vine_dp_set_peer_left_cb() * @see vine_dp_unset_peer_left_cb() */ -typedef void(*vine_dp_peer_left_cb)(vine_dp_h dp, const char *ip, int port, void *user_data); +typedef void(*vine_dp_peer_left_cb)(vine_dp_h dp, const char *peer_id, void *user_data); /** * @brief Registers the callback called when a pubsub peer is left. diff --git a/packaging/capi-network-vine.spec b/packaging/capi-network-vine.spec index 5260543..8c245c4 100755 --- a/packaging/capi-network-vine.spec +++ b/packaging/capi-network-vine.spec @@ -2,7 +2,7 @@ %bcond_without lws_static_prebuilt Name: capi-network-vine Summary: An service discovery framework -Version: 1.0.2 +Version: 1.0.3 Release: 0 Group: Network & Connectivity/API License: Apache-2.0 diff --git a/src/include/vine-dp.h b/src/include/vine-dp.h index f070950..2e9ab9c 100644 --- a/src/include/vine-dp.h +++ b/src/include/vine-dp.h @@ -218,13 +218,14 @@ public: virtual int set_peer_left_cb(vine_dp_peer_left_cb callback, void *user_data); virtual int unset_peer_left_cb(); - void invoke_peer_joined_cb(const char *ip, int port); - void invoke_peer_left_cb(const char *ip, int port); + void invoke_peer_joined_cb(const char *peer_id); + void invoke_peer_left_cb(const char *peer_id); int connect(const char *service_name, const char *ip, int port); int close_server_dp(); bool is_joined_peer(const char *service_name, const char *ip); int get_joined_peer(); + const char *get_joined_peer_id(vine_data_path_h datapath); void add_joined_peer(const char *service_name, vine_data_path_h datapath); void del_joined_peer(vine_data_path_h datapath); void clear_joined_peer(); @@ -233,7 +234,7 @@ public: int publish_service(); int subscribe_service(); - void set_service_name(const char *service_name) { mServiceName = service_name; } + void set_id(const char *id) { mId = id; } bool check_if_connect(const char *peer_rank, vine_address_family_e ip_type, const char *peer_ip, int peer_port); int get_rank() { return mRank; } @@ -244,7 +245,7 @@ private: std::string mTopic; vine_disc_h mSdSub; vine_disc_h mSdPub; - std::string mServiceName; + std::string mId; vine_address_family_e mAddrFamily; std::set mIpList; @@ -264,6 +265,8 @@ private: int create_rank(); int compare_ip_priority(const char *peer_ip); + void create_id(char id[]); + }; } // namespace vine diff --git a/src/vine-dp.cpp b/src/vine-dp.cpp index 014bc95..3a77b0d 100644 --- a/src/vine-dp.cpp +++ b/src/vine-dp.cpp @@ -145,11 +145,13 @@ static void _pubsub_terminated_cb(vine_data_path_h datapath, void *user_data) VINE_LOGD("datapath[%p] is terminated by peer.", datapath); DPPubSub *dp = static_cast(user_data); - dp->del_joined_peer(datapath); - const char *ip = vine_data_path_get_ip(datapath); - int port = vine_data_path_get_port(datapath); - dp->invoke_peer_left_cb(ip, port); + char *peer_id = STRDUP(dp->get_joined_peer_id(datapath)); + dp->del_joined_peer(datapath); + if (peer_id) { + dp->invoke_peer_left_cb(peer_id); + free(peer_id); + } vine_data_path_destroy(datapath); } @@ -199,14 +201,12 @@ static void _pubsub_accepted_cb(vine_data_path_h datapath, void *user_data) } dp->add_joined_peer(token, datapath); - free(token); vine_data_path_set_received_cb(datapath, _pubsub_received_cb, user_data); vine_data_path_set_terminated_cb(datapath, _pubsub_terminated_cb, user_data); - const char *ip = vine_data_path_get_ip(datapath); - int port = vine_data_path_get_port(datapath); - dp->invoke_peer_joined_cb(ip, port); + dp->invoke_peer_joined_cb(token); + free(token); } struct pubsub_connect_data { @@ -235,10 +235,7 @@ static void _pubsub_connected_cb(vine_data_path_h datapath, int result, void *us vine_data_path_set_received_cb(datapath, _pubsub_received_cb, conn_data->dp); vine_data_path_set_terminated_cb(datapath, _pubsub_terminated_cb, conn_data->dp); - const char *ip = vine_data_path_get_ip(datapath); - int port = vine_data_path_get_port(datapath); - dp->invoke_peer_joined_cb(ip, port); - + dp->invoke_peer_joined_cb(conn_data->service_name); conn_data->dp = NULL; free(conn_data); } @@ -378,7 +375,7 @@ static void _service_published_cb(vine_disc_h disc, return; DPPubSub *dp = static_cast(user_data); - dp->set_service_name(service_name); + dp->set_id(service_name); int ret = dp->subscribe_service(); if (ret != VINE_ERROR_NONE) dp->close(); @@ -829,7 +826,7 @@ DPPubSub::DPPubSub(void *event_fd) mTopic = ""; mSdSub = NULL; mSdPub = NULL; - mServiceName = ""; + mId = ""; // Network Info mAddrFamily = VINE_ADDRESS_FAMILY_DEFAULT; @@ -959,16 +956,16 @@ int DPPubSub::unset_peer_left_cb() return VINE_ERROR_NONE; } -void DPPubSub::invoke_peer_joined_cb(const char *ip, int port) +void DPPubSub::invoke_peer_joined_cb(const char *peer_id) { if (mPeerJoinedCb) - mPeerJoinedCb(static_cast(this), ip, port, mPeerJoinedCbData); + mPeerJoinedCb(static_cast(this), peer_id, mPeerJoinedCbData); } -void DPPubSub::invoke_peer_left_cb(const char *ip, int port) +void DPPubSub::invoke_peer_left_cb(const char *peer_id) { if (mPeerLeftCb) - mPeerLeftCb(static_cast(this), ip, port, mPeerJoinedCbData); + mPeerLeftCb(static_cast(this), peer_id, mPeerJoinedCbData); } int DPPubSub::connect(const char *service_name, const char *ip, int port) @@ -982,7 +979,7 @@ int DPPubSub::connect(const char *service_name, const char *ip, int port) conn_data->service_name = STRDUP(service_name); int ret = vine_data_path_connect(mAddrFamily, ip, port, iface_name, - mSecurity, mServiceName.c_str(), + mSecurity, mId.c_str(), _pubsub_connected_cb, (void *)conn_data, &datapath, mEventFd); return ret; @@ -995,6 +992,20 @@ int DPPubSub::close_server_dp() return ret; } +void DPPubSub::create_id(char id[]) +{ + const char *map = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const size_t map_len = strlen(map); + + string rand_str; + generate_n(back_inserter(rand_str), 6, + [&](){ + return map[rand() % map_len]; + }); + snprintf(id, VINE_MAX_SERVICE_NAME_LEN, "%s-%s", + VINE_DP_PUBSUB_SERVICE_NAME_PREFIX, rand_str.c_str()); +} + int DPPubSub::publish_service() { vine_service_h service; @@ -1011,9 +1022,8 @@ int DPPubSub::publish_service() mRank = create_rank(); sprintf(rank_str, "%d", mRank); - snprintf(service_name, VINE_MAX_SERVICE_NAME_LEN, - "%s-%d", VINE_DP_PUBSUB_SERVICE_NAME_PREFIX, mRank); + create_id(service_name); vine_service_set_name(service, service_name); vine_service_add_attribute(service, VINE_DP_PUBSUB_RANK_KEY, (const char *)rank_str); @@ -1146,7 +1156,7 @@ int DPPubSub::recv(unsigned char *buf, size_t buf_len, size_t *read_len) bool DPPubSub::is_joined_peer(const char *service_name, const char *ip) { - if (mServiceName.compare(service_name) == 0) { + if (mId.compare(service_name) == 0) { VINE_LOGD("It's me!"); mIpList.insert(ip); return true; @@ -1160,6 +1170,27 @@ int DPPubSub::get_joined_peer() return mDataPathList.size(); } +const char *DPPubSub::get_joined_peer_id(vine_data_path_h datapath) +{ + if (!datapath) + return NULL; + + DPMap::iterator found = std::find_if(mDataPathList.begin(), + mDataPathList.end(), + [datapath](std::pair const& item) + { + VINE_LOGD("item.second[%p]", item.second); + return (item.second == datapath); + }); + + if (found == mDataPathList.end()) { + VINE_LOGE("Cannot find the datapath[%p].", datapath); + return NULL; + } + + return found->first.c_str(); +} + void DPPubSub::add_joined_peer(const char *service_name, vine_data_path_h datapath) { if (!service_name || !datapath) diff --git a/tests/unittest/vine-unittest-dp.cpp b/tests/unittest/vine-unittest-dp.cpp index 209bbad..c3f23a7 100755 --- a/tests/unittest/vine-unittest-dp.cpp +++ b/tests/unittest/vine-unittest-dp.cpp @@ -66,11 +66,11 @@ static void __terminated_cb(vine_dp_h dp, void *user_data) { } -static void __peer_joined_cb(vine_dp_h dp, const char *ip, int port, void *user_data) +static void __peer_joined_cb(vine_dp_h dp, const char *peer_id, void *user_data) { } -static void __peer_left_cb(vine_dp_h dp, const char *ip, int port, void *user_data) +static void __peer_left_cb(vine_dp_h dp, const char *peer_id, void *user_data) { } diff --git a/tests/vine-test/vine-pubsub-open-close-test.cpp b/tests/vine-test/vine-pubsub-open-close-test.cpp index 104028d..fcc2ab0 100644 --- a/tests/vine-test/vine-pubsub-open-close-test.cpp +++ b/tests/vine-test/vine-pubsub-open-close-test.cpp @@ -196,12 +196,12 @@ static void open_dp(vine_session_h session) PRINT_LOG("dp[%p] is closed.", dp); }, NULL), "vine_dp_set_terminated_cb"); PRINT_IF_ERROR(vine_dp_set_peer_joined_cb(dp, - [](vine_dp_h dp, const char *ip, int port, void *user_data) { - PRINT_LOG("dp[%p]'s peer[%s:%d] is joined.", dp, ip, port); + [](vine_dp_h dp, const char *peer_id, void *user_data) { + PRINT_LOG("dp[%p]'s peer[%s] is joined.", dp, peer_id); }, NULL), "vine_dp_set_peer_joined_cb"); PRINT_IF_ERROR(vine_dp_set_peer_left_cb(dp, - [](vine_dp_h dp, const char *ip, int port, void *user_data) { - PRINT_LOG("dp[%p]'s peer[%s:%d] is left.", dp, ip, port); + [](vine_dp_h dp, const char *peer_id, void *user_data) { + PRINT_LOG("dp[%p]'s peer[%s] is left.", dp, peer_id); }, NULL), "vine_dp_set_peer_left_cb"); PRINT_IF_ERROR(vine_dp_open(dp, [](vine_dp_h dp, vine_error_e result, void *user_data) { diff --git a/tool/tool_run.cpp b/tool/tool_run.cpp index 4bb1635..d1e06fb 100644 --- a/tool/tool_run.cpp +++ b/tool/tool_run.cpp @@ -139,15 +139,15 @@ static void __accepted_cb(vine_dp_h dp, vine_dp_h accepted_dp, void *user_data) send_message(accepted_dp); } -static void __peer_joined_cb(vine_dp_h dp, const char *ip, int port, void *user_data) +static void __peer_joined_cb(vine_dp_h dp, const char *peer_id, void *user_data) { - printf("pubsub peer(%s:%d) is joined.\n", ip, port); + printf("pubsub peer(%s) is joined.\n", peer_id); send_message(dp); } -static void __peer_left_cb(vine_dp_h dp, const char *ip, int port, void *user_data) +static void __peer_left_cb(vine_dp_h dp, const char *peer_id, void *user_data) { - printf("pubsub peer(%s:%d) is left.\n", ip, port); + printf("pubsub peer(%s) is left.\n", peer_id); } static void __registered_cb(vine_session_h session, -- 2.7.4 From 2202eed499e35458ad3c785278cbce0581a60434 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Tue, 1 Jun 2021 18:35:14 +0900 Subject: [PATCH 09/16] Add vine_dp_get_id() #2 Change-Id: I84c80a5f970caa8bee6222ff92a5e407540e3c4c --- src/include/vine-dp.h | 7 ++++++- src/vine-dp.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/vine.cpp | 8 ++++++++ tests/unittest/vine-unittest-dp.cpp | 14 ++++++++++++++ tool/tool_run.cpp | 18 ++++++++++++------ 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/include/vine-dp.h b/src/include/vine-dp.h index 2e9ab9c..d76a553 100644 --- a/src/include/vine-dp.h +++ b/src/include/vine-dp.h @@ -47,6 +47,7 @@ public: virtual int send(unsigned char *buf, size_t len) = 0; virtual int recv(unsigned char *buf, size_t buf_len, size_t *read_len) = 0; + virtual int get_id(char **id) = 0; virtual int set_addr_family(vine_address_family_e addr_family) = 0; virtual int set_remote_ip(vine_address_family_e, const std::string &ip) = 0; virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip) = 0; @@ -104,6 +105,7 @@ public: virtual int send(unsigned char *buf, size_t len); virtual int recv(unsigned char *buf, size_t buf_len, size_t *read_len); + virtual int get_id(char **id); virtual int set_addr_family(vine_address_family_e addr_family); virtual int set_remote_ip(vine_address_family_e, const std::string &ip); virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip); @@ -147,6 +149,7 @@ public: virtual int send(unsigned char *buf, size_t len); virtual int recv(unsigned char *buf, size_t buf_len, size_t *read_len); + virtual int get_id(char **id); virtual int set_addr_family(vine_address_family_e addr_family); virtual int set_remote_ip(vine_address_family_e, const std::string &ip); virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip); @@ -200,6 +203,7 @@ public: virtual int send(unsigned char *buf, size_t len); virtual int recv(unsigned char *buf, size_t buf_len, size_t *read_len); + virtual int get_id(char **id); virtual int set_addr_family(vine_address_family_e addr_family); virtual int set_remote_ip(vine_address_family_e, const std::string &ip); virtual int get_remote_ip(vine_address_family_e *addr_family, char **ip); @@ -234,7 +238,7 @@ public: int publish_service(); int subscribe_service(); - void set_id(const char *id) { mId = id; } + void set_id(const char *id); bool check_if_connect(const char *peer_rank, vine_address_family_e ip_type, const char *peer_ip, int peer_port); int get_rank() { return mRank; } @@ -273,6 +277,7 @@ private: int _vine_dp_create(vine_session_h session, vine_dp_type_e type, vine_dp_h *dp); int _vine_dp_destroy(vine_dp_h dp); +int _vine_dp_get_id(vine_dp_h dp, char **id); int _vine_dp_set_iface_name(vine_dp_h dp, const char *iface_name); int _vine_dp_set_addr_family(vine_dp_h dp, vine_address_family_e addr_family); int _vine_dp_set_remote_ip(vine_dp_h dp, vine_address_family_e addr_family, const char *ip); diff --git a/src/vine-dp.cpp b/src/vine-dp.cpp index 3a77b0d..9fe1f4c 100644 --- a/src/vine-dp.cpp +++ b/src/vine-dp.cpp @@ -474,6 +474,11 @@ DPServer::~DPServer() vine_data_path_destroy(mDataPath); } +int DPServer::get_id(char **id) +{ + return VINE_ERROR_INVALID_OPERATION; +} + int DPServer::set_addr_family(vine_address_family_e addr_family) { mAddrFamily = addr_family; @@ -671,6 +676,11 @@ DPClient::~DPClient() vine_data_path_destroy(mDataPath); } +int DPClient::get_id(char **id) +{ + return VINE_ERROR_INVALID_OPERATION; +} + int DPClient::set_addr_family(vine_address_family_e addr_family) { return VINE_ERROR_INVALID_OPERATION; @@ -843,6 +853,21 @@ DPPubSub::~DPPubSub() close(); } +void DPPubSub::set_id(const char *id) +{ + if (id == NULL || mId.compare(id) == 0) + return; + + VINE_LOGD("Id is changed %s -> %s", mId, id); + mId = id; +} + +int DPPubSub::get_id(char **id) +{ + *id = STRDUP(mId.c_str()); + return VINE_ERROR_NONE; +} + int DPPubSub::set_addr_family(vine_address_family_e addr_family) { mAddrFamily = addr_family; @@ -1024,6 +1049,8 @@ int DPPubSub::publish_service() sprintf(rank_str, "%d", mRank); create_id(service_name); + set_id(service_name); + vine_service_set_name(service, service_name); vine_service_add_attribute(service, VINE_DP_PUBSUB_RANK_KEY, (const char *)rank_str); @@ -1357,6 +1384,15 @@ int _vine_dp_destroy(vine_dp_h dp) return VINE_ERROR_NONE; } +int _vine_dp_get_id(vine_dp_h dp, char **id) +{ + RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null."); + RET_VAL_IF(id == NULL, VINE_ERROR_INVALID_PARAMETER, "id is null."); + + DataPath *_dp = static_cast(dp); + return _dp->get_id(id); +} + int _vine_dp_set_iface_name(vine_dp_h dp, const char *iface_name) { RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null."); @@ -1416,6 +1452,7 @@ int _vine_dp_get_remote_port(vine_dp_h dp, int *port) *port = remote_port; return VINE_ERROR_NONE; } + int _vine_dp_get_ip(vine_dp_h dp, vine_address_family_e *addr_family, char **ip) { RET_VAL_IF(dp == NULL, VINE_ERROR_INVALID_PARAMETER, "dp is null."); diff --git a/src/vine.cpp b/src/vine.cpp index bd16968..29fe7b4 100755 --- a/src/vine.cpp +++ b/src/vine.cpp @@ -325,6 +325,14 @@ API int vine_dp_destroy(vine_dp_h dp) return _vine_dp_destroy(dp); } +API int vine_dp_get_id(vine_dp_h dp, char **id) +{ + __VINE_FUNC_ENTER__; + CHECK_FEATURE_SUPPORTED; + + return _vine_dp_get_id(dp, id); +} + API int vine_dp_set_iface_name(vine_dp_h dp, const char *iface_name) { __VINE_FUNC_ENTER__; diff --git a/tests/unittest/vine-unittest-dp.cpp b/tests/unittest/vine-unittest-dp.cpp index c3f23a7..26fcfac 100755 --- a/tests/unittest/vine-unittest-dp.cpp +++ b/tests/unittest/vine-unittest-dp.cpp @@ -110,6 +110,20 @@ TEST_F(VineDpTest, DestroyP) vine_dp_destroy(dp)); } +TEST_F(VineDpTest, GetIdN) +{ + char *id = NULL; + EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, vine_dp_get_id(pubsub_dp, NULL)); + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, vine_dp_get_id(server_dp, &id)); + EXPECT_EQ(VINE_ERROR_INVALID_OPERATION, vine_dp_get_id(client_dp, &id)); +} + +TEST_F(VineDpTest, GetIdP) +{ + char *id = NULL; + EXPECT_EQ(VINE_ERROR_NONE, vine_dp_get_id(pubsub_dp, &id)); +} + TEST_F(VineDpTest, SetRemoteIpN) { EXPECT_EQ(VINE_ERROR_INVALID_PARAMETER, diff --git a/tool/tool_run.cpp b/tool/tool_run.cpp index d1e06fb..3563524 100644 --- a/tool/tool_run.cpp +++ b/tool/tool_run.cpp @@ -97,17 +97,23 @@ static void __opened_cb(vine_dp_h dp, vine_error_e result, void *user_data) return; vine_address_family_e addr_family; + char *id = NULL; char *ip = NULL; int port = 0; - vine_dp_get_port(dp, &port); - printf("\t> %s port: %d\n", - vine_configs.dp_type == VINE_DP_TYPE_CLIENT ? "connected" : "listen", - port); + if (vine_configs.dp_type == VINE_DP_TYPE_PUBSUB) { + vine_dp_get_id(dp, &id); + printf("\t> ID: %s\n", id); + } else { + vine_dp_get_port(dp, &port); + printf("\t> %s port: %d\n", + vine_configs.dp_type == VINE_DP_TYPE_CLIENT ? "connected" : "listen", + port); vine_dp_get_ip(dp, &addr_family, &ip); - printf("\t> local IP: %s, address family: %d \n", ip, addr_family); - free(ip); + printf("\t> local IP: %s, address family: %d \n", ip, addr_family); + free(ip); + } vine_dp_set_received_cb(dp, __received_cb, NULL); vine_dp_set_terminated_cb(dp, __terminated_cb, NULL); -- 2.7.4 From 317ae38b8c4759e173669061d1ea1c5e548accc1 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 2 Jun 2021 11:14:17 +0900 Subject: [PATCH 10/16] bug fix: pass a proper argument to printf() Change-Id: If02199c3b59a4a2a03838f7614f98a6cca082814 --- src/vine-dp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vine-dp.cpp b/src/vine-dp.cpp index 9fe1f4c..e0af7fa 100644 --- a/src/vine-dp.cpp +++ b/src/vine-dp.cpp @@ -858,7 +858,7 @@ void DPPubSub::set_id(const char *id) if (id == NULL || mId.compare(id) == 0) return; - VINE_LOGD("Id is changed %s -> %s", mId, id); + VINE_LOGD("Id is changed %s -> %s", mId.c_str(), id); mId = id; } -- 2.7.4 From 51e46bf06787e4c64707631b78e9c60a3d90f8e2 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 2 Jun 2021 14:37:25 +0900 Subject: [PATCH 11/16] Verifier: send a message in joined callback for pubsub test Change-Id: I78ac15aef4552ed8c8eabf2e8b5c8dc829170677 --- tests/verifier/vine-verifier.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/verifier/vine-verifier.cpp b/tests/verifier/vine-verifier.cpp index 92d2c94..b5fe0bc 100644 --- a/tests/verifier/vine-verifier.cpp +++ b/tests/verifier/vine-verifier.cpp @@ -421,12 +421,10 @@ static void __start_client(bool use_tls, bool use_psk) static void __pubsub_opened_cb(vine_dp_h dp, vine_error_e result, void *user_data) { - if (result == VINE_ERROR_NONE) { + if (result == VINE_ERROR_NONE) printf("Success to open a pub/sub data path\n"); - vine_dp_send(dp, (unsigned char *)PUBSUB_MSG, strlen(PUBSUB_MSG)); - } else { + else PRINT_IF_ERROR(result, "Fail to open the pub/sub data path."); - } } static void __pubsub_received_cb(vine_dp_h dp, size_t received_len, void *user_data) @@ -441,6 +439,17 @@ static void __pubsub_received_cb(vine_dp_h dp, size_t received_len, void *user_d } while (received_len > 0); } +static void __pubsub_peer_joined_cb(vine_dp_h dp, const char *peer_id, void *user_data) +{ + printf("peer[%s] is joiend.\n", peer_id); + vine_dp_send(dp, (unsigned char *)PUBSUB_MSG, strlen(PUBSUB_MSG)); +} + +static void __pubsub_peer_left_cb(vine_dp_h dp, const char *peer_id, void *user_data) +{ + printf("peer[%s] is left.\n", peer_id); +} + static void __start_pubsub(bool use_tls, bool use_psk) { printf("Start pub/sub\n"); @@ -463,6 +472,8 @@ static void __start_pubsub(bool use_tls, bool use_psk) vine_dp_set_security(dp, security); vine_dp_set_topic(dp, TOPIC); vine_dp_set_received_cb(dp, __pubsub_received_cb, NULL); + vine_dp_set_peer_joined_cb(dp, __pubsub_peer_joined_cb, NULL); + vine_dp_set_peer_left_cb(dp, __pubsub_peer_left_cb, NULL); PRINT_RESULT(vine_dp_open(dp, __pubsub_opened_cb, session), "vine_dp_open"); vine_security_destroy(security); } -- 2.7.4 From 988757b04949e7ce68b44de5ac4ada342ef30fa7 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Mon, 7 Jun 2021 16:10:00 +0900 Subject: [PATCH 12/16] Fix epoll() performance issue vine event-loop runs on independent thread. So, It is suitable to make a timeout to -1. https://man7.org/linux/man-pages/man2/epoll_wait.2.html Change-Id: Id4711937baeebe085ae947abc52436d09862692a --- src/vine-event-loop.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vine-event-loop.cpp b/src/vine-event-loop.cpp index f069db0..b4378c5 100644 --- a/src/vine-event-loop.cpp +++ b/src/vine-event-loop.cpp @@ -63,8 +63,7 @@ static void *__vine_event_loop_run(void *arg) VINE_LOGD("Run Vine event loop"); struct epoll_event events[MAX_VINE_EPOLL_EVENTS]; - // TODO: Do we have to use timeout? - int timeout = 0; + int timeout = -1; do { int n = epoll_wait(__vine_epoll_fd, events, MAX_VINE_EPOLL_EVENTS, timeout); -- 2.7.4 From 373f37738b2c53f0608ab7411d763e26982366bc Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 9 Jun 2021 15:27:19 +0900 Subject: [PATCH 13/16] Wake the eventloop up when requesting deinitialize Change-Id: If0145571a4d98caeb29111beb2029ea030ba3ba4 --- src/vine-event-loop.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vine-event-loop.cpp b/src/vine-event-loop.cpp index b4378c5..9c1bbcc 100644 --- a/src/vine-event-loop.cpp +++ b/src/vine-event-loop.cpp @@ -124,10 +124,22 @@ int vine_event_loop_start() return VINE_ERROR_NONE; } +static void _vine_event_loop_wake_up() +{ + uint64_t v = 1; + int fd = eventfd(0, 0); + + VINE_LOGD("fd[%d] to wake the eventloop up"); + vine_event_loop_add_io_handler(fd, VINE_POLLOUT, NULL, NULL); + if (write(fd, &v, sizeof(v)) == -1) + VINE_LOGE("Write error(%d)", errno); +} + void vine_event_loop_stop() { VINE_LOGD("vine_event_loop_stop"); __cleanup = true; + _vine_event_loop_wake_up(); pthread_join(__vine_event_loop_tid, NULL); __vine_event_loop_tid = 0; } -- 2.7.4 From 5464dc81d12b0eb8515c0292de59a078553a80b6 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Mon, 7 Jun 2021 10:09:58 +0900 Subject: [PATCH 14/16] Select proper vhost when connecting with a client [problem] Sometimes, Segfault occurs when pubsub open/close repeatedly for the same port. [cause] libwebsockets doesn't close the vhost and a listen socket immediately eventhough a vine requests it. After then, if the accept event occurs, libwebsockets returns old vhost which has the same listen port from the vhost_list. Change-Id: Ieded5f672b077939a126764b99ef1f052a01461b --- packaging/capi-network-vine.spec | 3 +- plugins/libwebsockets/libwebsockets-plugin.cpp | 88 ++++++++++++++++++++--- src/include/vine-data-path-plugin.h | 2 + src/include/vine-data-path.h | 5 +- src/include/vine-set.h | 92 +++++++++++++++++++++++++ src/vine-data-path.cpp | 34 +++++++-- src/vine-dp.cpp | 19 ++--- tests/vine-test/vine-pubsub-open-close-test.cpp | 10 +-- 8 files changed, 223 insertions(+), 30 deletions(-) create mode 100755 src/include/vine-set.h diff --git a/packaging/capi-network-vine.spec b/packaging/capi-network-vine.spec index 8c245c4..473e4ac 100755 --- a/packaging/capi-network-vine.spec +++ b/packaging/capi-network-vine.spec @@ -2,7 +2,7 @@ %bcond_without lws_static_prebuilt Name: capi-network-vine Summary: An service discovery framework -Version: 1.0.3 +Version: 1.0.5 Release: 0 Group: Network & Connectivity/API License: Apache-2.0 @@ -96,6 +96,7 @@ export LDFLAGS+=" -lgcov" -DUSE_LIBWEBSOCKETS_STATIC_PREBUILT=OFF \ %endif -DWITH_UNITTEST=ON \ + -DENABLE_DATAPATH_PLUGIN_DEBUG=ON \ -DWITH_VINE_TEST=ON make %{?jobs:-j%jobs} diff --git a/plugins/libwebsockets/libwebsockets-plugin.cpp b/plugins/libwebsockets/libwebsockets-plugin.cpp index a16c942..ed0c6fe 100755 --- a/plugins/libwebsockets/libwebsockets-plugin.cpp +++ b/plugins/libwebsockets/libwebsockets-plugin.cpp @@ -16,7 +16,7 @@ */ #include - +#include #include #include #include @@ -32,6 +32,7 @@ #include "vine-log.h" #include "vine-utils.h" #include "vine-queue.h" +#include "vine-set.h" #ifdef ENABLE_DATAPATH_PLUGIN_DEBUG #define DEBUG_LEVEL (LLL_USER | LLL_ERR | LLL_WARN | LLL_DEBUG | LLL_NOTICE | LLL_INFO) @@ -51,10 +52,12 @@ typedef struct { typedef struct { struct lws *wsi; struct lws_vhost *vh; + bool is_server; bool close_requested; int curr_conn; int max_conn; + char *host_name; unsigned char *token; int token_len; @@ -82,6 +85,7 @@ typedef struct { } websocket_op_s; static VineQueue op_queue; +static VineSet listen_vh_list; static int g_ref_count = 0; static pthread_mutex_t g_lws_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -375,6 +379,18 @@ static void _invoke_connected_cb(struct lws *wsi, bool connected, void *user_dat g_callbacks.connected_cb(0, user_data); } +static int __check_vhost(struct lws_vhost *vh) +{ + auto it = listen_vh_list.find(vh); + if (it == listen_vh_list.end()) { + VINE_LOGE("vh[%p] isn't used. port[%d]", + vh, lws_get_vhost_port(vh)); + return 0; + } + + return 1; +} + static int _websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { @@ -466,12 +482,19 @@ static int _websocket_protocol_cb(struct lws *wsi, case LWS_CALLBACK_ESTABLISHED: { VINE_LOGI("Websocket connection is established."); websocket_s *client_ws = (websocket_s *)lws_wsi_user(wsi); + if (!__check_vhost(lws_get_vhost(wsi))) { + VINE_LOGE("Ignore a connection."); + return -1; + } vhd->curr_conn++; if (g_callbacks.accepted_cb) { vine_dp_addr_family_e addr_family; char ip[INET6_ADDRSTRLEN]; int port; _get_peer_network_info(wsi, &addr_family, ip, &port); + VINE_LOGE("vh[%p] wsi[%p] vhd->user[%p] port[%d]", + lws_get_vhost(wsi), + wsi, vhd->user, lws_get_vhost_port(lws_get_vhost(wsi))); g_callbacks.accepted_cb(addr_family, ip, port, client_ws, vhd->user); } break; @@ -498,7 +521,8 @@ static int _websocket_protocol_cb(struct lws *wsi, } if (ws->close_requested) { - VINE_LOGI("Close websocket."); + VINE_LOGI("Close websocket. ws[%p] ws->user[%p] wsi[%p]", + ws, ws->user, wsi); return -1; } @@ -610,6 +634,13 @@ static int websocket_init(void) return VINE_DATA_PATH_ERROR_NONE; } +static void _clear_listen_vhosts(void) +{ + for (auto &vh : listen_vh_list) + lws_vhost_destroy(vh); + listen_vh_list.clear(); +} + static void websocket_deinit(void) { if (__sync_sub_and_fetch(&g_ref_count, 1) > 0) { @@ -626,6 +657,7 @@ static void websocket_deinit(void) it = g_pollfds.erase(it); } + _clear_listen_vhosts(); VINE_LOGD("lws is deinitialized."); } @@ -655,7 +687,13 @@ static long __get_ssl_ctx_options(vine_dp_tls_version_e tls_version) return options; } -static struct lws_vhost *_create_vhost(int addr_family, +static void __vhost_finalized_cb(struct lws_vhost *vh, void *arg) +{ + VINE_LOGE("vh[%p] is finalized", vh); + listen_vh_list.erase(vh); +} + +static struct lws_vhost *_create_vhost(const char *host_name, int addr_family, int port, const char *iface_name, vine_dp_ssl ssl) { struct lws_context_creation_info info; @@ -676,9 +714,9 @@ static struct lws_vhost *_create_vhost(int addr_family, info.ssl_cert_filepath = ssl.cert_path; info.ssl_private_key_filepath = ssl.key_path; info.protocols = protocols; - info.vhost_name = "vine-websocket-server"; + info.vhost_name = host_name ? STRDUP(host_name) : "vine-websocket-server"; info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | LWS_SERVER_OPTION_EXPLICIT_VHOSTS; - + info.finalize = __vhost_finalized_cb; if (addr_family == VINE_DP_IPV4) info.options |= LWS_SERVER_OPTION_DISABLE_IPV6; else if (addr_family == VINE_DP_IPV6) @@ -692,7 +730,7 @@ static void _open_server(websocket_s *ws, int addr_family, int port, const char *iface_name, int max_conn, vine_dp_ssl ssl) { ws->max_conn = max_conn; - ws->vh = _create_vhost(addr_family, port, iface_name, ssl); + ws->vh = _create_vhost(ws->host_name, addr_family, port, iface_name, ssl); if (!ws->vh) { VINE_LOGE("Failed to create vhost."); if (g_callbacks.opened_cb) @@ -700,12 +738,16 @@ static void _open_server(websocket_s *ws, int addr_family, return; } + //listen_vh_list.insert((void *)ws->vh); + listen_vh_list.insert(ws->vh); + void *user_data = lws_protocol_vh_priv_zalloc(ws->vh, protocols, sizeof(websocket_s)); memcpy(user_data, ws, sizeof(websocket_s)); int vport = lws_get_vhost_port(ws->vh); if (g_callbacks.opened_cb) g_callbacks.opened_cb(VINE_DATA_PATH_ERROR_NONE, vport, ws->user); + VINE_LOGD("vh[%p] user[%p] port[%d]", ws->vh, ws->user, vport); } static int websocket_open(vine_dp_plugin_h handle, @@ -714,6 +756,9 @@ static int websocket_open(vine_dp_plugin_h handle, RET_VAL_IF(!handle, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL"); RET_VAL_IF(!g_context, VINE_DATA_PATH_ERROR_INVALID_OPERATION, "g_context is NULL"); + websocket_s *ws = (websocket_s *)handle; + ws->is_server = true; + VINE_LOGD("ws[%p]", ws); if (_add_websocket_op_request(WEBSOCKET_OP_OPEN, (websocket_s *)handle, addr_family, NULL, port, iface_name, max_conn, &ssl) < 0) return VINE_DATA_PATH_ERROR_OPERATION_FAILED; @@ -734,7 +779,7 @@ static void _connect_server(websocket_s *ws, int addr_family, const char *ip, in client_conn_info.address = ip; client_conn_info.iface = iface_name; client_conn_info.path = "/"; - client_conn_info.host = client_conn_info.address; + client_conn_info.host = ws->host_name ? ws->host_name : client_conn_info.address; client_conn_info.origin = client_conn_info.address; client_conn_info.protocol = "vine-websocket-protocol"; @@ -748,7 +793,8 @@ static void _connect_server(websocket_s *ws, int addr_family, const char *ip, in client_conn_info.ssl_connection |= LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK; client_conn_info.userdata = (void *)ws; - client_conn_info.vhost = _create_vhost(addr_family, CONTEXT_PORT_NO_LISTEN, iface_name, ssl); + client_conn_info.vhost = _create_vhost(ws->host_name, + addr_family, CONTEXT_PORT_NO_LISTEN, iface_name, ssl); ws->wsi = lws_client_connect_via_info(&client_conn_info); } @@ -930,6 +976,14 @@ static int websocket_close(vine_dp_plugin_h handle) websocket_s *ws = (websocket_s *)handle; ws->close_requested = true; + if (ws->is_server) { + VINE_LOGE("vh destroy[%p]", ws->vh); + listen_vh_list.erase(ws->vh); + lws_vhost_destroy(ws->vh); + ws->vh = NULL; + return VINE_DATA_PATH_ERROR_NONE; + } + if (ws->wsi) lws_callback_on_writable(ws->wsi); @@ -973,7 +1027,7 @@ static int websocket_create(vine_dp_plugin_h *handle, void *plugin_data, void *u (websocket_s *)plugin_data : (websocket_s *)calloc(1, sizeof(websocket_s)); RET_VAL_IF(ws == NULL, VINE_DATA_PATH_ERROR_OUT_OF_MEMORY, "Out of memory"); - VINE_LOGD("plugin_data[%p]", plugin_data); + VINE_LOGD("ws[%p], user[%p]", ws, user); ws->close_requested = false; ws->curr_conn = 0; @@ -990,12 +1044,15 @@ static int websocket_destroy(vine_dp_plugin_h handle) { RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL"); + VINE_LOGE("ws[%p] is destroyed", handle); websocket_s *ws = (websocket_s *)handle; ws->wsi = NULL; ws->vh = NULL; ws->user = NULL; + free(ws->host_name); + ws->host_name = NULL; free(ws->token); ws->token = NULL; ws->token_len = 0; @@ -1059,6 +1116,18 @@ static int websocket_get_token(vine_dp_plugin_h handle, char **token) return VINE_DATA_PATH_ERROR_NONE; } +static int websocket_set_host_name(vine_dp_plugin_h handle, const char *name) +{ + RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL"); + RET_VAL_IF(name == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "name is NULL"); + + websocket_s *ws = (websocket_s *)handle; + if (ws->host_name) + free(ws->host_name); + ws->host_name = strdup(name); + return VINE_DATA_PATH_ERROR_NONE; +} + void vine_data_path_plugin_init(vine_dp_plugin_fn *fn) { fn->init = websocket_init; @@ -1078,4 +1147,5 @@ void vine_data_path_plugin_init(vine_dp_plugin_fn *fn) fn->set_token = websocket_set_token; fn->get_token = websocket_get_token; + fn->set_host_name = websocket_set_host_name; } diff --git a/src/include/vine-data-path-plugin.h b/src/include/vine-data-path-plugin.h index 3f8a4c9..214d0d8 100755 --- a/src/include/vine-data-path-plugin.h +++ b/src/include/vine-data-path-plugin.h @@ -110,6 +110,8 @@ typedef struct { // DPPubSub uses it to inform own service name to a peer. int (*set_token)(vine_dp_plugin_h handle, const char *token); int (*get_token)(vine_dp_plugin_h handle, char **token); + + int (*set_host_name)(vine_dp_plugin_h handle, const char *name); } vine_dp_plugin_fn; extern "C" void vine_data_path_plugin_init(vine_dp_plugin_fn *fn); diff --git a/src/include/vine-data-path.h b/src/include/vine-data-path.h index 15421ff..f25ed47 100755 --- a/src/include/vine-data-path.h +++ b/src/include/vine-data-path.h @@ -36,14 +36,15 @@ int vine_data_path_init(void); int vine_data_path_deinit(void); int vine_data_path_open(vine_address_family_e addr_family, int port, - const char *iface_name, int max_conn, vine_security_h security, + const char *iface_name, int max_conn, + vine_security_h security, const char *host_name, vine_data_path_opened_cb opened_cb, void *opened_cb_data, vine_data_path_accepted_cb accepted_cb, void *accepted_cb_data, vine_data_path_h *opened_datapath, vine_event_queue_h event_fd); int vine_data_path_connect(vine_address_family_e addr_family, const char *ip, int port, const char *iface_name, - vine_security_h security, const char *token, + vine_security_h security, const char *host_name, const char *token, vine_data_path_connected_cb callback, void *user_data, vine_data_path_h *connected_datapath, vine_event_queue_h event_fd); diff --git a/src/include/vine-set.h b/src/include/vine-set.h new file mode 100755 index 0000000..3be5dcd --- /dev/null +++ b/src/include/vine-set.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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. + * +*/ +#pragma once + +#include +#include +#include + +#include "vine-log.h" + +template +class VineSet +{ +public: + using iterator = typename std::set::iterator; + VineSet() + { + VINE_LOGD("New Set"); + } + virtual ~VineSet() + { + VINE_LOGD("Destroy Set"); + } + + void insert(const T &element) + { + std::lock_guard lock_guard(_s_mutex); + _set.insert(element); + } + + void erase(const T &element) + { + std::lock_guard lock_guard(_s_mutex); + if (_set.empty()) + return; + _set.erase(element); + } + + void clear() + { + std::lock_guard lock_guard(_s_mutex); + _set.clear(); + } + + size_t size() + { + std::lock_guard lock_guard(_s_mutex); + return _set.size(); + } + + bool empty() + { + std::lock_guard lock_guard(_s_mutex); + return _set.empty(); + } + + iterator find(const T &element) + { + std::lock_guard lock_guard(_s_mutex); + return _set.find(element); + } + + iterator begin() + { + std::lock_guard lock_guard(_s_mutex); + return _set.begin(); + } + + iterator end() + { + std::lock_guard lock_guard(_s_mutex); + return _set.end(); + } + +private: + std::set _set; + std::mutex _s_mutex; +}; diff --git a/src/vine-data-path.cpp b/src/vine-data-path.cpp index d20890f..f217c61 100755 --- a/src/vine-data-path.cpp +++ b/src/vine-data-path.cpp @@ -271,6 +271,8 @@ static void __accepted_cb(vine_dp_addr_family_e addr_family, char *addr, RET_IF(user_data == NULL, "listen_dp is NULL"); vine_data_path_s *listen_dp = (vine_data_path_s *)user_data; + + VINE_LOGE("listen_dp[%p], security[%p]", listen_dp, listen_dp->security); vine_data_path_s *connected_dp = _vine_data_path_create(__convert_addr_family(addr_family), addr, port, listen_dp->security, plugin_data, listen_dp->event_fd); RET_IF(connected_dp == NULL, "Out of memory"); @@ -507,14 +509,13 @@ static vine_data_path_s *_vine_data_path_create(vine_address_family_e addr_famil if (ret != VINE_DATA_PATH_ERROR_NONE) { free(dp->addr); _vine_security_destroy(dp->security); + dp->security = NULL; free(dp); return NULL; } dp->state = vine_get_default_state(dp, dp->plugin_handle); - VINE_LOGD("datapath[%p] is created.", dp); - return dp; } @@ -527,9 +528,13 @@ int vine_data_path_destroy(vine_data_path_h datapath) dp->plugin_handle = NULL; free(dp->addr); dp->addr = NULL; + _vine_security_destroy(dp->security); + dp->security = NULL; + dp->listen_dp = NULL; delete dp->state; - free(datapath); + VINE_LOGD("data_path[%p] is destroyed", datapath); + free(datapath); return VINE_ERROR_NONE; } @@ -667,7 +672,7 @@ static void _destroy_security_info(vine_dp_ssl *dest) } int vine_data_path_open(vine_address_family_e addr_family, int port, const char *iface_name, - int max_conn, vine_security_h security, + int max_conn, vine_security_h security, const char *host_name, vine_data_path_opened_cb opened_cb, void *opened_cb_data, vine_data_path_accepted_cb accepted_cb, void *accepted_cb_data, vine_data_path_h *opened_datapath, @@ -692,6 +697,15 @@ int vine_data_path_open(vine_address_family_e addr_family, int port, const char dp->accepted_cb = accepted_cb; dp->accepted_cb_data = accepted_cb_data; + // optional + if (host_name) { + ret = g_dp_plugin_fn.set_host_name(dp->plugin_handle, host_name); + if (ret != VINE_DATA_PATH_ERROR_NONE) { + vine_data_path_destroy(dp); + return __convert_data_path_error_to_vine_error((vine_data_path_error)ret); + } + } + ret = g_dp_plugin_fn.open(dp->plugin_handle, dp_addr_family, port, iface_name, max_conn, ssl); _destroy_security_info(&ssl); @@ -711,7 +725,7 @@ int vine_data_path_open(vine_address_family_e addr_family, int port, const char int vine_data_path_connect(vine_address_family_e addr_family, const char *ip, int port, const char *iface_name, - vine_security_h security, const char *token, + vine_security_h security, const char *host_name, const char *token, vine_data_path_connected_cb callback, void *user_data, vine_data_path_h *connected_datapath, vine_event_queue_h event_fd) { @@ -728,6 +742,16 @@ int vine_data_path_connect(vine_address_family_e addr_family, _extract_security_info(security, &ssl); int ret; + + // optional + if (host_name) { + ret = g_dp_plugin_fn.set_host_name(dp->plugin_handle, host_name); + if (ret != VINE_DATA_PATH_ERROR_NONE) { + vine_data_path_destroy(dp); + return __convert_data_path_error_to_vine_error((vine_data_path_error)ret); + } + } + if (token) { ret = g_dp_plugin_fn.set_token(dp->plugin_handle, token); if (ret != VINE_DATA_PATH_ERROR_NONE) { diff --git a/src/vine-dp.cpp b/src/vine-dp.cpp index e0af7fa..1349b7c 100644 --- a/src/vine-dp.cpp +++ b/src/vine-dp.cpp @@ -601,7 +601,7 @@ int DPServer::open(vine_dp_opened_cb callback, void *user_data) int ret = vine_data_path_open(mAddrFamily, mListenPort, mIfaceName.size() > 0 ? mIfaceName.c_str() : NULL, - mMaxConnNum, mSecurity, + mMaxConnNum, mSecurity, NULL, _opened_cb, static_cast(this), _accepted_cb, static_cast(this), &mDataPath, mEventFd); @@ -791,7 +791,7 @@ int DPClient::open(vine_dp_opened_cb callback, void *user_data) int ret = vine_data_path_connect(mAddrFamily, mPeerIp.c_str(), mPeerPort, mIfaceName.size() > 0 ? mIfaceName.c_str() : NULL, - mSecurity, NULL, + mSecurity, NULL, NULL, _connected_cb, static_cast(this), &mDataPath, mEventFd); if (ret != VINE_ERROR_NONE) mOpenState = VINE_DP_OPEN_STATE_NONE; @@ -1004,7 +1004,7 @@ int DPPubSub::connect(const char *service_name, const char *ip, int port) conn_data->service_name = STRDUP(service_name); int ret = vine_data_path_connect(mAddrFamily, ip, port, iface_name, - mSecurity, mId.c_str(), + mSecurity, service_name, mId.c_str(), _pubsub_connected_cb, (void *)conn_data, &datapath, mEventFd); return ret; @@ -1023,6 +1023,7 @@ void DPPubSub::create_id(char id[]) const size_t map_len = strlen(map); string rand_str; + srand(time(NULL)); generate_n(back_inserter(rand_str), 6, [&](){ return map[rand() % map_len]; @@ -1036,7 +1037,6 @@ int DPPubSub::publish_service() vine_service_h service; int ret; char rank_str[VINE_DP_PUBSUB_RANK_LEN] = {0 , }; - char service_name[VINE_MAX_SERVICE_NAME_LEN + 1] = {0 , }; ret = vine_service_create(&service); if (ret != VINE_ERROR_NONE) @@ -1048,10 +1048,7 @@ int DPPubSub::publish_service() mRank = create_rank(); sprintf(rank_str, "%d", mRank); - create_id(service_name); - set_id(service_name); - - vine_service_set_name(service, service_name); + vine_service_set_name(service, mId.c_str()); vine_service_add_attribute(service, VINE_DP_PUBSUB_RANK_KEY, (const char *)rank_str); if (mSdPub == NULL) { @@ -1112,9 +1109,13 @@ int DPPubSub::open(vine_dp_opened_cb callback, void *user_data) mOpenedCb = callback; mOpenedCbData = user_data; + char service_name[VINE_MAX_SERVICE_NAME_LEN + 1] = {0 , }; + create_id(service_name); + set_id(service_name); + int ret = vine_data_path_open(mAddrFamily, mListenPort, mIfaceName.size() > 0 ? mIfaceName.c_str() : NULL, - mMaxConnNum, mSecurity, + mMaxConnNum, mSecurity, mId.c_str(), _pubsub_opened_cb, static_cast(this), _pubsub_accepted_cb, static_cast(this), &mServerDataPath, mEventFd); diff --git a/tests/vine-test/vine-pubsub-open-close-test.cpp b/tests/vine-test/vine-pubsub-open-close-test.cpp index fcc2ab0..17b6336 100644 --- a/tests/vine-test/vine-pubsub-open-close-test.cpp +++ b/tests/vine-test/vine-pubsub-open-close-test.cpp @@ -18,7 +18,7 @@ * Test: vine-pubsub-open-close-test * Description: * a PubSub DP opens and closes repeatedly in one session. - * The interval is 100ms. (DP_LIFETIME) + * The interval is 500ms. (DP_LIFETIME) */ #include @@ -34,7 +34,7 @@ #define MAX_EVENTS 50 #define DEFAULT_REPETITION_TIME 100 -#define DP_LIFETIME 100000000 // nanoseconds +#define DP_LIFETIME 500000000 // nanoseconds #define TOPIC "pubsub-test" static int epollfd = 0; @@ -206,8 +206,10 @@ static void open_dp(vine_session_h session) PRINT_IF_ERROR(vine_dp_open(dp, [](vine_dp_h dp, vine_error_e result, void *user_data) { if (result != VINE_ERROR_NONE) - return; - PRINT_LOG("dp[%p] is opened.", dp); + return; + int port = 0; + vine_dp_get_port(dp, &port); + PRINT_LOG("dp[%p] is opened. port[%d]", dp, port); _start_timer(dp, DP_LIFETIME); }, NULL), "vine_dp_open"); } -- 2.7.4 From d3b6cbad1d34aa4171b85ce1c954bb39acabf7e3 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 16 Jun 2021 20:30:40 +0900 Subject: [PATCH 15/16] unittest: fix a crash issue Change-Id: Ifa02a44987f082e3ca9577c11c87f244c91d6d6b --- .../unittest/mocks/vine-mock-data-path-plugin.cpp | 39 ++++++++++++++++++++++ tests/unittest/vine-unittest-capabilities.cpp | 2 ++ 2 files changed, 41 insertions(+) diff --git a/tests/unittest/mocks/vine-mock-data-path-plugin.cpp b/tests/unittest/mocks/vine-mock-data-path-plugin.cpp index db13024..f43b3a8 100644 --- a/tests/unittest/mocks/vine-mock-data-path-plugin.cpp +++ b/tests/unittest/mocks/vine-mock-data-path-plugin.cpp @@ -88,6 +88,39 @@ static int __mock_data_path_plugin_close(vine_dp_plugin_h handle) return VINE_DATA_PATH_ERROR_NONE; } +static int __mock_data_path_plugin_get_local_addr(vine_dp_plugin_h handle, + int *addr_family, char local_ip[], int *port) +{ + if (!handle || !addr_family || !local_ip || !port) + return VINE_DATA_PATH_ERROR_INVALID_PARAMETER; + + return VINE_DATA_PATH_ERROR_NONE; +} + +static int __mock_data_path_plugin_set_token(vine_dp_plugin_h handle, const char *token) +{ + if (!handle || !token) + return VINE_DATA_PATH_ERROR_INVALID_PARAMETER; + + return VINE_DATA_PATH_ERROR_NONE; +} + +static int __mock_data_path_plugin_get_token(vine_dp_plugin_h handle, char **token) +{ + if (!handle || !token) + return VINE_DATA_PATH_ERROR_INVALID_PARAMETER; + + return VINE_DATA_PATH_ERROR_NONE; +} + +static int __mock_data_path_plugin_set_host_name(vine_dp_plugin_h handle, const char *name) +{ + if (!handle || !name) + return VINE_DATA_PATH_ERROR_INVALID_PARAMETER; + + return VINE_DATA_PATH_ERROR_NONE; +} + static void __mock_data_path_plugin_process_event(int fd, int events) { return; @@ -147,4 +180,10 @@ void __mock_vine_data_path_plugin_init(vine_dp_plugin_fn *fn) fn->read = __mock_data_path_plugin_read; fn->write = __mock_data_path_plugin_write; fn->close = __mock_data_path_plugin_close; + + fn->get_local_address_info = __mock_data_path_plugin_get_local_addr; + + fn->set_token = __mock_data_path_plugin_set_token; + fn->get_token = __mock_data_path_plugin_get_token; + fn->set_host_name = __mock_data_path_plugin_set_host_name; } diff --git a/tests/unittest/vine-unittest-capabilities.cpp b/tests/unittest/vine-unittest-capabilities.cpp index b62ba8f..1cc6d6b 100755 --- a/tests/unittest/vine-unittest-capabilities.cpp +++ b/tests/unittest/vine-unittest-capabilities.cpp @@ -24,11 +24,13 @@ class VineCapaTest : public ::testing::Test { protected: void SetUp() override { + vine_mock_set_memory_result(true); vine_initialize(); } void TearDown() override { + vine_mock_set_memory_result(true); vine_deinitialize(); } }; -- 2.7.4 From c3ebc04b0e8db79f2fba58bad577998501c15598 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 16 Jun 2021 20:34:58 +0900 Subject: [PATCH 16/16] Resolve IP based on address family Change-Id: I3e4ea81420ac2430f724a6b41af31f95a00e39d7 --- include/vine.h | 6 +- packaging/capi-network-vine.spec | 2 +- plugins/dns-sd/dns-sd-plugin.cpp | 21 +++++-- src/include/vine-disc-plugin.h | 8 ++- src/include/vine-service.h | 3 + src/include/vine-session.h | 3 +- src/vine-disc.cpp | 3 +- src/vine-event-loop.cpp | 2 +- src/vine-service.cpp | 18 ++++++ src/vine-session.cpp | 4 +- src/vine.cpp | 6 +- tests/unittest/mocks/vine-mock-dns-sd.cpp | 2 +- tests/verifier/vine-verifier.cpp | 2 +- tests/vine-test/vine-test.cpp | 3 +- tool/tool_run.cpp | 91 ++++++++++++++++--------------- 15 files changed, 113 insertions(+), 61 deletions(-) diff --git a/include/vine.h b/include/vine.h index 4972a6a..97cfa95 100755 --- a/include/vine.h +++ b/include/vine.h @@ -548,7 +548,7 @@ int vine_session_stop_discovery(vine_session_h session); * @since_tizen 6.5 * @param[in] service The service * @param[in] ip The IP address - * @param[in] address_family The address familye + * @param[in] address_family The address family * @param[in] user_data The user data passed from the callback registration function * @see vine_service_resolve_ip() */ @@ -562,6 +562,7 @@ typedef void(*vine_session_ip_resolved_cb)(vine_session_h session, vine_service_ * @since_tizen 6.5 * @param[in] session The session handle * @param[in] service The service handle + * @param[in] address_family The address family * @param[in] callback The resolved callback * @param[in] user_data The user data * @return 0 on success, otherwise a negative error value @@ -570,7 +571,8 @@ typedef void(*vine_session_ip_resolved_cb)(vine_session_h session, vine_service_ * @retval #VINE_ERROR_NOT_SUPPORTED Not supported */ int vine_session_set_ip_resolved_cb(vine_session_h session, - vine_service_h service, vine_session_ip_resolved_cb callback, void *user_data); + vine_service_h service, vine_address_family_e address_family, + vine_session_ip_resolved_cb callback, void *user_data); /** * @brief Stop resolving IP addresses for @a service. diff --git a/packaging/capi-network-vine.spec b/packaging/capi-network-vine.spec index 473e4ac..b6385f6 100755 --- a/packaging/capi-network-vine.spec +++ b/packaging/capi-network-vine.spec @@ -2,7 +2,7 @@ %bcond_without lws_static_prebuilt Name: capi-network-vine Summary: An service discovery framework -Version: 1.0.5 +Version: 1.0.6 Release: 0 Group: Network & Connectivity/API License: Apache-2.0 diff --git a/plugins/dns-sd/dns-sd-plugin.cpp b/plugins/dns-sd/dns-sd-plugin.cpp index f0c9e66..f741843 100755 --- a/plugins/dns-sd/dns-sd-plugin.cpp +++ b/plugins/dns-sd/dns-sd-plugin.cpp @@ -310,9 +310,22 @@ static void __get_addr_info_reply(DNSServiceRef sdRef, ip, address_family, dns_sd_handle->user_data); } +static DNSServiceProtocol get_protocol(int family) +{ + switch (family) { + case VINE_DISC_ADDR_FAMILY_IPV4: + return kDNSServiceProtocol_IPv4; + case VINE_DISC_ADDR_FAMILY_IPV6: + return kDNSServiceProtocol_IPv6; + case VINE_DISC_ADDR_FAMILY_DEFAULT: + default: + return (kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6); + } +} + vine_disc_error dns_sd_resolve_ip(void *plugin_handle, const char *service_type, const char *service_name, - const char *host_name, const char *iface_name) + const char *host_name, const char *iface_name, int family) { RET_VAL_IF(!plugin_handle, VINE_DISC_ERROR_INVALID_PARAMETER, "plugin_handle is NULL"); RET_VAL_IF(!service_type, VINE_DISC_ERROR_INVALID_PARAMETER, "service_type is NULL"); @@ -320,17 +333,17 @@ vine_disc_error dns_sd_resolve_ip(void *plugin_handle, RET_VAL_IF(!host_name, VINE_DISC_ERROR_INVALID_PARAMETER, "host_name is NULL"); VINE_LOGD("Start to resolve IP. plugin_handle[%p]\n", plugin_handle); - VINE_LOGD("type[%s] name[%s] host[%s] iface[%s]", - service_type, service_name, host_name, iface_name); + VINE_LOGD("type[%s] name[%s] host[%s] iface[%s] address family[%d]", + service_type, service_name, host_name, iface_name, family); vine_dns_sd_s *dns_sd_handle = (vine_dns_sd_s *)plugin_handle; DNSServiceRef service_ref; DNSServiceFlags flags = 0; + DNSServiceProtocol protocol = get_protocol(family); unsigned int if_index = kDNSServiceInterfaceIndexAny; vine_disc_error ret = get_if_index(iface_name, &if_index); RET_VAL_IF(ret != VINE_DISC_ERROR_NONE, ret, "get_if_index"); - DNSServiceProtocol protocol = kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6; DNSServiceErrorType err = DNSServiceGetAddrInfo(&service_ref, flags, if_index, protocol, host_name, __get_addr_info_reply, dns_sd_handle); diff --git a/src/include/vine-disc-plugin.h b/src/include/vine-disc-plugin.h index 3dcbd20..932e10c 100755 --- a/src/include/vine-disc-plugin.h +++ b/src/include/vine-disc-plugin.h @@ -40,6 +40,12 @@ typedef enum { VINE_DISC_SERVICE_UNAVAILABLE, } vine_disc_service_state; +typedef enum { + VINE_DISC_ADDR_FAMILY_DEFAULT = 0, + VINE_DISC_ADDR_FAMILY_IPV4, + VINE_DISC_ADDR_FAMILY_IPV6 +} vine_disc_addr_family; + typedef struct { void (*published_cb)(void *plugin_handle, const char *service_name, vine_disc_error error, void *disc_handle); @@ -66,7 +72,7 @@ typedef struct { vine_disc_error (*stop_subscribe)(void *plugin_handle); vine_disc_error (*resolve_ip)(void *plugin_handle, const char *service_type, const char *service_name, - const char *host_name, const char *iface_name); + const char *host_name, const char *iface_name, int family); vine_disc_error (*cancel_resolve_ip)(void *plugin_handle); vine_disc_error (*process_event)(void *plugin_handle, int fd); diff --git a/src/include/vine-service.h b/src/include/vine-service.h index 86fc28e..302a491 100755 --- a/src/include/vine-service.h +++ b/src/include/vine-service.h @@ -39,6 +39,9 @@ const char *_vine_service_get_name(vine_service_h service); int _vine_service_set_host_name(vine_service_h service, const char *host_name); const char *_vine_service_get_host_name(vine_service_h service); +int _vine_service_set_address_family(vine_service_h service, vine_address_family_e address_family); +vine_address_family_e _vine_service_get_address_family(vine_service_h service); + int _vine_service_add_attribute(vine_service_h service, const char *key, const char *value); int _vine_service_remove_attribute(vine_service_h service, const char *key); diff --git a/src/include/vine-session.h b/src/include/vine-session.h index 0ebe6f0..371e2cb 100755 --- a/src/include/vine-session.h +++ b/src/include/vine-session.h @@ -45,7 +45,8 @@ int _vine_session_start_discovery(vine_session_h session, const char *service_type, const char *iface_name); int _vine_session_stop_discovery(vine_session_h session); int _vine_session_set_ip_resolved_cb(vine_session_h session, - vine_service_h service, vine_session_ip_resolved_cb callback, void *user_data); + vine_service_h service, vine_address_family_e address_family, + vine_session_ip_resolved_cb callback, void *user_data); int _vine_session_unset_ip_resolved_cb(vine_session_h session, vine_service_h service); diff --git a/src/vine-disc.cpp b/src/vine-disc.cpp index 60dc8d5..4f13669 100755 --- a/src/vine-disc.cpp +++ b/src/vine-disc.cpp @@ -629,7 +629,8 @@ vine_error_e __vine_disc_plugin_resolve_ip(vine_disc_h disc, vine_service_h serv } error = disc_handle->plugin_fn->resolve_ip(plugin_handle, _vine_service_get_type(service), _vine_service_get_name(service), - _vine_service_get_host_name(service), _vine_service_get_iface_name(service)); + _vine_service_get_host_name(service), _vine_service_get_iface_name(service), + (int)_vine_service_get_address_family(service)); if (error != VINE_DISC_ERROR_NONE) { VINE_LOGE("Fail to resolve ip %d", error); disc_handle->plugin_fn->deinit(plugin_handle); diff --git a/src/vine-event-loop.cpp b/src/vine-event-loop.cpp index 9c1bbcc..9b40295 100644 --- a/src/vine-event-loop.cpp +++ b/src/vine-event-loop.cpp @@ -129,7 +129,7 @@ static void _vine_event_loop_wake_up() uint64_t v = 1; int fd = eventfd(0, 0); - VINE_LOGD("fd[%d] to wake the eventloop up"); + VINE_LOGD("fd[%d] to wake the eventloop up", fd); vine_event_loop_add_io_handler(fd, VINE_POLLOUT, NULL, NULL); if (write(fd, &v, sizeof(v)) == -1) VINE_LOGE("Write error(%d)", errno); diff --git a/src/vine-service.cpp b/src/vine-service.cpp index 095af9f..7fa39ce 100755 --- a/src/vine-service.cpp +++ b/src/vine-service.cpp @@ -80,6 +80,7 @@ int _vine_service_create(vine_service_h *service, bool published) memset(s->iface_name, 0, IF_NAMESIZE + 1); s->port = -1; s->state = VINE_SERVICE_UNAVAILABLE; + s->family = VINE_ADDRESS_FAMILY_DEFAULT; s->disc_handle = NULL; s->ip_resolving_session = NULL; @@ -194,6 +195,23 @@ const char *_vine_service_get_host_name(vine_service_h service) return s->host_name; } +int _vine_service_set_address_family(vine_service_h service, vine_address_family_e address_family) +{ + RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL"); + + vine_service_s *s = (vine_service_s *)service; + s->family = address_family; + return VINE_ERROR_NONE; +} + +vine_address_family_e _vine_service_get_address_family(vine_service_h service) +{ + RET_VAL_IF(service == NULL, VINE_ADDRESS_FAMILY_DEFAULT, "service is NULL"); + + vine_service_s *s = (vine_service_s *)service; + return s->family; +} + static bool __check_len_key(const char *key) { RET_VAL_IF(key == NULL, false, "key is NULL"); diff --git a/src/vine-session.cpp b/src/vine-session.cpp index a42933a..14220a9 100755 --- a/src/vine-session.cpp +++ b/src/vine-session.cpp @@ -382,7 +382,8 @@ static void __ip_resolved_cb(vine_disc_h disc, vine_service_h service, bool add, } int _vine_session_set_ip_resolved_cb(vine_session_h session, - vine_service_h service, vine_session_ip_resolved_cb callback, void *user_data) + vine_service_h service, vine_address_family_e address_family, + vine_session_ip_resolved_cb callback, void *user_data) { RET_VAL_IF(session == NULL, VINE_ERROR_INVALID_PARAMETER, "session is NULL"); RET_VAL_IF(service == NULL, VINE_ERROR_INVALID_PARAMETER, "service is NULL"); @@ -399,6 +400,7 @@ int _vine_session_set_ip_resolved_cb(vine_session_h session, ret = _vine_service_set_disc_handle(service, disc_handle); RET_VAL_IF(ret != VINE_ERROR_NONE, ret, "Fail to set disc_handle"); + _vine_service_set_address_family(service, address_family); _vine_service_set_ip_resolved_cb(service, session, callback, user_data); ret = vine_disc_resolve_ip(disc_handle, service, diff --git a/src/vine.cpp b/src/vine.cpp index 29fe7b4..9c72307 100755 --- a/src/vine.cpp +++ b/src/vine.cpp @@ -161,12 +161,14 @@ API int vine_session_stop_discovery(vine_session_h session) } API int vine_session_set_ip_resolved_cb(vine_session_h session, - vine_service_h service, vine_session_ip_resolved_cb callback, void *user_data) + vine_service_h service, vine_address_family_e address_family, + vine_session_ip_resolved_cb callback, void *user_data) { __VINE_FUNC_ENTER__; CHECK_FEATURE_SUPPORTED; - return _vine_session_set_ip_resolved_cb(session, service, callback, user_data); + return _vine_session_set_ip_resolved_cb(session, service, + address_family, callback, user_data); } API int vine_session_unset_ip_resolved_cb(vine_session_h session, diff --git a/tests/unittest/mocks/vine-mock-dns-sd.cpp b/tests/unittest/mocks/vine-mock-dns-sd.cpp index 1aa8af1..c574d79 100644 --- a/tests/unittest/mocks/vine-mock-dns-sd.cpp +++ b/tests/unittest/mocks/vine-mock-dns-sd.cpp @@ -74,7 +74,7 @@ vine_disc_error __mock_disc_plugin_stop_subscribe(void *plugin_handle) vine_disc_error __mock_disc_plugin_resolve_ip(void *plugin_handle, const char *service_type, const char *service_name, - const char *host_name, const char *iface_name) + const char *host_name, const char *iface_name, int family) { return VINE_DISC_ERROR_NONE; } diff --git a/tests/verifier/vine-verifier.cpp b/tests/verifier/vine-verifier.cpp index b5fe0bc..60be8be 100644 --- a/tests/verifier/vine-verifier.cpp +++ b/tests/verifier/vine-verifier.cpp @@ -390,7 +390,7 @@ static void __discovered_cb(vine_session_h session, vine_service_h service, vine_service_h s; ret = vine_service_clone(service, &s); PRINT_IF_ERROR(ret, "vine_service_clone"); - ret = vine_session_set_ip_resolved_cb(session, s, __ip_resolved_cb, user_data); + ret = vine_session_set_ip_resolved_cb(session, s, VINE_ADDRESS_FAMILY_DEFAULT, __ip_resolved_cb, user_data); PRINT_IF_ERROR(ret, "vine_session_set_ip_resolved_cb"); } diff --git a/tests/vine-test/vine-test.cpp b/tests/vine-test/vine-test.cpp index b954140..1319481 100644 --- a/tests/vine-test/vine-test.cpp +++ b/tests/vine-test/vine-test.cpp @@ -422,7 +422,8 @@ static vine_service_h __get_service() static void __resolve_ip() { CHECK_SESSION; - int ret = vine_session_set_ip_resolved_cb(g_session, __get_service(), __ip_resolved_cb, NULL); + int ret = vine_session_set_ip_resolved_cb(g_session, __get_service(), + VINE_ADDRESS_FAMILY_DEFAULT,__ip_resolved_cb, NULL); PRINT_IF_ERROR(ret, "vine_session_set_ip_resolved_cb"); } diff --git a/tool/tool_run.cpp b/tool/tool_run.cpp index 3563524..82fa950 100644 --- a/tool/tool_run.cpp +++ b/tool/tool_run.cpp @@ -64,6 +64,50 @@ static std::map timerfds; static int send_message(vine_dp_h dp); static void _stop_message_timer(vine_dp_h dp); +static vine_dp_type_e _convert_dp_type(dp_type_t type) +{ + switch (type) { + case DP_TYPE_CLIENT: + return VINE_DP_TYPE_CLIENT; + case DP_TYPE_SERVER: + return VINE_DP_TYPE_SERVER; + case DP_TYPE_PUBSUB: + return VINE_DP_TYPE_PUBSUB; + case DP_TYPE_UNKNOWN: + default: + return VINE_DP_TYPE_UNKNOWN; + } +} + +static vine_security_type_e _convert_sec_type(sec_type_t type) +{ + switch (type) { + case SEC_TYPE_NONE: + return VINE_SECURITY_TYPE_NONE; + case SEC_TYPE_TLS: + return VINE_SECURITY_TYPE_TLS; + case SEC_TYPE_PSK_OVER_TLS: + return VINE_SECURITY_TYPE_PSK_OVER_TLS; + default: + return VINE_SECURITY_TYPE_NONE; + } +} + +static vine_address_family_e _convert_addr_family(int family) +{ + switch (family) { + case 0: + return VINE_ADDRESS_FAMILY_DEFAULT; + case 4: + return VINE_ADDRESS_FAMILY_IPV4; + case 6: + return VINE_ADDRESS_FAMILY_IPV6; + default: + return VINE_ADDRESS_FAMILY_DEFAULT; + } +} + + static void __print_received_data(unsigned char *buf, size_t len) { for (int i = 0; i < (int)len; i++) @@ -204,50 +248,9 @@ static void __discovered_cb(vine_session_h session, vine_service_h service, printf("available[%d]\n", state); vine_service_h s; vine_service_clone(service, &s); - vine_session_set_ip_resolved_cb(session, s, __ip_resolved_cb, NULL); -} - -static vine_dp_type_e _convert_dp_type(dp_type_t type) -{ - switch (type) { - case DP_TYPE_CLIENT: - return VINE_DP_TYPE_CLIENT; - case DP_TYPE_SERVER: - return VINE_DP_TYPE_SERVER; - case DP_TYPE_PUBSUB: - return VINE_DP_TYPE_PUBSUB; - case DP_TYPE_UNKNOWN: - default: - return VINE_DP_TYPE_UNKNOWN; - } -} - -static vine_security_type_e _convert_sec_type(sec_type_t type) -{ - switch (type) { - case SEC_TYPE_NONE: - return VINE_SECURITY_TYPE_NONE; - case SEC_TYPE_TLS: - return VINE_SECURITY_TYPE_TLS; - case SEC_TYPE_PSK_OVER_TLS: - return VINE_SECURITY_TYPE_PSK_OVER_TLS; - default: - return VINE_SECURITY_TYPE_NONE; - } -} - -static vine_address_family_e _convert_addr_family(int family) -{ - switch (family) { - case 0: - return VINE_ADDRESS_FAMILY_DEFAULT; - case 4: - return VINE_ADDRESS_FAMILY_IPV4; - case 6: - return VINE_ADDRESS_FAMILY_IPV6; - default: - return VINE_ADDRESS_FAMILY_DEFAULT; - } + vine_session_set_ip_resolved_cb(session, s, + _convert_addr_family(tool_config_get_address_family()), + __ip_resolved_cb, NULL); } static void _start_message_timer(vine_dp_h dp, int sec) -- 2.7.4