1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
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);
}
|