Settings are now made via the configuration file;
Option to block IANA reserved IPs (against DOS attacks)
This commit is contained in:
parent
0c32025590
commit
fdfc36f736
36
src/main.c
36
src/main.c
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue