Various changes. SEGFAULT fixed.

This commit is contained in:
Naim A 2012-11-26 23:33:12 +02:00
parent 00a68330cd
commit ce247fc7d5
6 changed files with 151 additions and 30 deletions

View file

@ -36,7 +36,7 @@ int db_add_peer (dbConnection *, uint8_t [20], db_peerEntry*);
* lst: pointer to an array whose maximum size is passed to sZ. * lst: pointer to an array whose maximum size is passed to sZ.
* sZ returns the amount of peers returned. * sZ returns the amount of peers returned.
*/ */
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], uint32_t *seeders, uint32_t *leechers, uint32_t *completed);
@ -45,4 +45,6 @@ int db_get_stats (dbConnection *, uint8_t [20], uint32_t *seeders, uint32_t *lee
*/ */
int db_cleanup (dbConnection *); int db_cleanup (dbConnection *);
int db_remove_peer (dbConnection *, uint8_t hash [20], db_peerEntry *);
#endif /* DATABASE_H_ */ #endif /* DATABASE_H_ */

View file

@ -14,7 +14,7 @@ struct dbConnection
static const char hexadecimal[] = "0123456789abcdef"; static const char hexadecimal[] = "0123456789abcdef";
static void _to_hex_str (const uint8_t *hash, char *data) void _to_hex_str (const uint8_t *hash, char *data)
{ {
int i; int i;
for (i = 0;i < 20;i++) for (i = 0;i < 20;i++)
@ -34,7 +34,7 @@ static int _db_make_torrent_table (sqlite3 *db, char *hash)
strcat(sql, hash); strcat(sql, hash);
strcat (sql, "' ("); strcat (sql, "' (");
strcat (sql, "peer_id blob(20) UNIQUE," strcat (sql, "peer_id blob(20),"
"ip blob(4)," "ip blob(4),"
"port blob(2)," "port blob(2),"
"uploaded blob(8)," // uint64 "uploaded blob(8)," // uint64
@ -42,12 +42,12 @@ static int _db_make_torrent_table (sqlite3 *db, char *hash)
"left blob(8)," "left blob(8),"
"last_seen INT DEFAULT 0"); "last_seen INT DEFAULT 0");
strcat(sql, ")"); strcat(sql, ", CONSTRAINT c1 UNIQUE (ip,port) ON CONFLICT REPLACE)");
// create table. // create table.
char *err_msg; char *err_msg;
int r = sqlite3_exec(db, sql, NULL, NULL, &err_msg); int r = sqlite3_exec(db, sql, NULL, NULL, &err_msg);
// printf("E:%s\n", err_msg); printf("E:%s\n", err_msg);
return r; return r;
} }
@ -131,7 +131,7 @@ int db_add_peer (dbConnection *db, uint8_t info_hash[20], db_peerEntry *pE)
return r; return r;
} }
int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry **lst, int *sZ) int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry *lst, int *sZ)
{ {
char sql [1000]; char sql [1000];
sql[0] = '\0'; sql[0] = '\0';
@ -150,16 +150,16 @@ int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry **lst,
int i = 0; int i = 0;
int r; int r;
while (1) while (*sZ > i)
{ {
r = sqlite3_step(stmt); r = sqlite3_step(stmt);
if (r == SQLITE_ROW) if (r == SQLITE_ROW)
{ {
const void *ip = sqlite3_column_blob (stmt, 0); const char *ip = (const char*)sqlite3_column_blob (stmt, 0);
const void *port = sqlite3_column_blob (stmt, 1); const char *port = (const char*)sqlite3_column_blob (stmt, 1);
memcpy(&lst[i]->ip, ip, 4); memcpy(&lst[i].ip, ip, 4);
memcpy(&lst[i]->port, port, 2); memcpy(&lst[i].port, port, 2);
i++; i++;
} }
@ -167,6 +167,8 @@ int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry **lst,
break; break;
} }
printf("%d Clients Dumped.\n", i);
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
*sZ = i; *sZ = i;
@ -286,3 +288,29 @@ int db_cleanup (dbConnection *db)
return 0; return 0;
} }
int db_remove_peer (dbConnection *db, uint8_t hash[20], db_peerEntry *pE)
{
char sql [1000];
char xHash [50];
_to_hex_str (hash, xHash);
strcpy (sql, "DELETE FROM 't");
strcat (sql, xHash);
strcat (sql, "' WHERE ip=? AND port=? AND peer_id=?");
sqlite3_stmt *stmt;
sqlite3_prepare (db->db, sql, -1, &stmt, NULL);
sqlite3_bind_blob(stmt, 0, (const void*)&pE->ip, 4, NULL);
sqlite3_bind_blob(stmt, 1, (const void*)&pE->port, 2, NULL);
sqlite3_bind_blob(stmt, 2, (const void*)pE->peer_id, 20, NULL);
sqlite3_step(stmt);
sqlite3_finalize(stmt);
return 0;
}

