Plugin Management support C plugin

This commit is contained in:
luwenpeng
2022-07-27 18:32:22 +08:00
parent 649d29e538
commit 50111e7cd0
35 changed files with 4220 additions and 193 deletions

View File

@@ -1,11 +1,9 @@
include_directories(${CMAKE_SOURCE_DIR}/sdk/include)
include_directories(${CMAKE_SOURCE_DIR}/deps/)
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)
@@ -16,4 +14,13 @@ add_executable(stellar
main.cpp
)
target_link_libraries(stellar pthread packet_io plugin_manager session_manager http)
target_link_libraries(
stellar
pthread
packet_io
plugin_manager
session_manager
http
toml
dl
)

View File

@@ -59,11 +59,12 @@ int main(int argc, char ** argv)
struct plugin_manager *plug_mgr = plugin_manager_create();
// register build-in plugin
plugin_manager_register(plug_mgr, "HTTP", http_decoder);
plugin_manager_register(plug_mgr, "HTTP", SESSION_EVENT_ALL, http_decoder);
// load external plugins
char absolute_plugin_file[] = "/op/tsg/sapp/plug/plugins.inf";
plugin_manager_load(plug_mgr, absolute_plugin_file);
char prefix_path[] = "/op/tsg/stellar/";
char file_path[] = "./plugs/plugins.inf";
plugin_manager_load(plug_mgr, prefix_path, file_path);
//packet_io_init
struct packet_io_device *dev = packet_io_init(1, "stellar", "cap0");
@@ -78,6 +79,7 @@ int main(int argc, char ** argv)
usleep(1);
}
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr);
return 0;

View File

@@ -1,4 +1,10 @@
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})
target_include_directories(plugin_manager PUBLIC ${CMAKE_SOURCE_DIR})
add_subdirectory(test)

View File

