Code cleanup (WIP)
This commit is contained in:
parent
edaa44bfc7
commit
1db33eb0b6
|
@ -20,7 +20,6 @@
|
||||||
#ifndef DATABASE_HPP_
|
#ifndef DATABASE_HPP_
|
||||||
#define DATABASE_HPP_
|
#define DATABASE_HPP_
|
||||||
|
|
||||||
#include "../settings.hpp"
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
namespace UDPT
|
namespace UDPT
|
||||||
|
|
33
src/exceptions.h
Normal file
33
src/exceptions.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
namespace UDPT
|
||||||
|
{
|
||||||
|
class UDPTException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UDPTException(const char* errorMsg = "", int errorCode = 0) : m_error(errorMsg), m_errorCode(errorCode)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char* what() const
|
||||||
|
{
|
||||||
|
return m_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int getErrorCode() const
|
||||||
|
{
|
||||||
|
return m_errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~UDPTException()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char* m_error;
|
||||||
|
const int m_errorCode;
|
||||||
|
};
|
||||||
|
}
|
|
@ -97,36 +97,12 @@ namespace UDPT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebApp::WebApp(HTTPServer *srv, DatabaseDriver *db, const boost::program_options::variables_map& conf) : m_conf(conf)
|
WebApp::WebApp(std::shared_ptr<HTTPServer> srv, DatabaseDriver *db, const boost::program_options::variables_map& conf) : m_conf(conf), m_server(srv)
|
||||||
{
|
{
|
||||||
this->instance = srv;
|
|
||||||
this->db = db;
|
this->db = db;
|
||||||
/* this->sc_api = settings->getClass("api");
|
// TODO: Implement authentication by keys
|
||||||
|
|
||||||
Settings::SettingClass *apiKeys = settings->getClass("api.keys");
|
m_server->setData("webapp", this);
|
||||||
if (apiKeys != NULL)
|
|
||||||
{
|
|
||||||
map<string, string>* aK = apiKeys->getMap();
|
|
||||||
map<string, string>::iterator it, end;
|
|
||||||
end = aK->end();
|
|
||||||
for (it = aK->begin();it != end;it++)
|
|
||||||
{
|
|
||||||
string key = it->first;
|
|
||||||
list<uint32_t> ips;
|
|
||||||
|
|
||||||
string::size_type strp = 0;
|
|
||||||
uint32_t ip;
|
|
||||||
while ((ip = _getNextIPv4(strp, it->second)) != 0)
|
|
||||||
{
|
|
||||||
ips.push_back( m_hton32(ip) );
|
|
||||||
}
|
|
||||||
|
|
||||||
this->ip_whitelist.insert(pair<string, list<uint32_t> >(key, ips));
|
|
||||||
}
|
|
||||||
|
|
||||||
} */
|
|
||||||
|
|
||||||
srv->setData("webapp", this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebApp::~WebApp()
|
WebApp::~WebApp()
|
||||||
|
@ -136,17 +112,17 @@ namespace UDPT
|
||||||
void WebApp::deploy()
|
void WebApp::deploy()
|
||||||
{
|
{
|
||||||
list<string> path;
|
list<string> path;
|
||||||
this->instance->addApp(&path, &WebApp::handleRoot);
|
m_server->addApp(&path, &WebApp::handleRoot);
|
||||||
|
|
||||||
path.push_back("api");
|
path.push_back("api");
|
||||||
this->instance->addApp(&path, &WebApp::handleAPI); // "/api"
|
m_server->addApp(&path, &WebApp::handleAPI); // "/api"
|
||||||
|
|
||||||
path.pop_back();
|
path.pop_back();
|
||||||
path.push_back("announce");
|
path.push_back("announce");
|
||||||
this->instance->addApp(&path, &WebApp::handleAnnounce);
|
m_server->addApp(&path, &WebApp::handleAnnounce);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApp::handleRoot (HTTPServer *srv, HTTPServer::Request *req, HTTPServer::Response *resp)
|
void WebApp::handleRoot(HTTPServer *srv, HTTPServer::Request *req, HTTPServer::Response *resp)
|
||||||
{
|
{
|
||||||
// It would be very appreciated to keep this in the code.
|
// It would be very appreciated to keep this in the code.
|
||||||
resp->write("<html>"
|
resp->write("<html>"
|
||||||
|
@ -201,7 +177,7 @@ namespace UDPT
|
||||||
|
|
||||||
void WebApp::doAddTorrent (HTTPServer::Request *req, HTTPServer::Response *resp)
|
void WebApp::doAddTorrent (HTTPServer::Request *req, HTTPServer::Response *resp)
|
||||||
{
|
{
|
||||||
string strHash = req->getParam("hash");
|
std::string strHash = req->getParam("hash");
|
||||||
if (strHash.length() != 40)
|
if (strHash.length() != 40)
|
||||||
{
|
{
|
||||||
resp->write("{\"error\":\"Hash length must be 40 characters.\"}");
|
resp->write("{\"error\":\"Hash length must be 40 characters.\"}");
|
||||||
|
@ -232,7 +208,7 @@ namespace UDPT
|
||||||
throw ServerException (0, "IPv4 supported Only.");
|
throw ServerException (0, "IPv4 supported Only.");
|
||||||
}
|
}
|
||||||
|
|
||||||
string key = req->getParam("auth");
|
std::string key = req->getParam("auth");
|
||||||
if (key.length() <= 0)
|
if (key.length() <= 0)
|
||||||
throw ServerException (0, "Bad Authentication Key");
|
throw ServerException (0, "Bad Authentication Key");
|
||||||
|
|
||||||
|
@ -247,7 +223,7 @@ namespace UDPT
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string action = req->getParam("action");
|
std::string action = req->getParam("action");
|
||||||
if (action == "add")
|
if (action == "add")
|
||||||
app->doAddTorrent(req, resp);
|
app->doAddTorrent(req, resp);
|
||||||
else if (action == "remove")
|
else if (action == "remove")
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
|
|
||||||
#include "httpserver.hpp"
|
#include "httpserver.hpp"
|
||||||
#include "../db/database.hpp"
|
#include "../db/database.hpp"
|
||||||
#include "../settings.hpp"
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -38,13 +38,13 @@ namespace UDPT
|
||||||
class WebApp
|
class WebApp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebApp(HTTPServer *, DatabaseDriver *, const boost::program_options::variables_map& conf);
|
WebApp(std::shared_ptr<HTTPServer> , DatabaseDriver *, const boost::program_options::variables_map& conf);
|
||||||
~WebApp();
|
virtual ~WebApp();
|
||||||
void deploy ();
|
void deploy ();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HTTPServer *instance;
|
std::shared_ptr<HTTPServer> m_server;
|
||||||
UDPT::Data::DatabaseDriver *db;
|
UDPT::Data::DatabaseDriver *db;
|
||||||
const boost::program_options::variables_map& m_conf;
|
const boost::program_options::variables_map& m_conf;
|
||||||
std::map<std::string, list<uint32_t> > ip_whitelist;
|
std::map<std::string, list<uint32_t> > ip_whitelist;
|
||||||
|
|
|
@ -27,10 +27,10 @@ using namespace std;
|
||||||
namespace UDPT {
|
namespace UDPT {
|
||||||
|
|
||||||
Logger::Logger(const boost::program_options::variables_map& s)
|
Logger::Logger(const boost::program_options::variables_map& s)
|
||||||
: logfile (&std::cout)
|
: m_logfile (std::cout)
|
||||||
{
|
{
|
||||||
const string& filename = s["logging.filename"].as<std::string>();
|
const std::string& filename = s["logging.filename"].as<std::string>();
|
||||||
const string& level = s["logging.level"].as<std::string>();
|
const std::string& level = s["logging.level"].as<std::string>();
|
||||||
|
|
||||||
closeStreamOnDestroy = false;
|
closeStreamOnDestroy = false;
|
||||||
|
|
||||||
|
@ -42,35 +42,10 @@ namespace UDPT {
|
||||||
this->loglevel = LL_INFO;
|
this->loglevel = LL_INFO;
|
||||||
else
|
else
|
||||||
this->loglevel = LL_ERROR;
|
this->loglevel = LL_ERROR;
|
||||||
|
|
||||||
if (filename.compare("stdout") != 0 && filename.length() > 0)
|
|
||||||
{
|
|
||||||
fstream fs;
|
|
||||||
fs.open(filename.c_str(), ios::binary | ios::out | ios::app);
|
|
||||||
if (!fs.is_open())
|
|
||||||
{
|
|
||||||
this->log(LL_ERROR, "Failed to open log file.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->logfile = &fs;
|
|
||||||
closeStreamOnDestroy = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::Logger(const boost::program_options::variables_map& s, ostream &os)
|
|
||||||
: logfile (&os), loglevel (LL_ERROR)
|
|
||||||
{
|
|
||||||
closeStreamOnDestroy = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::~Logger()
|
Logger::~Logger()
|
||||||
{
|
{
|
||||||
fstream *f = (fstream*)this->logfile;
|
|
||||||
f->flush();
|
|
||||||
if (closeStreamOnDestroy)
|
|
||||||
{
|
|
||||||
f->close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::log(enum LogLevel lvl, string msg)
|
void Logger::log(enum LogLevel lvl, string msg)
|
||||||
|
@ -78,7 +53,7 @@ namespace UDPT {
|
||||||
const char letters[] = "EWID";
|
const char letters[] = "EWID";
|
||||||
if (lvl <= this->loglevel)
|
if (lvl <= this->loglevel)
|
||||||
{
|
{
|
||||||
(*logfile) << time (NULL) << ": ("
|
m_logfile << time (NULL) << ": ("
|
||||||
<< ((char)letters[lvl]) << "): "
|
<< ((char)letters[lvl]) << "): "
|
||||||
<< msg << "\n";
|
<< msg << "\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#ifndef LOGGING_H_
|
#ifndef LOGGING_H_
|
||||||
#define LOGGING_H_
|
#define LOGGING_H_
|
||||||
|
|
||||||
#include "settings.hpp"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -28,7 +27,6 @@
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
namespace UDPT {
|
namespace UDPT {
|
||||||
using namespace std;
|
|
||||||
class Logger
|
class Logger
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -42,17 +40,15 @@ namespace UDPT {
|
||||||
|
|
||||||
Logger(const boost::program_options::variables_map& s);
|
Logger(const boost::program_options::variables_map& s);
|
||||||
|
|
||||||
Logger(const boost::program_options::variables_map& s, ostream &os);
|
|
||||||
|
|
||||||
virtual ~Logger();
|
virtual ~Logger();
|
||||||
|
|
||||||
void log(enum LogLevel, string msg);
|
void log(enum LogLevel, std::string msg);
|
||||||
private:
|
private:
|
||||||
ostream *logfile;
|
std::ostream& m_logfile;
|
||||||
enum LogLevel loglevel;
|
enum LogLevel loglevel;
|
||||||
bool closeStreamOnDestroy;
|
bool closeStreamOnDestroy;
|
||||||
|
|
||||||
static void setStream(Logger *logger, ostream &s);
|
static void setStream(Logger *logger, std::ostream &s);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
168
src/main.cpp
168
src/main.cpp
|
@ -19,128 +19,35 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "logging.h"
|
|
||||||
#include "multiplatform.h"
|
|
||||||
#include "udpTracker.hpp"
|
|
||||||
#include "settings.hpp"
|
|
||||||
#include "http/httpserver.hpp"
|
|
||||||
#include "http/webapp.hpp"
|
|
||||||
#include <cstdlib> // atoi
|
#include <cstdlib> // atoi
|
||||||
#include <csignal> // signal
|
#include <csignal> // signal
|
||||||
#include <cstring> // strlen
|
#include <cstring> // strlen
|
||||||
#include <memory.h>
|
#include <memory>
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
using namespace std;
|
#include "logging.h"
|
||||||
using namespace UDPT;
|
#include "multiplatform.h"
|
||||||
using namespace UDPT::Server;
|
#include "udpTracker.hpp"
|
||||||
|
#include "http/httpserver.hpp"
|
||||||
|
#include "http/webapp.hpp"
|
||||||
|
|
||||||
Logger *logger;
|
UDPT::Logger *logger;
|
||||||
static struct {
|
|
||||||
Settings *settings;
|
|
||||||
UDPTracker *usi;
|
|
||||||
WebApp *wa;
|
|
||||||
HTTPServer *httpserver;
|
|
||||||
} Instance;
|
|
||||||
|
|
||||||
|
|
||||||
static void _print_usage ()
|
|
||||||
{
|
|
||||||
cout << "Usage: udpt [<configuration file>]" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _doAPIStart (const boost::program_options::variables_map& settings, WebApp **wa, HTTPServer **srv, DatabaseDriver *drvr)
|
|
||||||
{
|
|
||||||
if (!settings["apiserver.enable"].as<bool>())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
*srv = Instance.httpserver = new HTTPServer(settings);
|
|
||||||
*wa = Instance.wa = new WebApp(*srv, drvr, settings);
|
|
||||||
(*wa)->deploy();
|
|
||||||
}
|
|
||||||
catch (const ServerException &e)
|
|
||||||
{
|
|
||||||
std::cerr << "ServerException #" << e.getErrorCode() << ": " << e.getErrorMsg() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets current working directory to executables directory.
|
|
||||||
*/
|
|
||||||
static void _setCWD (char *argv0)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
wchar_t strFileName [MAX_PATH];
|
|
||||||
DWORD r, i;
|
|
||||||
r = GetModuleFileNameW(NULL, strFileName, MAX_PATH);
|
|
||||||
for (i = r;i >= 0;i--)
|
|
||||||
{
|
|
||||||
if (strFileName[i] == '\\')
|
|
||||||
{
|
|
||||||
strFileName[i] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SetCurrentDirectoryW(strFileName);
|
|
||||||
|
|
||||||
#elif defined(linux)
|
|
||||||
int len, i;
|
|
||||||
char *strFN;
|
|
||||||
if (argv0 != NULL)
|
|
||||||
{
|
|
||||||
len = strlen (argv0);
|
|
||||||
strFN = new char [len + 1];
|
|
||||||
|
|
||||||
for (i = len;i >= 0;i--)
|
|
||||||
{
|
|
||||||
if (strFN[i] == '/')
|
|
||||||
{
|
|
||||||
strFN = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chdir (strFN);
|
|
||||||
delete [] strFN;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Releases resources before exit.
|
|
||||||
*/
|
|
||||||
static void _doCleanup ()
|
|
||||||
{
|
|
||||||
delete Instance.wa;
|
|
||||||
delete Instance.httpserver;
|
|
||||||
delete Instance.usi;
|
|
||||||
delete Instance.settings;
|
|
||||||
delete logger;
|
|
||||||
|
|
||||||
memset (&Instance, 0, sizeof(Instance));
|
|
||||||
logger = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _signal_handler (int sig)
|
static void _signal_handler (int sig)
|
||||||
{
|
{
|
||||||
stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Signal " << sig << " raised. Terminating...";
|
ss << "Signal " << sig << " raised. ";
|
||||||
logger->log(Logger::LL_INFO, ss.str());
|
logger->log(Logger::LL_INFO, ss.str());
|
||||||
_doCleanup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
UDPTracker *usi;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
WSAStartup(MAKEWORD(2, 2), &wsadata);
|
::WSAStartup(MAKEWORD(2, 2), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boost::program_options::options_description commandLine("Command line options");
|
boost::program_options::options_description commandLine("Command line options");
|
||||||
|
@ -194,7 +101,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string config_filename(var_map["config"].as<std::string>());
|
std::string config_filename(var_map["config"].as<std::string>());
|
||||||
bool isTest = var_map.count("test");
|
bool isTest = (0 != var_map.count("test"));
|
||||||
|
|
||||||
if (var_map.count("config"))
|
if (var_map.count("config"))
|
||||||
{
|
{
|
||||||
|
@ -218,8 +125,6 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&Instance, 0, sizeof(Instance));
|
|
||||||
|
|
||||||
#ifdef SIGBREAK
|
#ifdef SIGBREAK
|
||||||
signal(SIGBREAK, &_signal_handler);
|
signal(SIGBREAK, &_signal_handler);
|
||||||
#endif
|
#endif
|
||||||
|
@ -235,7 +140,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logger = new Logger(var_map);
|
logger = new UDPT::Logger(var_map);
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
|
@ -243,41 +148,42 @@ int main(int argc, char *argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
usi = Instance.usi = new UDPTracker(var_map);
|
std::shared_ptr<UDPTracker> tracker;
|
||||||
|
std::shared_ptr<UDPT::Server::HTTPServer> apiSrv;
|
||||||
|
std::shared_ptr<UDPT::Server::WebApp> webApp;
|
||||||
|
|
||||||
HTTPServer *apiSrv = NULL;
|
try
|
||||||
WebApp *wa = NULL;
|
{
|
||||||
|
tracker = std::shared_ptr<UDPTracker>(new UDPTracker(var_map));
|
||||||
|
tracker->start();
|
||||||
|
|
||||||
r = usi->start();
|
if (var_map["apiserver.enable"].as<bool>())
|
||||||
if (r != UDPTracker::START_OK)
|
|
||||||
{
|
{
|
||||||
cerr << "Error While trying to start server." << endl;
|
try
|
||||||
switch (r)
|
|
||||||
{
|
{
|
||||||
case UDPTracker::START_ESOCKET_FAILED:
|
apiSrv = std::shared_ptr<UDPT::Server::HTTPServer>(new UDPT::Server::HTTPServer(var_map));
|
||||||
cerr << "Failed to create socket." << endl;
|
webApp = std::shared_ptr<UDPT::Server::WebApp>(new UDPT::Server::WebApp(apiSrv, tracker->conn, var_map));
|
||||||
break;
|
webApp->deploy();
|
||||||
case UDPTracker::START_EBIND_FAILED:
|
|
||||||
cerr << "Failed to bind socket." << endl;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cerr << "Unknown Error" << endl;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
goto cleanup;
|
catch (const UDPT::Server::ServerException &e)
|
||||||
|
{
|
||||||
|
std::cerr << "ServerException #" << e.getErrorCode() << ": " << e.getErrorMsg() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const UDPT::UDPTException& ex)
|
||||||
|
{
|
||||||
|
std::cerr << "UDPTException: " << ex.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
_doAPIStart(var_map, &wa, &apiSrv, usi->conn);
|
std::cout << "Hit Control-C to exit." << endl;
|
||||||
|
|
||||||
cout << "Hit Control-C to exit." << endl;
|
tracker->wait();
|
||||||
|
|
||||||
usi->wait();
|
std::cout << endl << "Goodbye." << endl;
|
||||||
|
|
||||||
cleanup:
|
|
||||||
cout << endl << "Goodbye." << endl;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSACleanup();
|
::WSACleanup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#define linux
|
#define linux
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VERSION "1.0.0-beta"
|
#define VERSION "1.0.2-dev"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
|
449
src/settings.cpp
449
src/settings.cpp
|
@ -1,449 +0,0 @@
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright © 2012-2016 Naim A.
|
|
||||||
*
|
|
||||||
* This file is part of UDPT.
|
|
||||||
*
|
|
||||||
* UDPT is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* UDPT is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with UDPT. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "settings.hpp"
|
|
||||||
#include <string.h> // still primitive - need for strlen()
|
|
||||||
#include <ctype.h> // need for isspace()
|
|
||||||
#include <exception>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include "tools.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace UDPT
|
|
||||||
{
|
|
||||||
Settings::SettingClass* Settings::getClass(const string classname)
|
|
||||||
{
|
|
||||||
if (classname == "")
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
map<string, SettingClass*>::iterator it;
|
|
||||||
it = this->classes.find(classname);
|
|
||||||
|
|
||||||
if (it == this->classes.end())
|
|
||||||
return NULL;
|
|
||||||
else
|
|
||||||
return it->second;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::Settings (const string filename)
|
|
||||||
{
|
|
||||||
this->filename = filename;
|
|
||||||
this->classes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void _settings_clean_string (char **str)
|
|
||||||
{
|
|
||||||
int len,
|
|
||||||
i,
|
|
||||||
offset;
|
|
||||||
|
|
||||||
len = strlen(*str);
|
|
||||||
|
|
||||||
//strip leading whitespaces.
|
|
||||||
offset = 0;
|
|
||||||
for (i = 0;i < len;i++)
|
|
||||||
{
|
|
||||||
if (isspace(*str[i]) == 0)
|
|
||||||
break;
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*str) += offset;
|
|
||||||
len -= offset;
|
|
||||||
|
|
||||||
for (i = len - 1;i >= 0;i--)
|
|
||||||
{
|
|
||||||
if (isspace( (*str)[i] ) != 0)
|
|
||||||
{
|
|
||||||
(*str)[i] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::parseSettings (char *data, int len)
|
|
||||||
{
|
|
||||||
char *className, *key, *value;
|
|
||||||
int i,
|
|
||||||
cil; // cil = Chars in line.
|
|
||||||
char c;
|
|
||||||
|
|
||||||
className = key = value = NULL;
|
|
||||||
cil = 0;
|
|
||||||
|
|
||||||
for (i = 0;i < len;i++)
|
|
||||||
{
|
|
||||||
c = data[i];
|
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
cil = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (cil == 0 && (c == ';' || c == '#'))
|
|
||||||
{
|
|
||||||
while (i < len)
|
|
||||||
{
|
|
||||||
if (data[i] == '\n')
|
|
||||||
break;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isspace(c) != 0 && cil == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (cil == 0 && c == '[')
|
|
||||||
{
|
|
||||||
className = (char*)(i + data + 1);
|
|
||||||
while (i < len)
|
|
||||||
{
|
|
||||||
if (data[i] != ']')
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
data[i] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isgraph(c) != 0 && cil == 0) // must be a key.
|
|
||||||
{
|
|
||||||
key = (char*)(i + data);
|
|
||||||
while (i < len)
|
|
||||||
{
|
|
||||||
if (data[i] == '\n')
|
|
||||||
{
|
|
||||||
key = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (data[i] == '=')
|
|
||||||
{
|
|
||||||
data[i] = '\0';
|
|
||||||
value = (char*)(data + i + 1);
|
|
||||||
while (i < len)
|
|
||||||
{
|
|
||||||
if (data[i] == '\n')
|
|
||||||
{
|
|
||||||
data[i] = '\0';
|
|
||||||
|
|
||||||
_settings_clean_string(&key);
|
|
||||||
_settings_clean_string(&value);
|
|
||||||
|
|
||||||
// add to settings...
|
|
||||||
this->set (className, key, value);
|
|
||||||
|
|
||||||
cil = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isgraph(c) != 0)
|
|
||||||
{
|
|
||||||
cil++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::load()
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *buffer;
|
|
||||||
|
|
||||||
fstream cfg;
|
|
||||||
cfg.open(this->filename.c_str(), ios::in | ios::binary);
|
|
||||||
|
|
||||||
if (!cfg.is_open())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
cfg.seekg(0, ios::end);
|
|
||||||
len = cfg.tellg();
|
|
||||||
cfg.seekg(0, ios::beg);
|
|
||||||
|
|
||||||
buffer = new char [len];
|
|
||||||
cfg.read(buffer, len);
|
|
||||||
cfg.close();
|
|
||||||
|
|
||||||
this->parseSettings(buffer, len);
|
|
||||||
|
|
||||||
delete[] buffer;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::save ()
|
|
||||||
{
|
|
||||||
SettingClass *sclass;
|
|
||||||
|
|
||||||
fstream cfg (this->filename.c_str(), ios::binary | ios::out);
|
|
||||||
if (!cfg.is_open())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
cfg << "; udpt Settings File - Created Automatically.\n";
|
|
||||||
|
|
||||||
map<string, SettingClass*>::iterator it;
|
|
||||||
for (it = this->classes.begin();it != this->classes.end();it++)
|
|
||||||
{
|
|
||||||
sclass = it->second;
|
|
||||||
cfg << "[" << it->first.c_str() << "]\n";
|
|
||||||
|
|
||||||
map<string, string>::iterator rec;
|
|
||||||
for (rec = sclass->entries.begin();rec != sclass->entries.end();rec++)
|
|
||||||
{
|
|
||||||
cfg << rec->first.c_str() << "=" << rec->second.c_str() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg << "\n";
|
|
||||||
}
|
|
||||||
cfg.close();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::~Settings()
|
|
||||||
{
|
|
||||||
map<string, SettingClass*>::iterator it;
|
|
||||||
for (it = this->classes.begin();it != this->classes.end();it++)
|
|
||||||
{
|
|
||||||
SettingClass *sc = it->second;
|
|
||||||
delete sc;
|
|
||||||
}
|
|
||||||
this->classes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
string Settings::get (const string classN, const string name)
|
|
||||||
{
|
|
||||||
SettingClass *c;
|
|
||||||
|
|
||||||
c = this->getClass(classN);
|
|
||||||
if (c == NULL)
|
|
||||||
return "";
|
|
||||||
return c->get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::set (const string classN, const string name, const string value)
|
|
||||||
{
|
|
||||||
SettingClass *c;
|
|
||||||
|
|
||||||
if (classN == "" || name == "" || value == "")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
c = this->getClass (classN);
|
|
||||||
|
|
||||||
if (c == NULL)
|
|
||||||
{
|
|
||||||
c = new SettingClass(classN);
|
|
||||||
this->classes.insert(pair<string, SettingClass*>(classN, c));
|
|
||||||
}
|
|
||||||
|
|
||||||
return c->set (name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::SettingClass::SettingClass(const string cn)
|
|
||||||
{
|
|
||||||
this->className = cn;
|
|
||||||
}
|
|
||||||
|
|
||||||
string Settings::SettingClass::get (const string& name)
|
|
||||||
{
|
|
||||||
if (this->entries.find(name) == this->entries.end())
|
|
||||||
return "";
|
|
||||||
return this->entries[name];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int _isTrue (string str)
|
|
||||||
{
|
|
||||||
int i, // loop index
|
|
||||||
len; // string's length
|
|
||||||
|
|
||||||
if (str == "")
|
|
||||||
return -1;
|
|
||||||
len = str.length();
|
|
||||||
for (i = 0;i < len;i++)
|
|
||||||
{
|
|
||||||
if (str[i] >= 'A' && str[i] <= 'Z')
|
|
||||||
{
|
|
||||||
str[i] = (str[i] - 'A' + 'a');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (str.compare ("yes") == 0)
|
|
||||||
return 1;
|
|
||||||
if (str.compare ("no") == 0)
|
|
||||||
return 0;
|
|
||||||
if (str.compare("true") == 0)
|
|
||||||
return 1;
|
|
||||||
if (str.compare ("false") == 0)
|
|
||||||
return 0;
|
|
||||||
if (str.compare("1") == 0)
|
|
||||||
return 1;
|
|
||||||
if (str.compare ("0") == 0)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::SettingClass::getBool(const string& name)
|
|
||||||
{
|
|
||||||
string v = this->get(name);
|
|
||||||
int r = _isTrue(v);
|
|
||||||
if (r == 0 || r == 1)
|
|
||||||
return (bool)r;
|
|
||||||
throw SettingsException("Invalid boolean value.");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::SettingClass::getBool (const string& key, bool defaultValue)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return this->getBool(key);
|
|
||||||
} catch (SettingsException &e)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::SettingClass::getIPs (const string& key, list<SOCKADDR_IN> &ip)
|
|
||||||
{
|
|
||||||
string v = this->get(key) + " "; // add padding for last entry.
|
|
||||||
// expect a.b.c.d[:port], IPv4 only supported with BEP-15.
|
|
||||||
|
|
||||||
string::size_type s, e;
|
|
||||||
s = e = 0;
|
|
||||||
char c;
|
|
||||||
for (string::size_type i = 0;i < v.length();i++)
|
|
||||||
{
|
|
||||||
c = v[i];
|
|
||||||
if (isspace(c) != 0 || c == ';' || c == ',')
|
|
||||||
{
|
|
||||||
if (s == e)
|
|
||||||
s = e = i;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string addr = v.substr(s, (e - s) + 1);
|
|
||||||
SOCKADDR_IN saddr;
|
|
||||||
memset(&saddr, 0, sizeof (SOCKADDR_IN));
|
|
||||||
saddr.sin_family = AF_INET;
|
|
||||||
saddr.sin_addr.s_addr = 0L;
|
|
||||||
saddr.sin_port = (6969);
|
|
||||||
|
|
||||||
{
|
|
||||||
uint8_t b; // temporary container for IP byte
|
|
||||||
uint16_t port;
|
|
||||||
uint32_t ip;
|
|
||||||
unsigned i, // loop index
|
|
||||||
stage; // 0,1,2,3=IP[a.b.c.d], 4=port
|
|
||||||
|
|
||||||
ip = 0;
|
|
||||||
b = 0;
|
|
||||||
stage = 0;
|
|
||||||
for (i = 0;i < addr.length();i++)
|
|
||||||
{
|
|
||||||
if (addr[i] >= '0' && addr[i] <= '9')
|
|
||||||
{
|
|
||||||
if (stage <= 3)
|
|
||||||
{
|
|
||||||
b *= 10;
|
|
||||||
b += (addr[i] - '0');
|
|
||||||
}
|
|
||||||
else if (stage == 4)
|
|
||||||
{
|
|
||||||
port *= 10;
|
|
||||||
port += (addr[i] - '0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (addr[i] == '.' && stage < 3)
|
|
||||||
{
|
|
||||||
stage ++;
|
|
||||||
ip *= 256;
|
|
||||||
ip += b;
|
|
||||||
b = 0;
|
|
||||||
}
|
|
||||||
else if (addr[i] == ':')
|
|
||||||
{
|
|
||||||
stage++;
|
|
||||||
port = 0;
|
|
||||||
|
|
||||||
ip *= 256;
|
|
||||||
ip += b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stage == 3) // port not provided.
|
|
||||||
{
|
|
||||||
port = 6969;
|
|
||||||
// add last byte.
|
|
||||||
ip *= 256;
|
|
||||||
ip += b;
|
|
||||||
}
|
|
||||||
saddr.sin_addr.s_addr = m_hton32(ip);
|
|
||||||
saddr.sin_port = m_hton16(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
ip.push_back(saddr);
|
|
||||||
|
|
||||||
s = e = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Settings::SettingClass::getInt (const string& key, int def)
|
|
||||||
{
|
|
||||||
string v = this->get (key);
|
|
||||||
if (v.length() == 0)
|
|
||||||
return def;
|
|
||||||
return std::atoi(v.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
map<string, string>* Settings::SettingClass::getMap()
|
|
||||||
{
|
|
||||||
return &this->entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Settings::SettingClass::set (const string name, const string value)
|
|
||||||
{
|
|
||||||
pair<map<string, string>::iterator, bool> r;
|
|
||||||
r = this->entries.insert(pair<string, string>(name, value));
|
|
||||||
if (!r.second)
|
|
||||||
{
|
|
||||||
r.first->second = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
121
src/settings.hpp
121
src/settings.hpp
|
@ -1,121 +0,0 @@
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Copyright © 2012-2016 Naim A.
|
|
||||||
*
|
|
||||||
* This file is part of UDPT.
|
|
||||||
*
|
|
||||||
* UDPT is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* UDPT is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with UDPT. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
#include "multiplatform.h"
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace UDPT
|
|
||||||
{
|
|
||||||
class Settings
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class SettingsException : public std::exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SettingsException (const char *str)
|
|
||||||
{
|
|
||||||
this->str = str;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * what ()
|
|
||||||
{
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char *str;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SettingClass
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SettingClass (const string className);
|
|
||||||
bool set (const string key, const string value);
|
|
||||||
string get (const string& key);
|
|
||||||
bool getBool (const string& key);
|
|
||||||
bool getBool (const string& key, bool defaultValue);
|
|
||||||
int getInt (const string& key, int def = -1);
|
|
||||||
map<string, string>* getMap ();
|
|
||||||
void getIPs (const string& key, list<SOCKADDR_IN> &ip);
|
|
||||||
private:
|
|
||||||
friend class Settings;
|
|
||||||
string className;
|
|
||||||
map<string, string> entries;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the settings type.
|
|
||||||
* @param filename the settings filename.
|
|
||||||
*/
|
|
||||||
Settings (const string filename);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a setting from a Settings type.
|
|
||||||
* @param class The class of the requested setting.
|
|
||||||
* @param name The name of the requested setting.
|
|
||||||
* @return The value for the requested setting, NULL if not available.
|
|
||||||
*/
|
|
||||||
SettingClass* getClass (const string name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads settings from file
|
|
||||||
* @return true on success, otherwise false.
|
|
||||||
*/
|
|
||||||
bool load ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves settings to file.
|
|
||||||
* @return true on success; otherwise false.
|
|
||||||
*/
|
|
||||||
bool save ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a setting in a settings type.
|
|
||||||
* @param className The class of the setting.
|
|
||||||
* @param key The name of the setting.
|
|
||||||
* @param value The value to set for the setting.
|
|
||||||
* @return true on success, otherwise false.
|
|
||||||
*/
|
|
||||||
bool set (const string className, const string key, const string value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the requested SettingClass.
|
|
||||||
* @param classname The name of the class to find (case sensitive).
|
|
||||||
* @return a pointer to the found class, or NULL if not found.
|
|
||||||
*/
|
|
||||||
string get (const string className, const string key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroys the settings "object"
|
|
||||||
*/
|
|
||||||
virtual ~Settings ();
|
|
||||||
private:
|
|
||||||
string filename;
|
|
||||||
map<string, SettingClass*> classes;
|
|
||||||
|
|
||||||
void parseSettings (char *data, int len);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -17,19 +17,19 @@
|
||||||
* along with UDPT. If not, see <http://www.gnu.org/licenses/>.
|
* along with UDPT. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "udpTracker.hpp"
|
|
||||||
#include "tools.h"
|
|
||||||
#include <cstdlib> // atoi
|
#include <cstdlib> // atoi
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <list>
|
||||||
|
#include "udpTracker.hpp"
|
||||||
|
#include "tools.h"
|
||||||
#include "multiplatform.h"
|
#include "multiplatform.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
extern UDPT::Logger *logger;
|
extern UDPT::Logger *logger;
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace UDPT::Data;
|
using namespace UDPT::Data;
|
||||||
|
|
||||||
#define UDP_BUFFER_SIZE 2048
|
#define UDP_BUFFER_SIZE 2048
|
||||||
|
@ -39,146 +39,146 @@ namespace UDPT
|
||||||
UDPTracker::UDPTracker(const boost::program_options::variables_map& conf) : m_conf(conf)
|
UDPTracker::UDPTracker(const boost::program_options::variables_map& conf) : m_conf(conf)
|
||||||
{
|
{
|
||||||
|
|
||||||
this->allowRemotes = conf["tracker.allow_remotes"].as<bool>();
|
this->m_allowRemotes = conf["tracker.allow_remotes"].as<bool>();
|
||||||
this->allowIANA_IPs = conf["tracker.allow_iana_ips"].as<bool>();
|
this->m_allowIANA_IPs = conf["tracker.allow_iana_ips"].as<bool>();
|
||||||
this->isDynamic = conf["tracker.is_dynamic"].as<bool>();
|
this->m_isDynamic = conf["tracker.is_dynamic"].as<bool>();
|
||||||
|
|
||||||
this->announce_interval = conf["tracker.announce_interval"].as<unsigned>();
|
this->m_announceInterval = conf["tracker.announce_interval"].as<unsigned>();
|
||||||
this->cleanup_interval = conf["tracker.cleanup_interval"].as<unsigned>();
|
this->m_cleanupInterval = conf["tracker.cleanup_interval"].as<unsigned>();
|
||||||
this->port = conf["tracker.port"].as<unsigned short>();
|
this->m_port = conf["tracker.port"].as<unsigned short>();
|
||||||
this->thread_count = conf["tracker.threads"].as<unsigned>() + 1;
|
this->m_threadCount = conf["tracker.threads"].as<unsigned>() + 1;
|
||||||
|
|
||||||
list<SOCKADDR_IN> addrs;
|
std::list<SOCKADDR_IN> addrs;
|
||||||
|
|
||||||
if (addrs.empty())
|
if (addrs.empty())
|
||||||
{
|
{
|
||||||
SOCKADDR_IN sa;
|
SOCKADDR_IN sa;
|
||||||
sa.sin_port = m_hton16(port);
|
sa.sin_port = m_hton16(m_port);
|
||||||
sa.sin_addr.s_addr = 0L;
|
sa.sin_addr.s_addr = 0L;
|
||||||
addrs.push_back(sa);
|
addrs.push_back(sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->localEndpoint = addrs.front();
|
this->m_localEndpoint = addrs.front();
|
||||||
|
|
||||||
|
|
||||||
this->threads = new HANDLE[this->thread_count];
|
this->m_threads = new HANDLE[this->m_threadCount];
|
||||||
|
|
||||||
this->isRunning = false;
|
this->m_isRunning = false;
|
||||||
this->conn = NULL;
|
this->conn = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPTracker::~UDPTracker ()
|
UDPTracker::~UDPTracker()
|
||||||
{
|
{
|
||||||
int i; // loop index
|
int i; // loop index
|
||||||
|
|
||||||
this->isRunning = false;
|
this->m_isRunning = false;
|
||||||
|
|
||||||
// drop listener connection to continue thread loops.
|
// drop listener connection to continue thread loops.
|
||||||
// wait for request to finish (1 second max; allot of time for a computer!).
|
// wait for request to finish (1 second max; allot of time for a computer!).
|
||||||
|
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
close (this->sock);
|
::close(this->m_sock);
|
||||||
|
|
||||||
sleep (1);
|
::sleep(1);
|
||||||
#elif defined (WIN32)
|
#elif defined (WIN32)
|
||||||
closesocket (this->sock);
|
::closesocket(this->m_sock);
|
||||||
|
|
||||||
Sleep (1000);
|
::Sleep(1000);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0;i < this->thread_count;i++)
|
for (i = 0;i < this->m_threadCount;i++)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
TerminateThread (this->threads[i], 0x00);
|
::TerminateThread(this->m_threads[i], 0x00);
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
pthread_detach (this->threads[i]);
|
::pthread_detach(this->m_threads[i]);
|
||||||
pthread_cancel (this->threads[i]);
|
::pthread_cancel(this->m_threads[i]);
|
||||||
#endif
|
#endif
|
||||||
stringstream str;
|
std::stringstream str;
|
||||||
str << "Thread (" << (i + 1) << "/" << ((int)this->thread_count) << ") terminated.";
|
str << "Thread (" << (i + 1) << "/" << ((int)this->m_threadCount) << ") terminated.";
|
||||||
logger->log(Logger::LL_INFO, str.str());
|
logger->log(Logger::LL_INFO, str.str());
|
||||||
}
|
}
|
||||||
if (this->conn != NULL)
|
if (this->conn != NULL)
|
||||||
delete this->conn;
|
delete this->conn;
|
||||||
delete[] this->threads;
|
delete[] this->m_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPTracker::wait()
|
void UDPTracker::wait()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WaitForMultipleObjects(this->thread_count, this->threads, TRUE, INFINITE);
|
WaitForMultipleObjects(this->m_threadCount, this->m_threads, TRUE, INFINITE);
|
||||||
#else
|
#else
|
||||||
int i;
|
int i;
|
||||||
for (i = 0;i < this->thread_count; i++)
|
for (i = 0;i < this->m_threadCount; i++)
|
||||||
{
|
{
|
||||||
pthread_join (this->threads[i], NULL);
|
pthread_join (this->m_threads[i], NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
enum UDPTracker::StartStatus UDPTracker::start ()
|
void UDPTracker::start()
|
||||||
{
|
{
|
||||||
stringstream ss;
|
std::stringstream ss;
|
||||||
SOCKET sock;
|
SOCKET sock;
|
||||||
int r, // saves results
|
int r, // saves results
|
||||||
i, // loop index
|
i, // loop index
|
||||||
yup; // just to set TRUE
|
yup; // just to set TRUE
|
||||||
string dbname;// saves the Database name.
|
std::string dbname;// saves the Database name.
|
||||||
|
|
||||||
sock = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sock = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (sock == INVALID_SOCKET)
|
if (sock == INVALID_SOCKET)
|
||||||
return START_ESOCKET_FAILED;
|
{
|
||||||
|
throw UDPT::UDPTException("Failed to create socket");
|
||||||
|
}
|
||||||
|
|
||||||
yup = 1;
|
yup = 1;
|
||||||
::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&yup, 1);
|
::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&yup, 1);
|
||||||
|
|
||||||
this->localEndpoint.sin_family = AF_INET;
|
this->m_localEndpoint.sin_family = AF_INET;
|
||||||
r = ::bind(sock, (SOCKADDR*)&this->localEndpoint, sizeof(SOCKADDR_IN));
|
r = ::bind(sock, reinterpret_cast<SOCKADDR*>(&this->m_localEndpoint), sizeof(SOCKADDR_IN));
|
||||||
|
|
||||||
if (r == SOCKET_ERROR)
|
if (r == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
closesocket (sock);
|
::closesocket(sock);
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
close (sock);
|
::close(sock);
|
||||||
#endif
|
#endif
|
||||||
return START_EBIND_FAILED;
|
throw UDPT::UDPTException("Failed to bind socket.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->sock = sock;
|
this->m_sock = sock;
|
||||||
|
|
||||||
this->conn = new Data::SQLite3Driver(m_conf, this->isDynamic);
|
this->conn = new Data::SQLite3Driver(m_conf, this->m_isDynamic);
|
||||||
|
|
||||||
this->isRunning = true;
|
this->m_isRunning = true;
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "Starting maintenance thread (1/" << ((int)this->thread_count) << ")";
|
ss << "Starting maintenance thread (1/" << ((int)this->m_threadCount) << ")";
|
||||||
logger->log(Logger::LL_INFO, ss.str());
|
logger->log(Logger::LL_INFO, ss.str());
|
||||||
|
|
||||||
// create maintainer thread.
|
// create maintainer thread.
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
this->threads[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_maintainance_start, (LPVOID)this, 0, NULL);
|
this->m_threads[0] = ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(_maintainance_start), (LPVOID)this, 0, NULL);
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
pthread_create (&this->threads[0], NULL, _maintainance_start, (void*)this);
|
::pthread_create (&this->m_threads[0], NULL, _maintainance_start, (void*)this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 1;i < this->thread_count; i++)
|
for (i = 1;i < this->m_threadCount; i++)
|
||||||
{
|
{
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss << "Starting thread (" << (i + 1) << "/" << ((int)this->thread_count) << ")";
|
ss << "Starting thread (" << (i + 1) << "/" << ((int)this->m_threadCount) << ")";
|
||||||
logger->log(Logger::LL_INFO, ss.str());
|
logger->log(Logger::LL_INFO, ss.str());
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
this->threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_thread_start, (LPVOID)this, 0, NULL);
|
this->m_threads[i] = ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(_thread_start), (LPVOID)this, 0, NULL);
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
pthread_create (&(this->threads[i]), NULL, _thread_start, (void*)this);
|
::pthread_create (&(this->m_threads[i]), NULL, _thread_start, (void*)this);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return START_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPTracker::sendError (UDPTracker *usi, SOCKADDR_IN *remote, uint32_t transactionID, const string &msg)
|
int UDPTracker::sendError(UDPTracker* usi, SOCKADDR_IN* remote, uint32_t transactionID, const std::string &msg)
|
||||||
{
|
{
|
||||||
struct udp_error_response error;
|
struct udp_error_response error;
|
||||||
int msg_sz, // message size to send.
|
int msg_sz, // message size to send.
|
||||||
|
@ -195,24 +195,22 @@ namespace UDPT
|
||||||
if (msg_sz > 1024)
|
if (msg_sz > 1024)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(buff, &error, 8);
|
::memcpy(buff, &error, 8);
|
||||||
for (i = 8;i <= msg_sz;i++)
|
for (i = 8;i <= msg_sz;i++)
|
||||||
{
|
{
|
||||||
buff[i] = msg[i - 8];
|
buff[i] = msg[i - 8];
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto(usi->sock, buff, msg_sz, 0, (SOCKADDR*)remote, sizeof(*remote));
|
::sendto(usi->m_sock, buff, msg_sz, 0, reinterpret_cast<SOCKADDR*>(remote), sizeof(*remote));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPTracker::handleConnection (UDPTracker *usi, SOCKADDR_IN *remote, char *data)
|
int UDPTracker::handleConnection(UDPTracker *usi, SOCKADDR_IN *remote, char *data)
|
||||||
{
|
{
|
||||||
ConnectionRequest *req;
|
ConnectionRequest *req = reinterpret_cast<ConnectionRequest*>(data);
|
||||||
ConnectionResponse resp;
|
ConnectionResponse resp;
|
||||||
|
|
||||||
req = (ConnectionRequest*)data;
|
|
||||||
|
|
||||||
resp.action = m_hton32(0);
|
resp.action = m_hton32(0);
|
||||||
resp.transaction_id = req->transaction_id;
|
resp.transaction_id = req->transaction_id;
|
||||||
|
|
||||||
|
@ -223,7 +221,7 @@ namespace UDPT
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto(usi->sock, (char*)&resp, sizeof(ConnectionResponse), 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
::sendto(usi->m_sock, (char*)&resp, sizeof(ConnectionResponse), 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -258,7 +256,7 @@ namespace UDPT
|
||||||
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->allowRemotes && req->ip_address != 0)
|
if (!usi->m_allowRemotes && req->ip_address != 0)
|
||||||
{
|
{
|
||||||
UDPTracker::sendError (usi, remote, req->transaction_id, "Tracker doesn't allow remote IP's; Request ignored.");
|
UDPTracker::sendError (usi, remote, req->transaction_id, "Tracker doesn't allow remote IP's; Request ignored.");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -309,7 +307,7 @@ namespace UDPT
|
||||||
|
|
||||||
resp = (AnnounceResponse*)buff;
|
resp = (AnnounceResponse*)buff;
|
||||||
resp->action = m_hton32(1);
|
resp->action = m_hton32(1);
|
||||||
resp->interval = m_hton32 ( usi->announce_interval );
|
resp->interval = m_hton32 ( usi->m_announceInterval );
|
||||||
resp->leechers = m_hton32(tE.leechers);
|
resp->leechers = m_hton32(tE.leechers);
|
||||||
resp->seeders = m_hton32 (tE.seeders);
|
resp->seeders = m_hton32 (tE.seeders);
|
||||||
resp->transaction_id = req->transaction_id;
|
resp->transaction_id = req->transaction_id;
|
||||||
|
@ -331,7 +329,7 @@ namespace UDPT
|
||||||
|
|
||||||
}
|
}
|
||||||
delete[] peers;
|
delete[] peers;
|
||||||
sendto(usi->sock, (char*)buff, bSize, 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
::sendto(usi->m_sock, (char*)buff, bSize, 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
||||||
|
|
||||||
// update DB.
|
// update DB.
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
|
@ -345,9 +343,9 @@ namespace UDPT
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UDPTracker::handleScrape (UDPTracker *usi, SOCKADDR_IN *remote, char *data, int len)
|
int UDPTracker::handleScrape(UDPTracker *usi, SOCKADDR_IN *remote, char *data, int len)
|
||||||
{
|
{
|
||||||
ScrapeRequest *sR;
|
ScrapeRequest *sR = reinterpret_cast<ScrapeRequest*>(data);
|
||||||
int v, // validation helper
|
int v, // validation helper
|
||||||
c, // torrent counter
|
c, // torrent counter
|
||||||
i, // loop counter
|
i, // loop counter
|
||||||
|
@ -356,14 +354,11 @@ namespace UDPT
|
||||||
ScrapeResponse *resp;
|
ScrapeResponse *resp;
|
||||||
uint8_t buffer [1024]; // up to 74 torrents can be scraped at once (17*74+8) < 1024
|
uint8_t buffer [1024]; // up to 74 torrents can be scraped at once (17*74+8) < 1024
|
||||||
|
|
||||||
|
|
||||||
sR = (ScrapeRequest*)data;
|
|
||||||
|
|
||||||
// validate request length:
|
// validate request length:
|
||||||
v = len - 16;
|
v = len - 16;
|
||||||
if (v < 0 || v % 20 != 0)
|
if (v < 0 || v % 20 != 0)
|
||||||
{
|
{
|
||||||
UDPTracker::sendError (usi, remote, sR->transaction_id, "Bad scrape request.");
|
UDPTracker::sendError(usi, remote, sR->transaction_id, "Bad scrape request.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,8 +372,8 @@ namespace UDPT
|
||||||
// get torrent count.
|
// get torrent count.
|
||||||
c = v / 20;
|
c = v / 20;
|
||||||
|
|
||||||
resp = (ScrapeResponse*)buffer;
|
resp = reinterpret_cast<ScrapeResponse*>(buffer);
|
||||||
resp->action = m_hton32 (2);
|
resp->action = m_hton32(2);
|
||||||
resp->transaction_id = sR->transaction_id;
|
resp->transaction_id = sR->transaction_id;
|
||||||
|
|
||||||
for (i = 0;i < c;i++)
|
for (i = 0;i < c;i++)
|
||||||
|
@ -402,12 +397,12 @@ namespace UDPT
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*seeders = m_hton32 (tE.seeders);
|
*seeders = m_hton32(tE.seeders);
|
||||||
*completed = m_hton32 (tE.completed);
|
*completed = m_hton32(tE.completed);
|
||||||
*leechers = m_hton32 (tE.leechers);
|
*leechers = m_hton32(tE.leechers);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto (usi->sock, (const char*)buffer, sizeof(buffer), 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
::sendto(usi->m_sock, reinterpret_cast<const char*>(buffer), sizeof(buffer), 0, reinterpret_cast<SOCKADDR*>(remote), sizeof(SOCKADDR_IN));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -422,14 +417,12 @@ static int _isIANA_IP (uint32_t ip)
|
||||||
|
|
||||||
int UDPTracker::resolveRequest (UDPTracker *usi, SOCKADDR_IN *remote, char *data, int r)
|
int UDPTracker::resolveRequest (UDPTracker *usi, SOCKADDR_IN *remote, char *data, int r)
|
||||||
{
|
{
|
||||||
ConnectionRequest *cR;
|
ConnectionRequest* cR = reinterpret_cast<ConnectionRequest*>(data);
|
||||||
uint32_t action;
|
uint32_t action;
|
||||||
|
|
||||||
cR = (ConnectionRequest*)data;
|
|
||||||
|
|
||||||
action = m_hton32(cR->action);
|
action = m_hton32(cR->action);
|
||||||
|
|
||||||
if (!usi->allowIANA_IPs)
|
if (!usi->m_allowIANA_IPs)
|
||||||
{
|
{
|
||||||
if (_isIANA_IP (remote->sin_addr.s_addr))
|
if (_isIANA_IP (remote->sin_addr.s_addr))
|
||||||
{
|
{
|
||||||
|
@ -438,14 +431,14 @@ static int _isIANA_IP (uint32_t ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == 0 && r >= 16)
|
if (action == 0 && r >= 16)
|
||||||
return UDPTracker::handleConnection (usi, remote, data);
|
return UDPTracker::handleConnection(usi, remote, data);
|
||||||
else if (action == 1 && r >= 98)
|
else if (action == 1 && r >= 98)
|
||||||
return UDPTracker::handleAnnounce (usi, remote, data);
|
return UDPTracker::handleAnnounce(usi, remote, data);
|
||||||
else if (action == 2)
|
else if (action == 2)
|
||||||
return UDPTracker::handleScrape (usi, remote, data, r);
|
return UDPTracker::handleScrape(usi, remote, data, r);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UDPTracker::sendError (usi, remote, cR->transaction_id, "Tracker couldn't understand Client's request.");
|
UDPTracker::sendError(usi, remote, cR->transaction_id, "Tracker couldn't understand Client's request.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,47 +461,44 @@ static int _isIANA_IP (uint32_t ip)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
char tmpBuff [UDP_BUFFER_SIZE];
|
char tmpBuff[UDP_BUFFER_SIZE];
|
||||||
|
|
||||||
usi = (UDPTracker*)arg;
|
usi = reinterpret_cast<UDPTracker*>(arg);
|
||||||
|
|
||||||
addrSz = sizeof (SOCKADDR_IN);
|
addrSz = sizeof(SOCKADDR_IN);
|
||||||
|
|
||||||
|
|
||||||
while (usi->isRunning)
|
while (usi->m_isRunning)
|
||||||
{
|
{
|
||||||
cout.flush();
|
|
||||||
// peek into the first 12 bytes of data; determine if connection request or announce request.
|
// peek into the first 12 bytes of data; determine if connection request or announce request.
|
||||||
r = recvfrom(usi->sock, (char*)tmpBuff, UDP_BUFFER_SIZE, 0, (SOCKADDR*)&remoteAddr, &addrSz);
|
r = ::recvfrom(usi->m_sock, (char*)tmpBuff, UDP_BUFFER_SIZE, 0, (SOCKADDR*)&remoteAddr, &addrSz);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
continue; // bad request...
|
continue; // bad request...
|
||||||
r = UDPTracker::resolveRequest (usi, &remoteAddr, tmpBuff, r);
|
r = UDPTracker::resolveRequest(usi, &remoteAddr, tmpBuff, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
pthread_exit (NULL);
|
::pthread_exit (NULL);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
DWORD UDPTracker::_maintainance_start (LPVOID arg)
|
DWORD UDPTracker::_maintainance_start(LPVOID arg)
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
void* UDPTracker::_maintainance_start (void *arg)
|
void* UDPTracker::_maintainance_start(void *arg)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
UDPTracker *usi;
|
UDPTracker* usi = reinterpret_cast<UDPTracker*>(arg);
|
||||||
|
|
||||||
usi = (UDPTracker *)arg;
|
while (usi->m_isRunning)
|
||||||
|
|
||||||
while (usi->isRunning)
|
|
||||||
{
|
{
|
||||||
usi->conn->cleanup();
|
usi->conn->cleanup();
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
Sleep (usi->cleanup_interval * 1000);
|
::Sleep(usi->m_cleanupInterval * 1000);
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
sleep (usi->cleanup_interval);
|
::sleep(usi->m_cleanupInterval);
|
||||||
#else
|
#else
|
||||||
#error Unsupported OS.
|
#error Unsupported OS.
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,18 +22,16 @@
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <boost/program_options.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include "exceptions.h"
|
||||||
#include "multiplatform.h"
|
#include "multiplatform.h"
|
||||||
#include "db/driver_sqlite.hpp"
|
#include "db/driver_sqlite.hpp"
|
||||||
#include "settings.hpp"
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
#define UDPT_DYNAMIC (0x01) // Track Any info_hash?
|
||||||
using namespace std;
|
#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_DYNAMIC 0x01 // Track Any info_hash?
|
#define UDPT_VALIDATE_CLIENT (0x08) // validate client before adding to Database? (check if connection is open?)
|
||||||
#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?)
|
|
||||||
|
|
||||||
|
|
||||||
namespace UDPT
|
namespace UDPT
|
||||||
|
@ -122,52 +120,51 @@ namespace UDPT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the Initialized instance.
|
* Starts the Initialized instance.
|
||||||
* @return 0 on success, otherwise non-zero.
|
|
||||||
*/
|
*/
|
||||||
enum StartStatus start ();
|
void start();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Joins all threads, and waits for all of them to terminate.
|
* Joins all threads, and waits for all of them to terminate.
|
||||||
*/
|
*/
|
||||||
void wait ();
|
void wait();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys resources that were created by constructor
|
* Destroys resources that were created by constructor
|
||||||
* @param usi Instance to destroy.
|
* @param usi Instance to destroy.
|
||||||
*/
|
*/
|
||||||
virtual ~UDPTracker ();
|
virtual ~UDPTracker();
|
||||||
|
|
||||||
Data::DatabaseDriver *conn;
|
Data::DatabaseDriver *conn;
|
||||||
private:
|
private:
|
||||||
SOCKET sock;
|
SOCKET m_sock;
|
||||||
SOCKADDR_IN localEndpoint;
|
SOCKADDR_IN m_localEndpoint;
|
||||||
uint16_t port;
|
uint16_t m_port;
|
||||||
uint8_t thread_count;
|
uint8_t m_threadCount;
|
||||||
bool isRunning;
|
bool m_isRunning;
|
||||||
bool isDynamic;
|
bool m_isDynamic;
|
||||||
bool allowRemotes;
|
bool m_allowRemotes;
|
||||||
bool allowIANA_IPs;
|
bool m_allowIANA_IPs;
|
||||||
HANDLE *threads;
|
HANDLE *m_threads;
|
||||||
uint32_t announce_interval;
|
uint32_t m_announceInterval;
|
||||||
uint32_t cleanup_interval;
|
uint32_t m_cleanupInterval;
|
||||||
|
|
||||||
const boost::program_options::variables_map& m_conf;
|
const boost::program_options::variables_map& m_conf;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static DWORD _thread_start (LPVOID arg);
|
static DWORD _thread_start(LPVOID arg);
|
||||||
static DWORD _maintainance_start (LPVOID arg);
|
static DWORD _maintainance_start(LPVOID arg);
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
static void* _thread_start (void *arg);
|
static void* _thread_start(void *arg);
|
||||||
static void* _maintainance_start (void *arg);
|
static void* _maintainance_start(void *arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int resolveRequest (UDPTracker *usi, SOCKADDR_IN *remote, char *data, int r);
|
static int resolveRequest(UDPTracker *usi, SOCKADDR_IN *remote, char *data, int r);
|
||||||
|
|
||||||
static int handleConnection (UDPTracker *usi, SOCKADDR_IN *remote, char *data);
|
static int handleConnection(UDPTracker *usi, SOCKADDR_IN *remote, char *data);
|
||||||
static int handleAnnounce (UDPTracker *usi, SOCKADDR_IN *remote, char *data);
|
static int handleAnnounce(UDPTracker *usi, SOCKADDR_IN *remote, char *data);
|
||||||
static int handleScrape (UDPTracker *usi, SOCKADDR_IN *remote, char *data, int len);
|
static int handleScrape(UDPTracker *usi, SOCKADDR_IN *remote, char *data, int len);
|
||||||
|
|
||||||
static int sendError (UDPTracker *, SOCKADDR_IN *remote, uint32_t transId, const string &);
|
static int sendError(UDPTracker *, SOCKADDR_IN *remote, uint32_t transId, const std::string &);
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue