Git changes...
This commit is contained in:
parent
ce247fc7d5
commit
7266aa2f5a
|
@ -38,7 +38,7 @@ int db_add_peer (dbConnection *, uint8_t [20], db_peerEntry*);
|
||||||
*/
|
*/
|
||||||
int db_load_peers (dbConnection *, uint8_t [20], db_peerEntry *lst, int *sZ);
|
int db_load_peers (dbConnection *, uint8_t [20], db_peerEntry *lst, int *sZ);
|
||||||
|
|
||||||
int db_get_stats (dbConnection *, uint8_t [20], uint32_t *seeders, uint32_t *leechers, uint32_t *completed);
|
int db_get_stats (dbConnection *, uint8_t [20], int32_t *seeders, int32_t *leechers, int32_t *completed);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates Stats, Removes expired data.
|
* Calculates Stats, Removes expired data.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "../multiplatform.h"
|
#include "../multiplatform.h"
|
||||||
|
#include "../tools.h"
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -11,7 +12,7 @@ struct dbConnection
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
HANDLE janitor;
|
HANDLE janitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char hexadecimal[] = "0123456789abcdef";
|
static const char hexadecimal[] = "0123456789abcdef";
|
||||||
|
|
||||||
void _to_hex_str (const uint8_t *hash, char *data)
|
void _to_hex_str (const uint8_t *hash, char *data)
|
||||||
|
@ -24,7 +25,7 @@ void _to_hex_str (const uint8_t *hash, char *data)
|
||||||
}
|
}
|
||||||
data[40] = '\0';
|
data[40] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _db_make_torrent_table (sqlite3 *db, char *hash)
|
static int _db_make_torrent_table (sqlite3 *db, char *hash)
|
||||||
{
|
{
|
||||||
char sql [2000];
|
char sql [2000];
|
||||||
|
@ -94,7 +95,7 @@ int db_add_peer (dbConnection *db, uint8_t info_hash[20], db_peerEntry *pE)
|
||||||
char xHash [50]; // we just need 40 + \0 = 41.
|
char xHash [50]; // we just need 40 + \0 = 41.
|
||||||
|
|
||||||
char *hash = xHash;
|
char *hash = xHash;
|
||||||
_to_hex_str(info_hash, hash);
|
to_hex_str(info_hash, hash);
|
||||||
|
|
||||||
_db_make_torrent_table(db->db, hash);
|
_db_make_torrent_table(db->db, hash);
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry *lst, i
|
||||||
sql[0] = '\0';
|
sql[0] = '\0';
|
||||||
|
|
||||||
char hash [50];
|
char hash [50];
|
||||||
_to_hex_str(info_hash, hash);
|
to_hex_str(info_hash, hash);
|
||||||
|
|
||||||
strcat(sql, "SELECT ip,port FROM 't");
|
strcat(sql, "SELECT ip,port FROM 't");
|
||||||
strcat(sql, hash);
|
strcat(sql, hash);
|
||||||
|
@ -176,7 +177,7 @@ int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry *lst, i
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int db_get_stats (dbConnection *db, uint8_t hash[20], uint32_t *seeders, uint32_t *leechers, uint32_t *completed)
|
int db_get_stats (dbConnection *db, uint8_t hash[20], int32_t *seeders, int32_t *leechers, int32_t *completed)
|
||||||
{
|
{
|
||||||
*seeders = 0;
|
*seeders = 0;
|
||||||
*leechers = 0;
|
*leechers = 0;
|
||||||
|
@ -217,7 +218,7 @@ int db_cleanup (dbConnection *db)
|
||||||
|
|
||||||
while (sqlite3_step(stmt) == SQLITE_ROW)
|
while (sqlite3_step(stmt) == SQLITE_ROW)
|
||||||
{
|
{
|
||||||
_to_hex_str(sqlite3_column_blob(stmt, 0), hash);
|
to_hex_str(sqlite3_column_blob(stmt, 0), hash);
|
||||||
|
|
||||||
// drop table:
|
// drop table:
|
||||||
strcpy(temp, "DROP TABLE IF EXISTS 't");
|
strcpy(temp, "DROP TABLE IF EXISTS 't");
|
||||||
|
@ -245,7 +246,7 @@ int db_cleanup (dbConnection *db)
|
||||||
while (sqlite3_step(stmt) == SQLITE_ROW)
|
while (sqlite3_step(stmt) == SQLITE_ROW)
|
||||||
{
|
{
|
||||||
uint8_t *binHash = sqlite3_column_blob(stmt, 0);
|
uint8_t *binHash = sqlite3_column_blob(stmt, 0);
|
||||||
_to_hex_str (binHash, hash);
|
to_hex_str (binHash, hash);
|
||||||
|
|
||||||
// total users...
|
// total users...
|
||||||
strcpy (temp, "SELECT COUNT(*) FROM 't");
|
strcpy (temp, "SELECT COUNT(*) FROM 't");
|
||||||
|
|
14
src/tools.c
14
src/tools.c
|
@ -30,3 +30,17 @@ uint32_t m_hton32 (uint32_t n)
|
||||||
m_byteswap (&r, &n, 4);
|
m_byteswap (&r, &n, 4);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char hexadecimal[] = "0123456789abcdef";
|
||||||
|
|
||||||
|
void to_hex_str (const uint8_t *hash, char *data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0;i < 20;i++)
|
||||||
|
{
|
||||||
|
data[i * 2] = hexadecimal[hash[i] / 16];
|
||||||
|
data[i * 2 + 1] = hexadecimal[hash[i] % 16];
|
||||||
|
}
|
||||||
|
data[40] = '\0';
|
||||||
|
}
|
||||||
|
|
|
@ -25,4 +25,6 @@ uint32_t m_hton32 (uint32_t n);
|
||||||
|
|
||||||
uint64_t m_hton64 (uint64_t n);
|
uint64_t m_hton64 (uint64_t n);
|
||||||
|
|
||||||
|
void to_hex_str (const uint8_t *hash, char *data);
|
||||||
|
|
||||||
#endif /* TOOLS_H_ */
|
#endif /* TOOLS_H_ */
|
||||||
|
|
138
src/udpTracker.c
138
src/udpTracker.c
|
@ -10,6 +10,7 @@
|
||||||
#define FLAG_RUNNING 0x01
|
#define FLAG_RUNNING 0x01
|
||||||
#define UDP_BUFFER_SIZE 2048
|
#define UDP_BUFFER_SIZE 2048
|
||||||
#define CLEANUP_INTERVAL 20
|
#define CLEANUP_INTERVAL 20
|
||||||
|
#define TRACKER_INTERVAL 60 // normally 1800
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static DWORD _thread_start (LPVOID arg);
|
static DWORD _thread_start (LPVOID arg);
|
||||||
|
@ -114,7 +115,6 @@ static int _send_error (udpServerInstance *usi, SOCKADDR_IN *remote, uint32_t tr
|
||||||
error.transaction_id = transactionID;
|
error.transaction_id = transactionID;
|
||||||
error.message = msg;
|
error.message = msg;
|
||||||
|
|
||||||
|
|
||||||
int msg_sz = 4 + 4 + 1 + strlen(msg);
|
int msg_sz = 4 + 4 + 1 + strlen(msg);
|
||||||
|
|
||||||
char buff [msg_sz];
|
char buff [msg_sz];
|
||||||
|
@ -125,7 +125,6 @@ static int _send_error (udpServerInstance *usi, SOCKADDR_IN *remote, uint32_t tr
|
||||||
buff[i] = msg[i - 8];
|
buff[i] = msg[i - 8];
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("ERROR SENT\n");
|
|
||||||
sendto(usi->sock, buff, msg_sz, 0, (SOCKADDR*)remote, sizeof(*remote));
|
sendto(usi->sock, buff, msg_sz, 0, (SOCKADDR*)remote, sizeof(*remote));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -145,30 +144,6 @@ static int _handle_connection (udpServerInstance *usi, SOCKADDR_IN *remote, char
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _is_good_peer (uint32_t ip, uint16_t port)
|
|
||||||
{
|
|
||||||
SOCKADDR_IN addr;
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
#ifdef WIN32
|
|
||||||
addr.sin_addr.S_un.S_addr = htonl( ip );
|
|
||||||
#elif defined (linux)
|
|
||||||
addr.sin_addr.s_addr = htonl( ip );
|
|
||||||
#endif
|
|
||||||
addr.sin_port = htons (port);
|
|
||||||
|
|
||||||
SOCKET cli = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
||||||
if (cli == INVALID_SOCKET)
|
|
||||||
return 1;
|
|
||||||
if (connect(cli, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
closesocket (cli);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf ("Client Verified.\n");
|
|
||||||
closesocket (cli);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _handle_announce (udpServerInstance *usi, SOCKADDR_IN *remote, char *data)
|
static int _handle_announce (udpServerInstance *usi, SOCKADDR_IN *remote, char *data)
|
||||||
{
|
{
|
||||||
AnnounceRequest *req = (AnnounceRequest*)data;
|
AnnounceRequest *req = (AnnounceRequest*)data;
|
||||||
|
@ -186,44 +161,28 @@ static int _handle_announce (udpServerInstance *usi, SOCKADDR_IN *remote, char *
|
||||||
req->uploaded = m_hton64 (req->uploaded);
|
req->uploaded = m_hton64 (req->uploaded);
|
||||||
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 (req->ip_address == 0) // default
|
|
||||||
{
|
|
||||||
req->ip_address = m_hton32 (remote->sin_addr.s_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (_is_good_peer(req->ip_address, req->port) != 0)
|
|
||||||
// {
|
|
||||||
// _send_error (usi, remote, req->transaction_id, "Couldn't verify your client.");
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// load peers
|
// load peers
|
||||||
int q = 30;
|
int q = 30;
|
||||||
if (req->num_want >= 1)
|
if (req->num_want >= 1)
|
||||||
q = min (q, req->num_want);
|
q = min (q, req->num_want);
|
||||||
|
|
||||||
db_peerEntry *peers = NULL;
|
db_peerEntry *peers = malloc (sizeof(db_peerEntry) * q);
|
||||||
|
|
||||||
|
db_load_peers(usi->conn, req->info_hash, peers, &q);
|
||||||
|
// printf("%d peers found.\n", q);
|
||||||
|
|
||||||
int bSize = 20; // header is 20 bytes
|
int bSize = 20; // header is 20 bytes
|
||||||
|
bSize += (6 * q); // + 6 bytes per peer.
|
||||||
|
|
||||||
if (req->event == 3) // stopped; they don't need anymore peers!
|
int32_t seeders, leechers, completed;
|
||||||
{
|
|
||||||
q = 0; // don't need any peers!
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
peers = malloc (sizeof(db_peerEntry) * q);
|
|
||||||
db_load_peers(usi->conn, req->info_hash, peers, &q);
|
|
||||||
}
|
|
||||||
|
|
||||||
bSize += (6 * q); // + 6 bytes per peer (ip->4, port->2).
|
|
||||||
|
|
||||||
uint32_t seeders, leechers, completed;
|
|
||||||
db_get_stats (usi->conn, req->info_hash, &seeders, &leechers, &completed);
|
db_get_stats (usi->conn, req->info_hash, &seeders, &leechers, &completed);
|
||||||
|
|
||||||
uint8_t buff [bSize];
|
uint8_t buff [bSize];
|
||||||
AnnounceResponse *resp = (AnnounceResponse*)buff;
|
AnnounceResponse *resp = (AnnounceResponse*)buff;
|
||||||
resp->action = m_hton32(1);
|
resp->action = m_hton32(1);
|
||||||
resp->interval = m_hton32 ( 1800 );
|
resp->interval = m_hton32 ( TRACKER_INTERVAL );
|
||||||
resp->leechers = m_hton32(leechers);
|
resp->leechers = m_hton32(leechers);
|
||||||
resp->seeders = m_hton32 (seeders);
|
resp->seeders = m_hton32 (seeders);
|
||||||
resp->transaction_id = req->transaction_id;
|
resp->transaction_id = req->transaction_id;
|
||||||
|
@ -246,29 +205,24 @@ static int _handle_announce (udpServerInstance *usi, SOCKADDR_IN *remote, char *
|
||||||
|
|
||||||
// printf("%u.%u.%u.%u:%u\n", buff[20 + x], buff[21 + x], buff[22 + x], buff[23 + x], peers[i].port);
|
// printf("%u.%u.%u.%u:%u\n", buff[20 + x], buff[21 + x], buff[22 + x], buff[23 + x], peers[i].port);
|
||||||
}
|
}
|
||||||
|
free (peers);
|
||||||
if (peers != NULL)
|
|
||||||
free (peers);
|
|
||||||
|
|
||||||
sendto(usi->sock, (char*)buff, bSize, 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
sendto(usi->sock, (char*)buff, bSize, 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
||||||
|
|
||||||
|
|
||||||
// Add peer to list:
|
// Add peer to list:
|
||||||
db_peerEntry pE;
|
db_peerEntry pE;
|
||||||
pE.downloaded = req->downloaded;
|
pE.downloaded = req->downloaded;
|
||||||
pE.uploaded = req->uploaded;
|
pE.uploaded = req->uploaded;
|
||||||
pE.left = req->left;
|
pE.left = req->left;
|
||||||
pE.peer_id = req->peer_id;
|
pE.peer_id = req->peer_id;
|
||||||
pE.ip = req->ip_address;
|
if (req->ip_address == 0) // default
|
||||||
pE.port = req->port;
|
|
||||||
|
|
||||||
if (req->event == 3) // stopped
|
|
||||||
{
|
{
|
||||||
// just remove client from swarm, and return empty peer list...
|
pE.ip = m_hton32 (remote->sin_addr.s_addr);
|
||||||
db_remove_peer(usi->conn, req->info_hash, &pE);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pE.ip = req->ip_address;
|
||||||
|
}
|
||||||
|
pE.port = req->port;
|
||||||
db_add_peer(usi->conn, req->info_hash, &pE);
|
db_add_peer(usi->conn, req->info_hash, &pE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -280,12 +234,52 @@ static int _handle_scrape (udpServerInstance *usi, SOCKADDR_IN *remote, char *da
|
||||||
|
|
||||||
// _send_error (usi, remote, sR->transaction_id, "Scrape wasn't implemented yet!");
|
// _send_error (usi, remote, sR->transaction_id, "Scrape wasn't implemented yet!");
|
||||||
|
|
||||||
ScrapeResponse resp;
|
// validate request length:
|
||||||
resp.resp_part = NULL;
|
int v = len - 16;
|
||||||
resp.action = 2;
|
if (v < 0 || v % 20 != 0)
|
||||||
resp.transaction_id = sR->transaction_id;
|
{
|
||||||
|
printf("BAD SCRAPE: len=%d\n", len);
|
||||||
|
_send_error (usi, remote, sR->transaction_id, "Bad scrape request.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
sendto (usi->sock, (const char*)&resp, 8, 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
// get torrent count.
|
||||||
|
int c = v / 20;
|
||||||
|
|
||||||
|
uint8_t hash [20];
|
||||||
|
char xHash [50];
|
||||||
|
|
||||||
|
uint8_t buffer [8 + (12 * c)];
|
||||||
|
ScrapeResponse *resp = (ScrapeResponse*)buffer;
|
||||||
|
resp->action = m_hton32 (2);
|
||||||
|
resp->transaction_id = sR->transaction_id;
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
printf("Scrape: (%d) \n", c);
|
||||||
|
for (i = 0;i < c;i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 20;j++)
|
||||||
|
hash[j] = data[j + (i*20)+16];
|
||||||
|
|
||||||
|
to_hex_str (hash, xHash);
|
||||||
|
|
||||||
|
printf("\t%s\n", xHash);
|
||||||
|
|
||||||
|
int32_t *seeders = (int32_t*)&buffer[i*12+8];
|
||||||
|
int32_t *completed = (int32_t*)&buffer[i*12+12];
|
||||||
|
int32_t *leechers = (int32_t*)&buffer[i*12+16];
|
||||||
|
|
||||||
|
int32_t s, c, l;
|
||||||
|
|
||||||
|
db_get_stats (usi->conn, hash, &s, &l, &c);
|
||||||
|
|
||||||
|
*seeders = m_hton32 (s);
|
||||||
|
*completed = m_hton32 (c);
|
||||||
|
*leechers = m_hton32 (l);
|
||||||
|
}
|
||||||
|
fflush (stdout);
|
||||||
|
|
||||||
|
sendto (usi->sock, buffer, sizeof(buffer), 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -297,7 +291,7 @@ static int _resolve_request (udpServerInstance *usi, SOCKADDR_IN *remote, char *
|
||||||
|
|
||||||
uint32_t action = m_hton32(cR->action);
|
uint32_t action = m_hton32(cR->action);
|
||||||
|
|
||||||
// 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)
|
||||||
return _handle_connection(usi, remote, data);
|
return _handle_connection(usi, remote, data);
|
||||||
|
@ -333,7 +327,9 @@ static void* _thread_start (void *arg)
|
||||||
{
|
{
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
// 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, tmpBuff, UDP_BUFFER_SIZE, 0, (SOCKADDR*)&remoteAddr, &addrSz);
|
r = recvfrom(usi->sock, tmpBuff, UDP_BUFFER_SIZE, 0, (SOCKADDR*)&remoteAddr, (unsigned*)&addrSz);
|
||||||
|
if (r <= 0)
|
||||||
|
continue; // bad request...
|
||||||
// printf("RECV:%d\n", r);
|
// printf("RECV:%d\n", r);
|
||||||
r = _resolve_request(usi, &remoteAddr, tmpBuff, r);
|
r = _resolve_request(usi, &remoteAddr, tmpBuff, r);
|
||||||
// printf("R=%d\n", r);
|
// printf("R=%d\n", r);
|
||||||
|
@ -345,7 +341,7 @@ static void* _thread_start (void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static DWORD _maintainance_start (LPVOID arg)
|
static DWORD _maintainance_start (LPVOID arg);
|
||||||
#elif defined (linux)
|
#elif defined (linux)
|
||||||
static void* _maintainance_start (void *arg)
|
static void* _maintainance_start (void *arg)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,20 +59,16 @@ struct udp_scrape_request
|
||||||
uint64_t connection_id;
|
uint64_t connection_id;
|
||||||
uint32_t action;
|
uint32_t action;
|
||||||
uint32_t transaction_id;
|
uint32_t transaction_id;
|
||||||
struct reqD {
|
|
||||||
uint8_t info_hash [20];
|
uint8_t *torrent_list_data;
|
||||||
} *req_part;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct udp_scrape_response
|
struct udp_scrape_response
|
||||||
{
|
{
|
||||||
uint32_t action;
|
uint32_t action;
|
||||||
uint32_t transaction_id;
|
uint32_t transaction_id;
|
||||||
struct respD {
|
|
||||||
uint32_t seeders;
|
uint8_t *data;
|
||||||
uint32_t completed;
|
|
||||||
uint32_t leechers;
|
|
||||||
} *resp_part;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct udp_error_response
|
struct udp_error_response
|
||||||
|
|
Loading…
Reference in a new issue