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.
|
||||
* 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);
|
||||
|
||||
|
@ -45,4 +45,6 @@ int db_get_stats (dbConnection *, uint8_t [20], uint32_t *seeders, uint32_t *lee
|
|||
*/
|
||||
int db_cleanup (dbConnection *);
|
||||
|
||||
int db_remove_peer (dbConnection *, uint8_t hash [20], db_peerEntry *);
|
||||
|
||||
#endif /* DATABASE_H_ */
|
||||
|
|
|
@ -14,7 +14,7 @@ struct dbConnection
|
|||
|
||||
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;
|
||||
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, "' (");
|
||||
|
||||
strcat (sql, "peer_id blob(20) UNIQUE,"
|
||||
strcat (sql, "peer_id blob(20),"
|
||||
"ip blob(4),"
|
||||
"port blob(2),"
|
||||
"uploaded blob(8)," // uint64
|
||||
|
@ -42,12 +42,12 @@ static int _db_make_torrent_table (sqlite3 *db, char *hash)
|
|||
"left blob(8),"
|
||||
"last_seen INT DEFAULT 0");
|
||||
|
||||
strcat(sql, ")");
|
||||
strcat(sql, ", CONSTRAINT c1 UNIQUE (ip,port) ON CONFLICT REPLACE)");
|
||||
|
||||
// create table.
|
||||
char *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;
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ int db_add_peer (dbConnection *db, uint8_t info_hash[20], db_peerEntry *pE)
|
|||
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];
|
||||
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 r;
|
||||
|
||||
while (1)
|
||||
while (*sZ > i)
|
||||
{
|
||||
r = sqlite3_step(stmt);
|
||||
if (r == SQLITE_ROW)
|
||||
{
|
||||
const void *ip = sqlite3_column_blob (stmt, 0);
|
||||
const void *port = sqlite3_column_blob (stmt, 1);
|
||||
const char *ip = (const char*)sqlite3_column_blob (stmt, 0);
|
||||
const char *port = (const char*)sqlite3_column_blob (stmt, 1);
|
||||
|
||||
memcpy(&lst[i]->ip, ip, 4);
|
||||
memcpy(&lst[i]->port, port, 2);
|
||||
memcpy(&lst[i].ip, ip, 4);
|
||||
memcpy(&lst[i].port, port, 2);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
@ -167,6 +167,8 @@ int db_load_peers (dbConnection *db, uint8_t info_hash[20], db_peerEntry **lst,
|
|||
break;
|
||||
}
|
||||
|
||||
printf("%d Clients Dumped.\n", i);
|
||||
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
*sZ = i;
|
||||
|
@ -286,3 +288,29 @@ int db_cleanup (dbConnection *db)
|
|||
|
||||
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 <time.h>
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
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
|
||||
WSADATA wsadata;
|
||||
WSAStartup(MAKEWORD(2, 2), &wsadata);
|
||||
#endif
|
||||
|
||||
udpServerInstance usi;
|
||||
UDPTracker_init(&usi, 6969, 1);
|
||||
UDPTracker_init(&usi, 6969, 5);
|
||||
|
||||
if (UDPTracker_start(&usi) != 0)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define INVALID_SOCKET 0
|
||||
#define SOCKET_ERROR -1
|
||||
#define DWORD uint64_t
|
||||
#define closesocket(s) close(s)
|
||||
typedef struct hostent HOSTENT;
|
||||
typedef struct sockaddr SOCKADDR;
|
||||
typedef struct sockaddr_in SOCKADDR_IN;
|
||||
|
|
|
@ -145,6 +145,30 @@ 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;
|
||||
|
@ -162,20 +186,36 @@ 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 = malloc (sizeof(db_peerEntry) * q);
|
||||
|
||||
db_load_peers(usi->conn, req->info_hash, &peers, &q);
|
||||
// printf("%d peers found.\n", q);
|
||||
|
||||
db_peerEntry *peers = NULL;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
if (peers != NULL)
|
||||
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;
|
||||
if (req->ip_address == 0) // default
|
||||
{
|
||||
pE.ip = m_hton32 (remote->sin_addr.s_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
pE.ip = req->ip_address;
|
||||
}
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -233,7 +278,14 @@ static int _handle_scrape (udpServerInstance *usi, SOCKADDR_IN *remote, char *da
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -59,8 +59,20 @@ 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;
|
||||
};
|
||||
|
||||
struct udp_error_response
|
||||
|
@ -89,6 +101,7 @@ typedef struct udp_connection_response ConnectionResponse;
|
|||
typedef struct udp_announce_request AnnounceRequest;
|
||||
typedef struct udp_announce_response AnnounceResponse;
|
||||
typedef struct udp_scrape_request ScrapeRequest;
|
||||
typedef struct udp_scrape_response ScrapeResponse;
|
||||
typedef struct udp_error_response ErrorResponse;
|
||||
|
||||
void UDPTracker_init (udpServerInstance *, uint16_t port, uint8_t threads);
|
||||
|
|
Loading…
Reference in a new issue