View file

@ -18,17 +18,42 @@
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
int main(void) int main(int argc, char *argv[])
{ {
printf("UDP BitTorrentTracker %s\t\tCopyright: (C) 2012 Naim Abda.\n\n", VERSION); printf("UDP BitTorrentTracker %s\t\tCopyright: (C) 2012 Naim Abda.\n\n", VERSION);
#ifdef linux
if (argc > 1)
{
if (strcmp(argv[1], "d") == 0)
{
pid_t pid;
pid = fork ();
if (pid < 0)
{
printf ("Failed to start daemon.\n");
exit (EXIT_FAILURE);
}
if (pid > 0)
{
printf("Daemon Started; pid=%d.\n", pid);
fclose (stdin);
fclose (stdout);
fclose (stderr);
exit (EXIT_SUCCESS);
}
}
}
#endif
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata); WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif #endif
udpServerInstance usi; udpServerInstance usi;
UDPTracker_init(&usi, 6969, 1); UDPTracker_init(&usi, 6969, 5);
if (UDPTracker_start(&usi) != 0) if (UDPTracker_start(&usi) != 0)
{ {

View file

@ -18,6 +18,7 @@
#define INVALID_SOCKET 0 #define INVALID_SOCKET 0
#define SOCKET_ERROR -1 #define SOCKET_ERROR -1
#define DWORD uint64_t #define DWORD uint64_t
#define closesocket(s) close(s)
typedef struct hostent HOSTENT; typedef struct hostent HOSTENT;
typedef struct sockaddr SOCKADDR; typedef struct sockaddr SOCKADDR;
typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr_in SOCKADDR_IN;

View file

@ -145,6 +145,30 @@ 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;
@ -162,20 +186,36 @@ 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 = malloc (sizeof(db_peerEntry) * q); db_peerEntry *peers = NULL;
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!
{
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; 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);
@ -206,24 +246,29 @@ 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;
if (req->ip_address == 0) // default pE.ip = req->ip_address;
{
pE.ip = m_hton32 (remote->sin_addr.s_addr);
}
else
{
pE.ip = req->ip_address;
}
pE.port = req->port; pE.port = req->port;
if (req->event == 3) // stopped
{
// just remove client from swarm, and return empty peer list...
db_remove_peer(usi->conn, req->info_hash, &pE);
return 0;
}
db_add_peer(usi->conn, req->info_hash, &pE); db_add_peer(usi->conn, req->info_hash, &pE);
return 0; return 0;
@ -233,7 +278,14 @@ static int _handle_scrape (udpServerInstance *usi, SOCKADDR_IN *remote, char *da
{ {
ScrapeRequest *sR = (ScrapeRequest*)data; ScrapeRequest *sR = (ScrapeRequest*)data;
_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;
resp.resp_part = NULL;
resp.action = 2;
resp.transaction_id = sR->transaction_id;
sendto (usi->sock, (const char*)&resp, 8, 0, (SOCKADDR*)remote, sizeof(SOCKADDR_IN));
return 0; return 0;
} }

View file

@ -59,8 +59,20 @@ 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];
} *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;
}; };
struct udp_error_response struct udp_error_response
@ -89,6 +101,7 @@ typedef struct udp_connection_response ConnectionResponse;
typedef struct udp_announce_request AnnounceRequest; typedef struct udp_announce_request AnnounceRequest;
typedef struct udp_announce_response AnnounceResponse; typedef struct udp_announce_response AnnounceResponse;
typedef struct udp_scrape_request ScrapeRequest; typedef struct udp_scrape_request ScrapeRequest;
typedef struct udp_scrape_response ScrapeResponse;
typedef struct udp_error_response ErrorResponse; typedef struct udp_error_response ErrorResponse;
void UDPTracker_init (udpServerInstance *, uint16_t port, uint8_t threads); void UDPTracker_init (udpServerInstance *, uint16_t port, uint8_t threads);