@@ -1,106 +1,313 @@
#include "deps/uthash/uthash.h"
#include "sdk/include/session.h"
#include "sdk/include/plugin.h"
#include "session_manager.h"
#include "plugin_manager.h"
#include "plugin_manager_util.h"
#include "plugin_manager_config.h"
#include "plugin_manager_module.h"
#include <sys/queue.h>
#include <assert.h>
#include <errno.h>
/******************************************************************************
* CallBack Static Hash Table (For Global)
* CallBack Runtime (For Per Session)
******************************************************************************/
struct session_event_callback_static
struct eventcb_runtime
{
enum session_event_type event;
fn_session_event_callback *callback;
};
/*
* Hast table
*
* key: string -> session_type
* val: array -> event_cbs
*/
struct managed_session_event_callback
{
char session_type[16];
struct session_event_callback_static event_cbs[0]; // dynamic array
// Record the number of callback functions that want to process the current session
int event_cbs_num;
UT_hash_handle hh;
};
/******************************************************************************
* CallBack Runtime Array (For Per Session)
******************************************************************************/
struct session_event_callback_runtime
{
int skip; // for skip this plugin callback
void *callback_args;
int skip;
void *cb_args;
enum session_event_type event;
fn_session_event_callback *callback;
fn_session_event_callback *cb;
};
struct session_plugin_ctx
{
int event_cbs_num;
struct session_event_callback_runtime event_cbs[0]; // dynamic array
int current_plugin_index;
int eventcb_num;
struct eventcb_runtime *eventcbs;
};
/******************************************************************************
* struct plugin_manager
* CallBack Static (For Per Plugin Manager)
******************************************************************************/
/*
* Each plugin has an init_cb and an exit_cb, but may have multiple entry_cb.
* entry_cb is stored in the global_session_callback_ctx.
*/
struct plugin_ctx
struct eventcb_static
{
char *name;
char *library;
/*
* Stores the context generated by the plugin initialization,
* which is used to release resources when the plugin ends.
*/
void *pme;
plugin_init_callback *init_cb;
plugin_exit_callback *exit_cb;
enum session_event_type event;
fn_session_event_callback *cb;
};
struct plugin_manager_eventcb
{
char session_name[MAX_SESSION_NAME_LENGTH]; // key
int eventcb_num; // val size
struct eventcb_static *eventcbs; // val: dynamic array
UT_hash_handle hh;
};
/******************************************************************************
* Struct plugin_manager
******************************************************************************/
struct plugin_manager
{
struct managed_session_event_callback *cb_table;
struct plugin_ctx plugins[MAX_PLUGIN_NUM];
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;
};
/******************************************************************************
* Private API
* Create/Destory plugin ctx (per session)
******************************************************************************/
static void plugin_manager_handle_opening_event(struct plugin_manager *plug_mgr, struct stellar_event *event)
static struct session_plugin_ctx *plugin_manager_create_plugin_ctx(struct plugin_manager *plug_mgr, const char *session_name)
{
if (session_name == NULL || strlen(session_name) == 0)
{
plugin_manager_log(ERROR, "invalid parameter, session name is empty");
return NULL;
}
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->eventcb_num = elem->eventcb_num;
plug_ctx->eventcbs = safe_alloc(struct eventcb_runtime, plug_ctx->eventcb_num);
for (int i = 0; i < plug_ctx->eventcb_num; i++)
{
plug_ctx->eventcbs[i].skip = 0;
plug_ctx->eventcbs[i].event = elem->eventcbs[i].event;
plug_ctx->eventcbs[i].cb = elem->eventcbs[i].cb;
plug_ctx->eventcbs[i].cb_args = NULL;
}
return plug_ctx;
}
}
static void plugin_manager_handle_data_event(struct plugin_manager *plug_mgr, struct stellar_event *event)
{
}
static void plugin_manager_handle_closing_event(struct plugin_manager *plug_mgr, struct stellar_event *event)
static void plugin_manager_destory_plugin_ctx(struct session_plugin_ctx *plug_ctx)
{
if (plug_ctx)
{
safe_free(plug_ctx->eventcbs);
safe_free(plug_ctx);
}
}
/******************************************************************************
* Public API
* Tools for managing plugins
******************************************************************************/
static int plugin_manager_parse_plugins(struct plugin_manager *plug_mgr, const char *prefix, const char *file)
{
char plugin_inf[4096] = {0};
char line_buffer[4096] = {0};
if (strlen(prefix) <= 0)
{
plugin_manager_log(ERROR, "Invalid parameter, plugin config file prefix cannot be empty");
return -1;
}
if (strlen(file) <= 0)
{
plugin_manager_log(ERROR, "Invalid parameter, plugin config file name cannot be empty");
return -1;
}
strcat_prefix_and_file(prefix, file, plugin_inf, sizeof(plugin_inf));
FILE *fp = fopen(plugin_inf, "r");
if (fp == NULL)
{
plugin_manager_log(ERROR, "can't open %s, %s", plugin_inf, 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;
}
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, prefix, 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;
}
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 *prefix, const char *file)
{
if (plugin_manager_parse_plugins(plug_mgr, prefix, 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 = NULL;
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;
}
@@ -109,45 +316,138 @@ 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->eventcbs);
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_load(struct plugin_manager *plug_mgr, const char *plugin_file)
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_name, enum session_event_type event, fn_session_event_callback *cb)
{
return 0;
}
if (strlen(session_name) <= 0)
{
plugin_manager_log(ERROR, "invalid parameter, session name is empty");
return -1;
}
void plugin_manager_unload(struct plugin_manager *plug_mgr)
{
}
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 (cb == NULL)
{
plugin_manager_log(ERROR, "invalid parameter, the 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 eventcbs dynamic array
if (elem)
{
elem->eventcbs = (struct eventcb_static *)realloc(elem->eventcbs, (elem->eventcb_num + 1) * sizeof(struct eventcb_static));
elem->eventcbs[elem->eventcb_num].event = event;
elem->eventcbs[elem->eventcb_num].cb = cb;
elem->eventcb_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->eventcbs = (struct eventcb_static *)realloc(elem->eventcbs, (elem->eventcb_num + 1) * sizeof(struct eventcb_static));
elem->eventcbs[elem->eventcb_num].event = event;
elem->eventcbs[elem->eventcb_num].cb = cb;
elem->eventcb_num++;
HASH_ADD_STR(plug_mgr->evcb_htable, session_name, elem);
}
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_type, fn_session_event_callback *callback)
{
return 0;
}
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event)
{
assert(event);
struct stellar_session_event_data *event_data = event->session_event_data;
assert(event_data);
session_event_type type = event_data->type;
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);
switch (type)
assert(seesion);
assert(session_name);
// the same session may trigger multi times opening events
if (event_type & SESSION_EVENT_OPENING)
{
case SESSION_EVENT_OPENING:
plugin_manager_handle_opening_event(plug_mgr, event);
break;
case SESSION_EVENT_RAWPKT: /* fall through */
case SESSION_EVENT_ORDPKT: /* fall through */
case SESSION_EVENT_META: /* fall through */
plugin_manager_handle_data_event(plug_mgr, event);
break;
case SESSION_EVENT_CLOSING:
plugin_manager_handle_closing_event(plug_mgr, event);
break;
default:
// TODO log error
break;
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");
return;
}
stellar_event_set_plugin_ctx(event, plug_ctx);
}
}
}
if (plug_ctx)
{
for (int i = 0; i < plug_ctx->eventcb_num; i++)
{
plug_ctx->current_plugin_index = i;
struct eventcb_runtime *runtime = &plug_ctx->eventcbs[i];
if (runtime->skip)
{
continue;
}
if (runtime->event & event_type)
{
runtime->cb(seesion, event_type, packet, payload, payload_len, &runtime->cb_args);
}
}
}
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);
}
}
/******************************************************************************
* Suppport LUA plugins
******************************************************************************/
// TODO

