summaryrefslogtreecommitdiff
path: root/ot_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_udp.c')
-rw-r--r--ot_udp.c78
1 files changed, 5 insertions, 73 deletions
diff --git a/ot_udp.c b/ot_udp.c
index 1ec5148..309cbdb 100644
--- a/ot_udp.c
+++ b/ot_udp.c
@@ -16,21 +16,11 @@
16#include "ot_random.h" 16#include "ot_random.h"
17#include "ot_rijndael.h" 17#include "ot_rijndael.h"
18#include "ot_socket.h" 18#include "ot_socket.h"
19#include "ot_worker.h"
19#include "ot_stats.h" 20#include "ot_stats.h"
20#include "ot_udp.h" 21#include "ot_udp.h"
21#include "trackerlogic.h" 22#include "trackerlogic.h"
22 23
23/* One of these per worker, each allocated on its own so that growing the
24 array below never moves the one a running worker holds. */
25struct udp_worker {
26 pthread_t thread;
27 int64_t sock;
28 _Atomic int left;
29};
30
31static struct udp_worker **g_workers;
32static size_t g_worker_count;
33
34static uint32_t g_rijndael_round_key[44] = {0}; 24static uint32_t g_rijndael_round_key[44] = {0};
35static volatile uint32_t g_key_of_the_hour[2] = {0}; 25static volatile uint32_t g_key_of_the_hour[2] = {0};
36static volatile ot_time g_hour_of_the_key; 26static volatile ot_time g_hour_of_the_key;
@@ -217,31 +207,9 @@ int handle_udp6(int64_t serversocket, struct ot_workstruct *ws) {
217 return 1; 207 return 1;
218} 208}
219 209
220static void *udp_worker(void *args) { 210static void udp_run(struct ot_worker *me) {
221 struct udp_worker *me = args;
222 struct ot_workstruct ws;
223 memset(&ws, 0, sizeof(ws));
224
225 stats_counters_register(&ws);
226 ws.inbuf = malloc(G_INBUF_SIZE);
227 ws.outbuf = malloc(G_OUTBUF_SIZE);
228#ifdef _DEBUG_HTTPERROR
229 ws.debugbuf = malloc(G_DEBUGBUF_SIZE);
230#endif
231
232 while (g_opentracker_running) 211 while (g_opentracker_running)
233 handle_udp6(me->sock, &ws); 212 handle_udp6(me->sock, &me->ws);
234
235 stats_counters_retire(&ws);
236
237 free(ws.inbuf);
238 free(ws.outbuf);
239#ifdef _DEBUG_HTTPERROR
240 free(ws.debugbuf);
241#endif
242
243 atomic_store(&me->left, 1);
244 return NULL;
245} 213}
246 214
247void udp_init(void) { 215void udp_init(void) {
@@ -250,47 +218,11 @@ void udp_init(void) {
250} 218}
251 219
252void udp_worker_install(int64_t sock) { 220void udp_worker_install(int64_t sock) {
253 struct udp_worker **grown = realloc(g_workers, (g_worker_count + 1) * sizeof(*g_workers));
254 struct udp_worker *worker;
255
256 if (!grown || !(worker = calloc(1, sizeof(*worker)))) {
257 fprintf(stderr, "Warning: out of memory installing a udp worker, this socket stays with the workers already running.\n");
258 g_workers = grown ? grown : g_workers;
259 return;
260 }
261 g_workers = grown;
262 worker->sock = sock;
263
264#ifdef _DEBUG 221#ifdef _DEBUG
265 fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); 222 fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock);
266#endif 223#endif
267 socket_set_blocking((int)sock, 1); 224 socket_set_blocking((int)sock, 1);
268 225
269 if (pthread_create(&worker->thread, NULL, udp_worker, worker)) 226 if (worker_start(udp_run, sock) == -1)
270 free(worker); 227 fprintf(stderr, "Warning: could not install a udp worker, this socket stays with the workers already running.\n");
271 else
272 g_workers[g_worker_count++] = worker;
273}
274
275void udp_workers_deinit(void) {
276 size_t i;
277
278 for (i = 0; i < g_worker_count; ++i) {
279 struct udp_worker *worker = g_workers[i];
280
281 /* Repeated because a signal only interrupts a read already under way: a
282 worker that was between two reads when the first one arrived is inside
283 the next one by now. */
284 while (!atomic_load(&worker->left)) {
285 pthread_kill(worker->thread, OT_SIGNAL_WAKE);
286 usleep(1000);
287 }
288 pthread_join(worker->thread, NULL);
289 free(worker);
290 }
291
292 free(g_workers);
293 g_workers = NULL;
294 g_worker_count = 0;
295} 228}
296