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 <time.h>
#include <string.h>
#include "settings.h"
static void _print_usage ()
{
printf ("Usage: udpt <udp-port>\n"
"\tDefault port is 6969.\n");
printf ("Usage: udpt [<configuration file>]\n");
}
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
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

View file

@ -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

View file

@ -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;

View file

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

View file

@ -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)

View file

@ -23,6 +23,7 @@
#include <stdint.h>
#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.