diff options
Diffstat (limited to 'ot_udp.c')
| -rw-r--r-- | ot_udp.c | 42 |
1 files changed, 40 insertions, 2 deletions
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <stdio.h> | 9 | #include <stdio.h> |
| 10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
| 11 | #include <string.h> | 11 | #include <string.h> |
| 12 | #include <sys/socket.h> | ||
| 12 | 13 | ||
| 13 | /* Opentracker */ | 14 | /* Opentracker */ |
| 14 | #include "ot_ip.h" | 15 | #include "ot_ip.h" |
| @@ -19,6 +20,17 @@ | |||
| 19 | #include "ot_udp.h" | 20 | #include "ot_udp.h" |
| 20 | #include "trackerlogic.h" | 21 | #include "trackerlogic.h" |
| 21 | 22 | ||
| 23 | /* How long a worker may sit in a read before it looks at the running flag */ | ||
| 24 | #define OT_UDP_WORKER_PATIENCE 1 | ||
| 25 | |||
| 26 | struct udp_worker { | ||
| 27 | pthread_t thread; | ||
| 28 | int64_t sock; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static struct udp_worker *g_workers; | ||
| 32 | static size_t g_worker_count; | ||
| 33 | |||
| 22 | static uint32_t g_rijndael_round_key[44] = {0}; | 34 | static uint32_t g_rijndael_round_key[44] = {0}; |
| 23 | static volatile uint32_t g_key_of_the_hour[2] = {0}; | 35 | static volatile uint32_t g_key_of_the_hour[2] = {0}; |
| 24 | static volatile ot_time g_hour_of_the_key; | 36 | static volatile ot_time g_hour_of_the_key; |
| @@ -236,11 +248,37 @@ void udp_init(void) { | |||
| 236 | } | 248 | } |
| 237 | 249 | ||
| 238 | void udp_worker_install(int64_t sock) { | 250 | void udp_worker_install(int64_t sock) { |
| 239 | pthread_t thread_id; | 251 | struct udp_worker *grown = realloc(g_workers, (g_worker_count + 1) * sizeof(*g_workers)); |
| 252 | |||
| 253 | if (!grown) { | ||
| 254 | fprintf(stderr, "Warning: out of memory installing a udp worker, this socket stays with the workers already running.\n"); | ||
| 255 | return; | ||
| 256 | } | ||
| 257 | g_workers = grown; | ||
| 240 | 258 | ||
| 241 | #ifdef _DEBUG | 259 | #ifdef _DEBUG |
| 242 | fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); | 260 | fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); |
| 243 | #endif | 261 | #endif |
| 244 | pthread_create(&thread_id, NULL, udp_worker, (void *)sock); | 262 | socket_set_blocking((int)sock, 1); |
| 263 | socket_set_timeout((int)sock, OT_UDP_WORKER_PATIENCE); | ||
| 264 | |||
| 265 | g_workers[g_worker_count].sock = sock; | ||
| 266 | if (!pthread_create(&g_workers[g_worker_count].thread, NULL, udp_worker, (void *)sock)) | ||
| 267 | ++g_worker_count; | ||
| 268 | } | ||
| 269 | |||
| 270 | void udp_workers_deinit(void) { | ||
| 271 | size_t i; | ||
| 272 | |||
| 273 | /* The receive timeout bounds this on its own, shutting the socket down | ||
| 274 | cuts it short wherever the platform wakes a blocked reader */ | ||
| 275 | for (i = 0; i < g_worker_count; ++i) | ||
| 276 | shutdown((int)g_workers[i].sock, SHUT_RD); | ||
| 277 | for (i = 0; i < g_worker_count; ++i) | ||
| 278 | pthread_join(g_workers[i].thread, NULL); | ||
| 279 | |||
| 280 | free(g_workers); | ||
| 281 | g_workers = NULL; | ||
| 282 | g_worker_count = 0; | ||
| 245 | } | 283 | } |
| 246 | 284 | ||