View File

@@ -1,11 +1,7 @@
#pragma once
#include "sdk/include/session.h"
#define MAX_PLUGIN_NUM 256
struct per_session_event_cbs;
struct plugin_manager;
struct plugin_manager *plugin_manager_create();
@@ -13,8 +9,8 @@ void plugin_manager_destory(struct plugin_manager *plug_mgr);
// return 0: success
// return -1: error
int plugin_manager_load(struct plugin_manager *plug_mgr, const char *plugin_file);
int plugin_manager_load(struct plugin_manager *plug_mgr, const char *prefix, const char *file);
void plugin_manager_unload(struct plugin_manager *plug_mgr);
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_type, fn_session_event_callback *callback);
int plugin_manager_register(struct plugin_manager *plug_mgr, const char *session_name, enum session_event_type event, fn_session_event_callback *callback);
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event);

View File

@@ -0,0 +1,358 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "toml/toml.h"
#include "sdk/include/session.h"
#include "plugin_manager_util.h"
#include "plugin_manager_config.h"
struct event_type_map
{
const char *type_str;
enum session_event_type type_int;
};
static struct event_type_map evtype_map[] =
{
{"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},
};
/******************************************************************************
* Private API (For Event Type)
******************************************************************************/
static enum session_event_type event_type_str2int(const char *evtype_str)
{
int num = sizeof(evtype_map) / sizeof(evtype_map[0]);
for (int i = 0; i < num; i++)
{
if (strcmp(evtype_str, evtype_map[i].type_str) == 0)
{
return evtype_map[i].type_int;
}
}
return SESSION_EVENT_UNKNOWN;
}
static void 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]);
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);
}
}
}
/******************************************************************************
* 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 = 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);
}
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->prefix_path = NULL;
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->prefix_path);
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_PREFIX] : %s", config->prefix_path);
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];
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 *prefix, const char *file)
{
FILE *fp = NULL;
toml_table_t *root = NULL;
char errbuf[200] = {0};
char tmp_buffer[4096] = {0};
config->prefix_path = safe_dup(prefix);
config->file_path = safe_dup(file);
strcat_prefix_and_file(prefix, file, tmp_buffer, sizeof(tmp_buffer));
fp = fopen(tmp_buffer, "r");
if (fp == NULL)
{
plugin_manager_log(ERROR, "can't open %s, %s", tmp_buffer, 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);
return 0;
err:
if (root)
{
toml_free(root);
}
if (fp)
{
fclose(fp);
fp = NULL;
}
return -1;
}
/******************************************************************************
* Test
******************************************************************************/
#ifdef PLUGIN_MANAGER_TEST
int main(int argc, char *argv[])
{
struct plugin_manager_config *config = plugin_mangager_config_create();
if (plugin_mangager_config_parse(config, argv[1], argv[2]) == -1)
{
plugin_manager_log(ERROR, "can't parser %s %s", argv[1], argv[2]);
}
plugin_mangager_config_dump(config);
plugin_mangager_config_destory(config);
return 0;
}
#endif

