From fdfc36f736fe274d07b99f5b18f29494175c1945 Mon Sep 17 00:00:00 2001 From: Naim A Date: Thu, 13 Dec 2012 13:52:55 +0200 Subject: [PATCH] Settings are now made via the configuration file; Option to block IANA reserved IPs (against DOS attacks) --- src/main.c | 36 +++++++++++++------ src/multiplatform.h | 3 +- src/settings.c | 4 +-- src/settings.h | 2 ++ src/udpTracker.c | 84 ++++++++++++++++++++++++++++++++++++++++++--- src/udpTracker.h | 11 +++++- 6 files changed, 121 insertions(+), 19 deletions(-) diff --git a/src/main.c b/src/main.c index 4549ac1..e5b777d 100644 --- a/src/main.c +++ b/src/main.c @@ -26,35 +26,51 @@ #include #include #include +#include "settings.h" static void _print_usage () { - printf ("Usage: udpt \n" - "\tDefault port is 6969.\n"); + printf ("Usage: udpt []\n"); } int main(int argc, char *argv[]) { - printf("UDP Tracker (UDPT) %s\nCopyright: (C) 2012 Naim Abda \n\n", VERSION); + printf("UDP Tracker (UDPT) %s\nCopyright: (C) 2012 Naim Abda \n", VERSION); + printf("Build Date: %s\n\n", __DATE__); #ifdef WIN32 WSADATA wsadata; WSAStartup(MAKEWORD(2, 2), &wsadata); #endif - uint16_t port = 6969; + char *config_file = "udpt.conf"; + if (argc <= 1) { _print_usage (); } - else if (argc == 2) + + Settings settings; + udpServerInstance usi; + + settings_init (&settings, config_file); + if (settings_load (&settings) != 0) { - port = atoi(argv[1]); - printf("selected port=%u\n", port); + // set default settings: + + settings_set (&settings, "database", "driver", "sqlite3"); + settings_set (&settings, "database", "file", "tracker.db"); + + settings_set (&settings, "tracker", "port", "6969"); + settings_set (&settings, "tracker", "threads", "5"); + settings_set (&settings, "tracker", "allow_remotes", "yes"); + settings_set (&settings, "tracker", "allow_iana_ips", "yes"); + + settings_save (&settings); + printf("Failed to read from '%s'. Using default settings.\n", config_file); } - udpServerInstance usi; - UDPTracker_init(&usi, port, 5); + UDPTracker_init(&usi, &settings); int r = UDPTracker_start(&usi); if (r != 0) @@ -81,7 +97,7 @@ int main(int argc, char *argv[]) cleanup: printf("\nGoodbye.\n"); - + settings_destroy (&settings); UDPTracker_destroy(&usi); #ifdef WIN32 diff --git a/src/multiplatform.h b/src/multiplatform.h index 202f662..87d746c 100644 --- a/src/multiplatform.h +++ b/src/multiplatform.h @@ -45,9 +45,8 @@ typedef struct hostent HOSTENT; typedef void* LPVOID; typedef void (LPTHREAD_START_ROUTINE)(LPVOID); typedef pthread_t HANDLE; -//#define IPPROTO_UDP 0 // no protocol set.. SOCK_DGRAM is enough. #define min(a,b) (a > b ? b : a) -#define VERSION "1.0.0 (Linux)" +#define VERSION "1.0.0-alpha (Linux)" #endif diff --git a/src/settings.c b/src/settings.c index 0b899c4..359097b 100644 --- a/src/settings.c +++ b/src/settings.c @@ -63,14 +63,14 @@ void _settings_clean_string (char **str) offset++; } - *str += offset; + (*str) += offset; len -= offset; for (i = len - 1;i >= 0;i--) { if (isspace( (*str)[i] ) != 0) { - *str[i] = '\0'; + (*str)[i] = '\0'; } else break; diff --git a/src/settings.h b/src/settings.h index f015248..49d80ce 100644 --- a/src/settings.h +++ b/src/settings.h @@ -18,6 +18,8 @@ * along with UDPT. If not, see . */ +#pragma once + #include typedef struct { diff --git a/src/udpTracker.c b/src/udpTracker.c index d2c4583..95474d6 100644 --- a/src/udpTracker.c +++ b/src/udpTracker.c @@ -38,13 +38,65 @@ static void* _thread_start (void *arg); static void* _maintainance_start (void *arg); #endif -void UDPTracker_init (udpServerInstance *usi, uint16_t port, uint8_t threads) +static int _isTrue (char *str) { + if (str == NULL) + return -1; + int i; + int len = strlen (str); + for (i = 0;i < len;i++) + { + if (str[i] >= 'A' && str[i] <= 'Z') + { + str[i] = (str[i] - 'A' + 'a'); + } + } + if (strcmp(str, "yes") == 0) + return 1; + if (strcmp(str, "no") == 0) + return 0; + if (strcmp(str, "true") == 0) + return 1; + if (strcmp(str, "false") == 0) + return 0; + if (strcmp(str, "1") == 0) + return 1; + if (strcmp(str, "0") == 0) + return 0; + return -1; +} + +void UDPTracker_init (udpServerInstance *usi, Settings *settings) +{ + int r; + int port = 6969; + int threads = 5; + uint8_t n_settings = 0; + + char *s_port = settings_get(settings, "tracker", "port"); + char *s_threads = settings_get(settings, "tracker", "threads"); + char *s_allow_remotes = settings_get (settings, "tracker", "allow_remotes"); + char *s_allow_iana_ip = settings_get (settings, "tracker", "allow_iana_ips"); + + r = _isTrue(s_allow_remotes); + if (r == 1) + n_settings |= UDPT_ALLOW_REMOTE_IP; + r = _isTrue(s_allow_iana_ip); + if (r != 0) + n_settings |= UDPT_ALLOW_IANA_IP; + + if (s_port != NULL) + port = atoi (s_port); + if (s_threads != NULL) + threads = atoi (s_threads); + usi->port = port; usi->thread_count = threads + 1; usi->threads = malloc (sizeof(HANDLE) * usi->thread_count); usi->flags = 0; usi->conn = NULL; + usi->settings = n_settings; + usi->o_settings = settings; } void UDPTracker_destroy (udpServerInstance *usi) @@ -81,7 +133,6 @@ void UDPTracker_destroy (udpServerInstance *usi) free (usi->threads); } - int UDPTracker_start (udpServerInstance *usi) { SOCKET sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -116,7 +167,11 @@ int UDPTracker_start (udpServerInstance *usi) usi->sock = sock; - db_open(&usi->conn, "tracker.db"); + char *dbname = settings_get (usi->o_settings, "database", "file"); + if (dbname == NULL) + dbname = "tracker.db"; + + db_open(&usi->conn, dbname); usi->flags |= FLAG_RUNNING; int i; @@ -125,7 +180,7 @@ int UDPTracker_start (udpServerInstance *usi) #ifdef WIN32 usi->threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_maintainance_start, (LPVOID)usi, 0, NULL); #elif defined (linux) - printf("Starting maintenance thread (1/6)...\n"); + printf("Starting maintenance thread (1/%u)...\n", usi->thread_count); pthread_create (&usi->threads[0], NULL, _maintainance_start, usi); #endif @@ -210,6 +265,11 @@ static int _handle_announce (udpServerInstance *usi, SOCKADDR_IN *remote, char * req->num_want = m_hton32 (req->num_want); req->left = m_hton64 (req->left); + if ((usi->settings & UDPT_ALLOW_REMOTE_IP) == 0 && req->ip_address != 0) + { + _send_error (usi, remote, req->transaction_id, "Tracker doesn't allow remote IP's; Request ignored."); + return 0; + } // load peers int q = 30; @@ -332,6 +392,14 @@ static int _handle_scrape (udpServerInstance *usi, SOCKADDR_IN *remote, char *da return 0; } +static int _isIANA_IP (uint32_t ip) +{ + uint8_t x = (ip % 256); + if (x == 0 || x == 10 || x == 127 || x >= 224) + return 1; + return 0; +} + static int _resolve_request (udpServerInstance *usi, SOCKADDR_IN *remote, char *data, int r) { ConnectionRequest *cR; @@ -339,6 +407,14 @@ static int _resolve_request (udpServerInstance *usi, SOCKADDR_IN *remote, char * uint32_t action = m_hton32(cR->action); + if ((usi->settings & UDPT_ALLOW_IANA_IP) > 0) + { + if (_isIANA_IP (remote->sin_addr.s_addr)) + { + return 0; // Access Denied: IANA reserved IP. + } + } + printf(":: %x:%u ACTION=%d\n", remote->sin_addr.s_addr , remote->sin_port, action); if (action == 0 && r >= 16) diff --git a/src/udpTracker.h b/src/udpTracker.h index 9ad9d3a..2f6f4d1 100644 --- a/src/udpTracker.h +++ b/src/udpTracker.h @@ -23,6 +23,7 @@ #include #include "multiplatform.h" #include "db/database.h" +#include "settings.h" struct udp_connection_request { @@ -90,6 +91,12 @@ struct udp_error_response char *message; }; +#define UDPT_DYNAMIC 0x01 // Track Any info_hash? +#define UDPT_ALLOW_REMOTE_IP 0x02 // Allow client's to send other IPs? +#define UDPT_ALLOW_IANA_IP 0x04 // allow IP's like 127.0.0.1 or other IANA reserved IPs? +#define UDPT_VALIDATE_CLIENT 0x08 // validate client before adding to Database? (check if connection is open?) + + typedef struct { SOCKET sock; @@ -98,9 +105,11 @@ typedef struct uint8_t thread_count; uint8_t flags; + uint8_t settings; HANDLE *threads; + Settings *o_settings; dbConnection *conn; } udpServerInstance; @@ -118,7 +127,7 @@ typedef struct udp_error_response ErrorResponse; * @param port The port to bind the server to * @param threads Amount of threads to start the server with. */ -void UDPTracker_init (udpServerInstance *usi, uint16_t port, uint8_t threads); +void UDPTracker_init (udpServerInstance *usi, Settings *); /** * Destroys resources that were created by UDPTracker_init.