Plugin Management support C plugin
This commit is contained in:
@@ -17,6 +17,7 @@ include_directories(${CMAKE_SOURCE_DIR}/sdk/include)
|
|||||||
|
|
||||||
#add vendor and source directory
|
#add vendor and source directory
|
||||||
add_subdirectory(vendor)
|
add_subdirectory(vendor)
|
||||||
|
add_subdirectory(deps/toml)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(sdk/example)
|
add_subdirectory(sdk/example)
|
||||||
|
|
||||||
|
|||||||
3
deps/toml/CMakeLists.txt
vendored
Normal file
3
deps/toml/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
set(CMAKE_C_FLAGS "-std=c99")
|
||||||
|
add_definitions(-fPIC)
|
||||||
|
add_library(toml STATIC toml.c)
|
||||||
2379
deps/toml/toml.c
vendored
Normal file
2379
deps/toml/toml.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
175
deps/toml/toml.h
vendored
Normal file
175
deps/toml/toml.h
vendored
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) CK Tan
|
||||||
|
https://github.com/cktan/tomlc99
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef TOML_H
|
||||||
|
#define TOML_H
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(disable: 4996)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define TOML_EXTERN extern "C"
|
||||||
|
#else
|
||||||
|
#define TOML_EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct toml_timestamp_t toml_timestamp_t;
|
||||||
|
typedef struct toml_table_t toml_table_t;
|
||||||
|
typedef struct toml_array_t toml_array_t;
|
||||||
|
typedef struct toml_datum_t toml_datum_t;
|
||||||
|
|
||||||
|
/* Parse a file. Return a table on success, or 0 otherwise.
|
||||||
|
* Caller must toml_free(the-return-value) after use.
|
||||||
|
*/
|
||||||
|
TOML_EXTERN toml_table_t *toml_parse_file(FILE *fp, char *errbuf, int errbufsz);
|
||||||
|
|
||||||
|
/* Parse a string containing the full config.
|
||||||
|
* Return a table on success, or 0 otherwise.
|
||||||
|
* Caller must toml_free(the-return-value) after use.
|
||||||
|
*/
|
||||||
|
TOML_EXTERN toml_table_t *toml_parse(char *conf, /* NUL terminated, please. */
|
||||||
|
char *errbuf, int errbufsz);
|
||||||
|
|
||||||
|
/* Free the table returned by toml_parse() or toml_parse_file(). Once
|
||||||
|
* this function is called, any handles accessed through this tab
|
||||||
|
* directly or indirectly are no longer valid.
|
||||||
|
*/
|
||||||
|
TOML_EXTERN void toml_free(toml_table_t *tab);
|
||||||
|
|
||||||
|
/* Timestamp types. The year, month, day, hour, minute, second, z
|
||||||
|
* fields may be NULL if they are not relevant. e.g. In a DATE
|
||||||
|
* type, the hour, minute, second and z fields will be NULLs.
|
||||||
|
*/
|
||||||
|
struct toml_timestamp_t {
|
||||||
|
struct { /* internal. do not use. */
|
||||||
|
int year, month, day;
|
||||||
|
int hour, minute, second, millisec;
|
||||||
|
char z[10];
|
||||||
|
} __buffer;
|
||||||
|
int *year, *month, *day;
|
||||||
|
int *hour, *minute, *second, *millisec;
|
||||||
|
char *z;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------
|
||||||
|
* Enhanced access methods
|
||||||
|
*/
|
||||||
|
struct toml_datum_t {
|
||||||
|
int ok;
|
||||||
|
union {
|
||||||
|
toml_timestamp_t *ts; /* ts must be freed after use */
|
||||||
|
char *s; /* string value. s must be freed after use */
|
||||||
|
int b; /* bool value */
|
||||||
|
int64_t i; /* int value */
|
||||||
|
double d; /* double value */
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* on arrays: */
|
||||||
|
/* ... retrieve size of array. */
|
||||||
|
TOML_EXTERN int toml_array_nelem(const toml_array_t *arr);
|
||||||
|
/* ... retrieve values using index. */
|
||||||
|
TOML_EXTERN toml_datum_t toml_string_at(const toml_array_t *arr, int idx);
|
||||||
|
TOML_EXTERN toml_datum_t toml_bool_at(const toml_array_t *arr, int idx);
|
||||||
|
TOML_EXTERN toml_datum_t toml_int_at(const toml_array_t *arr, int idx);
|
||||||
|
TOML_EXTERN toml_datum_t toml_double_at(const toml_array_t *arr, int idx);
|
||||||
|
TOML_EXTERN toml_datum_t toml_timestamp_at(const toml_array_t *arr, int idx);
|
||||||
|
/* ... retrieve array or table using index. */
|
||||||
|
TOML_EXTERN toml_array_t *toml_array_at(const toml_array_t *arr, int idx);
|
||||||
|
TOML_EXTERN toml_table_t *toml_table_at(const toml_array_t *arr, int idx);
|
||||||
|
|
||||||
|
/* on tables: */
|
||||||
|
/* ... retrieve the key in table at keyidx. Return 0 if out of range. */
|
||||||
|
TOML_EXTERN const char *toml_key_in(const toml_table_t *tab, int keyidx);
|
||||||
|
/* ... returns 1 if key exists in tab, 0 otherwise */
|
||||||
|
TOML_EXTERN int toml_key_exists(const toml_table_t *tab, const char *key);
|
||||||
|
/* ... retrieve values using key. */
|
||||||
|
TOML_EXTERN toml_datum_t toml_string_in(const toml_table_t *arr,
|
||||||
|
const char *key);
|
||||||
|
TOML_EXTERN toml_datum_t toml_bool_in(const toml_table_t *arr, const char *key);
|
||||||
|
TOML_EXTERN toml_datum_t toml_int_in(const toml_table_t *arr, const char *key);
|
||||||
|
TOML_EXTERN toml_datum_t toml_double_in(const toml_table_t *arr,
|
||||||
|
const char *key);
|
||||||
|
TOML_EXTERN toml_datum_t toml_timestamp_in(const toml_table_t *arr,
|
||||||
|
const char *key);
|
||||||
|
/* .. retrieve array or table using key. */
|
||||||
|
TOML_EXTERN toml_array_t *toml_array_in(const toml_table_t *tab,
|
||||||
|
const char *key);
|
||||||
|
TOML_EXTERN toml_table_t *toml_table_in(const toml_table_t *tab,
|
||||||
|
const char *key);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------
|
||||||
|
* lesser used
|
||||||
|
*/
|
||||||
|
/* Return the array kind: 't'able, 'a'rray, 'v'alue, 'm'ixed */
|
||||||
|
TOML_EXTERN char toml_array_kind(const toml_array_t *arr);
|
||||||
|
|
||||||
|
/* For array kind 'v'alue, return the type of values
|
||||||
|
i:int, d:double, b:bool, s:string, t:time, D:date, T:timestamp, 'm'ixed
|
||||||
|
0 if unknown
|
||||||
|
*/
|
||||||
|
TOML_EXTERN char toml_array_type(const toml_array_t *arr);
|
||||||
|
|
||||||
|
/* Return the key of an array */
|
||||||
|
TOML_EXTERN const char *toml_array_key(const toml_array_t *arr);
|
||||||
|
|
||||||
|
/* Return the number of key-values in a table */
|
||||||
|
TOML_EXTERN int toml_table_nkval(const toml_table_t *tab);
|
||||||
|
|
||||||
|
/* Return the number of arrays in a table */
|
||||||
|
TOML_EXTERN int toml_table_narr(const toml_table_t *tab);
|
||||||
|
|
||||||
|
/* Return the number of sub-tables in a table */
|
||||||
|
TOML_EXTERN int toml_table_ntab(const toml_table_t *tab);
|
||||||
|
|
||||||
|
/* Return the key of a table*/
|
||||||
|
TOML_EXTERN const char *toml_table_key(const toml_table_t *tab);
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------
|
||||||
|
* misc
|
||||||
|
*/
|
||||||
|
TOML_EXTERN int toml_utf8_to_ucs(const char *orig, int len, int64_t *ret);
|
||||||
|
TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]);
|
||||||
|
TOML_EXTERN void toml_set_memutil(void *(*xxmalloc)(size_t),
|
||||||
|
void (*xxfree)(void *));
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------
|
||||||
|
* deprecated
|
||||||
|
*/
|
||||||
|
/* A raw value, must be processed by toml_rto* before using. */
|
||||||
|
typedef const char *toml_raw_t;
|
||||||
|
TOML_EXTERN toml_raw_t toml_raw_in(const toml_table_t *tab, const char *key);
|
||||||
|
TOML_EXTERN toml_raw_t toml_raw_at(const toml_array_t *arr, int idx);
|
||||||
|
TOML_EXTERN int toml_rtos(toml_raw_t s, char **ret);
|
||||||
|
TOML_EXTERN int toml_rtob(toml_raw_t s, int *ret);
|
||||||
|
TOML_EXTERN int toml_rtoi(toml_raw_t s, int64_t *ret);
|
||||||
|
TOML_EXTERN int toml_rtod(toml_raw_t s, double *ret);
|
||||||
|
TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double *ret, char *buf, int buflen);
|
||||||
|
TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t *ret);
|
||||||
|
|
||||||
|
#endif /* TOML_H */
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
|
add_library(custom_event_plugin SHARED
|
||||||
add_definitions(-fPIC)
|
|
||||||
|
|
||||||
add_library(custom_event_plugin
|
|
||||||
custom_event_plugin.cpp
|
custom_event_plugin.cpp
|
||||||
)
|
)
|
||||||
set_target_properties(custom_event_plugin PROPERTIES PREFIX "")
|
set_target_properties(custom_event_plugin PROPERTIES PREFIX "")
|
||||||
|
|
||||||
add_library(http_event_plugin
|
add_library(http_event_plugin SHARED
|
||||||
http_event_plugin.cpp
|
http_event_plugin.cpp
|
||||||
)
|
)
|
||||||
set_target_properties(http_event_plugin PROPERTIES PREFIX "")
|
set_target_properties(http_event_plugin PROPERTIES PREFIX "")
|
||||||
@@ -2,37 +2,57 @@
|
|||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
struct custom_session_event *_event = nullptr;
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
void *custom_decode(const char *payload, uint32_t len, void **pme)
|
static char *g_handler = NULL;
|
||||||
|
|
||||||
|
static void *custom_decode(const char *payload, uint16_t len, void **pme)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int custom_plugin_entry(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint32_t len, void **pme)
|
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)
|
||||||
{
|
{
|
||||||
struct stellar_session_event_extras *info= (struct stellar_session_event_extras *)custom_decode(payload, len, pme);
|
char **per_session_pme = (char **)pme;
|
||||||
struct stellar_session *new_session=session_manager_session_derive(s, "CUSTOM_A");
|
|
||||||
|
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_OPENING, info);
|
||||||
session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
|
session_manager_trigger_event(new_session, SESSION_EVENT_META, info);
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int custom_event_plugin_entry(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint32_t len, void **pme)
|
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)
|
||||||
{
|
{
|
||||||
return 0;
|
char **per_session_pme = (char **)pme;
|
||||||
|
|
||||||
|
printf("RUN custom_plugin_custom_entry, event: %d\n", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
int custom_plugin_init()
|
extern "C" int custom_plugin_init(void)
|
||||||
{
|
{
|
||||||
//plugin_manager_event_register("TCP", custom_plugin_entry, nullptr);
|
printf("RUN custom_plugin_init\n");
|
||||||
//plugin_manager_event_register("CUSTOM_A", custom_event_plugin_entry, nullptr);
|
|
||||||
|
if (g_handler == NULL)
|
||||||
|
{
|
||||||
|
g_handler = (char *)malloc(1024);
|
||||||
|
snprintf(g_handler, 1024, "222222");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void custom_plugin_destroy()
|
extern "C" void custom_plugin_exit(void)
|
||||||
{
|
{
|
||||||
return ;
|
printf("RUN custom_plugin_exit\n");
|
||||||
|
|
||||||
|
if (g_handler)
|
||||||
|
{
|
||||||
|
free(g_handler);
|
||||||
|
g_handler = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,82 @@
|
|||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "http.h"
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static char *g_handler = NULL;
|
||||||
|
|
||||||
int http_event_plugin_entry(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint32_t len, void **pme)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int http_event_plugin_init()
|
extern "C" void http_event_plugin_exit(void)
|
||||||
{
|
{
|
||||||
//plugin_manager_event_register("HTTP", http_event_plugin_entry, nullptr);
|
printf("RUN http_event_plugin_exit\n");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void http_event_plugin_destroy()
|
if (g_handler)
|
||||||
{
|
{
|
||||||
return ;
|
free(g_handler);
|
||||||
|
g_handler = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,14 @@
|
|||||||
[PLUGINFO]
|
[PLUGINFO]
|
||||||
INIT_FUNC=custom_plugin_init
|
INIT_FUNC="custom_plugin_init"
|
||||||
EXIT_FUNC=custom_plugin_exit
|
EXIT_FUNC="custom_plugin_exit"
|
||||||
LIBRARY_PATH=./plugins/custom_event_plugin/custom_event_plugin.so
|
LIBRARY_PATH="./plugins/custom_event_plugin/custom_event_plugin.so"
|
||||||
|
|
||||||
|
# Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
|
||||||
|
|
||||||
# Support SESSION_EVENT_TYPE
|
[SESSION_NAME.TCP]
|
||||||
# OPENING,RAWPKT,ORDPKT,META,CLOSING,ALL
|
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||||
|
SESSION_EVENT_CALLBACK="custom_plugin_tcp_entry"
|
||||||
|
|
||||||
[SESSION_TYPE.TCP]
|
[SESSION_NAME.CUSTOM]
|
||||||
SESSION_EVENT_TYPE=ALL
|
SESSION_EVENT_TYPE=["SESSION_EVENT_OPENING","SESSION_EVENT_ORDPKT","SESSION_EVENT_CLOSING"]
|
||||||
SESSION_EVENT_CALLBACK=custom_plugin_entry
|
SESSION_EVENT_CALLBACK="custom_plugin_custom_entry"
|
||||||
|
|
||||||
[SESSION_TYPE.CUSTOM_A]
|
|
||||||
SESSION_EVENT_TYPE=OPENING,ORDPKT,CLOSING
|
|
||||||
SESSION_EVENT_CALLBACK=custom_event_plugin_entry
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
[PLUGINFO]
|
[PLUGINFO]
|
||||||
INIT_FUNC=http_event_plugin_init
|
INIT_FUNC="http_event_plugin_init"
|
||||||
EXIT_FUNC=http_event_plugin_exit
|
EXIT_FUNC="http_event_plugin_exit"
|
||||||
LIBRARY_PATH=./plugins/http_event_plugin/http_event_plugin.so
|
LIBRARY_PATH="./plugins/http_event_plugin/http_event_plugin.so"
|
||||||
|
|
||||||
[SESSION_TYPE.HTTP]
|
# Support SESSION_EVENT_TYPE: "SESSION_EVENT_OPENING", "SESSION_EVENT_RAWPKT", "SESSION_EVENT_ORDPKT", "SESSION_EVENT_META", "SESSION_EVENT_CLOSING", "SESSION_EVENT_ALL"
|
||||||
SESSION_EVENT_TYPE=ALL
|
|
||||||
SESSION_EVENT_CALLBACK=http_event_plugin_entry
|
[SESSION_NAME.HTTP]
|
||||||
|
SESSION_EVENT_TYPE=["SESSION_EVENT_ALL"]
|
||||||
|
SESSION_EVENT_CALLBACK="http_event_plugin_entry"
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
./http_event_plugin/http_event_plugin.inf
|
# Relative path, relative to the installation path of stellar
|
||||||
./custom_event_plugin/custom_event_plugin.inf
|
|
||||||
|
./plugins/http_event_plugin/http_event_plugin.inf
|
||||||
|
./plugins/custom_event_plugin/custom_event_plugin.inf
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "packet.h"
|
|
||||||
#include "session.h"
|
#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);
|
||||||
@@ -2,8 +2,14 @@
|
|||||||
|
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
|
|
||||||
typedef int plugin_init_callback(void **pme);
|
typedef int plugin_init_callback(void);
|
||||||
typedef void plugin_exit_callback(void *pme);
|
typedef void plugin_exit_callback(void);
|
||||||
|
|
||||||
void plugin_remove_from_session_event(struct stellar_event *ev,
|
void plugin_remove_from_session_event(struct stellar_event *ev, struct stellar_session *s);
|
||||||
struct stellar_session *s);
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Public API: between plugin and plugin_manager
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// TODO
|
||||||
@@ -25,6 +25,7 @@ enum stellar_session_type
|
|||||||
|
|
||||||
enum session_event_type
|
enum session_event_type
|
||||||
{
|
{
|
||||||
|
SESSION_EVENT_UNKNOWN = (0x00),
|
||||||
SESSION_EVENT_OPENING = (0x01 << 1),
|
SESSION_EVENT_OPENING = (0x01 << 1),
|
||||||
SESSION_EVENT_RAWPKT = (0x01 << 2),
|
SESSION_EVENT_RAWPKT = (0x01 << 2),
|
||||||
SESSION_EVENT_ORDPKT = (0x01 << 3),
|
SESSION_EVENT_ORDPKT = (0x01 << 3),
|
||||||
@@ -35,11 +36,7 @@ enum session_event_type
|
|||||||
|
|
||||||
struct stellar_session_event_extras;
|
struct stellar_session_event_extras;
|
||||||
|
|
||||||
typedef void (fn_session_event_callback)(const struct stellar_session *s, int what, struct stellar_packet *p, const char *payload, uint16_t len, void **pme);
|
typedef void(fn_session_event_callback)(const struct stellar_session *s, enum session_event_type event, struct stellar_packet *p, const char *payload, uint16_t len, void **pme);
|
||||||
|
|
||||||
void session_manager_trigger_event(struct stellar_session *s,
|
void session_manager_trigger_event(struct stellar_session *s, enum session_event_type type, struct stellar_session_event_extras *info);
|
||||||
enum session_event_type type,
|
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session, const char *session_name);
|
||||||
struct stellar_session_event_extras *info);
|
|
||||||
|
|
||||||
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session,
|
|
||||||
const char *new_session_type_name);
|
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/sdk/include)
|
include_directories(${CMAKE_SOURCE_DIR}/sdk/include)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/deps/)
|
include_directories(${CMAKE_SOURCE_DIR}/deps/)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src/packet_io/)
|
include_directories(${CMAKE_SOURCE_DIR}/src/packet_io/)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src/session_manager/)
|
include_directories(${CMAKE_SOURCE_DIR}/src/session_manager/)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src/plugin_manager/)
|
include_directories(${CMAKE_SOURCE_DIR}/src/plugin_manager/)
|
||||||
|
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(packet_io)
|
add_subdirectory(packet_io)
|
||||||
add_subdirectory(session_manager)
|
add_subdirectory(session_manager)
|
||||||
@@ -16,4 +14,13 @@ add_executable(stellar
|
|||||||
main.cpp
|
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
|
||||||
|
)
|
||||||
@@ -59,11 +59,12 @@ int main(int argc, char ** argv)
|
|||||||
struct plugin_manager *plug_mgr = plugin_manager_create();
|
struct plugin_manager *plug_mgr = plugin_manager_create();
|
||||||
|
|
||||||
// register build-in plugin
|
// 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
|
// load external plugins
|
||||||
char absolute_plugin_file[] = "/op/tsg/sapp/plug/plugins.inf";
|
char prefix_path[] = "/op/tsg/stellar/";
|
||||||
plugin_manager_load(plug_mgr, absolute_plugin_file);
|
char file_path[] = "./plugs/plugins.inf";
|
||||||
|
plugin_manager_load(plug_mgr, prefix_path, file_path);
|
||||||
|
|
||||||
//packet_io_init
|
//packet_io_init
|
||||||
struct packet_io_device *dev = packet_io_init(1, "stellar", "cap0");
|
struct packet_io_device *dev = packet_io_init(1, "stellar", "cap0");
|
||||||
@@ -78,6 +79,7 @@ int main(int argc, char ** argv)
|
|||||||
usleep(1);
|
usleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugin_manager_unload(plug_mgr);
|
||||||
plugin_manager_destory(plug_mgr);
|
plugin_manager_destory(plug_mgr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
add_library(plugin_manager
|
add_library(plugin_manager
|
||||||
plugin_manager.cpp
|
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)
|
||||||
@@ -1,106 +1,313 @@
|
|||||||
#include "deps/uthash/uthash.h"
|
#include "deps/uthash/uthash.h"
|
||||||
#include "sdk/include/session.h"
|
|
||||||
#include "sdk/include/plugin.h"
|
|
||||||
#include "session_manager.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 <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;
|
int skip;
|
||||||
fn_session_event_callback *callback;
|
void *cb_args;
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
enum session_event_type event;
|
enum session_event_type event;
|
||||||
fn_session_event_callback *callback;
|
fn_session_event_callback *cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct session_plugin_ctx
|
struct session_plugin_ctx
|
||||||
{
|
{
|
||||||
int event_cbs_num;
|
int current_plugin_index;
|
||||||
struct session_event_callback_runtime event_cbs[0]; // dynamic array
|
int eventcb_num;
|
||||||
|
struct eventcb_runtime *eventcbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* struct plugin_manager
|
* CallBack Static (For Per Plugin Manager)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/*
|
struct eventcb_static
|
||||||
* 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
|
|
||||||
{
|
{
|
||||||
char *name;
|
enum session_event_type event;
|
||||||
char *library;
|
fn_session_event_callback *cb;
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 plugin_manager
|
||||||
{
|
{
|
||||||
struct managed_session_event_callback *cb_table;
|
int used_module_num;
|
||||||
struct plugin_ctx plugins[MAX_PLUGIN_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_destory_plugin_ctx(struct session_plugin_ctx *plug_ctx)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void plugin_manager_handle_closing_event(struct plugin_manager *plug_mgr, struct stellar_event *event)
|
|
||||||
{
|
{
|
||||||
|
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 *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;
|
return plug_mgr;
|
||||||
}
|
}
|
||||||
@@ -109,45 +316,138 @@ void plugin_manager_destory(struct plugin_manager *plug_mgr)
|
|||||||
{
|
{
|
||||||
if (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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event)
|
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event)
|
||||||
{
|
{
|
||||||
assert(event);
|
const struct stellar_session *seesion = stellar_event_get_session(event);
|
||||||
struct stellar_session_event_data *event_data = event->session_event_data;
|
struct session_plugin_ctx *plug_ctx = stellar_event_get_plugin_ctx(event);
|
||||||
assert(event_data);
|
enum session_event_type event_type = stellar_event_get_type(event);
|
||||||
session_event_type type = event_data->type;
|
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:
|
if (plug_ctx == NULL)
|
||||||
plugin_manager_handle_opening_event(plug_mgr, event);
|
{
|
||||||
break;
|
plug_ctx = plugin_manager_create_plugin_ctx(plug_mgr, session_name);
|
||||||
case SESSION_EVENT_RAWPKT: /* fall through */
|
if (plug_ctx == NULL)
|
||||||
case SESSION_EVENT_ORDPKT: /* fall through */
|
{
|
||||||
case SESSION_EVENT_META: /* fall through */
|
plugin_manager_log(ERROR, "can't create runtime plugin ctx for session '%s', Please check whether the callback is registered in the current session");
|
||||||
plugin_manager_handle_data_event(plug_mgr, event);
|
return;
|
||||||
break;
|
}
|
||||||
case SESSION_EVENT_CLOSING:
|
stellar_event_set_plugin_ctx(event, plug_ctx);
|
||||||
plugin_manager_handle_closing_event(plug_mgr, event);
|
}
|
||||||
break;
|
}
|
||||||
default:
|
|
||||||
// TODO log error
|
if (plug_ctx)
|
||||||
break;
|
{
|
||||||
|
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
|
||||||
@@ -1,11 +1,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sdk/include/session.h"
|
#include "sdk/include/session.h"
|
||||||
|
|
||||||
#define MAX_PLUGIN_NUM 256
|
|
||||||
|
|
||||||
struct per_session_event_cbs;
|
|
||||||
struct plugin_manager;
|
struct plugin_manager;
|
||||||
|
|
||||||
struct plugin_manager *plugin_manager_create();
|
struct plugin_manager *plugin_manager_create();
|
||||||
@@ -13,8 +9,8 @@ void plugin_manager_destory(struct plugin_manager *plug_mgr);
|
|||||||
|
|
||||||
// return 0: success
|
// return 0: success
|
||||||
// return -1: error
|
// 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);
|
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);
|
void plugin_manager_dispatch(struct plugin_manager *plug_mgr, struct stellar_event *event);
|
||||||
358
src/plugin_manager/plugin_manager_config.cpp
Normal file
358
src/plugin_manager/plugin_manager_config.cpp
Normal 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
|
||||||
34
src/plugin_manager/plugin_manager_config.h
Normal file
34
src/plugin_manager/plugin_manager_config.h
Normal 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);
|
||||||
168
src/plugin_manager/plugin_manager_module.cpp
Normal file
168
src/plugin_manager/plugin_manager_module.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/plugin_manager/plugin_manager_module.h
Normal file
12
src/plugin_manager/plugin_manager_module.h
Normal 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);
|
||||||
40
src/plugin_manager/plugin_manager_util.cpp
Normal file
40
src/plugin_manager/plugin_manager_util.cpp
Normal 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);
|
||||||
|
}
|
||||||
61
src/plugin_manager/plugin_manager_util.h
Normal file
61
src/plugin_manager/plugin_manager_util.h
Normal 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);
|
||||||
18
src/plugin_manager/test/CMakeLists.txt
Normal file
18
src/plugin_manager/test/CMakeLists.txt
Normal 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 ./)
|
||||||
159
src/plugin_manager/test/gtest_plugin_manager.cpp
Normal file
159
src/plugin_manager/test/gtest_plugin_manager.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
@@ -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,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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
#include "http.h"
|
#include "sdk/include/session.h"
|
||||||
#include "session_manager.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_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_OPENING, info);
|
||||||
session_manager_trigger_event(new_session, SESSION_EVENT_META, 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;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "sdk/include/session.h"
|
||||||
#include "session_manager.h"
|
#include "session_manager.h"
|
||||||
|
|
||||||
struct session_manager
|
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()
|
struct session_manager *session_manager_init()
|
||||||
@@ -10,16 +14,12 @@ struct session_manager *session_manager_init()
|
|||||||
return nullptr;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session,
|
struct stellar_session *session_manager_session_derive(const struct stellar_session *this_session, const char *session_name)
|
||||||
const char *new_session_type_name)
|
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -29,8 +29,54 @@ struct stellar_event *session_manager_commit(struct session_manager *h, struct s
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct stellar_event *session_manager_fetch_event(struct session_manager *h)
|
struct stellar_event *session_manager_fetch_event(struct session_manager *h)
|
||||||
{
|
{
|
||||||
return nullptr;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include "sdk/include/session.h"
|
#include "sdk/include/session.h"
|
||||||
|
|
||||||
struct per_session_evcb_runtime_ctx;
|
|
||||||
|
|
||||||
struct stellar_session_event_data
|
struct stellar_session_event_data
|
||||||
{
|
{
|
||||||
struct stellar_session *s;
|
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_commit(struct session_manager *session_mgr, struct stellar_packet *pkt);
|
||||||
struct stellar_event *session_manager_fetch_event(struct session_manager *session_mgr);
|
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
|
struct stellar_session
|
||||||
{
|
{
|
||||||
stellar_session_type type;
|
stellar_session_type type;
|
||||||
@@ -29,3 +23,18 @@ struct stellar_session
|
|||||||
void *addr;
|
void *addr;
|
||||||
void *data;
|
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);
|
||||||
Reference in New Issue
Block a user