View File

@@ -0,0 +1,34 @@
#pragma once
#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 *prefix_path; // absolute path to stellar installation
char *file_path; // relative path to stellar installation
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 *prefix, const char *file);
void plugin_mangager_config_dump(struct plugin_manager_config *config);

View File

@@ -0,0 +1,168 @@
#include <time.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include "sdk/include/plugin.h"
#include "plugin_manager_util.h"
#include "plugin_manager_config.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 *prefix;
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->prefix);
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;
}
char dynamic_lib_path[4096] = {0};
struct plugin_manager_module *module = safe_alloc(struct plugin_manager_module, 1);
module->prefix = safe_dup(config->prefix_path);
module->lib_path = safe_dup(config->plugin_section.lib_path);
strcat_prefix_and_file(module->prefix, module->lib_path, dynamic_lib_path, sizeof(dynamic_lib_path));
module->evcbs_num = 0;
module->dl_handle = dlopen(dynamic_lib_path, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND);
if (module->dl_handle == NULL)
{
plugin_manager_log(ERROR, "can't dlopen %s, %s", dynamic_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, dynamic_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, dynamic_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, dynamic_lib_path, dlerror());
goto err;
}
}
}
return module;
err:
plugin_manager_module_close(module);
return NULL;
}
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;
}
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();
if (ret == -1)
{
plugin_manager_log(ERROR, "dynamic library '%s' initialization failed", module->lib_path);
return -1;
}
clock_gettime(CLOCK_MONOTONIC, &end);
long elapsed = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
plugin_manager_log(INFO, "plugin '%s' init success, using '%lld' us", module->lib_path, elapsed);
return 0;
}
void plugin_manager_module_exit(struct plugin_manager_module *module)
{
if (module && module->exit_cb_ptr)
{
module->exit_cb_ptr();
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "plugin_manager_config.h"
struct plugin_manager_module;
struct plugin_manager_module *plugin_manager_module_open(struct plugin_manager_config *config);
int plugin_manager_module_register(struct plugin_manager *plug_mgr, 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_close(struct plugin_manager_module *module);

View File

@@ -0,0 +1,40 @@
#include <string.h>
#include <stdlib.h>
#include "plugin_manager_util.h"
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;
}
void strcat_prefix_and_file(const char *prefix, const char *file, char *buff, int size)
{
char prefix_buffer[4096] = {0};
char file_buffer[4096] = {0};
char *ptr = NULL;
memcpy(prefix_buffer, prefix, strlen(prefix));
memcpy(file_buffer, file, strlen(file));
if (prefix_buffer[strlen(prefix_buffer) - 1] != '/')
{
prefix_buffer[strlen(prefix_buffer)] = '/';
}
file_buffer[strcspn(file_buffer, "\r\n")] = 0;
ptr = file_buffer;
if (file_buffer[0] == '.' && file_buffer[1] == '/')
{
ptr += 2;
}
snprintf(buff, size, "%s%s", prefix_buffer, ptr);
}

View File

@@ -0,0 +1,61 @@
#pragma once
#include <stdio.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,
INFO = 0x12,
ERROR = 0x13,
};
#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 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
/******************************************************************************
* Str
******************************************************************************/
void strcat_prefix_and_file(const char *prefix, const char *file, char *buff, int size);

View File

@@ -0,0 +1,18 @@
add_executable(gtest_plugin_manager
gtest_plugin_manager.cpp
)
target_link_libraries(
gtest_plugin_manager
gtest_main
plugin_manager
session_manager
toml
dl
)
include(GoogleTest)
gtest_discover_tests(gtest_plugin_manager)
add_subdirectory(test_plugins/plugins_library)
file(COPY test_plugins/plugins_config DESTINATION ./)

View File

@@ -0,0 +1,159 @@
#include <gtest/gtest.h>
#include "../plugin_manager_config.h"
#include "../plugin_manager.h"
#include "session_manager.h"
TEST(PLUGIN_MANAGER_TEST, plugin_manager_config_HTTP)
{
char prefix_path[] = "./";
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, prefix_path, file_path) == 0);
EXPECT_STREQ(config->prefix_path, "./");
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);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_config_CUSTOM)
{
char prefix_path[] = "./";
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, prefix_path, file_path) == 0);
EXPECT_STREQ(config->prefix_path, "./");
EXPECT_STREQ(config->file_path, "./plugins_config/custom_event_plugin/custom_event_plugin.inf");
EXPECT_STREQ(config->plugin_section.init_func_name, "custom_plugin_init");
EXPECT_STREQ(config->plugin_section.exit_func_name, "custom_plugin_exit");
EXPECT_STREQ(config->plugin_section.lib_path, "./test_plugins/plugins_library/custom_event_plugin_test.so");
EXPECT_TRUE(config->session_section_num == 2);
EXPECT_STREQ(config->session_section[0].session_name, "TCP");
EXPECT_STREQ(config->session_section[0].cb_func_name, "custom_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, "CUSTOM");
EXPECT_STREQ(config->session_section[1].cb_func_name, "custom_plugin_custom_entry");
EXPECT_TRUE(config->session_section[1].event == (0x01 << 1) | (0x01 << 3) | (0x01 << 5));
plugin_mangager_config_dump(config);
plugin_mangager_config_destory(config);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_load)
{
char prefix_path[] = "./";
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, prefix_path, file_path) == 0);
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_HTTP)
{
char prefix_path[] = "./";
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;
struct plugin_manager *plug_mgr = plugin_manager_create();
EXPECT_TRUE(plug_mgr != nullptr);
EXPECT_TRUE(plugin_manager_load(plug_mgr, prefix_path, file_path) == 0);
event_data.type = SESSION_EVENT_OPENING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_RAWPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ORDPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_META;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_CLOSING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ALL;
plugin_manager_dispatch(plug_mgr, &event);
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr);
}
TEST(PLUGIN_MANAGER_TEST, plugin_manager_dispatch_CUSTOM)
{
char prefix_path[] = "./";
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;
struct plugin_manager *plug_mgr = plugin_manager_create();
EXPECT_TRUE(plug_mgr != nullptr);
EXPECT_TRUE(plugin_manager_load(plug_mgr, prefix_path, file_path) == 0);
event_data.type = SESSION_EVENT_OPENING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_RAWPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ORDPKT;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_META;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_CLOSING;
plugin_manager_dispatch(plug_mgr, &event);
event_data.type = SESSION_EVENT_ALL;
plugin_manager_dispatch(plug_mgr, &event);
plugin_manager_unload(plug_mgr);
plugin_manager_destory(plug_mgr);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
}

