移植KNIv1版本的acceptor到4a分支,兼容原kni的实现。
This commit is contained in:
@@ -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)
|
||||
|
||||
7
platform/include/internal/acceptor_kni_v1.h
Normal file
7
platform/include/internal/acceptor_kni_v1.h
Normal file
@@ -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);
|
||||
7
platform/include/internal/acceptor_kni_v2.h
Normal file
7
platform/include/internal/acceptor_kni_v2.h
Normal file
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
#include <event2/listener.h>
|
||||
#include <event2/util.h>
|
||||
#include <event2/bufferevent.h>
|
||||
|
||||
#include <MESA/MESA_prof_load.h>
|
||||
#include <tfe_stream.h>
|
||||
#include <tfe_cmsg.h>
|
||||
#include <acceptor_scm.h>
|
||||
#include <proxy.h>
|
||||
#include <platform.h>
|
||||
#
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -24,8 +24,10 @@
|
||||
#include <event2/thread.h>
|
||||
|
||||
#include <MESA/MESA_handle_logger.h>
|
||||
#include <tango_cache_client.h>
|
||||
#include <MESA/MESA_prof_load.h>
|
||||
#include <MESA/field_stat2.h>
|
||||
|
||||
#include <tango_cache_client.h>
|
||||
#include <tfe_utils.h>
|
||||
#include <tfe_future.h>
|
||||
#include <tfe_stream.h>
|
||||
@@ -35,15 +37,13 @@
|
||||
|
||||
#include <platform.h>
|
||||
#include <proxy.h>
|
||||
#include <acceptor_scm.h>
|
||||
#include <tcp_stream.h>
|
||||
#include <MESA/MESA_prof_load.h>
|
||||
#include <MESA/field_stat2.h>
|
||||
#include <acceptor_kni_v1.h>
|
||||
#include <acceptor_kni_v2.h>
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user