Settings are now made via the configuration file;

Option to block IANA reserved IPs (against DOS attacks)
This commit is contained in:
Naim A 2012-12-13 13:52:55 +02:00
parent 0c32025590
commit fdfc36f736
6 changed files with 121 additions and 19 deletions

View file

@ -26,35 +26,51 @@
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include "settings.h"
static void _print_usage () static void _print_usage ()
{ {
printf ("Usage: udpt <udp-port>\n" printf ("Usage: udpt [<configuration file>]\n");
"\tDefault port is 6969.\n");
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
printf("UDP Tracker (UDPT) %s\nCopyright: (C) 2012 Naim Abda <naim94a@gmail.com>\n\n", VERSION); printf("UDP Tracker (UDPT) %s\nCopyright: (C) 2012 Naim Abda <naim94a@gmail.com>\n", VERSION);
printf("Build Date: %s\n\n", __DATE__);
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata); WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif #endif
uint16_t port = 6969; char *config_file = "udpt.conf";
if (argc <= 1) if (argc <= 1)
{ {
_print_usage (); _print_usage ();
} }
else if (argc == 2)
Settings settings;
udpServerInstance usi;
settings_init (&settings, config_file);
if (settings_load (&settings) != 0)
{ {
port = atoi(argv[1]); // set default settings:
printf("selected port=%u\n", port);
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, &settings);
UDPTracker_init(&usi, port, 5);
int r = UDPTracker_start(&usi); int r = UDPTracker_start(&usi);
if (r != 0) if (r != 0)
@ -81,7 +97,7 @@ int main(int argc, char *argv[])
cleanup: cleanup:
printf("\nGoodbye.\n"); printf("\nGoodbye.\n");
settings_destroy (&settings);
UDPTracker_destroy(&usi); UDPTracker_destroy(&usi);
#ifdef WIN32 #ifdef WIN32

View file

@ -45,9 +45,8 @@ typedef struct hostent HOSTENT;
typedef void* LPVOID; typedef void* LPVOID;
typedef void (LPTHREAD_START_ROUTINE)(LPVOID); typedef void (LPTHREAD_START_ROUTINE)(LPVOID);
typedef pthread_t HANDLE; typedef pthread_t HANDLE;
//#define IPPROTO_UDP 0 // no protocol set.. SOCK_DGRAM is enough.
#define min(a,b) (a > b ? b : a) #define min(a,b) (a > b ? b : a)
#define VERSION "1.0.0 (Linux)" #define VERSION "1.0.0-alpha (Linux)"
#endif #endif

View file

@ -63,14 +63,14 @@ void _settings_clean_string (char **str)
offset++; offset++;
} }
*str += offset; (*str) += offset;
len -= offset; len -= offset;
for (i = len - 1;i >= 0;i--) for (i = len - 1;i >= 0;i--)
{ {
if (isspace( (*str)[i] ) != 0) if (isspace( (*str)[i] ) != 0)
{ {
*str[i] = '\0'; (*str)[i] = '\0';
} }
else else
break; break;

View file

@ -18,6 +18,8 @@
* along with UDPT. If not, see <http://www.gnu.org/licenses/>. * along with UDPT. If not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct {

View file

@ -38,13 +38,65 @@ static void* _thread_start (void *arg);
static void* _maintainance_start (void *arg); static void* _maintainance_start (void *arg);
#endif #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->port = port;
usi->thread_count = threads + 1; usi->thread_count = threads + 1;
usi->threads = malloc (sizeof(HANDLE) * usi->thread_count); usi->threads = malloc (sizeof(HANDLE) * usi->thread_count);
usi->flags = 0; usi->flags = 0;
usi->conn = NULL; usi->conn = NULL;
usi->settings = n_settings;
usi->o_settings = settings;
} }
void UDPTracker_destroy (udpServerInstance *usi) void UDPTracker_destroy (udpServerInstance *usi)
@ -81,7 +133,6 @@ void UDPTracker_destroy (udpServerInstance *usi)
free (usi->threads); free (usi->threads);
} }
int UDPTracker_start (udpServerInstance *usi) int UDPTracker_start (udpServerInstance *usi)
{ {
SOCKET sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); SOCKET sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@ -116,7 +167,11 @@ int UDPTracker_start (udpServerInstance *usi)
usi->sock = sock; 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; usi->flags |= FLAG_RUNNING;
int i; int i;
@ -125,7 +180,7 @@ int UDPTracker_start (udpServerInstance *usi)
#ifdef WIN32 #ifdef WIN32
usi->threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_maintainance_start, (LPVOID)usi, 0, NULL); usi->threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_maintainance_start, (LPVOID)usi, 0, NULL);
#elif defined (linux) #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); pthread_create (&usi->threads[0], NULL, _maintainance_start, usi);
#endif #endif
@ -210,6 +265,11 @@ static int _handle_announce (udpServerInstance *usi, SOCKADDR_IN *remote, char *
req->num_want = m_hton32 (req->num_want); req->num_want = m_hton32 (req->num_want);
req->left = m_hton64 (req->left); 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 // load peers
int q = 30; int q = 30;
@ -332,6 +392,14 @@ static int _handle_scrape (udpServerInstance *usi, SOCKADDR_IN *remote, char *da
return 0; 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) static int _resolve_request (udpServerInstance *usi, SOCKADDR_IN *remote, char *data, int r)
{ {
ConnectionRequest *cR; ConnectionRequest *cR;
@ -339,6 +407,14 @@ static int _resolve_request (udpServerInstance *usi, SOCKADDR_IN *remote, char *
uint32_t action = m_hton32(cR->action); 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); printf(":: %x:%u ACTION=%d\n", remote->sin_addr.s_addr , remote->sin_port, action);
if (action == 0 && r >= 16) if (action == 0 && r >= 16)

View file

@ -23,6 +23,7 @@
#include <stdint.h> #include <stdint.h>
#include "multiplatform.h" #include "multiplatform.h"
#include "db/database.h" #include "db/database.h"
#include "settings.h"
struct udp_connection_request struct udp_connection_request
{ {
@ -90,6 +91,12 @@ struct udp_error_response
char *message; 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 typedef struct
{ {
SOCKET sock; SOCKET sock;
@ -98,9 +105,11 @@ typedef struct
uint8_t thread_count; uint8_t thread_count;
uint8_t flags; uint8_t flags;
uint8_t settings;
HANDLE *threads; HANDLE *threads;
Settings *o_settings;
dbConnection *conn; dbConnection *conn;
} udpServerInstance; } udpServerInstance;
@ -118,7 +127,7 @@ typedef struct udp_error_response ErrorResponse;
* @param port The port to bind the server to * @param port The port to bind the server to
* @param threads Amount of threads to start the server with. * @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. * Destroys resources that were created by UDPTracker_init.