#pragma once #include #include #include #include #include #include #include // #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); }