From ad541c67761b8aa6da1566802c347cac4018d0c2 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Mon, 2 Nov 2026 20:50:24 +0100 Subject: Move the build sources into src/ --- ot_tcp.c | 180 --------------------------------------------------------------- 1 file changed, 180 deletions(-) delete mode 100644 ot_tcp.c (limited to 'ot_tcp.c') diff --git a/ot_tcp.c b/ot_tcp.c deleted file mode 100644 index 1351b92..0000000 --- a/ot_tcp.c +++ /dev/null @@ -1,180 +0,0 @@ -/* This software was written by Dirk Engling - It is considered beerware. Prost. Skol. Cheers or whatever. */ - -/* System */ -#include -#include -#include -#include -#include -#include -#include - -/* Opentracker */ -#include "ot_batch.h" -#include "ot_buf.h" -#include "ot_event.h" -#include "ot_fdstate.h" -#include "ot_http.h" -#include "ot_mutex.h" -#include "ot_socket.h" -#include "ot_worker.h" -#include "ot_stats.h" -#include "ot_tcp.h" -#include "trackerlogic.h" - -static ssize_t header_complete(char *request, ssize_t byte_count) { - ssize_t i = 0, state = 0; - - for (i = 1; i < byte_count; i += 2) - if (request[i] <= 13) { - i--; - for (state = 0; i < byte_count; ++i) { - char c = request[i]; - if (c == '\r' || c == '\n') - state = (state >> 2) | ((c << 6) & 0xc0); - else - break; - if (state >= 0xa0 || state == 0x99) - return i + 1; - } - } - return 0; -} - -void tcp_read(const int64_t sock, struct ot_workstruct *ws) { - struct http_data *cookie = fdstate_cookie(sock); - ssize_t byte_count = read((int)sock, ws->inbuf, G_INBUF_SIZE); - - if (byte_count == 0 || (byte_count == -1 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)) { - http_close(sock); - return; - } - - if (byte_count == -1) - return; - - ws->request = NULL; - ws->request_size = 0; - ws->header_size = 0; - ws->keep_alive = 0; - - /* If we get the whole request in one packet, handle it without copying */ - if (!cookie->request.data) { - if ((ws->header_size = header_complete(ws->inbuf, byte_count))) { - ws->request = ws->inbuf; - ws->request_size = byte_count; - http_handle_request(sock, ws); - } else if (buf_cat(&cookie->request, ws->inbuf, (size_t)byte_count)) - http_close(sock); - return; - } - - if (buf_cat(&cookie->request, ws->inbuf, (size_t)byte_count) || cookie->request.size > G_INBUF_SIZE) { - http_issue_error(sock, ws, CODE_HTTPERROR_500); - return; - } - - while ((ws->header_size = header_complete(cookie->request.data, (ssize_t)cookie->request.size))) { - ws->request = cookie->request.data; - ws->request_size = (ssize_t)cookie->request.size; - http_handle_request(sock, ws); -#ifdef WANT_KEEPALIVE - if (!ws->keep_alive) -#endif - return; - } -} - -void tcp_write(const int64_t sock) { - struct http_data *cookie = fdstate_cookie(sock); - int chunked = 0; - int keep_alive = 0; - - if (cookie) { - chunked = (cookie->flag & STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER) != 0; - keep_alive = (cookie->flag & STRUCT_HTTP_FLAG_KEEPALIVE) != 0; - - if (cookie->batch) { - if (batch_send(sock, cookie->batch) == BATCH_FAILED) { - http_close(sock); - return; - } - if (batch_pending(cookie->batch)) - return; - } - } - - /* In a chunked transfer, wait for the next piece once everything queued has gone out */ - if (chunked) - http_interest_set(sock, cookie, 0); - else if (keep_alive) { - /* The reply is out and the client asked to keep the connection, so go - back to waiting for the next request */ - http_interest_set(sock, cookie, EVENT_IN); - fdstate_set_expiry(sock, time_future_seconds(OT_CLIENT_TIMEOUT)); - } else - http_close(sock); -} - -/* The fast path, assuming that the complete request has usually arrived by the time a - connection is accepted, so it is answered here outside the event loop. The more load - a tracker has, the more likely it is that by the time it accepts, the roundtrip to - the peer has completed. - If the request could not be completely handled, the stack cookie is promoted to heap - and the connection handed over to the event loop to finish */ -void tcp_accept(const int64_t serversocket, struct ot_workstruct *ws) { - int64_t sock; - ot_ip6 ip; - uint16_t port; - - while ((sock = socket_accept(serversocket, ip, &port)) != -1) { - struct http_data cookie; - uint32_t generation; - - memset(&cookie, 0, sizeof(cookie)); - memcpy(cookie.ip, ip, sizeof(ot_ip6)); - cookie.interest = EVENT_IN; - cookie.flag = STRUCT_HTTP_FLAG_ONSTACK; - - generation = fdstate_open(sock, &cookie, time_future_seconds(OT_CLIENT_TIMEOUT)); - if (!fdstate_claim((int)sock, generation)) { - fdstate_close(sock); - event_close((int)sock); - continue; - } - - stats_issue_event(ws, EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); - - tcp_read(sock, ws); - - /* Gone already if it was answered and closed inline */ - if (fdstate_generation((int)sock) != generation) - continue; - - /* Handling it may already have given it a heap home and handed it to - another thread, and then it is no longer this frame's to touch */ - if (fdstate_cookie((int)sock) != &cookie) - fdstate_release((int)sock); - else if (!http_adopt(sock)) - http_close(sock); - else - fdstate_release((int)sock); - } -} - -/* A worker blocks in accept and nowhere else: the connection it is handed is - non blocking, so a client that stops talking is given to the event loop - rather than keeping this thread. */ -static void tcp_run(struct ot_worker *me) { - while (g_opentracker_running) - tcp_accept(me->sock, &me->ws); -} - -void tcp_worker_install(int64_t sock) { - socket_set_blocking((int)sock, 1); - socket_defer_accept((int)sock); - - if (worker_start(tcp_run, sock) == -1) - fprintf(stderr, "Warning: could not install a tcp worker, this socket stays with the workers already running.\n"); -} -- cgit v1.3