View File

@@ -0,0 +1,14 @@
[PLUGINFO]
INIT_FUNC="custom_plugin_init"
EXIT_FUNC="custom_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_plugin_tcp_entry"
[SESSION_NAME.CUSTOM]
SESSION_EVENT_TYPE=["SESSION_EVENT_OPENING","SESSION_EVENT_ORDPKT","SESSION_EVENT_CLOSING"]
SESSION_EVENT_CALLBACK="custom_plugin_custom_entry"

View File

@@ -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"

View File

@@ -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

View File

@@ -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 "")

View File

@@ -0,0 +1,58 @@
#include "session.h"
#include "packet.h"
#include "plugin.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
static char *g_handler = NULL;
static void *custom_decode(const char *payload, uint16_t len, void **pme)
{
return NULL;
}
extern "C" void custom_plugin_tcp_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{
char **per_session_pme = (char **)pme;
printf("RUN custom_plugin_tcp_entry, event: %d\n", event);
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(s, "CUSTOM");
session_manager_trigger_event(new_session, SESSION_EVENT_OPENING, info);
session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
}
extern "C" void custom_plugin_custom_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{
char **per_session_pme = (char **)pme;
printf("RUN custom_plugin_custom_entry, event: %d\n", event);
}
extern "C" int custom_plugin_init(void)
{
printf("RUN custom_plugin_init\n");
if (g_handler == NULL)
{
g_handler = (char *)malloc(1024);
snprintf(g_handler, 1024, "222222");
}
return 0;
}
extern "C" void custom_plugin_exit(void)
{
printf("RUN custom_plugin_exit\n");
if (g_handler)
{
free(g_handler);
g_handler = NULL;
}
}

