Various changes. SEGFAULT fixed.
This commit is contained in:
parent
00a68330cd
commit
ce247fc7d5
|
@ -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_ */
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
29
src/main.c
29
src/main.c
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (peers != NULL)
|
||||||
free (peers);
|
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 = m_hton32 (remote->sin_addr.s_addr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pE.ip = req->ip_address;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue