summaryrefslogtreecommitdiff
path: root/src/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugin.c')
-rw-r--r--src/plugin.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/plugin.c b/src/plugin.c
new file mode 100644
index 0000000..cfee5d4
--- /dev/null
+++ b/src/plugin.c
@@ -0,0 +1,163 @@
+#pragma once
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+//
+#include "common.c"
+
+typedef uint8_t byte;
+
+// contracts
+
+void __init_plugin_func(void);
+typedef typeof(__init_plugin_func) init_plugin;
+
+struct relay_info;
+struct relay_neighbor;
+struct data_packet;
+
+// runs when the server wants to respond to a server audit request
+void __modify_server_stats_func(struct relay_info *server_stats);
+typedef typeof(__modify_server_stats_func) modify_server_stats;
+
+// runs when the server wants to decide whether to add a neighbor by request or not
+bool __decide_neighbor_registry_func(struct relay_neighbor new_neighbor);
+typedef typeof(__decide_neighbor_registry_func) decide_neighbor_registry;
+
+// runs when the server wants to decide whether to propagate
+bool __decide_packet_propogation_func(struct data_packet packet);
+typedef typeof(__decide_packet_propogation_func) decide_packet_propogation;
+
+// runs before the paste_server function performs any logic
+void __paste_server_start_func(
+ char **ip_addr_ref,
+ size_t *ip_size_ref,
+ byte **in_ref,
+ size_t *in_len_ref,
+ byte ***out_ref,
+ size_t **out_len_ref);
+typedef typeof(__paste_server_start_func) paste_server_start;
+
+// runs when the server wants to decide whether to save the packet to disk
+bool __decide_packet_save_to_disk_func(struct data_packet packet);
+typedef typeof(__decide_packet_save_to_disk_func) decide_packet_save_to_disk;
+
+// runs when the server wants a plugin to modify a packet (e.g., keepalive, run PoW, etc)
+void __modify_packet_func(struct data_packet *packet);
+typedef typeof(__modify_packet_func) modify_packet;
+
+// runs when the server wants to decide whether to wipe a packet
+bool __decide_packet_cleanup_func(struct data_packet packet);
+typedef typeof(__decide_packet_cleanup_func) decide_packet_cleanup;
+
+// runs when the server logs a message
+void __custom_log_func(int level, const char *msg);
+typedef typeof(__custom_log_func) custom_log;
+
+// runs when the server is shutting down
+void __on_server_shutdown_func(void);
+typedef typeof(__on_server_shutdown_func) on_server_shutdown;
+
+// data
+
+enum plugin_handler_code_types {
+ code_modify_server_stats = 1,
+ code_decide_neighbor_registry = 2,
+ code_decide_packet_propogation = 3,
+ code_paste_server_start = 4,
+ code_decide_packet_save_to_disk = 5,
+ code_modify_packet = 6,
+ code_decide_packet_cleanup = 7,
+ code_on_server_shutdown = 8,
+ code_custom_log = 9
+};
+
+void *plugin_handle = NULL;
+init_plugin *init_plugin_func = NULL;
+modify_server_stats *modify_server_stats_func = NULL;
+decide_neighbor_registry *decide_neighbor_registry_func = NULL;
+decide_packet_propogation *decide_packet_propogation_func = NULL;
+paste_server_start *paste_server_start_func = NULL;
+decide_packet_save_to_disk *decide_packet_save_to_disk_func = NULL;
+modify_packet *modify_packet_func = NULL;
+decide_packet_cleanup *decide_packet_cleanup_func = NULL;
+custom_log *custom_log_func = NULL;
+on_server_shutdown *on_server_shutdown_func = NULL; // unused for now
+
+pthread_mutex_t plugin_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// implementation
+
+void load_plugins(const char *plugin_path) {
+ pthread_mutex_lock(&plugin_mutex);
+ if (plugin_handle) {
+ dlclose(plugin_handle);
+ plugin_handle = NULL;
+ init_plugin_func = NULL;
+ modify_server_stats_func = NULL;
+ decide_neighbor_registry_func = NULL;
+ decide_packet_propogation_func = NULL;
+ paste_server_start_func = NULL;
+ decide_packet_save_to_disk_func = NULL;
+ modify_packet_func = NULL;
+ decide_packet_cleanup_func = NULL;
+ custom_log_func = NULL;
+ on_server_shutdown_func = NULL;
+ }
+
+ plugin_handle = dlopen(plugin_path, RTLD_NOW);
+ if (!plugin_handle) {
+ fprintf(stderr, "%s\n", dlerror());
+ pthread_mutex_unlock(&plugin_mutex);
+ return;
+ }
+
+ if (init_plugin_func) {
+ init_plugin_func();
+ log(_info, "loaded %s\n", plugin_path);
+ } else {
+ log(_error, "%s has no MP_init_plugin", plugin_path);
+ dlclose(plugin_handle);
+ plugin_handle = NULL;
+ pthread_mutex_unlock(&plugin_mutex);
+ return;
+ }
+
+ init_plugin_func = dlsym(plugin_handle, "MP_init_plugin");
+ modify_server_stats_func = dlsym(plugin_handle, "MP_modify_server_stats");
+ decide_neighbor_registry_func = dlsym(plugin_handle, "MP_decide_neighbor_registry");
+ decide_packet_propogation_func = dlsym(plugin_handle, "MP_decide_packet_propogation");
+ paste_server_start_func = dlsym(plugin_handle, "MP_paste_server_start");
+ decide_packet_save_to_disk_func = dlsym(plugin_handle, "MP_decide_packet_save_to_disk");
+ modify_packet_func = dlsym(plugin_handle, "MP_modify_packet");
+ decide_packet_cleanup_func = dlsym(plugin_handle, "MP_decide_packet_cleanup");
+ custom_log_func = dlsym(plugin_handle, "MP_custom_log");
+ on_server_shutdown_func = dlsym(plugin_handle, "MP_on_server_shutdown");
+
+ pthread_mutex_unlock(&plugin_mutex);
+}
+
+void cleanup_plugins(void) {
+ pthread_mutex_lock(&plugin_mutex);
+ if (plugin_handle) {
+ if (on_server_shutdown_func) { on_server_shutdown_func(); }
+ dlclose(plugin_handle);
+ plugin_handle = NULL;
+ init_plugin_func = NULL;
+ modify_server_stats_func = NULL;
+ decide_neighbor_registry_func = NULL;
+ decide_packet_propogation_func = NULL;
+ paste_server_start_func = NULL;
+ decide_packet_save_to_disk_func = NULL;
+ modify_packet_func = NULL;
+ decide_packet_cleanup_func = NULL;
+ custom_log_func = NULL;
+ on_server_shutdown_func = NULL;
+ }
+ pthread_mutex_unlock(&plugin_mutex);
+}