Merge branch develop-0.0
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/sdk/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/deps/)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/common/)
|
||||
@@ -6,7 +5,6 @@ include_directories(${CMAKE_SOURCE_DIR}/src/packet_io/)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/session_manager/)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/plugin_manager/)
|
||||
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(packet_io)
|
||||
add_subdirectory(session_manager)
|
||||
@@ -17,4 +15,16 @@ add_executable(stellar
|
||||
main.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(stellar packet_io plugin_manager session_manager http dl pcap)
|
||||
target_link_libraries(
|
||||
stellar
|
||||
pthread
|
||||
packet_io
|
||||
plugin_manager
|
||||
session_manager
|
||||
http
|
||||
toml
|
||||
dl
|
||||
pcap
|
||||
)
|
||||
|
||||
install(TARGETS stellar RUNTIME DESTINATION bin COMPONENT Program)
|
||||
@@ -8,6 +8,26 @@
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "global_var.h"
|
||||
|
||||
struct stellar_engine g_engine_instance;
|
||||
struct stellar_engine g_engine_instance;
|
||||
|
||||
int strncpy_safe(char *dst, const char *src, size_t dst_size)
|
||||
{
|
||||
if (nullptr == dst || nullptr == src || dst_size == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t slen = strlen(src);
|
||||
if (slen >= dst_size) {
|
||||
strncpy(dst, src, dst_size);
|
||||
dst[dst_size - 1] = '\0';
|
||||
} else {
|
||||
strcpy(dst, src);
|
||||
dst[slen - 1] = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -79,4 +79,11 @@ struct stellar_engine {
|
||||
struct stellar_config config;
|
||||
};
|
||||
|
||||
extern struct stellar_engine g_engine_instance;
|
||||
extern struct stellar_engine g_engine_instance;
|
||||
|
||||
/**
|
||||
* @brief string copy safely,
|
||||
*
|
||||
* @retval -1(failed), 0(success)
|
||||
*/
|
||||
int strncpy_safe(char *dst, const char *src, size_t dst_size);
|
||||
@@ -48,7 +48,7 @@ void pio_packet_enqueue(struct pio_packet_queue *q, struct pio_packet *p)
|
||||
|
||||
struct pio_packet *pio_packet_dequeue(struct pio_packet_queue *q)
|
||||
{
|
||||
struct pio_packet *p = NULL;
|
||||
struct pio_packet *p = nullptr;
|
||||
|
||||
/* if the queue is empty there are no packets left. */
|
||||
if (q->len == 0) {
|
||||
@@ -87,4 +87,4 @@ void release_pio_packet_queue(struct pio_packet_queue *q)
|
||||
q->len--;
|
||||
FREE(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
81
src/main.cpp
81
src/main.cpp
@@ -7,38 +7,43 @@
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include "./common/global_var.h"
|
||||
#include "./packet_io/packet_io.h"
|
||||
#include "./session_manager/session_manager.h"
|
||||
#include "./plugin_manager/plugin_manager.h"
|
||||
#include "../sdk/include/http.h"
|
||||
#include "../sdk/include/logger.h"
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct packet_io_loop_arg
|
||||
#include "global_var.h"
|
||||
#include "logger.h"
|
||||
#include "packet_io.h"
|
||||
#include "session_manager.h"
|
||||
#include "plugin_manager.h"
|
||||
#include "http.h"
|
||||
|
||||
struct stellar_event_base_loop_arg
|
||||
{
|
||||
struct packet_io_device *dev;
|
||||
int thread_id;
|
||||
struct session_manager *session_mgr;
|
||||
struct plugin_manager *plug_mgr;
|
||||
int tid;
|
||||
};
|
||||
|
||||
void packet_io_loop(struct packet_io_loop_arg *arg)
|
||||
void *stellar_event_base_loop(void *arg)
|
||||
{
|
||||
struct packet *rx_pkt;
|
||||
struct session_event *event;
|
||||
struct stellar_packet *rx_pkt;
|
||||
struct stellar_event *event;
|
||||
struct stellar_event_base_loop_arg *thread_arg = (struct stellar_event_base_loop_arg *)arg;
|
||||
while(1)
|
||||
{
|
||||
int fetch_num = packet_io_device_rx(arg->dev, arg->thread_id, &rx_pkt, 1);
|
||||
int fetch_num = packet_io_device_rx(thread_arg->dev, thread_arg->tid, &rx_pkt, 1);
|
||||
if(fetch_num > 0)
|
||||
{
|
||||
/*
|
||||
event = session_manager_commit(rx_pkt);
|
||||
event = session_manager_commit(thread_arg->session_mgr, rx_pkt);
|
||||
while(event)
|
||||
{
|
||||
plugin_manager_dispatch(event);
|
||||
event = session_manager_fetch_event();
|
||||
}*/
|
||||
printf("fetch_num:%d\n", fetch_num);
|
||||
plugin_manager_dispatch(thread_arg->plug_mgr ,event);
|
||||
event = session_manager_fetch_event(thread_arg->session_mgr);
|
||||
}
|
||||
|
||||
//clean session_manager event queue
|
||||
packet_io_device_tx(arg->dev, arg->thread_id, &rx_pkt, 1);
|
||||
packet_io_device_tx(thread_arg->dev, thread_arg->tid, &rx_pkt, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -48,7 +53,7 @@ void packet_io_loop(struct packet_io_loop_arg *arg)
|
||||
//dispatch to trigger polling event
|
||||
}
|
||||
}
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,23 +76,33 @@ packet_io_init(const char *instance_name, const enum packet_io_run_mode mode, co
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
/* global engine instance init */
|
||||
memset(&g_engine_instance, 0, sizeof(g_engine_instance));
|
||||
//packet_io_init
|
||||
struct packet_io_device *dev = packet_io_init("stellar", PACKET_IO_RUN_MODE_PCAP_LIVE, 2);
|
||||
|
||||
g_engine_instance.config.packet_io.mode = PACKET_IO_RUN_MODE_PCAP_FILE;
|
||||
strncpy(g_engine_instance.config.packet_io.dev_name[0], "./test.pcap", sizeof(NAME_MAX));
|
||||
g_engine_instance.config.packet_io.dev_cnt = 1;
|
||||
//manager_init
|
||||
struct session_manager *session_mgr = session_manager_init();
|
||||
struct plugin_manager *plug_mgr = plugin_manager_create();
|
||||
|
||||
/* packet io init */
|
||||
packet_io_init("stellar", g_engine_instance.config.packet_io.mode, 2);
|
||||
// register build-in plugin
|
||||
plugin_manager_register(plug_mgr, "HTTP", SESSION_EVENT_ALL, http_decoder);
|
||||
|
||||
// load external plugins
|
||||
char file_path[] = "./plugs/plugins.inf";
|
||||
plugin_manager_load(plug_mgr, file_path);
|
||||
|
||||
//session_manager_session_event_register(http_decoder, SESSION_TYPE_HTTP);
|
||||
struct packet_io_loop_arg arg;
|
||||
while (1) {
|
||||
//packet_io_loop();
|
||||
}
|
||||
//create_worker_thread
|
||||
|
||||
stellar_event_base_loop_arg arg = {dev, session_mgr, plug_mgr, 0};
|
||||
pthread_t worker_pid;
|
||||
pthread_create(&worker_pid, nullptr, stellar_event_base_loop, (void *)&arg);
|
||||
//main_loop
|
||||
while (1)
|
||||
{
|
||||
/* main loop code */
|
||||
usleep(1);
|
||||
}
|
||||
|
||||
plugin_manager_unload(plug_mgr);
|
||||
plugin_manager_destory(plug_mgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ int pio_marsio_device_close(struct packet_io_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pio_marsio_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts)
|
||||
int pio_marsio_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
struct mr_vdev *mr_dev_handle = pdev->entity.marsio_dev_ctx->mr_dev_handle;
|
||||
marsio_buff_t *rx_buff[MARSIO_BURST_PKT_MAX];
|
||||
@@ -328,14 +328,14 @@ int pio_marsio_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, st
|
||||
/* receive some pkts, copy mbuf pointer to packet structure */
|
||||
if (recv_res > 0) {
|
||||
for (int i = 0; i < recv_res; i++) {
|
||||
pkts[i]= (struct packet *)rx_buff[i];
|
||||
pkts[i]= (struct stellar_packet *)rx_buff[i];
|
||||
}
|
||||
}
|
||||
|
||||
return recv_res;
|
||||
}
|
||||
|
||||
int pio_marsio_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct packet **pkts, int nr_pkts)
|
||||
int pio_marsio_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
struct mr_sendpath *sendpath_handle = pdev->entity.marsio_dev_ctx->mr_sendpath_handle;
|
||||
int ret = g_marsio_dll_func.marsio_send_burst(sendpath_handle, txq_id, (marsio_buff_t **)pkts, nr_pkts);
|
||||
@@ -347,7 +347,7 @@ int pio_marsio_device_send(struct packet_io_device *pdev, uint32_t txq_id, struc
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pio_marsio_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
void pio_marsio_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
struct mr_instance *mr_inst = pdev->ppio_inst->entity.marsio_inst_ctx->mr_inst_handle;
|
||||
g_marsio_dll_func.marsio_buff_free(mr_inst, (marsio_buff_t **)pkts, nr_pkts, MARSIO_SOCKET_ID_ANY, qid);
|
||||
@@ -424,24 +424,24 @@ void pio_marsio_instance_destroy(struct packet_io_instance *pinst)
|
||||
}
|
||||
}
|
||||
|
||||
void *pio_marsio_device_buff_ctrlzone(struct packet *p)
|
||||
void *pio_marsio_device_buff_ctrlzone(struct stellar_packet *p)
|
||||
{
|
||||
int zone_id = 0;
|
||||
|
||||
return g_marsio_dll_func.marsio_buff_ctrlzone((marsio_buff_t *)p, zone_id);
|
||||
}
|
||||
|
||||
char *pio_marsio_device_buff_mtod(struct packet *p)
|
||||
char *pio_marsio_device_buff_mtod(struct stellar_packet *p)
|
||||
{
|
||||
return g_marsio_dll_func.marsio_buff_mtod((marsio_buff_t *)p);
|
||||
}
|
||||
|
||||
uint32_t pio_marsio_device_buff_buflen(struct packet *p)
|
||||
uint32_t pio_marsio_device_buff_buflen(struct stellar_packet *p)
|
||||
{
|
||||
return g_marsio_dll_func.marsio_buff_buflen((marsio_buff_t *)p);
|
||||
}
|
||||
|
||||
uint32_t pio_marsio_device_buff_datalen(struct packet *p)
|
||||
uint32_t pio_marsio_device_buff_datalen(struct stellar_packet *p)
|
||||
{
|
||||
return g_marsio_dll_func.marsio_buff_datalen((marsio_buff_t *)p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ int pio_marsio_device_close(struct packet_io_device *pdev);
|
||||
*
|
||||
* @retval number of packets actually received
|
||||
*/
|
||||
int pio_marsio_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts);
|
||||
int pio_marsio_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
/**
|
||||
* @brief send packets by device's single tx queue which specified by txq_id
|
||||
@@ -148,7 +148,7 @@ int pio_marsio_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, st
|
||||
*
|
||||
* @retval if ret<0, means the sending fails; if ret==0 means the sending succeeds
|
||||
*/
|
||||
int pio_marsio_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct packet **pkts, int nr_pkts);
|
||||
int pio_marsio_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
/**
|
||||
* @brief manually free packet's memory
|
||||
@@ -158,12 +158,12 @@ int pio_marsio_device_send(struct packet_io_device *pdev, uint32_t txq_id, struc
|
||||
* @param pkts:
|
||||
* @param nr_pkts:
|
||||
*/
|
||||
void pio_marsio_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts);
|
||||
void pio_marsio_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
void *pio_marsio_device_buff_ctrlzone(struct packet *p);
|
||||
void *pio_marsio_device_buff_ctrlzone(struct stellar_packet *p);
|
||||
|
||||
char *pio_marsio_device_buff_mtod(struct packet *p);
|
||||
char *pio_marsio_device_buff_mtod(struct stellar_packet *p);
|
||||
|
||||
uint32_t pio_marsio_device_buff_buflen(struct packet *p);
|
||||
uint32_t pio_marsio_device_buff_buflen(struct stellar_packet *p);
|
||||
|
||||
uint32_t pio_marsio_device_buff_datalen(struct packet *p);
|
||||
uint32_t pio_marsio_device_buff_datalen(struct stellar_packet *p);
|
||||
@@ -84,11 +84,16 @@ packet_io_instance_create(const char *inst_name, const enum packet_io_run_mode m
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
strncpy(pio_instance->inst_name, inst_name, strlen(inst_name));
|
||||
int ret = strncpy_safe(pio_instance->inst_name, inst_name, sizeof(pio_instance->inst_name));
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "packet_io instance name copy failed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pio_instance->mode = mode;
|
||||
pio_instance->inst_ops = &pio_instance_ops_array[mode];
|
||||
|
||||
int ret = pio_instance->inst_ops->create(pio_instance);
|
||||
ret = pio_instance->inst_ops->create(pio_instance);
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_PIO_INSTANCE, "packet_io instance create failed.");
|
||||
return nullptr;
|
||||
@@ -115,7 +120,12 @@ packet_io_device_open(struct packet_io_instance *pinst, const char *dev_name, ui
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
strncpy(ppio_dev->dev_name, dev_name, strlen(dev_name));
|
||||
int ret = strncpy_safe(ppio_dev->dev_name, dev_name, sizeof(ppio_dev->dev_name));
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "packet_io device name copy failed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ppio_dev->rxq_num = nr_rxq;
|
||||
ppio_dev->txq_num = nr_txq;
|
||||
ppio_dev->ppio_inst = pinst;
|
||||
@@ -127,7 +137,7 @@ packet_io_device_open(struct packet_io_instance *pinst, const char *dev_name, ui
|
||||
**/
|
||||
pinst->devices[pinst->dev_cnt++] = ppio_dev;
|
||||
|
||||
int ret = ppio_dev->dev_ops->open(ppio_dev);
|
||||
ret = ppio_dev->dev_ops->open(ppio_dev);
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_PIO_DEVICE, "packet_io device open failed.");
|
||||
FREE(ppio_dev);
|
||||
@@ -156,37 +166,37 @@ void packet_io_device_close(struct packet_io_device *pdev)
|
||||
FREE(pdev);
|
||||
}
|
||||
|
||||
int packet_io_device_rx(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts)
|
||||
int packet_io_device_rx(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
return pdev->dev_ops->recv(pdev, rxq_id, pkts, nr_pkts);
|
||||
}
|
||||
|
||||
int packet_io_device_tx(struct packet_io_device *pdev, uint32_t txq_id, struct packet **pkts, int nr_pkts)
|
||||
int packet_io_device_tx(struct packet_io_device *pdev, uint32_t txq_id, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
return pdev->dev_ops->send(pdev, txq_id, pkts, nr_pkts);
|
||||
}
|
||||
|
||||
void packet_io_pkts_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
void packet_io_pkts_free(struct packet_io_device *pdev, uint32_t qid, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
return pdev->dev_ops->pkt_free(pdev, qid, pkts, nr_pkts);
|
||||
}
|
||||
|
||||
void *packet_io_buff_ctrlzone(struct packet_io_device *pdev, struct packet *p)
|
||||
void *packet_io_buff_ctrlzone(struct packet_io_device *pdev, struct stellar_packet *p)
|
||||
{
|
||||
return pdev->dev_ops->buff_ctrlzone(p);
|
||||
}
|
||||
|
||||
char *packet_io_buff_mtod(struct packet_io_device *pdev, struct packet *p)
|
||||
char *packet_io_buff_mtod(struct packet_io_device *pdev, struct stellar_packet *p)
|
||||
{
|
||||
return pdev->dev_ops->buff_mtod(p);
|
||||
}
|
||||
|
||||
uint32_t packet_io_buff_buflen(struct packet_io_device *pdev, struct packet *p)
|
||||
uint32_t packet_io_buff_buflen(struct packet_io_device *pdev, struct stellar_packet *p)
|
||||
{
|
||||
return pdev->dev_ops->buff_buflen(p);
|
||||
}
|
||||
|
||||
uint32_t packet_io_buff_datalen(struct packet_io_device *pdev, struct packet *p)
|
||||
uint32_t packet_io_buff_datalen(struct packet_io_device *pdev, struct stellar_packet *p)
|
||||
{
|
||||
return pdev->dev_ops->buff_datalen(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,19 +60,19 @@ struct pio_device_operations {
|
||||
|
||||
int (*close)(struct packet_io_device *pdev);
|
||||
|
||||
int (*recv)(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts);
|
||||
int (*recv)(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
int (*send)(struct packet_io_device *pdev, uint32_t txq_id, struct packet **pkts, int nr_pkts);
|
||||
int (*send)(struct packet_io_device *pdev, uint32_t txq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
void (*pkt_free)(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts);
|
||||
void (*pkt_free)(struct packet_io_device *pdev, uint32_t qid, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
void *(*buff_ctrlzone)(struct packet *p);
|
||||
void *(*buff_ctrlzone)(struct stellar_packet *p);
|
||||
|
||||
char *(*buff_mtod)(struct packet *p);
|
||||
char *(*buff_mtod)(struct stellar_packet *p);
|
||||
|
||||
uint32_t (*buff_buflen)(struct packet *p);
|
||||
uint32_t (*buff_buflen)(struct stellar_packet *p);
|
||||
|
||||
uint32_t (*buff_datalen)(struct packet *p);
|
||||
uint32_t (*buff_datalen)(struct stellar_packet *p);
|
||||
};
|
||||
|
||||
struct packet_io_device {
|
||||
@@ -133,7 +133,7 @@ void packet_io_device_close(struct packet_io_device *dev);
|
||||
* @param p: received packet's pointer array
|
||||
* @param nr_p: number of received packets
|
||||
*/
|
||||
int packet_io_device_rx(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts);
|
||||
int packet_io_device_rx(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
/**
|
||||
* @brief packet_io device send function
|
||||
@@ -143,30 +143,30 @@ int packet_io_device_rx(struct packet_io_device *pdev, uint32_t rxq_id, struct p
|
||||
* @param p: prepare to send packet's pointer array
|
||||
* @param nr_p: number of packets which prepare to send
|
||||
*/
|
||||
int packet_io_device_tx(struct packet_io_device *pdev, uint32_t txq_id, struct packet **pkts, int nr_pkts);
|
||||
int packet_io_device_tx(struct packet_io_device *pdev, uint32_t txq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
/*
|
||||
* @brief packet_io free packet buff
|
||||
*/
|
||||
void packet_io_pkts_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts);
|
||||
void packet_io_pkts_free(struct packet_io_device *pdev, uint32_t qid, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
/**
|
||||
* @brief get packet_io packet's ctrlzone
|
||||
* @note ctrlzone's memory is 64 bytes, do not exceed it
|
||||
*/
|
||||
void *packet_io_buff_ctrlzone(struct packet_io_device *pdev, struct packet *p);
|
||||
void *packet_io_buff_ctrlzone(struct packet_io_device *pdev, struct stellar_packet *p);
|
||||
|
||||
/**
|
||||
* @brief get packet_io packet's data pointer
|
||||
*/
|
||||
char *packet_io_buff_mtod(struct packet_io_device *pdev, struct packet *p);
|
||||
char *packet_io_buff_mtod(struct packet_io_device *pdev, struct stellar_packet *p);
|
||||
|
||||
/**
|
||||
* @brief get packet_io packet's buffer length
|
||||
*/
|
||||
uint32_t packet_io_buff_buflen(struct packet_io_device *pdev, struct packet *p);
|
||||
uint32_t packet_io_buff_buflen(struct packet_io_device *pdev, struct stellar_packet *p);
|
||||
|
||||
/**
|
||||
* @brief get packet_io packet's data length
|
||||
*/
|
||||
uint32_t packet_io_buff_datalen(struct packet_io_device *pdev, struct packet *p);
|
||||
uint32_t packet_io_buff_datalen(struct packet_io_device *pdev, struct stellar_packet *p);
|
||||
@@ -93,7 +93,7 @@ static int init_pcap_file(struct pcap_plain_file_info *pfile_info)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&pfile_info->handle_mutex, NULL);
|
||||
pthread_mutex_init(&pfile_info->handle_mutex, nullptr);
|
||||
|
||||
if (pfile_info->shared != nullptr && pfile_info->shared->bpf_string != nullptr) {
|
||||
if (pcap_compile(pfile_info->pcap_handle, &pfile_info->filter,
|
||||
@@ -133,9 +133,14 @@ static int pcap_plain_file_init(struct pio_pcap_file_device_context *pfile_dev_c
|
||||
}
|
||||
|
||||
/* TODO: get conf and assign pfile_info */
|
||||
strncpy(pfile_info->file_name, file_name, strlen(file_name));
|
||||
int ret = strncpy_safe(pfile_info->file_name, file_name, sizeof(pfile_info->file_name));
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "pcap plain file name copy failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pfile_info->shared = &pfile_dev_ctx->shared;
|
||||
int ret = init_pcap_file(pfile_info);
|
||||
ret = init_pcap_file(pfile_info);
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_PIO_PCAP_FILE_DEVICE, "init_pcap_file failed.");
|
||||
FREE(pfile_info);
|
||||
@@ -161,7 +166,12 @@ static int pcap_directory_file_init(struct pio_pcap_file_device_context *pfile_d
|
||||
}
|
||||
|
||||
/* TODO: get conf and assign pdir_info */
|
||||
strncpy(pdir_info->dir_name, dir_name, strlen(dir_name));
|
||||
int ret = strncpy_safe(pdir_info->dir_name, dir_name, sizeof(pdir_info->dir_name));
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "pcap directory name copy failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//pdir_info->delay = 30;
|
||||
pdir_info->shared = &pfile_dev_ctx->shared;
|
||||
pdir_info->directory = directory;
|
||||
@@ -182,8 +192,13 @@ static int pcap_file_shared_init(struct pio_pcap_file_device_context *pfile_dev_
|
||||
/* TODO: get conf and assign pfile_dev_ctx->shared */
|
||||
if ((g_engine_instance.config.packet_io.mode == PACKET_IO_RUN_MODE_PCAP_FILE) &&
|
||||
g_engine_instance.config.packet_io.bpf_string != nullptr) {
|
||||
strncpy(pfile_dev_ctx->shared.bpf_string, g_engine_instance.config.packet_io.bpf_string,
|
||||
strlen(g_engine_instance.config.packet_io.bpf_string));
|
||||
memset(pfile_dev_ctx->shared.bpf_string, 0, sizeof(pfile_dev_ctx->shared.bpf_string));
|
||||
int ret = strncpy_safe(pfile_dev_ctx->shared.bpf_string, g_engine_instance.config.packet_io.bpf_string,
|
||||
sizeof(pfile_dev_ctx->shared.bpf_string));
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "pcap file bpf string copy failed.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
pfile_dev_ctx->shared.should_delete = g_engine_instance.config.packet_io.should_delete;
|
||||
@@ -315,7 +330,7 @@ void pcap_file_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_hdr, u_c
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t nr_rxq = pfile_dev_ctx->pio_dev->rxq_num;
|
||||
//uint32_t nr_rxq = pfile_dev_ctx->pio_dev->rxq_num;
|
||||
/*
|
||||
hash to specific queue id and enqueue
|
||||
hash_id = decode_packet(p) % nr_rxq;
|
||||
@@ -328,7 +343,7 @@ void pcap_file_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_hdr, u_c
|
||||
}
|
||||
|
||||
static int pcap_file_dispatch(struct pio_pcap_file_device_context *pfile_dev_ctx, uint32_t rxq_id,
|
||||
struct packet **pkts, int nr_pkts)
|
||||
struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
if (pfile_dev_ctx->entity.file->first_pkt_hdr != nullptr) {
|
||||
pthread_mutex_lock(&pfile_dev_ctx->entity.file->handle_mutex);
|
||||
@@ -361,7 +376,7 @@ static int pcap_file_dispatch(struct pio_pcap_file_device_context *pfile_dev_ctx
|
||||
pthread_mutex_lock(&pfile_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
do {
|
||||
p = pio_packet_dequeue(&pfile_dev_ctx->pkt_queues[rxq_id]);
|
||||
pkts[i] = (struct packet *)p;
|
||||
pkts[i] = (struct stellar_packet *)p;
|
||||
i++;
|
||||
} while (p != nullptr && (i < nr_pkts));
|
||||
pthread_mutex_unlock(&pfile_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
@@ -401,7 +416,7 @@ find_pending_file_to_add(struct pio_pcap_file_device_context *pfile_dev_ctx, str
|
||||
{
|
||||
char abs_path[PATH_MAX] = {0};
|
||||
|
||||
snprintf(abs_path, PATH_MAX, "%s/%s", pfile_dev_ctx->entity.dir->dir_name, dir->d_name);
|
||||
snprintf(abs_path, sizeof(abs_path), "%s/%s", pfile_dev_ctx->entity.dir->dir_name, dir->d_name);
|
||||
struct timespec temp_time;
|
||||
memset(&temp_time, 0, sizeof(struct timespec));
|
||||
|
||||
@@ -420,7 +435,12 @@ find_pending_file_to_add(struct pio_pcap_file_device_context *pfile_dev_ctx, str
|
||||
}
|
||||
|
||||
struct pending_file *file_to_add = CALLOC(struct pending_file, 1);
|
||||
strncpy(file_to_add->file_name, abs_path, strlen(abs_path));
|
||||
int ret = strncpy_safe(file_to_add->file_name, abs_path, sizeof(file_to_add->file_name));
|
||||
if (ret < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "file_to_add file name copy failed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
copy_timespec(&temp_time, &file_to_add->modified_time);
|
||||
log_info("found \"%s\" at %" PRIuMAX, file_to_add->file_name,
|
||||
(uintmax_t)timespec_to_millisecond(&file_to_add->modified_time));
|
||||
@@ -499,7 +519,7 @@ static int pcap_directory_collect_pending_files(struct pio_pcap_file_device_cont
|
||||
}
|
||||
|
||||
static int pcap_directory_dispatch(struct pio_pcap_file_device_context *pfile_dev_ctx, uint32_t rxq_id,
|
||||
struct packet **pkts, int nr_pkts)
|
||||
struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
int res = -1;
|
||||
struct timespec deadline;
|
||||
@@ -535,7 +555,14 @@ static int pcap_directory_dispatch(struct pio_pcap_file_device_context *pfile_de
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(pfile_info->file_name, current_file->file_name, strlen(current_file->file_name));
|
||||
res = strncpy_safe(pfile_info->file_name, current_file->file_name, sizeof(pfile_info->file_name));
|
||||
if (res < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "pfile_info file name copy failed.");
|
||||
FREE(current_file);
|
||||
FREE(pfile_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pfile_info->shared = &pfile_dev_ctx->shared;
|
||||
|
||||
if (init_pcap_file(pfile_info) < 0) {
|
||||
@@ -576,13 +603,7 @@ static int pcap_directory_dispatch(struct pio_pcap_file_device_context *pfile_de
|
||||
return res;
|
||||
}
|
||||
|
||||
static int pcap_file_exit(int status, struct timespec *last_processed)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pio_pcap_file_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts)
|
||||
int pio_pcap_file_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
struct pio_pcap_file_device_context *pfile_dev_ctx = pdev->entity.pcap_file_dev_ctx;
|
||||
if (nullptr == pfile_dev_ctx) {
|
||||
@@ -599,14 +620,12 @@ int pio_pcap_file_device_receive(struct packet_io_device *pdev, uint32_t rxq_id,
|
||||
res = pcap_directory_dispatch(pfile_dev_ctx, rxq_id, pkts, nr_pkts);
|
||||
}
|
||||
|
||||
//pcap_file_exit(status, &pfile_dev_ctx->shared.last_processed_ts);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void pio_pcap_file_device_pkt_free(__unused struct packet_io_device *pdev, __unused uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
void pio_pcap_file_device_pkt_free(__unused struct packet_io_device *pdev, __unused uint32_t qid, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
for (uint32_t i = 0; i < nr_pkts; i++) {
|
||||
for (int i = 0; i < nr_pkts; i++) {
|
||||
struct pio_packet *p = (struct pio_packet *)pkts[i];
|
||||
FREE(p);
|
||||
}
|
||||
@@ -642,26 +661,26 @@ void pio_pcap_file_instance_destroy(struct packet_io_instance *pinst)
|
||||
}
|
||||
}
|
||||
|
||||
void *pio_pcap_file_device_buff_ctrlzone(struct packet *p)
|
||||
void *pio_pcap_file_device_buff_ctrlzone(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return pkt->pkt_hdr;
|
||||
}
|
||||
|
||||
char *pio_pcap_file_device_buff_mtod(struct packet *p)
|
||||
char *pio_pcap_file_device_buff_mtod(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return (char *)pkt->pkt_payload;
|
||||
}
|
||||
|
||||
uint32_t pio_pcap_file_device_buff_buflen(struct packet *p)
|
||||
uint32_t pio_pcap_file_device_buff_buflen(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return (pkt->pkt_len + CUSTOM_ZONE_LEN);
|
||||
}
|
||||
|
||||
uint32_t pio_pcap_file_device_buff_datalen(struct packet *p)
|
||||
uint32_t pio_pcap_file_device_buff_datalen(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return (pkt->pkt_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,14 +127,14 @@ int pio_pcap_file_device_open(struct packet_io_device *pdev);
|
||||
*/
|
||||
int pio_pcap_file_device_close(struct packet_io_device *pdev);
|
||||
|
||||
int pio_pcap_file_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts);
|
||||
int pio_pcap_file_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
void pio_pcap_file_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts);
|
||||
void pio_pcap_file_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
void *pio_pcap_file_device_buff_ctrlzone(struct packet *p);
|
||||
void *pio_pcap_file_device_buff_ctrlzone(struct stellar_packet *p);
|
||||
|
||||
char *pio_pcap_file_device_buff_mtod(struct packet *p);
|
||||
char *pio_pcap_file_device_buff_mtod(struct stellar_packet *p);
|
||||
|
||||
uint32_t pio_pcap_file_device_buff_buflen(struct packet *p);
|
||||
uint32_t pio_pcap_file_device_buff_buflen(struct stellar_packet *p);
|
||||
|
||||
uint32_t pio_pcap_file_device_buff_datalen(struct packet *p);
|
||||
uint32_t pio_pcap_file_device_buff_datalen(struct stellar_packet *p);
|
||||
@@ -76,8 +76,13 @@ static int pcap_live_init(struct pio_pcap_live_device_context *pcap_live_dev_ctx
|
||||
|
||||
/* set bpf filter */
|
||||
if (strlen(g_engine_instance.config.packet_io.bpf_string) != 0) {
|
||||
strncpy(pcap_live_dev_ctx->bpf_string, g_engine_instance.config.packet_io.bpf_string,
|
||||
strlen(g_engine_instance.config.packet_io.bpf_string));
|
||||
res = strncpy_safe(pcap_live_dev_ctx->bpf_string, g_engine_instance.config.packet_io.bpf_string,
|
||||
sizeof(pcap_live_dev_ctx->bpf_string));
|
||||
if (res < 0) {
|
||||
log_error(ST_ERR_STR_COPY, "pcap_live_dev_ctx bpf string copy failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pcap_compile(pcap_live_dev_ctx->pcap_handle, &pcap_live_dev_ctx->filter,
|
||||
pcap_live_dev_ctx->bpf_string, 1, 0) < 0) {
|
||||
log_error(ST_ERR_BPF, "bpf compliation error %s",
|
||||
@@ -160,7 +165,7 @@ static void pcap_live_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_h
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t nr_rxq = plive_dev_ctx->pio_dev->rxq_num;
|
||||
//uint32_t nr_rxq = plive_dev_ctx->pio_dev->rxq_num;
|
||||
/*
|
||||
hash to specific queue id and enqueue
|
||||
hash_id = decode_packet(p) % nr_rxq;
|
||||
@@ -172,7 +177,7 @@ static void pcap_live_pkt_callback_oneshot(char *user, struct pcap_pkthdr *pkt_h
|
||||
pthread_mutex_unlock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
}
|
||||
|
||||
int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts)
|
||||
int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
@@ -198,7 +203,7 @@ int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id,
|
||||
pthread_mutex_lock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
do {
|
||||
p = pio_packet_dequeue(&plive_dev_ctx->pkt_queues[rxq_id]);
|
||||
pkts[i] = (struct packet *)p;
|
||||
pkts[i] = (struct stellar_packet *)p;
|
||||
i++;
|
||||
} while (p != nullptr && (i < nr_pkts));
|
||||
pthread_mutex_unlock(&plive_dev_ctx->pkt_queues[rxq_id].mutex_q);
|
||||
@@ -213,7 +218,7 @@ int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id,
|
||||
return res;
|
||||
}
|
||||
|
||||
int pio_pcap_live_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct packet **pkts, int nr_pkts)
|
||||
int pio_pcap_live_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
@@ -223,9 +228,8 @@ int pio_pcap_live_device_send(struct packet_io_device *pdev, uint32_t txq_id, st
|
||||
return res;
|
||||
}
|
||||
|
||||
int packet_q_len = nr_pkts;
|
||||
pthread_mutex_lock(&plive_dev_ctx->handle_mutex);
|
||||
for (uint32_t i = 0; i < nr_pkts; i++) {
|
||||
for (int i = 0; i < nr_pkts; i++) {
|
||||
struct pio_packet *p = (struct pio_packet *)pkts[i];
|
||||
res = pcap_sendpacket(plive_dev_ctx->pcap_handle, (u_char *)p->pkt_payload, p->pkt_len);
|
||||
}
|
||||
@@ -235,9 +239,9 @@ int pio_pcap_live_device_send(struct packet_io_device *pdev, uint32_t txq_id, st
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pio_pcap_live_device_pkt_free(__unused struct packet_io_device *pdev, __unused uint32_t qid, struct packet **pkts, int nr_pkts)
|
||||
void pio_pcap_live_device_pkt_free(__unused struct packet_io_device *pdev, __unused uint32_t qid, struct stellar_packet **pkts, int nr_pkts)
|
||||
{
|
||||
for (uint32_t i = 0; i < nr_pkts; i++) {
|
||||
for (int i = 0; i < nr_pkts; i++) {
|
||||
struct pio_packet *p = (struct pio_packet *)pkts[i];
|
||||
FREE(p);
|
||||
}
|
||||
@@ -273,26 +277,26 @@ void pio_pcap_live_instance_destroy(struct packet_io_instance *pinst)
|
||||
}
|
||||
}
|
||||
|
||||
void *pio_pcap_live_device_buff_ctrlzone(struct packet *p)
|
||||
void *pio_pcap_live_device_buff_ctrlzone(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return pkt->pkt_hdr;
|
||||
}
|
||||
|
||||
char *pio_pcap_live_device_buff_mtod(struct packet *p)
|
||||
char *pio_pcap_live_device_buff_mtod(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return (char *)pkt->pkt_payload;
|
||||
}
|
||||
|
||||
uint32_t pio_pcap_live_device_buff_buflen(struct packet *p)
|
||||
uint32_t pio_pcap_live_device_buff_buflen(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return (pkt->pkt_len + CUSTOM_ZONE_LEN);
|
||||
}
|
||||
|
||||
uint32_t pio_pcap_live_device_buff_datalen(struct packet *p)
|
||||
uint32_t pio_pcap_live_device_buff_datalen(struct stellar_packet *p)
|
||||
{
|
||||
struct pio_packet *pkt = (struct pio_packet *)p;
|
||||
return (pkt->pkt_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,16 +87,16 @@ int pio_pcap_live_device_open(struct packet_io_device *pdev);
|
||||
*/
|
||||
int pio_pcap_live_device_close(struct packet_io_device *pdev);
|
||||
|
||||
int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct packet **pkts, int nr_pkts);
|
||||
int pio_pcap_live_device_receive(struct packet_io_device *pdev, uint32_t rxq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
int pio_pcap_live_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct packet **pkts, int nr_pkts);
|
||||
int pio_pcap_live_device_send(struct packet_io_device *pdev, uint32_t txq_id, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
void pio_pcap_live_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct packet **pkts, int nr_pkts);
|
||||
void pio_pcap_live_device_pkt_free(struct packet_io_device *pdev, uint32_t qid, struct stellar_packet **pkts, int nr_pkts);
|
||||
|
||||
void *pio_pcap_live_device_buff_ctrlzone(struct packet *p);
|
||||
void *pio_pcap_live_device_buff_ctrlzone(struct stellar_packet *p);
|
||||
|
||||
char *pio_pcap_live_device_buff_mtod(struct packet *p);
|
||||
char *pio_pcap_live_device_buff_mtod(struct stellar_packet *p);
|
||||
|
||||
uint32_t pio_pcap_live_device_buff_buflen(struct packet *p);
|
||||
uint32_t pio_pcap_live_device_buff_buflen(struct stellar_packet *p);
|
||||
|
||||
uint32_t pio_pcap_live_device_buff_datalen(struct packet *p);
|
||||
uint32_t pio_pcap_live_device_buff_datalen(struct stellar_packet *p);
|
||||
@@ -4,7 +4,7 @@ add_executable(gtest_packet_io
|
||||
|
||||
target_link_libraries(
|
||||
gtest_packet_io
|
||||
gtest_main
|
||||
gtest
|
||||
packet_io
|
||||
dl
|
||||
pcap
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../packet_io.h"
|
||||
#include "packet_io.h"
|
||||
|
||||
TEST(PACKET_IO_Test, packet_io_instance_create) {
|
||||
struct packet_io_config ppio_config;
|
||||
struct packet_io_instance *ppio_inst = packet_io_instance_create("stellar", PACKET_IO_RUN_MODE_PCAP_FILE);
|
||||
EXPECT_NE(ppio_inst, nullptr);
|
||||
}
|
||||
|
||||
TEST(PACKET_IO_Test, packet_io_open_device) {
|
||||
struct packet_io_config ppio_config;
|
||||
struct packet_io_instance *ppio_inst = packet_io_instance_create("stellar", PACKET_IO_RUN_MODE_PCAP_FILE);
|
||||
EXPECT_EQ(packet_io_device_open(ppio_inst, nullptr, 1, 1), nullptr);
|
||||
EXPECT_EQ(packet_io_device_open(ppio_inst, NULL, 1, 1), nullptr);
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
include_directories(${CMAKE_SOURCE_DIR}/session_manager/)
|
||||
add_library(plugin_manager
|
||||
plugin_manager.cpp
|
||||
)
|
||||
add_library(plugin_manager
|
||||
plugin_manager_config.cpp
|
||||
plugin_manager_module.cpp
|
||||
plugin_manager_util.cpp
|
||||
plugin_manager.cpp
|
||||
)
|
||||
|
||||
target_include_directories(plugin_manager PUBLIC ${CMAKE_SOURCE_DIR})
|
||||
|
||||
add_subdirectory(test)
|
||||
@@ -1,60 +1,547 @@
|
||||
#include "plugin.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "uthash/uthash.h"
|
||||
|
||||
#include "session_manager.h"
|
||||
#include "plugin_manager_module.h"
|
||||
|
||||
#include "utils.h"
|
||||
/******************************************************************************
|
||||
* CallBack Runtime (For Per Session)
|
||||
******************************************************************************/
|
||||
|
||||
struct session_event_callback
|
||||
enum plugin_status
|
||||
{
|
||||
const char *session_name;
|
||||
fn_session_event_callback callback;
|
||||
TAILQ_ENTRY(session_event_callback) session_event_cb_tq_entries;
|
||||
UT_hash_handle hh;
|
||||
PLUGIN_STATUS_NORMAL = 0x00,
|
||||
PLUGIN_STATUS_DETTACH_ME = 0x01,
|
||||
PLUGIN_STATUS_TAKEN_OVER = 0x02, // Noitce: this is taken over not take over
|
||||
};
|
||||
|
||||
TAILQ_HEAD(session_event_callback_list, session_event_callback);
|
||||
|
||||
struct session_event_callback_map
|
||||
struct callback_runtime
|
||||
{
|
||||
struct session_event_callback_list session_ev_cb_list;
|
||||
UT_hash_handle hh;
|
||||
void *cb_args;
|
||||
fn_session_event_callback *event_cb;
|
||||
|
||||
enum session_event_type event;
|
||||
enum plugin_status status;
|
||||
int is_be_called;
|
||||
};
|
||||
|
||||
struct session_plugin_ctx
|
||||
{
|
||||
int callback_index;
|
||||
int callback_num;
|
||||
struct callback_runtime *callbacks;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* CallBack Static (For Per Plugin Manager)
|
||||
******************************************************************************/
|
||||
|
||||
struct callback_static
|
||||
{
|
||||
enum session_event_type event;
|
||||
fn_session_event_callback *event_cb;
|
||||
};
|
||||
|
||||
struct plugin_manager_eventcb
|
||||
{
|
||||
char session_name[MAX_SESSION_NAME_LENGTH]; // key
|
||||
|
||||
int callback_num; // val size
|
||||
struct callback_static *callbacks; // val: dynamic array
|
||||
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* Struct plugin_manager
|
||||
******************************************************************************/
|
||||
|
||||
struct plugin_manager
|
||||
{
|
||||
struct session_event_callback_list fixed_event_cbs[SESSION_TYPE_MAX];
|
||||
struct session_event_callback_map *session_ev_cb_map;
|
||||
int used_module_num;
|
||||
int used_config_num;
|
||||
int used_evencb_num; // only plugin register eventcb numbers
|
||||
|
||||
struct plugin_manager_module *modules[MAX_PLUGIN_NUM];
|
||||
struct plugin_manager_config *configs[MAX_PLUGIN_NUM];
|
||||
struct plugin_manager_eventcb *evcb_htable;
|
||||
};
|
||||
|
||||
struct plugin_manager g_plug_mgr;
|
||||
/******************************************************************************
|
||||
* Create/Destory plugin ctx (per session)
|
||||
******************************************************************************/
|
||||
|
||||
void plugin_manager_dispatch(struct session_event *event)
|
||||
static struct session_plugin_ctx *plugin_manager_create_plugin_ctx(struct plugin_manager *plug_mgr, const char *session_name)
|
||||
{
|
||||
struct session *s = container_of(event, struct session, cur_ev);
|
||||
struct session_event_callback_map *t_map;
|
||||
struct session_event_callback *session_ev_cb;
|
||||
HASH_FIND(hh, g_plug_mgr.session_ev_cb_map, s->name, strlen(s->name), t_map);
|
||||
if(!t_map) return;
|
||||
switch (s->state)
|
||||
if (session_name == NULL || strlen(session_name) == 0)
|
||||
{
|
||||
case SESSION_EVENT_OPENING:
|
||||
TAILQ_FOREACH(session_ev_cb, &t_map->session_ev_cb_list, session_event_cb_tq_entries)
|
||||
{
|
||||
struct session_event *ev = CALLOC(struct session_event, 1);
|
||||
ev->callback = session_ev_cb->callback;
|
||||
ev->callback(s, SESSION_EVENT_OPENING, NULL, NULL, 0, &ev->cb_pme);
|
||||
if(ev->state == 1)
|
||||
{
|
||||
TAILQ_INSERT_TAIL(&s->ev_list, ev, session_event_tq_entries);
|
||||
}
|
||||
else
|
||||
{
|
||||
FREE(ev);// TODO;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
plugin_manager_log(ERROR, "invalid parameter, session name is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
struct plugin_manager_eventcb *elem;
|
||||
HASH_FIND_STR(plug_mgr->evcb_htable, session_name, elem);
|
||||
if (elem == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't find event callback for session name '%s'", session_name);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct session_plugin_ctx *plug_ctx = safe_alloc(struct session_plugin_ctx, 1);
|
||||
plug_ctx->callback_num = elem->callback_num;
|
||||
plug_ctx->callbacks = safe_alloc(struct callback_runtime, plug_ctx->callback_num);
|
||||
|
||||
for (int i = 0; i < plug_ctx->callback_num; i++)
|
||||
{
|
||||
plug_ctx->callbacks[i].is_be_called = 0;
|
||||
plug_ctx->callbacks[i].status = PLUGIN_STATUS_NORMAL;
|
||||
plug_ctx->callbacks[i].event = elem->callbacks[i].event;
|
||||
plug_ctx->callbacks[i].event_cb = elem->callbacks[i].event_cb;
|
||||
plug_ctx->callbacks[i].cb_args = NULL;
|
||||
}
|
||||
|
||||
return plug_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
static void plugin_manager_destory_plugin_ctx(struct session_plugin_ctx *plug_ctx)
|
||||
{
|
||||
if (plug_ctx)
|
||||
{
|
||||
safe_free(plug_ctx->callbacks);
|
||||
safe_free(plug_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Tools for managing plugins
|
||||
******************************************************************************/
|
||||
|
||||
static int plugin_manager_parse_plugins(struct plugin_manager *plug_mgr, const char *file)
|
||||
{
|
||||
char line_buffer[4096] = {0};
|
||||
|
||||
if (strlen(file) <= 0)
|
||||
{
|
||||
plugin_manager_log(ERROR, "Invalid parameter, plugin config file name cannot be empty");
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(file, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't open %s, %s", file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(line_buffer, sizeof(line_buffer), fp))
|
||||
{
|
||||
if ('#' == line_buffer[0] || '\n' == line_buffer[0])
|
||||
{
|
||||
memset(line_buffer, 0, sizeof(line_buffer));
|
||||
continue;
|
||||
}
|
||||
line_buffer[strcspn(line_buffer, "\r\n")] = 0;
|
||||
|
||||
if (plug_mgr->used_config_num >= MAX_PLUGIN_NUM)
|
||||
{
|
||||
plugin_manager_log(ERROR, "the number of registered plugins exceeds the limit and cannot exceed %d", MAX_PLUGIN_NUM);
|
||||
goto err;
|
||||
}
|
||||
|
||||
struct plugin_manager_config *config = plugin_mangager_config_create();
|
||||
if (plugin_mangager_config_parse(config, line_buffer) == -1)
|
||||
{
|
||||
plugin_mangager_config_destory(config);
|
||||
goto err;
|
||||
}
|
||||
|
||||
plug_mgr->configs[plug_mgr->used_config_num] = config;
|
||||
plug_mgr->used_config_num++;
|
||||
memset(line_buffer, 0, sizeof(line_buffer));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int plugin_manager_open_plugins(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
for (int i = 0; i < plug_mgr->used_config_num; i++)
|
||||
{
|
||||
struct plugin_manager_config *config = plug_mgr->configs[i];
|
||||
struct plugin_manager_module *module = plugin_manager_module_open(config);
|
||||
if (module == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
plugin_manager_module_dump(module, config);
|
||||
|
||||
plug_mgr->modules[plug_mgr->used_module_num] = module;
|
||||
plug_mgr->used_module_num++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int plugin_manager_register_plugins(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
for (int i = 0; i < plug_mgr->used_module_num; i++)
|
||||
{
|
||||
struct plugin_manager_module *module = plug_mgr->modules[i];
|
||||
if (plugin_manager_module_register(plug_mgr, module) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
plug_mgr->used_evencb_num++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int plugin_manager_init_plugins(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
for (int i = 0; i < plug_mgr->used_module_num; i++)
|
||||
{
|
||||
struct plugin_manager_module *module = plug_mgr->modules[i];
|
||||
if (plugin_manager_module_init(module) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
double percentage = ((double)(i + 1)) / ((double)plug_mgr->used_module_num) * ((double)100);
|
||||
plugin_manager_log(INFO, "Plugin initialization progress: [%.2f%%]", percentage);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void plugin_manager_exit_plugins(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
if (plug_mgr && plug_mgr->used_module_num)
|
||||
{
|
||||
for (int i = 0; i < plug_mgr->used_module_num; i++)
|
||||
{
|
||||
struct plugin_manager_module *module = plug_mgr->modules[i];
|
||||
plugin_manager_module_exit(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void plugin_manager_close_plugins(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
if (plug_mgr && plug_mgr->used_module_num)
|
||||
{
|
||||
for (int i = 0; i < plug_mgr->used_module_num; i++)
|
||||
{
|
||||
struct plugin_manager_module *module = plug_mgr->modules[i];
|
||||
plugin_manager_module_close(module);
|
||||
}
|
||||
plug_mgr->used_module_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// deparse for destory parse
|
||||
static void plugin_manager_deparse_plugins(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
if (plug_mgr && plug_mgr->used_config_num)
|
||||
{
|
||||
for (int i = 0; i < plug_mgr->used_config_num; i++)
|
||||
{
|
||||
struct plugin_manager_config *config = plug_mgr->configs[i];
|
||||
plugin_mangager_config_destory(config);
|
||||
}
|
||||
plug_mgr->used_config_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public API for managing plugins
|
||||
******************************************************************************/
|
||||
|
||||
int plugin_manager_load(struct plugin_manager *plug_mgr, const char *file)
|
||||
{
|
||||
if (plugin_manager_parse_plugins(plug_mgr, file) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (plugin_manager_open_plugins(plug_mgr) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (plugin_manager_register_plugins(plug_mgr) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (plugin_manager_init_plugins(plug_mgr) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plugin_manager_unload(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
plugin_manager_exit_plugins(plug_mgr);
|
||||
plugin_manager_close_plugins(plug_mgr);
|
||||
plugin_manager_deparse_plugins(plug_mgr);
|
||||
}
|
||||
|
||||
struct plugin_manager *plugin_manager_create()
|
||||
{
|
||||
struct plugin_manager *plug_mgr = safe_alloc(struct plugin_manager, 1);
|
||||
|
||||
plug_mgr->used_module_num = 0;
|
||||
plug_mgr->used_config_num = 0;
|
||||
plug_mgr->used_evencb_num = 0;
|
||||
|
||||
plug_mgr->evcb_htable = NULL;
|
||||
|
||||
return plug_mgr;
|
||||
}
|
||||
|
||||
void plugin_manager_destory(struct plugin_manager *plug_mgr)
|
||||
{
|
||||
if (plug_mgr)
|
||||
{
|
||||
if (plug_mgr->evcb_htable)
|
||||
{
|
||||
struct plugin_manager_eventcb *elem;
|
||||
struct plugin_manager_eventcb *tmp;
|
||||
HASH_ITER(hh, plug_mgr->evcb_htable, elem, tmp)
|
||||
{
|
||||
HASH_DEL(plug_mgr->evcb_htable, elem);
|
||||
|
||||
safe_free(elem->callbacks);
|
||||
safe_free(elem);
|
||||
}
|
||||
|
||||
plug_mgr->evcb_htable = NULL;
|
||||
plug_mgr->used_evencb_num = 0;
|
||||
}
|
||||
|
||||
plugin_manager_unload(plug_mgr);
|
||||
safe_free(plug_mgr);
|
||||
}
|
||||
}
|
||||
|
||||
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_name, enum session_event_type event, fn_session_event_callback *event_cb)
|
||||
{
|
||||
if (strlen(session_name) <= 0)
|
||||
{
|
||||
plugin_manager_log(ERROR, "invalid parameter, session name is empty");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strlen(session_name) > MAX_SESSION_NAME_LENGTH)
|
||||
{
|
||||
plugin_manager_log(ERROR, "invalid parameter, session name '%s' is too long and exceeds '%d' bytes", session_name, MAX_SESSION_NAME_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (event_cb == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "invalid parameter, the event callback corresponding to the session name '%s' is null", session_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct plugin_manager_eventcb *elem;
|
||||
HASH_FIND_STR(plug_mgr->evcb_htable, session_name, elem);
|
||||
// session_name exists, add a new cb to the end of the callbacks dynamic array
|
||||
if (elem)
|
||||
{
|
||||
elem->callbacks = (struct callback_static *)realloc(elem->callbacks, (elem->callback_num + 1) * sizeof(struct callback_static));
|
||||
|
||||
elem->callbacks[elem->callback_num].event = event;
|
||||
elem->callbacks[elem->callback_num].event_cb = event_cb;
|
||||
|
||||
elem->callback_num++;
|
||||
}
|
||||
// session_name does not exist, allocate a new node elem, and add elem to the hash table
|
||||
else
|
||||
{
|
||||
elem = safe_alloc(struct plugin_manager_eventcb, 1);
|
||||
memcpy(elem->session_name, session_name, strlen(session_name));
|
||||
|
||||
elem->callbacks = (struct callback_static *)realloc(elem->callbacks, (elem->callback_num + 1) * sizeof(struct callback_static));
|
||||
|
||||
elem->callbacks[elem->callback_num].event = event;
|
||||
elem->callbacks[elem->callback_num].event_cb = event_cb;
|
||||
|
||||
elem->callback_num++;
|
||||
|
||||
HASH_ADD_STR(plug_mgr->evcb_htable, session_name, elem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event)
|
||||
{
|
||||
const struct stellar_session *seesion = stellar_event_get_session(event);
|
||||
struct session_plugin_ctx *plug_ctx = stellar_event_get_plugin_ctx(event);
|
||||
enum session_event_type event_type = stellar_event_get_type(event);
|
||||
const char *session_name = stellar_event_get_session_name(event);
|
||||
struct stellar_packet *packet = stellar_event_get_packet(event);
|
||||
uint16_t payload_len = stellar_event_get_payload_length(event);
|
||||
const char *payload = stellar_event_get_payload(event);
|
||||
|
||||
assert(seesion);
|
||||
assert(session_name);
|
||||
|
||||
char event_str_buffer[1024] = {0};
|
||||
session_event_type_int2str(event_type, event_str_buffer, 1024);
|
||||
|
||||
// the same session may trigger multi times opening events
|
||||
if (event_type & SESSION_EVENT_OPENING)
|
||||
{
|
||||
if (plug_ctx == NULL)
|
||||
{
|
||||
plug_ctx = plugin_manager_create_plugin_ctx(plug_mgr, session_name);
|
||||
if (plug_ctx == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't create runtime plugin ctx for session '%s', Please check whether the callback is registered in the current session", session_name);
|
||||
return;
|
||||
}
|
||||
stellar_event_set_plugin_ctx(event, plug_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (plug_ctx)
|
||||
{
|
||||
for (int i = 0; i < plug_ctx->callback_num; i++)
|
||||
{
|
||||
struct callback_runtime *runtime = &plug_ctx->callbacks[i];
|
||||
|
||||
if (runtime->status == PLUGIN_STATUS_DETTACH_ME)
|
||||
{
|
||||
plugin_manager_log(DEBUG, "dispatch, skip event_cb: %p, plugin status: 'dettach me', session: %s, event: (%d, %s)", runtime->event_cb, session_name, event_type, event_str_buffer);
|
||||
continue;
|
||||
}
|
||||
else if (runtime->status == PLUGIN_STATUS_TAKEN_OVER)
|
||||
{
|
||||
if ((event_type & SESSION_EVENT_CLOSING) && (runtime->event & SESSION_EVENT_CLOSING) && runtime->is_be_called)
|
||||
{
|
||||
plug_ctx->callback_index = i;
|
||||
plugin_manager_log(DEBUG, "dispatch, run event_cb: %p, plugin status: 'taken over', session: %s, event: (%d, %s)", runtime->event_cb, session_name, event_type, event_str_buffer);
|
||||
runtime->event_cb(seesion, SESSION_EVENT_CLOSING, packet, payload, payload_len, &runtime->cb_args);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin_manager_log(DEBUG, "dispatch, skip event_cb: %p, plugin status: 'taken over', session: %s, event: (%d, %s)", runtime->event_cb, session_name, event_type, event_str_buffer);
|
||||
}
|
||||
}
|
||||
else if (runtime->status == PLUGIN_STATUS_NORMAL)
|
||||
{
|
||||
if (runtime->event & event_type)
|
||||
{
|
||||
plug_ctx->callback_index = i;
|
||||
plugin_manager_log(DEBUG, "dispatch, run event_cb: %p, plugin status: 'normal', session: %s, event: (%d, %s)", runtime->event_cb, session_name, event_type, event_str_buffer);
|
||||
runtime->event_cb(seesion, event_type, packet, payload, payload_len, &runtime->cb_args);
|
||||
runtime->is_be_called = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin_manager_log(DEBUG, "dispatch, skip event_cb: %p, plugin status: 'normal', session: %s, event: (%d, %s)", runtime->event_cb, session_name, event_type, event_str_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin_manager_log(ERROR, "session '%s' runtime plugin ctx is null when running event callback", session_name);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (event_type & SESSION_EVENT_CLOSING)
|
||||
{
|
||||
plugin_manager_destory_plugin_ctx(plug_ctx);
|
||||
stellar_event_set_plugin_ctx(event, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public API For Plugin
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* pm_session_dettach_me just sets the flag to disable this plugin and no longer call this event callback.
|
||||
* Before calling pm_session_dettach_me, the current plugin must release related resources for the current session.
|
||||
*/
|
||||
void pm_session_dettach_me(const struct stellar_session *session)
|
||||
{
|
||||
struct session_plugin_ctx *plugin_ctx = stellar_session_get_plugin_ctx(session);
|
||||
assert(plugin_ctx);
|
||||
struct callback_runtime *runtime_me = &plugin_ctx->callbacks[plugin_ctx->callback_index];
|
||||
|
||||
runtime_me->status = PLUGIN_STATUS_DETTACH_ME;
|
||||
plugin_manager_log(DEBUG, "%p dettach me, disable event_cb: %p, session: %s", runtime_me->event_cb, runtime_me->event_cb, stellar_session_get_name(session));
|
||||
}
|
||||
|
||||
/*
|
||||
* The current plugin(cb2) takes over the current session, the pm_session_take_over setting flag disables other plugins,
|
||||
* and the current session does not call other plugins except for the SESSION_EVENT_CLOSING event.
|
||||
*
|
||||
* +-----+ +-----+ +-----+ +-----+
|
||||
* Plugin runtime callback list: | cb1 |-->| cb2 |-->| cb3 |-->| cb4 |
|
||||
* +-----+ +-----+ +-----+ +-----+
|
||||
* /|\
|
||||
* |
|
||||
* plugin cb2 run pm_session_take_over
|
||||
*
|
||||
* A plugin(cb1/cb3/cb4) that is taken over, if the plugin was called before being taken over and has a registered SESSION_EVENT_CLOSING event,
|
||||
* it will be called again when the SESSION_EVENT_CLOSING event comes. Otherwise, the plugin will not be called.
|
||||
*/
|
||||
void pm_session_take_over(const struct stellar_session *session)
|
||||
{
|
||||
struct session_plugin_ctx *plugin_ctx = stellar_session_get_plugin_ctx(session);
|
||||
assert(plugin_ctx);
|
||||
struct callback_runtime *runtime_me = &plugin_ctx->callbacks[plugin_ctx->callback_index];
|
||||
|
||||
for (int i = 0; i < plugin_ctx->callback_num; i++)
|
||||
{
|
||||
if (i != plugin_ctx->callback_index)
|
||||
{
|
||||
struct callback_runtime *runtime_other = &plugin_ctx->callbacks[i];
|
||||
runtime_other->status = PLUGIN_STATUS_TAKEN_OVER;
|
||||
plugin_manager_log(DEBUG, "%p take over, disable event_cb: %p, session: %s", runtime_me->event_cb, runtime_other->event_cb, stellar_session_get_name(session));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Util For Gtest
|
||||
******************************************************************************/
|
||||
|
||||
void *pm_session_get_plugin_pme(const struct stellar_session *session)
|
||||
{
|
||||
struct session_plugin_ctx *plugin_ctx = stellar_session_get_plugin_ctx(session);
|
||||
assert(plugin_ctx);
|
||||
struct callback_runtime *runtime_me = &plugin_ctx->callbacks[plugin_ctx->callback_index];
|
||||
|
||||
return runtime_me->cb_args;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Suppport LUA plugins
|
||||
******************************************************************************/
|
||||
|
||||
// TODO
|
||||
@@ -1,6 +1,29 @@
|
||||
#ifndef _PLUGIN_MANAGER_H
|
||||
#define _PLUGIN_MANAGER_H
|
||||
|
||||
#pragma once
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "plugin.h"
|
||||
#include "sdk/include/session.h"
|
||||
|
||||
void plugin_manager_dispatch(struct session_event *event);
|
||||
struct plugin_manager;
|
||||
|
||||
struct plugin_manager *plugin_manager_create();
|
||||
void plugin_manager_destory(struct plugin_manager *plug_mgr);
|
||||
|
||||
int plugin_manager_load(struct plugin_manager *plug_mgr, const char *file);
|
||||
void plugin_manager_unload(struct plugin_manager *plug_mgr);
|
||||
|
||||
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_name, enum session_event_type event, fn_session_event_callback *event_cb);
|
||||
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event);
|
||||
|
||||
// only use for gtest
|
||||
void *pm_session_get_plugin_pme(const struct stellar_session *session);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
281
src/plugin_manager/plugin_manager_config.cpp
Normal file
281
src/plugin_manager/plugin_manager_config.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "toml/toml.h"
|
||||
|
||||
#include "plugin_manager_config.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Private API (For Parse)
|
||||
******************************************************************************/
|
||||
|
||||
static int toml_parse_string(toml_table_t *table, const char *string_key, const char *file, char **out)
|
||||
{
|
||||
toml_datum_t string_val = toml_string_in(table, string_key);
|
||||
if (!string_val.ok)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't find '%s' configuration iterm in %s", string_key, file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strlen(string_val.u.s) <= 0)
|
||||
{
|
||||
plugin_manager_log(ERROR, "invalid value for '%s' configuration item in %s", string_key, file);
|
||||
safe_free(string_val.u.s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out = safe_dup(string_val.u.s);
|
||||
safe_free(string_val.u.s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int toml_parse_table(toml_table_t *table, const char *string_key, const char *file, toml_table_t **out)
|
||||
{
|
||||
*out = toml_table_in(table, string_key);
|
||||
if (*out == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't find '%s' section in %s", string_key, file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int toml_parse_plugin_section(toml_table_t *root, struct plugin_manager_config *config, const char *file)
|
||||
{
|
||||
toml_table_t *plugin_section = NULL;
|
||||
|
||||
if (toml_parse_table(root, "PLUGINFO", file, &plugin_section) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (toml_parse_string(plugin_section, "INIT_FUNC", file, &config->plugin_section.init_func_name) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (toml_parse_string(plugin_section, "EXIT_FUNC", file, &config->plugin_section.exit_func_name) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (toml_parse_string(plugin_section, "LIBRARY_PATH", file, &config->plugin_section.lib_path) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int toml_parse_session_section(toml_table_t *root, struct plugin_manager_config *config, const char *file)
|
||||
{
|
||||
toml_table_t *session_section = NULL;
|
||||
toml_table_t *sub_session_section = NULL;
|
||||
const char *session_name = NULL;
|
||||
toml_array_t *event_type_array = NULL;
|
||||
toml_datum_t type_str;
|
||||
enum session_event_type type_int;
|
||||
|
||||
if (toml_parse_table(root, "SESSION_NAME", file, &session_section) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < toml_table_ntab(session_section); i++)
|
||||
{
|
||||
session_name = NULL;
|
||||
sub_session_section = NULL;
|
||||
event_type_array = NULL;
|
||||
|
||||
config->session_section = (struct session_section_config *)realloc(config->session_section, sizeof(struct session_section_config) * (config->session_section_num + 1));
|
||||
config->session_section[config->session_section_num].event = SESSION_EVENT_UNKNOWN;
|
||||
config->session_section[config->session_section_num].cb_func_name = NULL;
|
||||
memset(config->session_section[config->session_section_num].session_name, 0, MAX_SESSION_NAME_LENGTH);
|
||||
|
||||
// parse session name
|
||||
session_name = toml_key_in(session_section, i);
|
||||
int session_name_len = strlen(session_name);
|
||||
if (session_name_len <= 0)
|
||||
{
|
||||
plugin_manager_log(ERROR, "invalid value for 'SESSION_NAME' configuration item in %s", file);
|
||||
return -1;
|
||||
}
|
||||
if (session_name_len > MAX_SESSION_NAME_LENGTH)
|
||||
{
|
||||
plugin_manager_log(ERROR, "invalid value for 'SESSION_NAME' configuration item in %s, '%s' is too long and exceeds %d bytes", file, session_name, MAX_SESSION_NAME_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
if (toml_parse_table(session_section, session_name, file, &sub_session_section) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
strncpy(config->session_section[config->session_section_num].session_name, session_name, session_name_len);
|
||||
|
||||
// parse session event callback
|
||||
if (toml_parse_string(sub_session_section, "SESSION_EVENT_CALLBACK", file, &config->session_section[config->session_section_num].cb_func_name) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
event_type_array = toml_array_in(sub_session_section, "SESSION_EVENT_TYPE");
|
||||
if (event_type_array == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't find 'SESSION_EVENT_TYPE' configuration iterm in '[SESSION_NAME.%s]' section of %s", session_name, file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < toml_array_nelem(event_type_array); i++)
|
||||
{
|
||||
type_int = SESSION_EVENT_UNKNOWN;
|
||||
|
||||
type_str = toml_string_at(event_type_array, i);
|
||||
if (!type_str.ok)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't parse 'SESSION_EVENT_TYPE' configuration iterm in '[SESSION_NAME.%s]' section of %s", session_name, file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
type_int = session_event_type_str2int(type_str.u.s);
|
||||
if (type_int == SESSION_EVENT_UNKNOWN)
|
||||
{
|
||||
plugin_manager_log(ERROR, "invalid value '%s' for 'SESSION_EVENT_TYPE' configuration item in '[SESSION_NAME.%s]' section of %s", type_str.u.s, session_name, file);
|
||||
safe_free(type_str.u.s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
(config->session_section[config->session_section_num].event) = (enum session_event_type)((config->session_section[config->session_section_num].event) | type_int);
|
||||
safe_free(type_str.u.s);
|
||||
}
|
||||
if ((config->session_section[config->session_section_num].event & SESSION_EVENT_CLOSING) == 0)
|
||||
{
|
||||
plugin_manager_log(WARN, "can't find 'SESSION_EVENT_CLOSING' value for 'SESSION_EVENT_TYPE' configuration item in '[SESSION_NAME.%s]' section of %s", session_name, file);
|
||||
}
|
||||
|
||||
config->session_section_num++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Public API
|
||||
******************************************************************************/
|
||||
|
||||
struct plugin_manager_config *plugin_mangager_config_create()
|
||||
{
|
||||
struct plugin_manager_config *config = safe_alloc(struct plugin_manager_config, 1);
|
||||
|
||||
config->file_path = NULL;
|
||||
config->session_section_num = 0;
|
||||
config->session_section = NULL;
|
||||
config->plugin_section.init_func_name = NULL;
|
||||
config->plugin_section.exit_func_name = NULL;
|
||||
config->plugin_section.lib_path = NULL;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void plugin_mangager_config_destory(struct plugin_manager_config *config)
|
||||
{
|
||||
if (config)
|
||||
{
|
||||
safe_free(config->file_path);
|
||||
|
||||
safe_free(config->plugin_section.init_func_name);
|
||||
safe_free(config->plugin_section.exit_func_name);
|
||||
safe_free(config->plugin_section.lib_path);
|
||||
|
||||
if (config->session_section)
|
||||
{
|
||||
for (int i = 0; i < config->session_section_num; i++)
|
||||
{
|
||||
struct session_section_config *temp = &config->session_section[i];
|
||||
safe_free(temp->cb_func_name);
|
||||
}
|
||||
config->session_section_num = 0;
|
||||
safe_free(config->session_section);
|
||||
}
|
||||
|
||||
safe_free(config);
|
||||
}
|
||||
}
|
||||
|
||||
void plugin_mangager_config_dump(struct plugin_manager_config *config)
|
||||
{
|
||||
if (config)
|
||||
{
|
||||
plugin_manager_log(DEBUG, "[CONFIG_FILE] : %s", config->file_path);
|
||||
plugin_manager_log(DEBUG, "[PLUGINFO]->INIT_FUNC : %s", config->plugin_section.init_func_name);
|
||||
plugin_manager_log(DEBUG, "[PLUGINFO]->EXIT_FUNC : %s", config->plugin_section.exit_func_name);
|
||||
plugin_manager_log(DEBUG, "[PLUGINFO]->LIBRARY_PATH : %s", config->plugin_section.lib_path);
|
||||
|
||||
if (config->session_section)
|
||||
{
|
||||
for (int i = 0; i < config->session_section_num; i++)
|
||||
{
|
||||
char tmp_buffer[1024] = {0};
|
||||
struct session_section_config *temp = &config->session_section[i];
|
||||
session_event_type_int2str(temp->event, tmp_buffer, 1024);
|
||||
plugin_manager_log(DEBUG, "[SESSION_NAME.%s]->SESSION_EVENT_TYPE : %d, %s", temp->session_name, temp->event, tmp_buffer);
|
||||
plugin_manager_log(DEBUG, "[SESSION_NAME.%s]->SESSION_EVENT_CALLBACK : %s", temp->session_name, temp->cb_func_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int plugin_mangager_config_parse(struct plugin_manager_config *config, const char *file)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
toml_table_t *root = NULL;
|
||||
char errbuf[200] = {0};
|
||||
|
||||
config->file_path = safe_dup(file);
|
||||
|
||||
fp = fopen(config->file_path, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't open %s, %s", config->file_path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
root = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||
if (root == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "toml parsing %s failed, %s", file, errbuf);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (toml_parse_plugin_section(root, config, file) == -1)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (toml_parse_session_section(root, config, file) == -1)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
toml_free(root);
|
||||
fclose(fp);
|
||||
|
||||
plugin_manager_log(INFO, "plugin config file '%s' parse success", config->file_path);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (root)
|
||||
{
|
||||
toml_free(root);
|
||||
}
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
45
src/plugin_manager/plugin_manager_config.h
Normal file
45
src/plugin_manager/plugin_manager_config.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef _PLUGIN_MANAGER_CONFIG_H
|
||||
#define _PLUGIN_MANAGER_CONFIG_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "plugin_manager_util.h"
|
||||
#include "sdk/include/session.h"
|
||||
|
||||
struct session_section_config
|
||||
{
|
||||
char session_name[MAX_SESSION_NAME_LENGTH];
|
||||
char *cb_func_name;
|
||||
enum session_event_type event;
|
||||
};
|
||||
|
||||
struct plugin_section_config
|
||||
{
|
||||
char *init_func_name;
|
||||
char *exit_func_name;
|
||||
char *lib_path;
|
||||
};
|
||||
|
||||
struct plugin_manager_config
|
||||
{
|
||||
char *file_path;
|
||||
|
||||
int session_section_num;
|
||||
struct session_section_config *session_section; // array
|
||||
struct plugin_section_config plugin_section;
|
||||
};
|
||||
|
||||
struct plugin_manager_config *plugin_mangager_config_create();
|
||||
void plugin_mangager_config_destory(struct plugin_manager_config *config);
|
||||
|
||||
int plugin_mangager_config_parse(struct plugin_manager_config *config, const char *file);
|
||||
void plugin_mangager_config_dump(struct plugin_manager_config *config);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
193
src/plugin_manager/plugin_manager_module.cpp
Normal file
193
src/plugin_manager/plugin_manager_module.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#include <time.h>
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sdk/include/plugin.h"
|
||||
#include "plugin_manager_module.h"
|
||||
#include "plugin_manager.h"
|
||||
|
||||
struct plugin_manager_module_evcb
|
||||
{
|
||||
char session_name[MAX_SESSION_NAME_LENGTH];
|
||||
fn_session_event_callback *event_cb_ptr;
|
||||
enum session_event_type event;
|
||||
};
|
||||
|
||||
struct plugin_manager_module
|
||||
{
|
||||
char *lib_path;
|
||||
void *dl_handle;
|
||||
|
||||
plugin_init_callback *init_cb_ptr;
|
||||
plugin_exit_callback *exit_cb_ptr;
|
||||
|
||||
struct plugin_manager_module_evcb *evcbs;
|
||||
int evcbs_num;
|
||||
};
|
||||
|
||||
void plugin_manager_module_close(struct plugin_manager_module *module)
|
||||
{
|
||||
if (module)
|
||||
{
|
||||
if (module->exit_cb_ptr)
|
||||
{
|
||||
module->exit_cb_ptr();
|
||||
}
|
||||
|
||||
if (module->dl_handle)
|
||||
{
|
||||
dlclose(module->dl_handle);
|
||||
module->dl_handle = NULL;
|
||||
}
|
||||
|
||||
safe_free(module->lib_path);
|
||||
safe_free(module->evcbs);
|
||||
module->evcbs_num = 0;
|
||||
|
||||
safe_free(module);
|
||||
}
|
||||
}
|
||||
|
||||
struct plugin_manager_module *plugin_manager_module_open(struct plugin_manager_config *config)
|
||||
{
|
||||
if (config == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct plugin_manager_module *module = safe_alloc(struct plugin_manager_module, 1);
|
||||
|
||||
module->lib_path = safe_dup(config->plugin_section.lib_path);
|
||||
|
||||
// RTLD_NOW | RTLD_GLOBAL
|
||||
module->evcbs_num = 0;
|
||||
module->dl_handle = dlopen(module->lib_path, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND);
|
||||
if (module->dl_handle == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't dlopen %s, %s", module->lib_path, dlerror());
|
||||
goto err;
|
||||
}
|
||||
|
||||
module->init_cb_ptr = (plugin_init_callback *)(dlsym(module->dl_handle, config->plugin_section.init_func_name));
|
||||
if (module->init_cb_ptr == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't find symbol name of '%s' in dynamic library %s, %s",
|
||||
config->plugin_section.init_func_name, module->lib_path, dlerror());
|
||||
goto err;
|
||||
}
|
||||
|
||||
module->exit_cb_ptr = (plugin_exit_callback *)(dlsym(module->dl_handle, config->plugin_section.exit_func_name));
|
||||
if (module->exit_cb_ptr == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't find symbol name of '%s' in dynamic library %s, %s",
|
||||
config->plugin_section.exit_func_name, module->lib_path, dlerror());
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (config->session_section)
|
||||
{
|
||||
module->evcbs = safe_alloc(struct plugin_manager_module_evcb, config->session_section_num);
|
||||
module->evcbs_num = config->session_section_num;
|
||||
|
||||
for (int i = 0; i < config->session_section_num; i++)
|
||||
{
|
||||
struct session_section_config *session_config = &config->session_section[i];
|
||||
struct plugin_manager_module_evcb *event_cb = &module->evcbs[i];
|
||||
|
||||
strncpy(event_cb->session_name, session_config->session_name, strlen(session_config->session_name));
|
||||
event_cb->event = session_config->event;
|
||||
event_cb->event_cb_ptr = (fn_session_event_callback *)(dlsym(module->dl_handle, session_config->cb_func_name));
|
||||
if (event_cb->event_cb_ptr == NULL)
|
||||
{
|
||||
plugin_manager_log(ERROR, "can't find symbol name of '%s' in dynamic library %s, %s",
|
||||
session_config->cb_func_name, module->lib_path, dlerror());
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plugin_manager_log(INFO, "plugin dynamic library '%s' dlopen success", module->lib_path);
|
||||
|
||||
return module;
|
||||
|
||||
err:
|
||||
plugin_manager_module_close(module);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int plugin_manager_module_init(struct plugin_manager_module *module)
|
||||
{
|
||||
struct timespec start;
|
||||
struct timespec end;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
int ret = module->init_cb_ptr();
|
||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||
if (ret == -1)
|
||||
{
|
||||
plugin_manager_log(ERROR, "dynamic library '%s' initialization failed", module->lib_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
long long elapsed = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
|
||||
plugin_manager_log(INFO, "plugin dynamic library '%s' init success, using '%lld' us", module->lib_path, elapsed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plugin_manager_module_exit(struct plugin_manager_module *module)
|
||||
{
|
||||
struct timespec start;
|
||||
struct timespec end;
|
||||
|
||||
if (module && module->exit_cb_ptr)
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC, &start);
|
||||
module->exit_cb_ptr();
|
||||
clock_gettime(CLOCK_MONOTONIC, &end);
|
||||
module->exit_cb_ptr = NULL;
|
||||
|
||||
long long elapsed = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
|
||||
plugin_manager_log(INFO, "plugin dynamic library '%s' exit success, using '%lld' us", module->lib_path, elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
int plugin_manager_module_register(struct plugin_manager *plug_mgr, struct plugin_manager_module *module)
|
||||
{
|
||||
if (module && module->evcbs)
|
||||
{
|
||||
for (int i = 0; i < module->evcbs_num; i++)
|
||||
{
|
||||
struct plugin_manager_module_evcb *event_cb = &module->evcbs[i];
|
||||
|
||||
if (plugin_manager_register(plug_mgr, event_cb->session_name, event_cb->event, event_cb->event_cb_ptr) == -1)
|
||||
{
|
||||
plugin_manager_log(ERROR, "dynamic library '%s' failed to register the event callback function of session '%s'", module->lib_path, event_cb->session_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plugin_manager_module_dump(struct plugin_manager_module *module, struct plugin_manager_config *config)
|
||||
{
|
||||
if (module)
|
||||
{
|
||||
plugin_manager_log(DEBUG, "[LIBRARY] : %s, %p", config->plugin_section.lib_path, module->dl_handle);
|
||||
plugin_manager_log(DEBUG, "[INIT_FUNC] : %s, %p", config->plugin_section.init_func_name, module->init_cb_ptr);
|
||||
plugin_manager_log(DEBUG, "[EXIT_FUNC] : %s, %p", config->plugin_section.exit_func_name, module->exit_cb_ptr);
|
||||
|
||||
for (int i = 0; i < module->evcbs_num; i++)
|
||||
{
|
||||
struct session_section_config *session_config = &config->session_section[i];
|
||||
struct plugin_manager_module_evcb *event_cb = &module->evcbs[i];
|
||||
|
||||
char event_str_buffer[1024] = {0};
|
||||
session_event_type_int2str(event_cb->event, event_str_buffer, 1024);
|
||||
plugin_manager_log(DEBUG, "[EVENT_FUNC] : %s, %p, %s, (%d: %s)", session_config->cb_func_name, event_cb->event_cb_ptr, event_cb->session_name, event_cb->event, event_str_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/plugin_manager/plugin_manager_module.h
Normal file
26
src/plugin_manager/plugin_manager_module.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _PLUGIN_MANAGER_MODULE_H
|
||||
#define _PLUGIN_MANAGER_MODULE_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "plugin_manager_config.h"
|
||||
|
||||
struct plugin_manager_module;
|
||||
|
||||
struct plugin_manager_module *plugin_manager_module_open(struct plugin_manager_config *config);
|
||||
void plugin_manager_module_close(struct plugin_manager_module *module);
|
||||
|
||||
int plugin_manager_module_init(struct plugin_manager_module *module);
|
||||
void plugin_manager_module_exit(struct plugin_manager_module *module);
|
||||
|
||||
void plugin_manager_module_dump(struct plugin_manager_module *module, struct plugin_manager_config *config);
|
||||
int plugin_manager_module_register(struct plugin_manager *plug_mgr, struct plugin_manager_module *module);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
98
src/plugin_manager/plugin_manager_util.cpp
Normal file
98
src/plugin_manager/plugin_manager_util.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "plugin_manager_util.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Malloc
|
||||
******************************************************************************/
|
||||
|
||||
char *safe_dup(const char *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *dup = safe_alloc(char, strlen(str) + 1);
|
||||
memcpy(dup, str, strlen(str));
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Session Event Type
|
||||
******************************************************************************/
|
||||
|
||||
struct event_type_map
|
||||
{
|
||||
const char *type_str;
|
||||
enum session_event_type type_int;
|
||||
};
|
||||
|
||||
static struct event_type_map evtype_map[] = {
|
||||
{"SESSION_EVENT_UNKNOWN", SESSION_EVENT_UNKNOWN},
|
||||
{"SESSION_EVENT_OPENING", SESSION_EVENT_OPENING},
|
||||
{"SESSION_EVENT_RAWPKT", SESSION_EVENT_RAWPKT},
|
||||
{"SESSION_EVENT_ORDPKT", SESSION_EVENT_ORDPKT},
|
||||
{"SESSION_EVENT_META", SESSION_EVENT_META},
|
||||
{"SESSION_EVENT_CLOSING", SESSION_EVENT_CLOSING},
|
||||
{"SESSION_EVENT_ALL", SESSION_EVENT_ALL},
|
||||
};
|
||||
|
||||
enum session_event_type session_event_type_str2int(const char *evtype_str)
|
||||
{
|
||||
enum session_event_type evtype_int = SESSION_EVENT_UNKNOWN;
|
||||
int num = sizeof(evtype_map) / sizeof(evtype_map[0]);
|
||||
|
||||
char *buffer = safe_dup(evtype_str);
|
||||
char *token = strtok(buffer, "|");
|
||||
while (token)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
if (strcmp(token, evtype_map[i].type_str) == 0)
|
||||
{
|
||||
evtype_int = (enum session_event_type)(evtype_int | evtype_map[i].type_int);
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, "|");
|
||||
}
|
||||
safe_free(buffer);
|
||||
|
||||
return evtype_int;
|
||||
}
|
||||
|
||||
void session_event_type_int2str(enum session_event_type evtype_int, char *buffer, int size)
|
||||
{
|
||||
int used = 0;
|
||||
int num = sizeof(evtype_map) / sizeof(evtype_map[0]);
|
||||
|
||||
if (evtype_int == SESSION_EVENT_UNKNOWN)
|
||||
{
|
||||
snprintf(buffer, size, "%s", "SESSION_EVENT_UNKNOWN");
|
||||
return;
|
||||
}
|
||||
|
||||
if (evtype_int == SESSION_EVENT_ALL)
|
||||
{
|
||||
snprintf(buffer, size, "%s", "SESSION_EVENT_ALL");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
if (evtype_map[i].type_int & evtype_int)
|
||||
{
|
||||
if (evtype_map[i].type_int == SESSION_EVENT_ALL && evtype_int != SESSION_EVENT_ALL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
used += snprintf(buffer + used, size - used, "%s|", evtype_map[i].type_str);
|
||||
}
|
||||
}
|
||||
|
||||
if (used)
|
||||
{
|
||||
buffer[used - 1] = '\0';
|
||||
}
|
||||
}
|
||||
82
src/plugin_manager/plugin_manager_util.h
Normal file
82
src/plugin_manager/plugin_manager_util.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef _PLUGIN_MANAGER_UTIL_H
|
||||
#define _PLUGIN_MANAGER_UTIL_H
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sdk/include/session.h"
|
||||
|
||||
#define MAX_PLUGIN_NUM 512
|
||||
#define MAX_SESSION_NAME_LENGTH 32
|
||||
|
||||
/******************************************************************************
|
||||
* Malloc
|
||||
******************************************************************************/
|
||||
|
||||
#define safe_alloc(type, number) ((type *)calloc(number, sizeof(type)))
|
||||
|
||||
#define safe_free(ptr) \
|
||||
{ \
|
||||
if (ptr) \
|
||||
{ \
|
||||
free(ptr); \
|
||||
ptr = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
char *safe_dup(const char *str);
|
||||
|
||||
/******************************************************************************
|
||||
* Logger
|
||||
******************************************************************************/
|
||||
|
||||
enum plugin_manager_log_level
|
||||
{
|
||||
DEBUG = 0x11,
|
||||
WARN = 0x12,
|
||||
INFO = 0x13,
|
||||
ERROR = 0x14,
|
||||
};
|
||||
|
||||
#ifndef plugin_manager_log
|
||||
#define plugin_manager_log(level, format, ...) \
|
||||
{ \
|
||||
switch (level) \
|
||||
{ \
|
||||
case DEBUG: \
|
||||
fprintf(stdout, "PLUGIN_MANAGER [DEBUG] " format "\n", ##__VA_ARGS__); \
|
||||
fflush(stdout); \
|
||||
break; \
|
||||
case WARN: \
|
||||
fprintf(stdout, "PLUGIN_MANAGER [WARN] " format "\n", ##__VA_ARGS__); \
|
||||
fflush(stdout); \
|
||||
break; \
|
||||
case INFO: \
|
||||
fprintf(stdout, "PLUGIN_MANAGER [INFO] " format "\n", ##__VA_ARGS__); \
|
||||
fflush(stdout); \
|
||||
break; \
|
||||
case ERROR: \
|
||||
fprintf(stderr, "PLUGIN_MANAGER [ERROR] " format "\n", ##__VA_ARGS__); \
|
||||
fflush(stderr); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Session Event Type
|
||||
******************************************************************************/
|
||||
|
||||
enum session_event_type session_event_type_str2int(const char *evtype_str);
|
||||
void session_event_type_int2str(enum session_event_type evtype_int, char *buffer, int size);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
21
src/plugin_manager/test/CMakeLists.txt
Normal file
21
src/plugin_manager/test/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
add_executable(gtest_plugin_manager
|
||||
gtest_plugin_manager.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
gtest_plugin_manager
|
||||
gtest
|
||||
plugin_manager
|
||||
session_manager
|
||||
toml
|
||||
dl
|
||||
)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--export-dynamic")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--export-dynamic")
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(gtest_plugin_manager)
|
||||
|
||||
add_subdirectory(test_plugins/plugins_library)
|
||||
file(COPY test_plugins/plugins_config DESTINATION ./)
|
||||
578
src/plugin_manager/test/gtest_plugin_manager.cpp
Normal file
578
src/plugin_manager/test/gtest_plugin_manager.cpp
Normal file
@@ -0,0 +1,578 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "sdk/include/session.h"
|
||||
|
||||
#include "../plugin_manager_util.h"
|
||||
#include "../plugin_manager_config.h"
|
||||
#include "../plugin_manager_module.h"
|
||||
#include "../plugin_manager.h"
|
||||
#include "session_manager.h"
|
||||
|
||||
/******************************************************************************
|
||||
* Test plugin_mangager_util API
|
||||
******************************************************************************/
|
||||
|
||||
#if 1
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_mangager_util_int2str)
|
||||
{
|
||||
enum session_event_type type_int;
|
||||
char buffer[1024] = {0};
|
||||
|
||||
type_int = SESSION_EVENT_UNKNOWN;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_UNKNOWN");
|
||||
|
||||
type_int = SESSION_EVENT_OPENING;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_OPENING");
|
||||
|
||||
type_int = SESSION_EVENT_RAWPKT;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_RAWPKT");
|
||||
|
||||
type_int = SESSION_EVENT_ORDPKT;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_ORDPKT");
|
||||
|
||||
type_int = SESSION_EVENT_META;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_META");
|
||||
|
||||
type_int = SESSION_EVENT_CLOSING;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_CLOSING");
|
||||
|
||||
type_int = SESSION_EVENT_ALL;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_ALL");
|
||||
|
||||
type_int = (enum session_event_type)(SESSION_EVENT_OPENING | SESSION_EVENT_RAWPKT);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_OPENING|SESSION_EVENT_RAWPKT");
|
||||
|
||||
type_int = (enum session_event_type)(SESSION_EVENT_OPENING | SESSION_EVENT_RAWPKT | SESSION_EVENT_ORDPKT);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_OPENING|SESSION_EVENT_RAWPKT|SESSION_EVENT_ORDPKT");
|
||||
|
||||
type_int = (enum session_event_type)(SESSION_EVENT_OPENING | SESSION_EVENT_RAWPKT | SESSION_EVENT_ORDPKT | SESSION_EVENT_META);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_OPENING|SESSION_EVENT_RAWPKT|SESSION_EVENT_ORDPKT|SESSION_EVENT_META");
|
||||
|
||||
type_int = (enum session_event_type)(SESSION_EVENT_OPENING | SESSION_EVENT_RAWPKT | SESSION_EVENT_ORDPKT | SESSION_EVENT_META | SESSION_EVENT_CLOSING);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
session_event_type_int2str(type_int, buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(buffer, "SESSION_EVENT_ALL");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_mangager_util_str2int)
|
||||
{
|
||||
enum session_event_type type_int;
|
||||
|
||||
const char *type_str1 = "SESSION_EVENT_UNKNOWN";
|
||||
const char *type_str2 = "SESSION_EVENT_OPENING";
|
||||
const char *type_str3 = "SESSION_EVENT_RAWPKT";
|
||||
const char *type_str4 = "SESSION_EVENT_ORDPKT";
|
||||
const char *type_str5 = "SESSION_EVENT_META";
|
||||
const char *type_str6 = "SESSION_EVENT_CLOSING";
|
||||
const char *type_str7 = "SESSION_EVENT_ALL";
|
||||
const char *type_str8 = "SESSION_EVENT_OPENING|SESSION_EVENT_RAWPKT";
|
||||
const char *type_str9 = "SESSION_EVENT_OPENING|SESSION_EVENT_RAWPKT|SESSION_EVENT_ORDPKT";
|
||||
const char *type_str10 = "SESSION_EVENT_OPENING|SESSION_EVENT_RAWPKT|SESSION_EVENT_ORDPKT|SESSION_EVENT_META";
|
||||
const char *type_str11 = "SESSION_EVENT_OPENING|SESSION_EVENT_RAWPKT|SESSION_EVENT_ORDPKT|SESSION_EVENT_META|SESSION_EVENT_CLOSING";
|
||||
|
||||
type_int = session_event_type_str2int(type_str1);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_UNKNOWN);
|
||||
|
||||
type_int = session_event_type_str2int(type_str2);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_OPENING);
|
||||
|
||||
type_int = session_event_type_str2int(type_str3);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_RAWPKT);
|
||||
|
||||
type_int = session_event_type_str2int(type_str4);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_ORDPKT);
|
||||
|
||||
type_int = session_event_type_str2int(type_str5);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_META);
|
||||
|
||||
type_int = session_event_type_str2int(type_str6);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_CLOSING);
|
||||
|
||||
type_int = session_event_type_str2int(type_str7);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_ALL);
|
||||
|
||||
type_int = session_event_type_str2int(type_str8);
|
||||
EXPECT_TRUE(type_int == (SESSION_EVENT_OPENING | SESSION_EVENT_RAWPKT));
|
||||
|
||||
type_int = session_event_type_str2int(type_str9);
|
||||
EXPECT_TRUE(type_int == (SESSION_EVENT_OPENING | SESSION_EVENT_RAWPKT | SESSION_EVENT_ORDPKT));
|
||||
|
||||
type_int = session_event_type_str2int(type_str10);
|
||||
EXPECT_TRUE(type_int == (SESSION_EVENT_OPENING | SESSION_EVENT_RAWPKT | SESSION_EVENT_ORDPKT | SESSION_EVENT_META));
|
||||
|
||||
type_int = session_event_type_str2int(type_str11);
|
||||
EXPECT_TRUE(type_int == SESSION_EVENT_ALL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Test plugin_mangager_config API
|
||||
******************************************************************************/
|
||||
|
||||
#if 1
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_mangager_config_HTTP)
|
||||
{
|
||||
char file_path[] = "./plugins_config/http_event_plugin/http_event_plugin.inf";
|
||||
|
||||
struct plugin_manager_config *config = plugin_mangager_config_create();
|
||||
EXPECT_TRUE(config != nullptr);
|
||||
|
||||
EXPECT_TRUE(plugin_mangager_config_parse(config, file_path) == 0);
|
||||
|
||||
EXPECT_STREQ(config->file_path, "./plugins_config/http_event_plugin/http_event_plugin.inf");
|
||||
EXPECT_STREQ(config->plugin_section.init_func_name, "http_event_plugin_init");
|
||||
EXPECT_STREQ(config->plugin_section.exit_func_name, "http_event_plugin_exit");
|
||||
EXPECT_STREQ(config->plugin_section.lib_path, "./test_plugins/plugins_library/http_event_plugin_test.so");
|
||||
|
||||
EXPECT_TRUE(config->session_section_num == 1);
|
||||
EXPECT_STREQ(config->session_section[0].session_name, "HTTP");
|
||||
EXPECT_STREQ(config->session_section[0].cb_func_name, "http_event_plugin_entry");
|
||||
EXPECT_TRUE(config->session_section[0].event == (0x01 << 1 | 0x01 << 2 | 0x01 << 3 | 0x01 << 4 | 0x01 << 5));
|
||||
|
||||
plugin_mangager_config_dump(config);
|
||||
plugin_mangager_config_destory(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_mangager_config_CUSTOM)
|
||||
{
|
||||
char file_path[] = "./plugins_config/custom_event_plugin/custom_event_plugin.inf";
|
||||
|
||||
struct plugin_manager_config *config = plugin_mangager_config_create();
|
||||
EXPECT_TRUE(config != nullptr);
|
||||
|
||||
EXPECT_TRUE(plugin_mangager_config_parse(config, file_path) == 0);
|
||||
|
||||
EXPECT_STREQ(config->file_path, "./plugins_config/custom_event_plugin/custom_event_plugin.inf");
|
||||
EXPECT_STREQ(config->plugin_section.init_func_name, "custom_event_plugin_init");
|
||||
EXPECT_STREQ(config->plugin_section.exit_func_name, "custom_event_plugin_exit");
|
||||
EXPECT_STREQ(config->plugin_section.lib_path, "./test_plugins/plugins_library/custom_event_plugin_test.so");
|
||||
|
||||
EXPECT_TRUE(config->session_section_num == 3);
|
||||
EXPECT_STREQ(config->session_section[0].session_name, "TCP");
|
||||
EXPECT_STREQ(config->session_section[0].cb_func_name, "custom_event_plugin_tcp_entry");
|
||||
EXPECT_TRUE(config->session_section[0].event == (0x01 << 1 | 0x01 << 2 | 0x01 << 3 | 0x01 << 4 | 0x01 << 5));
|
||||
|
||||
EXPECT_STREQ(config->session_section[1].session_name, "HTTP");
|
||||
EXPECT_STREQ(config->session_section[1].cb_func_name, "custom_event_plugin_http_entry");
|
||||
EXPECT_TRUE(config->session_section[1].event == (0x01 << 1 | 0x01 << 2 | 0x01 << 3 | 0x01 << 4 | 0x01 << 5));
|
||||
|
||||
EXPECT_STREQ(config->session_section[2].session_name, "CUSTOM");
|
||||
EXPECT_STREQ(config->session_section[2].cb_func_name, "custom_event_plugin_custom_entry");
|
||||
EXPECT_TRUE(config->session_section[2].event == (enum session_event_type)((0x01 << 1) | (0x01 << 3) | (0x01 << 5)));
|
||||
|
||||
plugin_mangager_config_dump(config);
|
||||
plugin_mangager_config_destory(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Test plugin_mangager_module API
|
||||
******************************************************************************/
|
||||
|
||||
#if 1
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_mangager_module_HTTP)
|
||||
{
|
||||
char file_path[] = "./plugins_config/http_event_plugin/http_event_plugin.inf";
|
||||
|
||||
struct plugin_manager_config *config = plugin_mangager_config_create();
|
||||
EXPECT_TRUE(config != nullptr);
|
||||
EXPECT_TRUE(plugin_mangager_config_parse(config, file_path) == 0);
|
||||
|
||||
struct plugin_manager_module *module = plugin_manager_module_open(config);
|
||||
EXPECT_TRUE(module != nullptr);
|
||||
EXPECT_TRUE(plugin_manager_module_init(module) == 0);
|
||||
plugin_manager_module_dump(module, config);
|
||||
plugin_manager_module_exit(module);
|
||||
plugin_manager_module_close(module);
|
||||
|
||||
plugin_mangager_config_destory(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_mangager_module_CUSTOM)
|
||||
{
|
||||
char file_path[] = "./plugins_config/custom_event_plugin/custom_event_plugin.inf";
|
||||
|
||||
struct plugin_manager_config *config = plugin_mangager_config_create();
|
||||
EXPECT_TRUE(config != nullptr);
|
||||
EXPECT_TRUE(plugin_mangager_config_parse(config, file_path) == 0);
|
||||
|
||||
struct plugin_manager_module *module = plugin_manager_module_open(config);
|
||||
EXPECT_TRUE(module != nullptr);
|
||||
EXPECT_TRUE(plugin_manager_module_init(module) == 0);
|
||||
plugin_manager_module_dump(module, config);
|
||||
plugin_manager_module_exit(module);
|
||||
plugin_manager_module_close(module);
|
||||
|
||||
plugin_mangager_config_destory(config);
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Test plugin_mangager API
|
||||
******************************************************************************/
|
||||
|
||||
#if 1
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_manager_load)
|
||||
{
|
||||
char file_path[] = "./plugins_config/plugins.inf";
|
||||
|
||||
struct plugin_manager *plug_mgr = plugin_manager_create();
|
||||
EXPECT_TRUE(plug_mgr != nullptr);
|
||||
EXPECT_TRUE(plugin_manager_load(plug_mgr, file_path) == 0);
|
||||
|
||||
plugin_manager_unload(plug_mgr);
|
||||
plugin_manager_destory(plug_mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// only SESSION_EVENT_OPENING | SESSION_EVENT_ORDPKT | SESSION_EVENT_CLOSING can trigger event callback
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_CUSTOM)
|
||||
{
|
||||
/*
|
||||
* [SESSION_NAME.CUSTOM]
|
||||
* SESSION_EVENT_TYPE=["SESSION_EVENT_OPENING","SESSION_EVENT_ORDPKT","SESSION_EVENT_CLOSING"]
|
||||
* SESSION_EVENT_CALLBACK="custom_event_plugin_custom_entry"
|
||||
*/
|
||||
|
||||
struct custom_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */
|
||||
};
|
||||
|
||||
struct custom_session_pme *pme;
|
||||
char file_path[] = "./plugins_config/plugins.inf";
|
||||
|
||||
const char *session_name = "CUSTOM";
|
||||
|
||||
struct stellar_session session;
|
||||
session.name = session_name;
|
||||
|
||||
struct stellar_session_event_data event_data;
|
||||
event_data.s = &session;
|
||||
event_data.plugin_ctx = NULL; // must be init to NULL
|
||||
|
||||
struct stellar_event event;
|
||||
event.session_event_data = &event_data;
|
||||
|
||||
session.event_data = &event_data; // must be set
|
||||
|
||||
struct plugin_manager *plug_mgr = plugin_manager_create();
|
||||
EXPECT_TRUE(plug_mgr != nullptr);
|
||||
EXPECT_TRUE(plugin_manager_load(plug_mgr, file_path) == 0);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_OPENING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct custom_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_OPENING);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_custom_entry");
|
||||
|
||||
// unrun evencb
|
||||
event_data.type = SESSION_EVENT_RAWPKT;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct custom_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_OPENING);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_custom_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_ORDPKT;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct custom_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_ORDPKT);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_custom_entry");
|
||||
|
||||
// unrun evencb
|
||||
event_data.type = SESSION_EVENT_META;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct custom_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_ORDPKT);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_custom_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_CLOSING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_ALL;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
plugin_manager_unload(plug_mgr);
|
||||
plugin_manager_destory(plug_mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// ALL SESSION_EVENT can trigger event callback
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_TCP)
|
||||
{
|
||||
/*
|
||||
* [SESSION_NAME.TCP]
|
||||
* SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
* SESSION_EVENT_CALLBACK="custom_event_plugin_tcp_entry"
|
||||
*/
|
||||
|
||||
struct tcp_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */
|
||||
};
|
||||
struct tcp_session_pme *pme;
|
||||
|
||||
char file_path[] = "./plugins_config/plugins.inf";
|
||||
|
||||
const char *session_name = "TCP";
|
||||
|
||||
struct stellar_session session;
|
||||
session.name = session_name;
|
||||
|
||||
struct stellar_session_event_data event_data;
|
||||
event_data.s = &session;
|
||||
event_data.plugin_ctx = NULL; // must be init to NULL
|
||||
|
||||
struct stellar_event event;
|
||||
event.session_event_data = &event_data;
|
||||
|
||||
session.event_data = &event_data; // must be set
|
||||
|
||||
struct plugin_manager *plug_mgr = plugin_manager_create();
|
||||
EXPECT_TRUE(plug_mgr != nullptr);
|
||||
EXPECT_TRUE(plugin_manager_load(plug_mgr, file_path) == 0);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_OPENING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct tcp_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_OPENING);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_tcp_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_RAWPKT;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct tcp_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_RAWPKT);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_tcp_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_ORDPKT;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct tcp_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_ORDPKT);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_tcp_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_META;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct tcp_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_META);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_tcp_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_CLOSING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_ALL;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
plugin_manager_unload(plug_mgr);
|
||||
plugin_manager_destory(plug_mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// http_event_plugin_entry + SESSION_EVENT_RAWPKT ==> pm_session_dettach_me
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_HTTP_dettach_me)
|
||||
{
|
||||
/*
|
||||
* [SESSION_NAME.HTTP]
|
||||
* SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
* SESSION_EVENT_CALLBACK="http_event_plugin_entry"
|
||||
*
|
||||
* [SESSION_NAME.HTTP]
|
||||
* SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
* SESSION_EVENT_CALLBACK="custom_event_plugin_http_entry"
|
||||
*/
|
||||
|
||||
struct http_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */;
|
||||
};
|
||||
|
||||
struct http_session_pme *pme = NULL;
|
||||
char file_path[] = "./plugins_config/plugins.inf";
|
||||
|
||||
const char *session_name = "HTTP";
|
||||
|
||||
struct stellar_session session;
|
||||
session.name = session_name;
|
||||
|
||||
struct stellar_session_event_data event_data;
|
||||
event_data.s = &session;
|
||||
event_data.plugin_ctx = NULL; // must be init to NULL
|
||||
|
||||
struct stellar_event event;
|
||||
event.session_event_data = &event_data;
|
||||
|
||||
session.event_data = &event_data; // must be set
|
||||
|
||||
struct plugin_manager *plug_mgr = plugin_manager_create();
|
||||
EXPECT_TRUE(plug_mgr != nullptr);
|
||||
EXPECT_TRUE(plugin_manager_load(plug_mgr, file_path) == 0);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_OPENING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct http_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_OPENING);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_http_entry");
|
||||
|
||||
// http_event_plugin_entry + SESSION_EVENT_RAWPKT ==> pm_session_dettach_me
|
||||
event_data.type = SESSION_EVENT_RAWPKT;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct http_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_RAWPKT);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_http_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_META;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct http_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_META);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_http_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_CLOSING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_ALL;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
plugin_manager_unload(plug_mgr);
|
||||
plugin_manager_destory(plug_mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// http_event_plugin_entry + SESSION_EVENT_ORDPKT ==> pm_session_take_over
|
||||
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_HTTP_take_over)
|
||||
{
|
||||
/*
|
||||
* [SESSION_NAME.HTTP]
|
||||
* SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
* SESSION_EVENT_CALLBACK="http_event_plugin_entry"
|
||||
*
|
||||
* [SESSION_NAME.HTTP]
|
||||
* SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
* SESSION_EVENT_CALLBACK="custom_event_plugin_http_entry"
|
||||
*/
|
||||
|
||||
struct http_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */;
|
||||
};
|
||||
|
||||
struct http_session_pme *pme = NULL;
|
||||
char file_path[] = "./plugins_config/plugins.inf";
|
||||
|
||||
const char *session_name = "HTTP";
|
||||
|
||||
struct stellar_session session;
|
||||
session.name = session_name;
|
||||
|
||||
struct stellar_session_event_data event_data;
|
||||
event_data.s = &session;
|
||||
event_data.plugin_ctx = NULL; // must be init to NULL
|
||||
|
||||
struct stellar_event event;
|
||||
event.session_event_data = &event_data;
|
||||
|
||||
session.event_data = &event_data; // must be set
|
||||
|
||||
struct plugin_manager *plug_mgr = plugin_manager_create();
|
||||
EXPECT_TRUE(plug_mgr != nullptr);
|
||||
EXPECT_TRUE(plugin_manager_load(plug_mgr, file_path) == 0);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_OPENING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct http_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_OPENING);
|
||||
EXPECT_STREQ(pme->data, "custom_event_plugin_http_entry");
|
||||
|
||||
// http_event_plugin_entry + SESSION_EVENT_ORDPKT ==> pm_session_take_over
|
||||
event_data.type = SESSION_EVENT_ORDPKT;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct http_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_ORDPKT);
|
||||
EXPECT_STREQ(pme->data, "http_event_plugin_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_META;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
pme = (struct http_session_pme *)pm_session_get_plugin_pme(&session);
|
||||
EXPECT_TRUE(pme->flags == SESSION_EVENT_META);
|
||||
EXPECT_STREQ(pme->data, "http_event_plugin_entry");
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_CLOSING;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
// run evencb
|
||||
event_data.type = SESSION_EVENT_ALL;
|
||||
plugin_manager_dispatch(plug_mgr, &event);
|
||||
EXPECT_TRUE(stellar_session_get_plugin_ctx(&session) == nullptr);
|
||||
|
||||
plugin_manager_unload(plug_mgr);
|
||||
plugin_manager_destory(plug_mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
[PLUGINFO]
|
||||
INIT_FUNC="custom_event_plugin_init"
|
||||
EXIT_FUNC="custom_event_plugin_exit"
|
||||
LIBRARY_PATH="./test_plugins/plugins_library/custom_event_plugin_test.so"
|
||||
|
||||
# Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
|
||||
|
||||
[SESSION_NAME.TCP]
|
||||
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
SESSION_EVENT_CALLBACK="custom_event_plugin_tcp_entry"
|
||||
|
||||
[SESSION_NAME.HTTP]
|
||||
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
SESSION_EVENT_CALLBACK="custom_event_plugin_http_entry"
|
||||
|
||||
[SESSION_NAME.CUSTOM]
|
||||
SESSION_EVENT_TYPE=["SESSION_EVENT_OPENING","SESSION_EVENT_ORDPKT","SESSION_EVENT_CLOSING"]
|
||||
SESSION_EVENT_CALLBACK="custom_event_plugin_custom_entry"
|
||||
@@ -0,0 +1,10 @@
|
||||
[PLUGINFO]
|
||||
INIT_FUNC="http_event_plugin_init"
|
||||
EXIT_FUNC="http_event_plugin_exit"
|
||||
LIBRARY_PATH="./test_plugins/plugins_library/http_event_plugin_test.so"
|
||||
|
||||
# Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
|
||||
|
||||
[SESSION_NAME.HTTP]
|
||||
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||
SESSION_EVENT_CALLBACK="http_event_plugin_entry"
|
||||
@@ -0,0 +1,4 @@
|
||||
# Relative path, relative to the installation path of stellar
|
||||
|
||||
./plugins_config/http_event_plugin/http_event_plugin.inf
|
||||
./plugins_config/custom_event_plugin/custom_event_plugin.inf
|
||||
@@ -0,0 +1,9 @@
|
||||
add_library(custom_event_plugin_test SHARED
|
||||
custom_event_plugin.cpp
|
||||
)
|
||||
set_target_properties(custom_event_plugin_test PROPERTIES PREFIX "")
|
||||
|
||||
add_library(http_event_plugin_test SHARED
|
||||
http_event_plugin.cpp
|
||||
)
|
||||
set_target_properties(http_event_plugin_test PROPERTIES PREFIX "")
|
||||
@@ -0,0 +1,216 @@
|
||||
#include "session.h"
|
||||
#include "packet.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static char *g_handler = NULL;
|
||||
|
||||
static void *custom_decode(const char *payload, uint16_t len, void **pme)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct tcp_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */
|
||||
};
|
||||
|
||||
struct custom_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */
|
||||
};
|
||||
|
||||
struct http_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */;
|
||||
};
|
||||
|
||||
static struct tcp_session_pme *tcp_session_pme_create()
|
||||
{
|
||||
struct tcp_session_pme *pme = (struct tcp_session_pme *)calloc(1, sizeof(struct tcp_session_pme));
|
||||
return pme;
|
||||
}
|
||||
|
||||
static void tcp_session_pme_destory(struct tcp_session_pme *pme)
|
||||
{
|
||||
if (pme)
|
||||
{
|
||||
free(pme);
|
||||
pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct custom_session_pme *custom_session_pme_create()
|
||||
{
|
||||
struct custom_session_pme *pme = (struct custom_session_pme *)calloc(1, sizeof(struct custom_session_pme));
|
||||
return pme;
|
||||
}
|
||||
|
||||
static void custom_session_pme_destory(struct custom_session_pme *pme)
|
||||
{
|
||||
if (pme)
|
||||
{
|
||||
free(pme);
|
||||
pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct http_session_pme *http_session_pme_create()
|
||||
{
|
||||
struct http_session_pme *pme = (struct http_session_pme *)calloc(1, sizeof(struct http_session_pme));
|
||||
return pme;
|
||||
}
|
||||
|
||||
static void http_session_pme_destory(struct http_session_pme *pme)
|
||||
{
|
||||
if (pme)
|
||||
{
|
||||
free(pme);
|
||||
pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void custom_event_plugin_tcp_entry(const struct stellar_session *session, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
|
||||
{
|
||||
struct tcp_session_pme **per_tcp_session_pme = (struct tcp_session_pme **)pme;
|
||||
|
||||
if (event & SESSION_EVENT_OPENING)
|
||||
{
|
||||
if (*per_tcp_session_pme == NULL)
|
||||
{
|
||||
struct tcp_session_pme *cur_ctx = tcp_session_pme_create();
|
||||
memcpy(cur_ctx->data, "custom_event_plugin_tcp_entry", strlen("custom_event_plugin_tcp_entry"));
|
||||
cur_ctx->flags = SESSION_EVENT_OPENING;
|
||||
*per_tcp_session_pme = *&cur_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_RAWPKT)
|
||||
{
|
||||
(*per_tcp_session_pme)->flags = SESSION_EVENT_RAWPKT;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_ORDPKT)
|
||||
{
|
||||
(*per_tcp_session_pme)->flags = SESSION_EVENT_ORDPKT;
|
||||
|
||||
struct stellar_session_event_extras *info = (struct stellar_session_event_extras *)custom_decode(payload, len, pme);
|
||||
struct stellar_session *new_session = session_manager_session_derive(session, "CUSTOM");
|
||||
|
||||
session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info);
|
||||
session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_META)
|
||||
{
|
||||
(*per_tcp_session_pme)->flags = SESSION_EVENT_META;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_CLOSING)
|
||||
{
|
||||
tcp_session_pme_destory(*per_tcp_session_pme);
|
||||
*per_tcp_session_pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void custom_event_plugin_custom_entry(const struct stellar_session *session, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
|
||||
{
|
||||
struct custom_session_pme **per_custom_session_pme = (struct custom_session_pme **)pme;
|
||||
|
||||
if (event & SESSION_EVENT_OPENING)
|
||||
{
|
||||
if (*per_custom_session_pme == NULL)
|
||||
{
|
||||
struct custom_session_pme *cur_ctx = custom_session_pme_create();
|
||||
memcpy(cur_ctx->data, "custom_event_plugin_custom_entry", strlen("custom_event_plugin_custom_entry"));
|
||||
cur_ctx->flags = SESSION_EVENT_OPENING;
|
||||
*per_custom_session_pme = *&cur_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_RAWPKT)
|
||||
{
|
||||
(*per_custom_session_pme)->flags = SESSION_EVENT_RAWPKT;
|
||||
}
|
||||
if (event & SESSION_EVENT_ORDPKT)
|
||||
{
|
||||
(*per_custom_session_pme)->flags = SESSION_EVENT_ORDPKT;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_META)
|
||||
{
|
||||
(*per_custom_session_pme)->flags = SESSION_EVENT_META;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_CLOSING)
|
||||
{
|
||||
custom_session_pme_destory(*per_custom_session_pme);
|
||||
*per_custom_session_pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void custom_event_plugin_http_entry(const struct stellar_session *session, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
|
||||
{
|
||||
struct http_session_pme **per_http_session_pme = (struct http_session_pme **)pme;
|
||||
|
||||
if (event & SESSION_EVENT_OPENING)
|
||||
{
|
||||
if (*per_http_session_pme == NULL)
|
||||
{
|
||||
struct http_session_pme *cur_ctx = http_session_pme_create();
|
||||
memcpy(cur_ctx->data, "custom_event_plugin_http_entry", strlen("custom_event_plugin_http_entry"));
|
||||
cur_ctx->flags = SESSION_EVENT_OPENING;
|
||||
*per_http_session_pme = *&cur_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_RAWPKT)
|
||||
{
|
||||
(*per_http_session_pme)->flags = SESSION_EVENT_RAWPKT;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_ORDPKT)
|
||||
{
|
||||
(*per_http_session_pme)->flags = SESSION_EVENT_ORDPKT;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_META)
|
||||
{
|
||||
(*per_http_session_pme)->flags = SESSION_EVENT_META;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_CLOSING)
|
||||
{
|
||||
http_session_pme_destory(*per_http_session_pme);
|
||||
*per_http_session_pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int custom_event_plugin_init(void)
|
||||
{
|
||||
if (g_handler == NULL)
|
||||
{
|
||||
g_handler = (char *)malloc(1024);
|
||||
snprintf(g_handler, 1024, "222222");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void custom_event_plugin_exit(void)
|
||||
{
|
||||
if (g_handler)
|
||||
{
|
||||
free(g_handler);
|
||||
g_handler = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "session.h"
|
||||
#include "packet.h"
|
||||
#include "plugin.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static char *g_handler = NULL;
|
||||
|
||||
struct http_session_pme
|
||||
{
|
||||
char data[64];
|
||||
int flags;
|
||||
/* data */;
|
||||
};
|
||||
|
||||
static struct http_session_pme *http_session_pme_create()
|
||||
{
|
||||
struct http_session_pme *pme = (struct http_session_pme *)calloc(1, sizeof(struct http_session_pme));
|
||||
return pme;
|
||||
}
|
||||
|
||||
static void http_session_pme_destory(struct http_session_pme *pme)
|
||||
{
|
||||
if (pme)
|
||||
{
|
||||
free(pme);
|
||||
pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void http_event_plugin_entry(const struct stellar_session *session, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
|
||||
{
|
||||
struct http_session_pme **per_http_session_pme = (struct http_session_pme **)pme;
|
||||
|
||||
if (event & SESSION_EVENT_OPENING)
|
||||
{
|
||||
if (*per_http_session_pme == NULL)
|
||||
{
|
||||
struct http_session_pme *cur_ctx = http_session_pme_create();
|
||||
memcpy(cur_ctx->data, "http_event_plugin_entry", strlen("http_event_plugin_entry"));
|
||||
cur_ctx->flags = SESSION_EVENT_OPENING;
|
||||
*per_http_session_pme = *&cur_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_RAWPKT)
|
||||
{
|
||||
/*
|
||||
* Note: pm_session_dettach_me()
|
||||
* The plugin manager just set the skip flag and don't call this event callback next.
|
||||
* Before calling pm_session_dettach_me, the current plugin must release related resources for the current session.
|
||||
*/
|
||||
http_session_pme_destory(*per_http_session_pme);
|
||||
*per_http_session_pme = NULL;
|
||||
pm_session_dettach_me(session);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_ORDPKT)
|
||||
{
|
||||
// TODO
|
||||
(*per_http_session_pme)->flags = SESSION_EVENT_ORDPKT;
|
||||
pm_session_take_over(session);
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_META)
|
||||
{
|
||||
// TODO
|
||||
(*per_http_session_pme)->flags = SESSION_EVENT_META;
|
||||
}
|
||||
|
||||
if (event & SESSION_EVENT_CLOSING)
|
||||
{
|
||||
http_session_pme_destory(*per_http_session_pme);
|
||||
*per_http_session_pme = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int http_event_plugin_init(void)
|
||||
{
|
||||
if (g_handler == NULL)
|
||||
{
|
||||
g_handler = (char *)malloc(1024);
|
||||
snprintf(g_handler, 1024, "111111");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void http_event_plugin_exit(void)
|
||||
{
|
||||
if (g_handler)
|
||||
{
|
||||
free(g_handler);
|
||||
g_handler = NULL;
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,5 @@
|
||||
|
||||
add_library(http
|
||||
http.cpp
|
||||
)
|
||||
)
|
||||
target_include_directories(http PUBLIC ${CMAKE_SOURCE_DIR})
|
||||
@@ -1,16 +1,12 @@
|
||||
#include "http.h"
|
||||
#include "session_manager.h"
|
||||
#include <stddef.h>
|
||||
|
||||
int http_decoder(const struct session *s, int what, struct packet *p, const char *payload, uint32_t len, void **pme)
|
||||
#include "sdk/include/session.h"
|
||||
|
||||
void http_decoder(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
|
||||
{
|
||||
void *info;
|
||||
struct session *new_session=session_manager_session_derive(s, SESSION_TYPE_HTTP);
|
||||
struct stellar_session_event_extras *info = NULL;
|
||||
struct stellar_session *new_session = session_manager_session_derive(s, "HTTP");
|
||||
|
||||
session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info);
|
||||
session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int http_peek(const struct session *s, const char *payload, uint32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
add_library(session_manager
|
||||
session_manager.cpp
|
||||
)
|
||||
)
|
||||
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR})
|
||||
@@ -1,43 +1,101 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sdk/include/session.h"
|
||||
#include "session_manager.h"
|
||||
|
||||
struct session_manager
|
||||
{
|
||||
struct session **tcp_table, **udp_table;
|
||||
struct stellar_session **tcp_table;
|
||||
struct stellar_session **udp_table;
|
||||
};
|
||||
|
||||
void session_manager_session_event_register(fn_session_event_callback decoder, session_type type)
|
||||
struct session_manager *session_manager_init()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void session_manager_trigger_event(struct stellar_session *s, enum session_event_type type, struct stellar_session_event_extras *info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct session *session_manager_custom_session_derive(const struct session *cur_session, struct custom_session_event *event)
|
||||
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session, const char *session_name)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void session_manager_trigger_event(struct session *s, session_event_type event, void *event_info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
struct session_event *session_manager_commit(struct packet *p)
|
||||
struct stellar_event *session_manager_commit(struct session_manager *h, struct stellar_packet *p)
|
||||
{
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
|
||||
struct custom_session_event *session_manager_custom_session_event_register(const char *event_name, int available_event)
|
||||
struct stellar_event *session_manager_fetch_event(struct session_manager *h)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct session *session_manager_session_derive(const struct session *cur_session, session_type type)
|
||||
/******************************************************************************
|
||||
* stellar_event API For Plugin Manager
|
||||
******************************************************************************/
|
||||
|
||||
struct session_plugin_ctx *stellar_event_get_plugin_ctx(struct stellar_event *event)
|
||||
{
|
||||
return nullptr;
|
||||
return event->session_event_data->plugin_ctx;
|
||||
}
|
||||
|
||||
struct session_event *session_manager_fetch_event()
|
||||
void stellar_event_set_plugin_ctx(struct stellar_event *event, struct session_plugin_ctx *plugin_ctx)
|
||||
{
|
||||
return nullptr;
|
||||
event->session_event_data->plugin_ctx = plugin_ctx;
|
||||
}
|
||||
|
||||
enum session_event_type stellar_event_get_type(struct stellar_event *event)
|
||||
{
|
||||
return event->session_event_data->type;
|
||||
}
|
||||
|
||||
const char *stellar_event_get_session_name(struct stellar_event *event)
|
||||
{
|
||||
return event->session_event_data->s->name;
|
||||
}
|
||||
|
||||
const struct stellar_session *stellar_event_get_session(struct stellar_event *event)
|
||||
{
|
||||
return event->session_event_data->s;
|
||||
}
|
||||
|
||||
// TODO
|
||||
struct stellar_packet *stellar_event_get_packet(struct stellar_event *event)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO
|
||||
const char *stellar_event_get_payload(struct stellar_event *event)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO
|
||||
uint16_t stellar_event_get_payload_length(struct stellar_event *event)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* stellar_session API For Plugin Manager
|
||||
******************************************************************************/
|
||||
|
||||
struct session_plugin_ctx *stellar_session_get_plugin_ctx(const struct stellar_session *session)
|
||||
{
|
||||
struct stellar_session_event_data *evdata = session->event_data;
|
||||
return evdata->plugin_ctx;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* stellar_session API For Plugin
|
||||
******************************************************************************/
|
||||
|
||||
const char *stellar_session_get_name(const struct stellar_session *session)
|
||||
{
|
||||
return session->name;
|
||||
}
|
||||
@@ -1,47 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "session.h"
|
||||
#include "uthash/uthash.h"
|
||||
#include "sdk/include/session.h"
|
||||
|
||||
#include <sys/queue.h> /* TAILQ(3) */
|
||||
|
||||
struct session_data
|
||||
struct stellar_session_event_data
|
||||
{
|
||||
/* data */
|
||||
struct stellar_session *s;
|
||||
enum session_event_type type;
|
||||
long last_active;
|
||||
struct session_plugin_ctx *plugin_ctx;
|
||||
};
|
||||
|
||||
enum session_state
|
||||
struct session_manager;
|
||||
struct session_manager *session_manager_init();
|
||||
|
||||
struct stellar_event *session_manager_commit(struct session_manager *session_mgr, struct stellar_packet *pkt);
|
||||
struct stellar_event *session_manager_fetch_event(struct session_manager *session_mgr);
|
||||
|
||||
struct stellar_session
|
||||
{
|
||||
SESSION_STATE_OPENING,
|
||||
SESSION_STATE_ACTIVE,
|
||||
SESSION_STATE_CLOSING,
|
||||
SESSION_STATE_CLOSED
|
||||
stellar_session_type type;
|
||||
const char *name;
|
||||
void *addr;
|
||||
void *data;
|
||||
struct stellar_session_event_data *event_data;
|
||||
};
|
||||
|
||||
struct session_event
|
||||
{
|
||||
enum session_state state;
|
||||
void *cb_pme;
|
||||
fn_session_event_callback callback;
|
||||
TAILQ_ENTRY(session_event) session_event_tq_entries;
|
||||
};
|
||||
/******************************************************************************
|
||||
* stellar_event API For Plugin Manager
|
||||
******************************************************************************/
|
||||
|
||||
TAILQ_HEAD(session_event_list, session_event);
|
||||
struct session_plugin_ctx *stellar_event_get_plugin_ctx(struct stellar_event *event);
|
||||
void stellar_event_set_plugin_ctx(struct stellar_event *event, struct session_plugin_ctx *plugin_ctx);
|
||||
|
||||
struct session
|
||||
{
|
||||
const char *name;
|
||||
enum session_type type;
|
||||
enum session_state state;
|
||||
struct session_data data;
|
||||
struct session_event cur_ev;
|
||||
struct session_event_list ev_list;
|
||||
TAILQ_ENTRY(session) session_tq_entries;
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
enum session_event_type stellar_event_get_type(struct stellar_event *event);
|
||||
const char *stellar_event_get_session_name(struct stellar_event *event);
|
||||
const struct stellar_session *stellar_event_get_session(struct stellar_event *event);
|
||||
struct stellar_packet *stellar_event_get_packet(struct stellar_event *event);
|
||||
|
||||
const char *stellar_event_get_payload(struct stellar_event *event);
|
||||
uint16_t stellar_event_get_payload_length(struct stellar_event *event);
|
||||
|
||||
/******************************************************************************
|
||||
* stellar_session API For Plugin Manager
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
void session_manager_session_event_register(fn_session_event_callback session_ev_cb, session_type type);
|
||||
struct session *session_manager_session_derive(const struct session *cur_session, session_type type);
|
||||
struct session_plugin_ctx *stellar_session_get_plugin_ctx(const struct stellar_session *session);
|
||||
Reference in New Issue
Block a user