diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index b6a1d2c..e6993d3 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(tfe src/acceptor_scm.cpp src/ssl_stream.cpp src/key_keeper.cpp +add_executable(tfe src/acceptor_kni_v1.cpp src/acceptor_kni_v2.cpp src/ssl_stream.cpp src/key_keeper.cpp src/ssl_sess_cache.cpp src/ssl_sess_ticket.cpp src/ssl_service_cache.cpp src/ssl_trusted_cert_storage.cpp src/ev_root_ca_metadata.cpp src/ssl_utils.cpp src/tcp_stream.cpp src/main.cpp src/proxy.cpp) diff --git a/platform/include/internal/acceptor_kni_v1.h b/platform/include/internal/acceptor_kni_v1.h new file mode 100644 index 0000000..1f46081 --- /dev/null +++ b/platform/include/internal/acceptor_kni_v1.h @@ -0,0 +1,7 @@ +#pragma once + +struct tfe_proxy; +struct acceptor_kni_v1; + +struct acceptor_kni_v1 * acceptor_kni_v1_create(struct tfe_proxy * proxy, const char * profile, void * logger); +void acceptor_kni_v1_destroy(struct acceptor_kni_v1 * ctx); diff --git a/platform/include/internal/acceptor_kni_v2.h b/platform/include/internal/acceptor_kni_v2.h new file mode 100644 index 0000000..3bd1be6 --- /dev/null +++ b/platform/include/internal/acceptor_kni_v2.h @@ -0,0 +1,7 @@ +#pragma once + +struct tfe_proxy; +struct acceptor_kni_v2; + +struct acceptor_kni_v2 * acceptor_kni_v2_create(struct tfe_proxy * proxy, const char * profile, void * logger); +void acceptor_kni_v2_destroy(struct acceptor_kni_v2 * ctx); diff --git a/platform/include/internal/acceptor_scm.h b/platform/include/internal/acceptor_scm.h deleted file mode 100644 index 266d18a..0000000 --- a/platform/include/internal/acceptor_scm.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -struct tfe_proxy; -struct acceptor_scm; - -struct acceptor_scm * acceptor_scm_create(struct tfe_proxy * proxy, const char * profile, void * logger); -void acceptor_scm_deinit(struct acceptor_scm * ctx); diff --git a/platform/include/internal/proxy.h b/platform/include/internal/proxy.h index 4b06ddc..c3db0f9 100644 --- a/platform/include/internal/proxy.h +++ b/platform/include/internal/proxy.h @@ -6,7 +6,7 @@ struct ssl_mgr; struct key_keeper; -struct acceptor_scm; +struct acceptor_kni_v2; enum TFE_STAT_FIELD { @@ -93,7 +93,12 @@ struct tfe_proxy struct ssl_mgr * ssl_mgr_handler; struct ssl_policy_enforcer* ssl_ply_enforcer; struct key_keeper * key_keeper_handler; - struct acceptor_scm * kni_acceptor_handler; + + unsigned int en_kni_v1_acceptor; + unsigned int en_kni_v2_acceptor; + + struct acceptor_kni_v1 * kni_v1_acceptor; + struct acceptor_kni_v2 * kni_v2_acceptor; /* DEBUG OPTIONS */ unsigned int tcp_all_passthrough; diff --git a/platform/src/acceptor_scm.cpp b/platform/src/acceptor_scm.cpp deleted file mode 100644 index 0a3cb5f..0000000 --- a/platform/src/acceptor_scm.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -# - -#ifndef TFE_CONFIG_SCM_SOCKET_FILE -#define TFE_CONFIG_SCM_SOCKET_FILE "/var/run/.tfe_kmod_scm_socket" -#endif - -struct acceptor_scm -{ - /* INPUT */ - struct tfe_proxy * proxy; - const char * profile; - void * logger; - - /* CONFIG */ - char str_scm_socket[TFE_STRING_MAX]; - - /* PERSIST RUNTIME RESOURCE */ - int fd_scm_socket; - struct event_base * ev_base; - struct event * ev_scm_socket; - pthread_t thread; -}; - -void acceptor_scm_event(evutil_socket_t fd, short what, void * user) -{ - struct acceptor_scm * __ctx = (struct acceptor_scm *) user; - struct cmsghdr * __cmsghdr; - struct tfe_proxy_accept_para __accept_para{}; - struct tfe_cmsg * cmsg = NULL; - - int * __fds = NULL; - assert(__ctx != NULL && __ctx->thread == pthread_self()); - assert(what & EV_READ); - - /* We use IOVEC to recieve the fds make by KNI. - * This is a kind of magic skill to share socket fds between two(or more) process. - * http://man7.org/tlpi/code/online/dist/sockets/scm_rights_send.c.html - */ - - constexpr static int __TRANS_FDS_MAX = 2; - constexpr static int __CONTROLLEN = CMSG_SPACE(__TRANS_FDS_MAX * sizeof(int)); - - char __buffer[4096] = {0}; - struct iovec __iovec[1]; - struct msghdr __msghdr; - - char __cmptr[__CONTROLLEN]; - - __iovec[0].iov_base = __buffer; - __iovec[0].iov_len = sizeof(__buffer); - - __msghdr.msg_iov = __iovec; - __msghdr.msg_iovlen = 1; - __msghdr.msg_name = NULL; - __msghdr.msg_namelen = 0; - __msghdr.msg_control = (void *) (__cmptr); - __msghdr.msg_controllen = (size_t) __CONTROLLEN; - - ssize_t rd = recvmsg(fd, &__msghdr, 0); - if (rd == -1 && (errno == EINTR || errno == EAGAIN)) - { - return; - } - else if (rd <= 0) - { - TFE_LOG_ERROR(__ctx->logger, "failed at recvmsg from scm socket: %s. ", strerror(errno)); - goto __die; - } - - __cmsghdr = CMSG_FIRSTHDR(&__msghdr); - if (unlikely(__cmsghdr == NULL)) - { - TFE_LOG_ERROR(__ctx->logger, "failed at fetch CMSG_FIRSTHDR() from incoming fds."); - goto __die; - } - - __fds = (int *) (CMSG_DATA(__cmsghdr)); - if (unlikely(__fds == NULL)) - { - TFE_LOG_ERROR(__ctx->logger, "failed at fetch CMSG_DATA() from incoming fds."); - goto __die; - } - - /* Apply a cmsg structure */ - if (tfe_cmsg_deserialize((const unsigned char *)__buffer, (uint16_t)rd, &cmsg) < 0) - { - /* TODO: dump the buffer in hexdump format */ - TFE_LOG_ERROR(__ctx->logger, "failed at cmsg_deserialize(), invalid format."); - goto __drop_recieved_fds; - } - - TFE_PROXY_STAT_INCREASE(STAT_FD_OPEN_BY_KNI_ACCEPT, 2); - if (tfe_proxy_fds_accept(__ctx->proxy, __fds[0], __fds[1], cmsg) < 0) - { - goto __drop_recieved_fds; - } - - return; - -__die: - DIE("Broken kni scm socket connection, abort."); - return; - -__drop_recieved_fds: - TFE_PROXY_STAT_INCREASE(STAT_FD_CLOSE_BY_KNI_ACCEPT_FAIL, 2); - if (__fds != NULL) evutil_closesocket(__fds[0]); - if (__fds != NULL) evutil_closesocket(__fds[1]); -} - -void * acceptor_scm_event_thread_entry(void * args) -{ - struct acceptor_scm * __ctx = (struct acceptor_scm *) args; - assert(__ctx != NULL && __ctx->thread == pthread_self()); - - TFE_LOG_INFO(__ctx->logger, "scm acceptor thread is running."); - event_base_dispatch(__ctx->ev_base); - DIE("scm acceptor thread is exited, abort."); -} - -void acceptor_scm_deinit(struct acceptor_scm * ctx) -{ - if (ctx != NULL && ctx->ev_base != NULL) - { - event_base_free(ctx->ev_base); - } - - if (ctx != NULL && ctx->fd_scm_socket != 0) - { - close(ctx->fd_scm_socket); - } - - if (ctx != NULL) - { - free(ctx); - } - - return; -} - -struct acceptor_scm * acceptor_scm_create(struct tfe_proxy * proxy, const char * profile, void * logger) -{ - struct acceptor_scm * __ctx = ALLOC(struct acceptor_scm, 1); - struct sockaddr_un __sockaddr_un{}; - - int ret = 0; - - __ctx->proxy = proxy; - __ctx->profile = profile; - __ctx->logger = logger; - - /* Read the unix domain socket file, this file is used to recieve fds from KNI */ - MESA_load_profile_string_def(profile, "acceptor_scm", "scm_socket_file", __ctx->str_scm_socket, - sizeof(__ctx->str_scm_socket), TFE_CONFIG_SCM_SOCKET_FILE); - - __sockaddr_un.sun_family = AF_UNIX; - strncpy(__sockaddr_un.sun_path, __ctx->str_scm_socket, sizeof(__sockaddr_un.sun_path)); - - if (remove(__ctx->str_scm_socket) < 0 && errno != ENOENT) - { - TFE_LOG_ERROR(__ctx->logger, "Failed at remove(%s) : %s", __ctx->str_scm_socket, strerror(errno)); - goto __errout; - } - - /* Create new event base, this event base will be dispatched at separated thread */ - __ctx->ev_base = event_base_new(); - if (unlikely(__ctx->ev_base == NULL)) - { - TFE_LOG_ERROR(__ctx->logger, "Failed at creating event_base. "); - goto __errout; - } - - __ctx->fd_scm_socket = socket(AF_UNIX, SOCK_DGRAM, 0); - if (unlikely(__ctx->fd_scm_socket < 0)) - { - TFE_LOG_ERROR(__ctx->logger, "Failed at create scm socket fd: %s", strerror(errno)); - goto __errout; - } - - ret = bind(__ctx->fd_scm_socket, (struct sockaddr *)&__sockaddr_un, sizeof(__sockaddr_un)); - if (unlikely(ret < 0)) - { - TFE_LOG_ERROR(__ctx->logger, "Failed at binding to %s: %s", __sockaddr_un.sun_path, strerror(errno)); - goto __errout; - } - - __ctx->ev_scm_socket = event_new(__ctx->ev_base, __ctx->fd_scm_socket, - EV_READ | EV_PERSIST, acceptor_scm_event, __ctx); - - if (unlikely(__ctx->ev_scm_socket == NULL)) - { - TFE_LOG_ERROR(__ctx->logger, "Failed at setup READ event for scm socket fd %d.", __ctx->fd_scm_socket); - goto __errout; - } - - ret = event_add(__ctx->ev_scm_socket, NULL); - if (unlikely(ret < 0)) - { - TFE_LOG_ERROR(__ctx->logger, "Failed at adding scm socket event to evbase. "); - goto __errout; - } - - /* Create a thread to dispatch ctx->evbase */ - ret = pthread_create(&__ctx->thread, NULL, acceptor_scm_event_thread_entry, (void *) __ctx); - if (unlikely(ret < 0)) - { - TFE_LOG_ERROR(__ctx->logger, "Failed at creating event thread: %s", strerror(errno)); - goto __errout; - } - - TFE_LOG_INFO(__ctx->logger, "scm socket file: %s", __ctx->str_scm_socket); - return __ctx; - -__errout: - acceptor_scm_deinit(__ctx); - return NULL; -} diff --git a/platform/src/proxy.cpp b/platform/src/proxy.cpp index 4c594d3..fe605ae 100644 --- a/platform/src/proxy.cpp +++ b/platform/src/proxy.cpp @@ -24,8 +24,10 @@ #include #include -#include +#include +#include +#include #include #include #include @@ -35,15 +37,13 @@ #include #include -#include #include -#include -#include +#include +#include extern struct ssl_policy_enforcer* ssl_policy_enforcer_create(void* logger); extern enum ssl_stream_action ssl_policy_enforce(struct ssl_stream *upstream, void* u_para); - static int signals[] = {SIGHUP, SIGPIPE, SIGUSR1}; /* Global Resource */ @@ -351,6 +351,26 @@ int tfe_stat_init(struct tfe_proxy * proxy, const char * profile) return 0; } +void tfe_proxy_acceptor_init(struct tfe_proxy * proxy, const char * profile) +{ + MESA_load_profile_uint_def(profile, "acceptor", "en_kni_v1", &proxy->en_kni_v1_acceptor, 0); + MESA_load_profile_uint_def(profile, "acceptor", "en_kni_v2", &proxy->en_kni_v2_acceptor, 1); + + if (proxy->en_kni_v1_acceptor) + { + g_default_proxy->kni_v1_acceptor = acceptor_kni_v1_create(proxy, profile, proxy->logger); + CHECK_OR_EXIT(g_default_proxy->kni_v2_acceptor, "Failed at init KNIv2 acceptor. Exit. "); + } + + if (proxy->en_kni_v2_acceptor) + { + g_default_proxy->kni_v2_acceptor = acceptor_kni_v2_create(g_default_proxy, profile, g_default_logger); + CHECK_OR_EXIT(g_default_proxy->kni_v2_acceptor, "Failed at init KNIv2 acceptor. Exit. "); + } + + return; +} + int main(int argc, char * argv[]) { const char * main_profile = "./conf/tfe/tfe.conf"; @@ -397,7 +417,6 @@ int main(int argc, char * argv[]) g_default_proxy->gcev = event_new(g_default_proxy->evbase, -1, EV_PERSIST, __gc_handler_cb, g_default_proxy); CHECK_OR_EXIT(g_default_proxy->gcev, "Failed at creating GC event. Exit. "); - /* SSL INIT */ g_default_proxy->ssl_mgr_handler = ssl_manager_init(main_profile, "ssl", g_default_proxy->evbase, g_default_logger); CHECK_OR_EXIT(g_default_proxy->ssl_mgr_handler, "Failed at init SSL manager. Exit."); @@ -414,11 +433,7 @@ int main(int argc, char * argv[]) /* WORKER THREAD CTX Create */ tfe_proxy_work_thread_create_ctx(g_default_proxy); - - /* ACCEPTOR INIT */ - g_default_proxy->kni_acceptor_handler = acceptor_scm_create(g_default_proxy, main_profile, g_default_logger); - CHECK_OR_EXIT(g_default_proxy->kni_acceptor_handler, "Failed at init KNI acceptor. Exit. "); - + tfe_proxy_acceptor_init(g_default_proxy, main_profile); /* PLUGIN INIT */ unsigned int plugin_iterator = 0;