summaryrefslogtreecommitdiff
path: root/ot_udp.c
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-10-31 15:59:41 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-10-31 15:59:41 +0100
commit4d030871c004c917458b5e1c296edcfc689a2e66 (patch)
treec6c057e47a17d8b03ea28a611ff029d950acfa8c /ot_udp.c
parent440cfeee71829308fa1cc9b5aef63beb7ab756dc (diff)
Make tcp worker multithreaded, too
This shamelessly steals the model established in the UDP workers, i.e. if the kernel is able to bind multiple listening sockets to the same endpoint, we will share them across threads. If it can't, all threads will accept on the same socket. The fast path handles most of the connections, only the rare case of no data yet on the socket is offloaded to the slow path (which used to be the mainloop) for completion. This scales nicely, as the higher the load is, the higher chances are that an accept happens only after the network roundtrip to the peer completes, leading to more connections that already have data waiting for us. We also consolidate the workstruct init and deinit code, preparation for later unifying all thread state structs for all protocols (mca, udc and tcp). The config file gains a per tcp connection worker count and some docs explaining what this knob buys and costs, nudging the user to either keep it 0 or dial it up to at least 2.
Diffstat (limited to 'ot_udp.c')
-rw-r--r--ot_udp.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/ot_udp.c b/ot_udp.c
index 1ec5148..00ec566 100644
--- a/ot_udp.c
+++ b/ot_udp.c
@@ -220,26 +220,17 @@ int handle_udp6(int64_t serversocket, struct ot_workstruct *ws) {
220static void *udp_worker(void *args) { 220static void *udp_worker(void *args) {
221 struct udp_worker *me = args; 221 struct udp_worker *me = args;
222 struct ot_workstruct ws; 222 struct ot_workstruct ws;
223 memset(&ws, 0, sizeof(ws));
224 223
225 stats_counters_register(&ws); 224 if (workstruct_init(&ws) == -1) {
226 ws.inbuf = malloc(G_INBUF_SIZE); 225 fprintf(stderr, "Warning: a udp worker could not get its buffers and will not run.\n");
227 ws.outbuf = malloc(G_OUTBUF_SIZE); 226 atomic_store(&me->left, 1);
228#ifdef _DEBUG_HTTPERROR 227 return NULL;
229 ws.debugbuf = malloc(G_DEBUGBUF_SIZE); 228 }
230#endif
231 229
232 while (g_opentracker_running) 230 while (g_opentracker_running)
233 handle_udp6(me->sock, &ws); 231 handle_udp6(me->sock, &ws);
234 232
235 stats_counters_retire(&ws); 233 workstruct_deinit(&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); 234 atomic_store(&me->left, 1);
244 return NULL; 235 return NULL;
245} 236}