From 7266aa2f5a75adf665f7efaf377542a0e9e7ead8 Mon Sep 17 00:00:00 2001 From: Naim A Date: Tue, 27 Nov 2012 16:01:40 +0200 Subject: [PATCH] Git changes... --- src/db/database.h | 2 +- src/db/driver_sqlite.c | 15 ++--- src/tools.c | 14 +++++ src/tools.h | 2 + src/udpTracker.c | 138 ++++++++++++++++++++--------------------- src/udpTracker.h | 12 ++-- 6 files changed, 96 insertions(+), 87 deletions(-) diff --git a/src/db/database.h b/src/db/database.h index f175ec4..19db4a8 100644 --- a/src/db/database.h +++ b/src/db/database.h @@ -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. diff --git a/src/db/driver_sqlite.c b/src/db/driver_sqlite.c index b7c0294..5decb65 100644 --- a/src/db/driver_sqlite.c +++ b/src/db/driver_sqlite.c @@ -1,5 +1,6 @@ #include "database.h" #include "../multiplatform.h" +#include "../tools.h" #include #include #include @@ -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"); diff --git a/src/tools.c b/src/tools.c index a259380..8c776b1 100644 --- a/src/tools.c +++ b/src/tools.c @@ -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'; +} diff --git a/src/tools.h b/src/tools.h index 03ee944..adae247 100644 --- a/src/tools.h +++ b/src/tools.h @@ -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_ */ diff --git a/src/udpTracker.c b/src/udpTracker.c index 4f1ff6e..34653bc 100644 --- a/src/udpTracker.c +++ b/src/udpTracker.c @@ -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 diff --git a/src/udpTracker.h b/src/udpTracker.h index f910c26..8accf31 100644 --- a/src/udpTracker.h +++ b/src/udpTracker.h @@ -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