View File

@@ -0,0 +1,82 @@
#include "session.h"
#include "packet.h"
#include "plugin.h"
#include <stdlib.h>
#include <stdio.h>
static char *g_handler = NULL;
struct per_session_pme_info
{
int flag;
char data[16];
};
extern "C" void http_event_plugin_entry(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
{
struct per_session_pme_info **per_session_pme = (struct per_session_pme_info **)pme;
printf("RUN http_event_plugin_entry, event: %d\n", event);
if (event & SESSION_EVENT_OPENING)
{
if (*per_session_pme == NULL)
{
struct per_session_pme_info *cur_ctx = (struct per_session_pme_info *)malloc(sizeof(struct per_session_pme_info));
snprintf(cur_ctx->data, 6, "******");
*per_session_pme = *&cur_ctx;
printf("http_event_plugin_entry->opening_handler\n");
}
}
if (event & SESSION_EVENT_RAWPKT)
{
printf("http_event_plugin_entry->rawpkt_handler\n");
}
if (event & SESSION_EVENT_ORDPKT)
{
printf("http_event_plugin_entry->ordpkt_handler\n");
}
if (event & SESSION_EVENT_META)
{
printf("http_event_plugin_entry->meta_handler\n");
}
if (event & SESSION_EVENT_CLOSING)
{
if (*per_session_pme)
{
printf("http_event_plugin_entry->closing_hanler\n");
free(*per_session_pme);
*per_session_pme = NULL;
}
}
}
extern "C" int http_event_plugin_init(void)
{
printf("RUN http_event_plugin_init\n");
if (g_handler == NULL)
{
g_handler = (char *)malloc(1024);
snprintf(g_handler, 1024, "111111");
}
return 0;
}
extern "C" void http_event_plugin_exit(void)
{
printf("RUN http_event_plugin_exit\n");
if (g_handler)
{
free(g_handler);
g_handler = NULL;
}
}

View File

@@ -1,15 +1,10 @@
#include "http.h"
#include "session_manager.h"
#include "sdk/include/session.h"
void http_decoder(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint16_t len, void **pme)
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)
{
struct stellar_session_event_extras *info;
struct stellar_session *new_session=session_manager_session_derive(s, "HTTP");
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);
}
int http_peek(const struct stellar_session *s, const char *payload, uint32_t len)
{
return 0;
}

View File

@@ -1,8 +1,12 @@
#include <stddef.h>
#include "sdk/include/session.h"
#include "session_manager.h"
struct session_manager
{
struct stellar_session **tcp_table, **udp_table;
struct stellar_session **tcp_table;
struct stellar_session **udp_table;
};
struct session_manager *session_manager_init()
@@ -10,16 +14,12 @@ 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)
void session_manager_trigger_event(struct stellar_session *s, enum session_event_type type, struct stellar_session_event_extras *info)
{
return;
}
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session,
const char *new_session_type_name)
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session, const char *session_name)
{
return nullptr;
}
@@ -29,8 +29,54 @@ struct stellar_event *session_manager_commit(struct session_manager *h, struct s
return nullptr;
};
struct stellar_event *session_manager_fetch_event(struct session_manager *h)
{
return nullptr;
}
/******************************************************************************
* API: between stellar_event and plugin_manager
******************************************************************************/
struct session_plugin_ctx *stellar_event_get_plugin_ctx(struct stellar_event *event)
{
return event->session_event_data->plugin_ctx;
}
void stellar_event_set_plugin_ctx(struct stellar_event *event, struct session_plugin_ctx *plugin_ctx)
{
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;
}

View File

@@ -2,8 +2,6 @@
#include "sdk/include/session.h"
struct per_session_evcb_runtime_ctx;
struct stellar_session_event_data
{
struct stellar_session *s;
@@ -18,10 +16,6 @@ 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);
// interfaces for data interaction between stellar event and plugin manager
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 stellar_session
{
stellar_session_type type;
@@ -29,3 +23,18 @@ struct stellar_session
void *addr;
void *data;
};
/******************************************************************************
* API: between stellar_event and plugin_manager
******************************************************************************/
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);
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);