summaryrefslogtreecommitdiff
path: root/platform/src/packet_adapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/src/packet_adapter.cpp')
-rw-r--r--platform/src/packet_adapter.cpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/platform/src/packet_adapter.cpp b/platform/src/packet_adapter.cpp
new file mode 100644
index 0000000..6fa94f0
--- /dev/null
+++ b/platform/src/packet_adapter.cpp
@@ -0,0 +1,240 @@
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/prctl.h>
+
+#include "log.h"
+#include "system.h"
+#include "packet_io.h"
+#include "packet_stat.h"
+#include "packet_handle.h"
+
+#define LOG_MAIN "PacketAdapter"
+
+#ifdef GIT_VERSION
+static __attribute__((__used__)) const char *Packet_Adapter_Version = GIT_VERSION;
+#else
+static __attribute__((__used__)) const char *Packet_Adapter_Version = "Unknown";
+#endif
+
+/******************************************************************************
+ * Struct
+ ******************************************************************************/
+
+struct thread
+{
+ int index;
+ pthread_t tid;
+ struct runtime_ctx *runtime;
+};
+
+struct runtime_ctx
+{
+ int enable_debug;
+ int need_stop;
+
+ struct metrics metrics;
+ struct packet_io *handle;
+ struct packet_stat *stat;
+ struct thread threads[MAX_THREAD_NUM];
+};
+
+/******************************************************************************
+ * Static
+ ******************************************************************************/
+
+struct runtime_ctx static_runtime_ctx = {0};
+struct runtime_ctx *runtime = &static_runtime_ctx;
+
+/******************************************************************************
+ * API
+ ******************************************************************************/
+
+static enum action packet_handle_callback(const char *data, int len, void *args)
+{
+ struct metrics *metrics = (struct metrics *)args;
+ packet_handle(data, len, metrics);
+
+ return ACTION_BYPASS;
+}
+
+static void *worker_thread_cycle(void *arg)
+{
+ struct thread *thread = (struct thread *)arg;
+ struct runtime_ctx *runtime = thread->runtime;
+ struct packet_io *handle = runtime->handle;
+
+ char thread_name[16];
+ snprintf(thread_name, sizeof(thread_name), "pkt-adapter:%d", thread->index);
+ prctl(PR_SET_NAME, (unsigned long long)thread_name, NULL, NULL, NULL);
+
+ if (packet_io_thread_init(handle, thread->index) != 0)
+ {
+ goto error_out;
+ }
+
+ LOG_INFO("%s: worker thread %d is running", LOG_MAIN, thread->index);
+ while (!runtime->need_stop)
+ {
+ if (packet_io_thread_polling(handle, thread->index) == 0)
+ {
+ packet_io_thread_wait(handle, thread->index, -1);
+ }
+ }
+
+error_out:
+ LOG_ERROR("%s: worker thread %d exiting", LOG_MAIN, thread->index);
+ return (void *)NULL;
+}
+
+static void signal_handler(int signo)
+{
+ if (signo == SIGUSR1)
+ {
+ runtime->enable_debug = 1;
+ LOG_ERROR("%s: received SIGUSR1, enable debug", LOG_MAIN);
+ }
+ if (signo == SIGUSR2)
+ {
+ runtime->enable_debug = 0;
+ LOG_ERROR("%s: received SIGUSR2, disable debug", LOG_MAIN);
+ }
+ if (signo == SIGHUP)
+ {
+ LOG_RELOAD();
+ LOG_ERROR("%s: received SIGHUP, reload zlog.conf", LOG_MAIN);
+ }
+ if (signo == SIGINT)
+ {
+ runtime->need_stop = 1;
+ LOG_ERROR("%s: received SIGINT, exit !!!", LOG_MAIN);
+ }
+ if (signo == SIGQUIT)
+ {
+ runtime->need_stop = 1;
+ LOG_ERROR("%s: received SIGQUIT, exit !!!", LOG_MAIN);
+ }
+ if (signo == SIGTERM)
+ {
+ runtime->need_stop = 1;
+ LOG_ERROR("%s: received SIGTERM, exit !!!", LOG_MAIN);
+ }
+}
+
+static void usage(char *cmd)
+{
+ fprintf(stderr, "USAGE: %s [OPTIONS]\n", cmd);
+ fprintf(stderr, " -v -- show version\n");
+ fprintf(stderr, " -d -- run daemon\n");
+ fprintf(stderr, " -h -- show help\n");
+ fprintf(stderr, "Signal: \n");
+ fprintf(stderr, " kill -s SIGUSR1 `pidof %s` -- enable debug\n", cmd);
+ fprintf(stderr, " kill -s SIGUSR2 `pidof %s` -- disable debug\n", cmd);
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ const char *profile = "./conf/packet_adapter.conf";
+
+ if (LOG_INIT("./conf/zlog.conf") == -1)
+ {
+ return -1;
+ }
+
+ while ((opt = getopt(argc, argv, "vdh")) != -1)
+ {
+ switch (opt)
+ {
+ case 'v':
+ fprintf(stderr, "Packet Adapter Version: %s\n", Packet_Adapter_Version);
+ return 0;
+ case 'd':
+ run_daemon();
+ break;
+ case 'h': /* fall through */
+ default:
+ usage(argv[0]);
+ return 0;
+ }
+ }
+
+ LOG_ERROR("%s: TSG Packet Adapter Engine, Version: %s Start ...", LOG_MAIN, Packet_Adapter_Version);
+
+ if (signal(SIGUSR1, signal_handler) == SIG_ERR)
+ {
+ LOG_ERROR("%s: failed at signal(SIGUSR1), %d: %s", LOG_MAIN, errno, strerror(errno));
+ goto error;
+ }
+ if (signal(SIGUSR2, signal_handler) == SIG_ERR)
+ {
+ LOG_ERROR("%s: failed at signal(SIGUSR2), %d: %s", LOG_MAIN, errno, strerror(errno));
+ goto error;
+ }
+ if (signal(SIGHUP, signal_handler) == SIG_ERR)
+ {
+ LOG_ERROR("%s: failed at signal(SIGHUP), %d: %s", LOG_MAIN, errno, strerror(errno));
+ goto error;
+ }
+ if (signal(SIGINT, signal_handler) == SIG_ERR)
+ {
+ LOG_ERROR("%s: failed at signal(SIGINT), %d: %s", LOG_MAIN, errno, strerror(errno));
+ goto error;
+ }
+ if (signal(SIGQUIT, signal_handler) == SIG_ERR)
+ {
+ LOG_ERROR("%s: failed at signal(SIGQUIT), %d: %s", LOG_MAIN, errno, strerror(errno));
+ goto error;
+ }
+
+ if (signal(SIGTERM, signal_handler) == SIG_ERR)
+ {
+ LOG_ERROR("%s: failed at signal(SIGTERM), %d: %s", LOG_MAIN, errno, strerror(errno));
+ goto error;
+ }
+
+ runtime->stat = packet_stat_create(profile);
+ if (runtime->stat == NULL)
+ {
+ goto error;
+ }
+
+ runtime->handle = packet_io_create(profile);
+ if (runtime->handle == NULL)
+ {
+ goto error;
+ }
+
+ packet_io_set_callback(runtime->handle, packet_handle_callback, &runtime->metrics);
+ for (int i = 0; i < packet_io_thread_number(runtime->handle); i++)
+ {
+ runtime->threads[i].tid = 0;
+ runtime->threads[i].index = i;
+ runtime->threads[i].runtime = runtime;
+ }
+
+ for (int i = 0; i < packet_io_thread_number(runtime->handle); i++)
+ {
+ struct thread *thread = &runtime->threads[i];
+ if (pthread_create(&thread->tid, NULL, worker_thread_cycle, (void *)thread) < 0)
+ {
+ LOG_ERROR("%s: unable to create worker thread %d, error %d: %s", LOG_MAIN, i, errno, strerror(errno));
+ runtime->need_stop = 1;
+ }
+ }
+
+ while (!runtime->need_stop)
+ {
+ packet_stat_output(runtime->stat, &runtime->metrics);
+ sleep(packet_stat_cycle(runtime->stat));
+ }
+
+error:
+ packet_stat_destory(runtime->stat);
+ packet_io_destory(runtime->handle);
+ LOG_CLOSE();
+
+ return 0;
+} \ No newline at end of file