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_udp.c | 226 --------------------------------------------------------------- 1 file changed, 226 deletions(-) delete mode 100644 ot_udp.c (limited to 'ot_udp.c') diff --git a/ot_udp.c b/ot_udp.c deleted file mode 100644 index 644b71d..0000000 --- a/ot_udp.c +++ /dev/null @@ -1,226 +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 - -/* Opentracker */ -#include "ot_ip.h" -#include "ot_random.h" -#include "ot_rijndael.h" -#include "ot_socket.h" -#include "ot_worker.h" -#include "ot_stats.h" -#include "ot_udp.h" -#include "trackerlogic.h" - -static uint32_t g_rijndael_round_key[44] = {0}; -static volatile uint32_t g_key_of_the_hour[2] = {0}; -static volatile ot_time g_hour_of_the_key; - - -static void udp_generate_rijndael_round_key(void) { - uint32_t key[16]; - random_bytes(key, sizeof(key)); - rijndaelKeySetupEnc128(g_rijndael_round_key, (uint8_t *)key); - - g_key_of_the_hour[0] = random_uint32(); - g_hour_of_the_key = time_now_minutes(); -} - -/* Generate current and previous connection id for ip */ -static void udp_make_connectionid(uint32_t connid[2], const ot_ip6 remoteip, int age) { - uint32_t plain[4], crypt[4]; - int i; - uint32_t current_key_of_the_hour; - - if (time_now_minutes() - g_hour_of_the_key >= 60) { - uint32_t old_key_of_the_hour = g_key_of_the_hour[0]; - uint32_t new_key_of_the_hour = random_uint32(); - /* If in the meantime another thread has performed - key rotation, do not overwrite their results */ - if (time_now_minutes() - g_hour_of_the_key >= 60) { - /* Upgrade en bloc */ - g_hour_of_the_key = time_now_minutes(); - g_key_of_the_hour[0] = new_key_of_the_hour; - g_key_of_the_hour[1] = old_key_of_the_hour; - } - } - - memcpy(plain, remoteip, sizeof(plain)); - current_key_of_the_hour = g_key_of_the_hour[age]; - for (i = 0; i < 4; ++i) - plain[i] ^= current_key_of_the_hour; - rijndaelEncrypt128(g_rijndael_round_key, (uint8_t *)plain, (uint8_t *)crypt); - connid[0] = crypt[0] ^ crypt[1]; - connid[1] = crypt[2] ^ crypt[3]; -} - -/* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */ -int handle_udp6(int64_t serversocket, struct ot_workstruct *ws) { - ot_ip6 remoteip; - uint32_t *inpacket = (uint32_t *)ws->inbuf; - uint32_t *outpacket = (uint32_t *)ws->outbuf; - uint32_t left, event; - uint32_t connid[2]; - uint32_t action; - uint16_t port, remoteport; - size_t byte_count, scrape_count; - - ssize_t result = socket_recv(serversocket, ws->inbuf, G_INBUF_SIZE, remoteip, &remoteport); - if (result <= 0) - return 0; - byte_count = (size_t)result; - - stats_issue_event(ws, EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip); - stats_issue_event(ws, EVENT_READ, FLAG_UDP, byte_count); - - /* Minimum udp tracker packet size, also catches error */ - if (byte_count < 16) - return 1; - - /* Get action to take. Ignore error messages and broken packets */ - action = ntohl(inpacket[2]); - if (action > 2) - return 1; - - /* Generate the connection id we give out and expect to and from - the requesting ip address, this prevents udp spoofing */ - udp_make_connectionid(connid, remoteip, 0); - - /* Initialise hash pointer */ - ws->hash = NULL; - ws->peer_id = NULL; - - /* If action is not 0 (connect), then we expect the derived - connection id in first 64 bit */ - if ((action > 0) && (inpacket[0] != connid[0] || inpacket[1] != connid[1])) { - /* If connection id does not match, try the one that was - valid in the previous hour. Only if this also does not - match, return an error packet */ - udp_make_connectionid(connid, remoteip, 1); - if (inpacket[0] != connid[0] || inpacket[1] != connid[1]) { - const char err_idmiss[] = "Connection ID missmatch."; - size_t s = sizeof(err_idmiss); - outpacket[0] = htonl(3); - outpacket[1] = inpacket[3]; - memcpy(&outpacket[2], &err_idmiss[0], s); - socket_send(serversocket, ws->outbuf, 8 + s, remoteip, remoteport); - stats_issue_event(ws, EVENT_CONNID_MISSMATCH, FLAG_UDP, 8 + s); - return 1; - } - } - - switch (action) { - case 0: /* This is a connect action */ - /* look for udp bittorrent magic id */ - if ((ntohl(inpacket[0]) != 0x00000417) || (ntohl(inpacket[1]) != 0x27101980)) - return 1; - - outpacket[0] = 0; - outpacket[1] = inpacket[3]; - outpacket[2] = connid[0]; - outpacket[3] = connid[1]; - - socket_send(serversocket, ws->outbuf, 16, remoteip, remoteport); - stats_issue_event(ws, EVENT_CONNECT, FLAG_UDP, 16); - break; - case 1: /* This is an announce action */ - /* Minimum udp announce packet size */ - if (byte_count < 98) - return 1; - - /* We do only want to know, if it is zero */ - left = inpacket[64 / 4] | inpacket[68 / 4]; - - event = ntohl(inpacket[80 / 4]); - port = *(uint16_t *)(((char *)inpacket) + 96); - ws->hash = (ot_hash *)(((char *)inpacket) + 16); - - OT_SETIP(ws->peer, remoteip); - OT_SETPORT(ws->peer, &port); - OT_PEERFLAG(ws->peer) = 0; - - switch (event) { - case 1: - OT_PEERFLAG(ws->peer) |= PEER_FLAG_COMPLETED; - break; - case 3: - OT_PEERFLAG(ws->peer) |= PEER_FLAG_STOPPED; - break; - default: - break; - } - - if (!left) - OT_PEERFLAG(ws->peer) |= PEER_FLAG_SEEDING; - - outpacket[0] = htonl(1); /* announce action */ - outpacket[1] = inpacket[12 / 4]; - - if (OT_PEERFLAG(ws->peer) & PEER_FLAG_STOPPED) { /* Peer is gone. */ - ws->reply = ws->outbuf; - ws->reply_size = remove_peer_from_torrent(FLAG_UDP, ws); - } else { - /* Limit amount of peers to OT_MAX_PEERS_UDP */ - uint32_t numwant = ntohl(inpacket[92 / 4]); - size_t max_peers = ip_is_v4mapped(remoteip) ? OT_MAX_PEERS_UDP4 : OT_MAX_PEERS_UDP6; - if (numwant > max_peers) - numwant = max_peers; - - ws->reply = ws->outbuf + 8; - ws->reply_size = add_peer_to_torrent_and_return_peers(FLAG_UDP, ws, numwant); - - if (!ws->reply_size) { - const char err_unauth[] = "Requested download is not authorized for use with this tracker."; - size_t s = sizeof(err_unauth); - outpacket[0] = htonl(3); - memcpy(&outpacket[2], &err_unauth[0], s); - socket_send(serversocket, ws->outbuf, 8 + s, remoteip, remoteport); - return 1; - } - ws->reply_size += 8; - } - - socket_send(serversocket, ws->outbuf, ws->reply_size, remoteip, remoteport); - stats_issue_event(ws, EVENT_ANNOUNCE, FLAG_UDP, ws->reply_size); - break; - - case 2: /* This is a scrape action */ - outpacket[0] = htonl(2); /* scrape action */ - outpacket[1] = inpacket[12 / 4]; - - for (scrape_count = 0; (scrape_count * 20 < byte_count - 16) && (scrape_count <= 74); scrape_count++) - return_udp_scrape_for_torrent(*(ot_hash *)(((char *)inpacket) + 16 + 20 * scrape_count), ((char *)outpacket) + 8 + 12 * scrape_count); - - socket_send(serversocket, ws->outbuf, 8 + 12 * scrape_count, remoteip, remoteport); - stats_issue_event(ws, EVENT_SCRAPE, FLAG_UDP, scrape_count); - break; - } - return 1; -} - -static void udp_run(struct ot_worker *me) { - while (g_opentracker_running) - handle_udp6(me->sock, &me->ws); -} - -void udp_init(void) { - if (!g_rijndael_round_key[0]) - udp_generate_rijndael_round_key(); -} - -void udp_worker_install(int64_t sock) { -#ifdef _DEBUG - fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); -#endif - socket_set_blocking((int)sock, 1); - - if (worker_start(udp_run, sock) == -1) - fprintf(stderr, "Warning: could not install a udp worker, this socket stays with the workers already running.\n"); -} -- cgit v1.3