This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-stellar/infra/stellar_core.c

335 lines
9.2 KiB
C
Raw Normal View History

2024-01-09 18:03:24 +08:00
#include <unistd.h>
#include <pthread.h>
#include <sys/prctl.h>
2024-01-09 18:03:24 +08:00
#include "stellar/stellar.h"
#include "stellar/module.h"
#include "packet_io.h"
#include "log_internal.h"
#include "utils_internal.h"
#include "packet_internal.h"
#include "packet_manager.h"
#define CORE_LOG_FATAL(format, ...) STELLAR_LOG_FATAL(__thread_local_logger, "core", format, ##__VA_ARGS__)
#define CORE_LOG_ERROR(format, ...) STELLAR_LOG_ERROR(__thread_local_logger, "core", format, ##__VA_ARGS__)
#define CORE_LOG_DEBUG(format, ...) STELLAR_LOG_DEBUG(__thread_local_logger, "core", format, ##__VA_ARGS__)
2024-08-16 10:43:00 +08:00
#ifdef STELLAR_GIT_VERSION
static __attribute__((__used__)) const char *version = STELLAR_GIT_VERSION;
#else
static __attribute__((__used__)) const char *version = "Unknown";
#endif
struct thread
{
pthread_t tid;
uint16_t idx;
uint64_t is_runing;
struct stellar *st;
};
2024-09-20 18:41:07 +08:00
struct stellar
{
2024-09-20 18:41:07 +08:00
uint16_t thread_num;
uint64_t need_exit;
struct logger *logger;
2024-09-20 18:41:07 +08:00
struct packet_io *pkt_io;
struct module_manager *mod_mgr;
struct thread threads[MAX_THREAD_NUM];
};
static void *worker_thread(void *arg)
2024-01-09 18:03:24 +08:00
{
int nr_recv = 0;
2024-09-20 18:41:07 +08:00
char thread_name[16] = {0};
struct packet *pkt = NULL;
struct packet *pkts[RX_BURST_MAX] = {NULL};
struct thread *thread = (struct thread *)arg;
2024-09-20 18:41:07 +08:00
uint16_t thread_id = thread->idx;
struct stellar *st = thread->st;
2024-09-20 18:41:07 +08:00
struct packet_io *pkt_io = st->pkt_io;
struct module_manager *mod_mgr = st->mod_mgr;
struct module *pkt_mgr_mod = module_manager_get_module(mod_mgr, PACKET_MANAGER_MODULE_NAME);
struct packet_manager *pkt_mgr = module_to_packet_manager(pkt_mgr_mod);
2024-09-20 18:41:07 +08:00
snprintf(thread_name, sizeof(thread_name), "stellar:%d", thread_id);
prctl(PR_SET_NAME, (unsigned long long)thread_name, NULL, NULL, NULL);
2024-09-20 18:41:07 +08:00
__thread_local_logger = st->logger;
module_manager_register_thread(mod_mgr, thread_id);
ATOMIC_SET(&thread->is_runing, 1);
2024-09-20 18:41:07 +08:00
CORE_LOG_FATAL("worker thread %d runing", thread_id);
2024-01-09 18:03:24 +08:00
2024-09-20 18:41:07 +08:00
while (ATOMIC_READ(&st->need_exit) == 0)
2024-01-09 18:03:24 +08:00
{
nr_recv = packet_io_recv(pkt_io, thread_id, pkts, RX_BURST_MAX);
for (int i = 0; i < nr_recv; i++)
2024-01-10 10:19:47 +08:00
{
packet_manager_ingress(pkt_mgr, thread_id, pkts[i]);
2024-01-10 10:19:47 +08:00
}
2024-01-09 18:03:24 +08:00
packet_manager_dispatch(pkt_mgr, thread_id);
while ((pkt = packet_manager_egress(pkt_mgr, thread_id)))
{
packet_io_send(pkt_io, thread_id, &pkt, 1);
}
packet_io_clean(pkt_io, thread_id);
module_manager_polling_dispatch(mod_mgr);
if (nr_recv == 0)
{
2024-09-20 18:41:07 +08:00
packet_io_yield(pkt_io, thread_id);
}
}
CORE_LOG_FATAL("worker thread %d cleaning", thread_id);
module_manager_unregister_thread(mod_mgr, thread_id);
ATOMIC_SET(&thread->is_runing, 0);
2024-09-20 18:41:07 +08:00
CORE_LOG_FATAL("worker thread %d exit", thread_id);
2024-01-09 18:03:24 +08:00
return NULL;
}
2024-09-20 18:41:07 +08:00
static int stellar_thread_run(struct stellar *st)
2024-01-29 14:15:33 +08:00
{
for (uint64_t i = 0; i < st->thread_num; i++)
2024-01-29 14:15:33 +08:00
{
struct thread *thread = &st->threads[i];
thread->idx = i;
thread->is_runing = 0;
thread->st = st;
if (pthread_create(&thread->tid, NULL, worker_thread, (void *)thread) < 0)
2024-01-29 14:15:33 +08:00
{
CORE_LOG_ERROR("unable to create worker thread, error %d: %s", errno, strerror(errno));
2024-01-29 14:15:33 +08:00
return -1;
}
}
return 0;
}
static void stellar_thread_join(struct stellar *st)
2024-01-29 14:15:33 +08:00
{
for (uint64_t i = 0; i < st->thread_num; i++)
2024-01-29 14:15:33 +08:00
{
2024-09-20 18:41:07 +08:00
if (st->threads[i].is_runing == 0)
{
continue;
}
struct thread *thread = &st->threads[i];
2024-09-20 18:41:07 +08:00
pthread_join(thread->tid, NULL);
2024-01-29 14:15:33 +08:00
}
}
#include "stellar/monitor.h"
#include "stellar/session.h"
#include "stellar/lpi_plus.h"
struct module_hooks mod_hooks[] = {
{monitor_on_init, monitor_on_exit, NULL, NULL},
{packet_manager_on_init, packet_manager_on_exit, packet_manager_on_thread_init, packet_manager_on_thread_exit},
{session_manager_on_init, session_manager_on_exit, session_manager_on_thread_init, session_manager_on_thread_exit},
{session_debugger_on_init, session_debugger_on_exit, NULL, NULL},
{session_monitor_on_init, session_monitor_on_exit, NULL, NULL},
{lpi_plus_init, lpi_plus_exit, NULL, NULL},
};
struct packet_node_spec
{
const char *module_name;
const char *node_name;
enum packet_stage stage;
uint64_t interested_tag_key_bits;
uint64_t interested_tag_val_bits;
on_packet_callback *cb;
};
struct packet_node_spec packet_nodes[] = {
// PACKET_STAGE_FORWARD
{SESSION_MANAGER_MODULE_NAME, "session_manager", PACKET_STAGE_FORWARD, PKT_TAG_KEY_IPPROTO, PKT_TAG_VAL_IPPROTO_TCP | PKT_TAG_VAL_IPPROTO_UDP, session_manager_on_packet_forward},
{SESSION_DEBUGGER_MODULE_NAME, "session_debugger", PACKET_STAGE_FORWARD, PKT_TAG_KEY_SESS, PKT_TAG_VAL_SESS_ALL, session_debugger_on_packet_forward},
{LPI_PLUS_MODULE_NAME, "lpi_plus", PACKET_STAGE_FORWARD, PKT_TAG_KEY_IPPROTO, PKT_TAG_VAL_IPPROTO_TCP | PKT_TAG_VAL_IPPROTO_UDP, lpi_plus_on_packet},
// PACKET_STAGE_OUTPUT
{SESSION_MANAGER_MODULE_NAME, "session_manager", PACKET_STAGE_OUTPUT, PKT_TAG_KEY_IPPROTO, PKT_TAG_VAL_IPPROTO_TCP | PKT_TAG_VAL_IPPROTO_UDP, session_manager_on_packet_output},
};
static int register_packet_node_for_module(struct module_manager *mod_mgr, struct packet_node_spec *specs, size_t n_specs)
{
struct module *pkt_mgr_mod = module_manager_get_module(mod_mgr, PACKET_MANAGER_MODULE_NAME);
struct packet_manager *pkt_mgr = module_to_packet_manager(pkt_mgr_mod);
struct module *mod = NULL;
for (size_t i = 0; i < n_specs; i++)
{
mod = module_manager_get_module(mod_mgr, specs[i].module_name);
if (mod == NULL)
{
CORE_LOG_FATAL("%s unable to get module %s", __FUNCTION__, specs[i].module_name);
continue;
}
if (packet_manager_register_node(pkt_mgr,
specs[i].node_name,
specs[i].stage,
specs[i].interested_tag_key_bits,
specs[i].interested_tag_val_bits,
specs[i].cb,
mod) < 0)
{
CORE_LOG_FATAL("%s failed to register node:%s for module:%s in stage:%d", __FUNCTION__, specs[i].node_name, specs[i].module_name, specs[i].stage);
}
else
{
CORE_LOG_FATAL("%s success to register node:%s for module:%s in stage:%d", __FUNCTION__, specs[i].node_name, specs[i].module_name, specs[i].stage);
}
}
return 0;
}
struct stellar *stellar_new(const char *toml_file)
{
if (toml_file == NULL)
{
printf("stellar config file is null\n");
return NULL;
}
struct stellar *st = (struct stellar *)calloc(1, sizeof(struct stellar));
if (st == NULL)
{
return NULL;
}
st->logger = log_new(toml_file);
2024-09-20 18:41:07 +08:00
if (st->logger == NULL)
{
printf("unable to create logger");
goto error_out;
}
2024-09-20 18:41:07 +08:00
__thread_local_logger = st->logger;
CORE_LOG_FATAL("stellar start (version: %s)", version);
if (load_toml_integer_config(toml_file, "packet_io.thread_num", (uint64_t *)&st->thread_num, 1, MAX_THREAD_NUM) != 0)
{
2024-09-20 18:41:07 +08:00
CORE_LOG_ERROR("unable to get thread number from config file");
goto error_out;
}
st->mod_mgr = module_manager_new(mod_hooks, count_of(mod_hooks), st->thread_num, toml_file, st->logger);
2024-09-20 18:41:07 +08:00
if (st->mod_mgr == NULL)
{
2024-10-11 06:08:50 +00:00
CORE_LOG_ERROR("unable to create packet manager");
goto error_out;
}
st->pkt_io = packet_io_new(toml_file);
2024-09-20 18:41:07 +08:00
if (st->pkt_io == NULL)
{
2024-09-20 18:41:07 +08:00
CORE_LOG_ERROR("unable to create packet io");
goto error_out;
}
if(register_packet_node_for_module(st->mod_mgr, packet_nodes, count_of(packet_nodes)) != 0)
{
CORE_LOG_ERROR("unable to register packet node");
goto error_out;
}
return st;
error_out:
2024-09-20 18:41:07 +08:00
stellar_free(st);
return NULL;
}
void stellar_run(struct stellar *st)
{
if (st == NULL)
{
return;
}
if (stellar_thread_run(st) != 0)
{
CORE_LOG_ERROR("unable to create worker thread");
return;
}
2024-09-20 18:41:07 +08:00
while (!ATOMIC_READ(&st->need_exit))
{
usleep(1000); // 1ms
// only available in pcap mode
2024-10-31 16:25:37 +08:00
if (packet_io_is_done(st->pkt_io))
{
2024-09-20 18:41:07 +08:00
ATOMIC_SET(&st->need_exit, 1);
break;
}
}
stellar_thread_join(st);
}
void stellar_free(struct stellar *st)
{
if (st)
{
2024-09-20 18:41:07 +08:00
packet_io_free(st->pkt_io);
module_manager_free(st->mod_mgr);
CORE_LOG_FATAL("stellar exit\n");
2024-09-20 18:41:07 +08:00
log_free(st->logger);
2024-08-23 17:19:05 +08:00
free(st);
st = NULL;
}
}
void stellar_loopbreak(struct stellar *st)
{
if (st)
{
2024-09-20 18:41:07 +08:00
ATOMIC_SET(&st->need_exit, 1);
}
}
void stellar_reload_log_level(struct stellar *st)
{
if (st)
{
2024-09-20 18:41:07 +08:00
log_reload_level(st->logger);
}
}
struct logger *stellar_get_logger(struct stellar *st)
{
if (st)
{
2024-09-20 18:41:07 +08:00
return st->logger;
}
else
{
return NULL;
}
}
struct module_manager *stellar_get_module_manager(struct stellar *st)
{
if (st)
{
return st->mod_mgr;
}
else
{
return NULL;
}
2024-06-27 15:07:54 +08:00
}