Git changes...

This commit is contained in:
Naim A 2012-11-27 16:01:40 +02:00
parent ce247fc7d5
commit 7266aa2f5a
6 changed files with 96 additions and 87 deletions

View file

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

View file

@ -1,5 +1,6 @@
#include "database.h"
#include "../multiplatform.h"
#include "../tools.h"
#include <sqlite3.h>
#include <stdlib.h>
#include <string.h>
@ -11,7 +12,7 @@ struct dbConnection
sqlite3 *db;
HANDLE janitor;
};
static const char hexadecimal[] = "0123456789abcdef";
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';
}
static int _db_make_torrent_table (sqlite3 *db, char *hash)
{
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 *hash = xHash;
_to_hex_str(info_hash, hash);
to_hex_str(info_hash, 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';
char hash [50];
_to_hex_str(info_hash, hash);
to_hex_str(info_hash, hash);
strcat(sql, "SELECT ip,port FROM 't");
strcat(sql, hash);
@ -176,7 +177,7 @@ int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry *lst, i
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;
*leechers = 0;
@ -217,7 +218,7 @@ int db_cleanup (dbConnection *db)
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:
strcpy(temp, "DROP TABLE IF EXISTS 't");
@ -245,7 +246,7 @@ int db_cleanup (dbConnection *db)
while (sqlite3_step(stmt) == SQLITE_ROW)
{
uint8_t *binHash = sqlite3_column_blob(stmt, 0);
_to_hex_str (binHash, hash);
to_hex_str (binHash, hash);
// total users...
strcpy (temp, "SELECT COUNT(*) FROM 't");

View file

@ -30,3 +30,17 @@ uint32_t m_hton32 (uint32_t n)
m_byteswap (&r, &n, 4);
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';
}

View file

@ -25,4 +25,6 @@ uint32_t m_hton32 (uint32_t n);
uint64_t m_hton64 (uint64_t n);
void to_hex_str (const uint8_t *hash, char *data);
#endif /* TOOLS_H_ */

View file

@ -10,6 +10,7 @@
#define FLAG_RUNNING 0x01
#define UDP_BUFFER_SIZE 2048
#define CLEANUP_INTERVAL 20
#define TRACKER_INTERVAL 60 // normally 1800
#ifdef WIN32
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.message = msg;
int msg_sz = 4 + 4 + 1 + strlen(msg);
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];
}
printf("ERROR SENT\n");
sendto(usi->sock, buff, msg_sz, 0, (SOCKADDR*)remote, sizeof(*remote));
return 0;
@ -145,30 +144,6 @@ static int _handle_connection (udpServerInstance *usi, SOCKADDR_IN *remote, char
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)
{
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->num_want = m_hton32 (req->num_want);
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
int q = 30;
if (req->num_want >= 1)
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
bSize += (6 * q); // + 6 bytes per peer.
if (req->event == 3) // stopped; they don't need anymore peers!
{
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;
int32_t seeders, leechers, completed;
db_get_stats (usi->conn, req->info_hash, &seeders, &leechers, &completed);
uint8_t buff [bSize];
AnnounceResponse *resp = (AnnounceResponse*)buff;
resp->action = m_hton32(1);
resp->interval = m_hton32 ( 1800 );
resp->interval = m_hton32 ( TRACKER_INTERVAL );
resp->leechers = m_hton32(leechers);
resp->seeders = m_hton32 (seeders);
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);
}
if (peers != NULL)
free (peers);
free (peers);
sendto(usi->sock, (char*)buff, bSize, 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
// Add peer to list:
db_peerEntry pE;
pE.downloaded = req->downloaded;
pE.uploaded = req->uploaded;
pE.left = req->left;
pE.peer_id = req->peer_id;
pE.ip = req->ip_address;
pE.port = req->port;
if (req->event == 3) // stopped
if (req->ip_address == 0) // default
{
// just remove client from swarm, and return empty peer list...
db_remove_peer(usi->conn, req->info_hash, &pE);
return 0;
pE.ip = m_hton32 (remote->sin_addr.s_addr);
}
else
{
pE.ip = req->ip_address;
}
pE.port = req->port;
db_add_peer(usi->conn, req->info_hash, &pE);
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!");
ScrapeResponse resp;
resp.resp_part = NULL;
resp.action = 2;
resp.transaction_id = sR->transaction_id;
// validate request length:
int v = len - 16;
if (v < 0 || v % 20 != 0)
{
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;
}
@ -297,7 +291,7 @@ static int _resolve_request (udpServerInstance *usi, SOCKADDR_IN *remote, char *
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)
return _handle_connection(usi, remote, data);
@ -333,7 +327,9 @@ static void* _thread_start (void *arg)
{
fflush(stdout);
// 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);
r = _resolve_request(usi, &remoteAddr, tmpBuff, r);
// printf("R=%d\n", r);
@ -345,7 +341,7 @@ static void* _thread_start (void *arg)
}
#ifdef WIN32
static DWORD _maintainance_start (LPVOID arg)
static DWORD _maintainance_start (LPVOID arg);
#elif defined (linux)
static void* _maintainance_start (void *arg)
#endif

View file

@ -59,20 +59,16 @@ struct udp_scrape_request
uint64_t connection_id;
uint32_t action;
uint32_t transaction_id;
struct reqD {
uint8_t info_hash [20];
} *req_part;
uint8_t *torrent_list_data;
};
struct udp_scrape_response
{
uint32_t action;
uint32_t transaction_id;
struct respD {
uint32_t seeders;
uint32_t completed;
uint32_t leechers;
} *resp_part;
uint8_t *data;
};
struct udp_error_response