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
|
/*
* mains_proxy — Main-to-Main mesh proxy.
*
* Peers attach via HBX/Circuit only (circuit_host, circuit_port, link_id).
* Service linking only — proxymail and proxychat payloads; no user data.
*/
#include "hybbx/plugin.h"
#include "hybbx/service.h"
#include "hybbx/mains_proxy.h"
#include "hybbx/limits.h"
#include "hybbx/util.h"
#include "hybbx/log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct mains_proxy_plugin_state {
hybbx_service_t *service;
hybbx_mains_proxy_mesh_t mesh;
int loaded;
} mains_proxy_plugin_state_t;
static mains_proxy_plugin_state_t g_state;
static hybbx_result_t mains_proxy_parse_instances(const char *config,
hybbx_mains_proxy_mesh_t *mesh)
{
const char *cursor;
const char *end;
char section_buf[HYBBX_CONFIG_LINE_MAX];
unsigned count = 0;
if (mesh == NULL) {
return HYBBX_ERR_INVALID;
}
hybbx_mains_proxy_mesh_init(mesh);
if (config == NULL || config[0] == '\0') {
return HYBBX_OK;
}
cursor = config;
while (*cursor != '\0' && count < HYBBX_MAINS_PROXY_MAX_PEERS) {
size_t len;
end = strchr(cursor, HYBBX_MAINS_PROXY_INSTANCE_SEP);
if (end == NULL) {
len = strlen(cursor);
} else {
len = (size_t)(end - cursor);
}
if (len >= sizeof(section_buf)) {
return HYBBX_ERR_INVALID;
}
memcpy(section_buf, cursor, len);
section_buf[len] = '\0';
if (hybbx_mains_proxy_peer_parse(section_buf, &mesh->peers[count]) !=
HYBBX_OK) {
return HYBBX_ERR_INVALID;
}
if (mesh->peers[count].enabled) {
count++;
}
if (end == NULL) {
break;
}
cursor = end + 1;
}
mesh->peer_count = count;
return HYBBX_OK;
}
static hybbx_result_t mains_proxy_init(hybbx_service_t *service)
{
memset(&g_state, 0, sizeof(g_state));
g_state.service = service;
hybbx_mains_proxy_mesh_init(&g_state.mesh);
g_state.loaded = 1;
return HYBBX_OK;
}
static void mains_proxy_shutdown(void)
{
hybbx_mains_proxy_mesh_stop(&g_state.mesh);
memset(&g_state, 0, sizeof(g_state));
}
static hybbx_result_t mains_proxy_start(const char *config)
{
hybbx_result_t rc;
if (!g_state.loaded) {
return HYBBX_ERR_INVALID;
}
rc = mains_proxy_parse_instances(config, &g_state.mesh);
if (rc != HYBBX_OK) {
hybbx_log_warn("[mains_proxy] invalid peer configuration");
return rc;
}
return hybbx_mains_proxy_mesh_start(g_state.service, &g_state.mesh);
}
static hybbx_result_t mains_proxy_stop(void)
{
hybbx_mains_proxy_mesh_stop(&g_state.mesh);
return HYBBX_OK;
}
const hybbx_transport_plugin_t hybbx_plugin_mains_proxy = {
.name = "mains_proxy",
.kind = HYBBX_TRANSPORT_MAINS_PROXY,
.version = 1,
.init = mains_proxy_init,
.shutdown = mains_proxy_shutdown,
.start = mains_proxy_start,
.stop = mains_proxy_stop,
.write = NULL,
};
void hybbx_mains_proxy_plugin_tick(void)
{
if (!g_state.loaded || !g_state.mesh.running) {
return;
}
hybbx_mains_proxy_mesh_tick(g_state.service, &g_state.mesh);
}
|