summaryrefslogtreecommitdiff
path: root/trackerlogic.c
diff options
context:
space:
mode:
Diffstat (limited to 'trackerlogic.c')
-rw-r--r--trackerlogic.c110
1 files changed, 58 insertions, 52 deletions
diff --git a/trackerlogic.c b/trackerlogic.c
index d2d279e..5bda0df 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -19,26 +19,12 @@
19#include "scan.h" 19#include "scan.h"
20#include "byte.h" 20#include "byte.h"
21 21
22#if defined( WANT_CLOSED_TRACKER ) || defined( WANT_BLACKLIST )
23#include <sys/stat.h>
24#endif
25
26/* GLOBAL VARIABLES */ 22/* GLOBAL VARIABLES */
27static ot_vector all_torrents[256]; 23static ot_vector all_torrents[256];
28static ot_vector changeset; 24static ot_vector changeset;
29size_t changeset_size = 0; 25size_t changeset_size = 0;
30time_t last_clean_time = 0; 26time_t last_clean_time = 0;
31 27
32#ifdef WANT_CLOSED_TRACKER
33int g_closedtracker = 1;
34static ot_torrent* const OT_TORRENT_NOT_ON_WHITELIST = (ot_torrent*)1;
35#endif
36
37#ifdef WANT_BLACKLIST
38int g_check_blacklist = 1;
39static ot_torrent* const OT_TORRENT_ON_BLACKLIST = (ot_torrent*)2;
40#endif
41
42/* Converter function from memory to human readable hex strings 28/* Converter function from memory to human readable hex strings
43 - definitely not thread safe!!! 29 - definitely not thread safe!!!
44*/ 30*/
@@ -162,25 +148,12 @@ static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) {
162 return 1; 148 return 1;
163} 149}
164 150
165ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) { 151ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset ) {
166 int exactmatch; 152 int exactmatch;
167 ot_torrent *torrent; 153 ot_torrent *torrent;
168 ot_peer *peer_dest; 154 ot_peer *peer_dest;
169 ot_vector *torrents_list = &all_torrents[*hash[0]], *peer_pool; 155 ot_vector *torrents_list = &all_torrents[*hash[0]], *peer_pool;
170#if defined( WANT_CLOSED_TRACKER ) || defined( WANT_BLACKLIST ) 156 int base_pool = 0;
171 struct stat dummy_sb;
172 char *fn = to_hex( (ot_byte*)hash );
173#endif
174
175#ifdef WANT_CLOSED_TRACKER
176 if( g_closedtracker && stat( fn, &dummy_sb ) )
177 return OT_TORRENT_NOT_ON_WHITELIST;
178#endif
179
180#ifdef WANT_BLACKLIST
181 if( g_check_blacklist && !stat( fn - 1, &dummy_sb ) )
182 return OT_TORRENT_ON_BLACKLIST;
183#endif
184 157
185 torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); 158 torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
186 if( !torrent ) return NULL; 159 if( !torrent ) return NULL;
@@ -202,7 +175,16 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
202 if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED ) 175 if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED )
203 OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED; 176 OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED;
204 177
205 peer_pool = &torrent->peer_list->peers[0]; 178 if( from_changeset ) {
179 /* Check, whether peer already is in current pool, do nothing if so */
180 peer_pool = &torrent->peer_list->peers[0];
181 binary_search( peer, peer_pool->data, peer_pool->size, sizeof(ot_peer), OT_PEER_COMPARE_SIZE, &exactmatch );
182 if( exactmatch )
183 return torrent;
184 base_pool = 1;
185 }
186
187 peer_pool = &torrent->peer_list->peers[ base_pool ];
206 peer_dest = vector_find_or_insert( peer_pool, (void*)peer, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch ); 188 peer_dest = vector_find_or_insert( peer_pool, (void*)peer, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
207 189
208 /* If we hadn't had a match in current pool, create peer there and 190 /* If we hadn't had a match in current pool, create peer there and
@@ -215,9 +197,9 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
215 torrent->peer_list->downloaded++; 197 torrent->peer_list->downloaded++;
216 198
217 if( OT_FLAG(peer) & PEER_FLAG_SEEDING ) 199 if( OT_FLAG(peer) & PEER_FLAG_SEEDING )
218 torrent->peer_list->seed_count[0]++; 200 torrent->peer_list->seed_count[ base_pool ]++;
219 201
220 for( i=1; i<OT_POOLS_COUNT; ++i ) { 202 for( i= base_pool + 1; i<OT_POOLS_COUNT; ++i ) {
221 switch( vector_remove_peer( &torrent->peer_list->peers[i], peer, 0 ) ) { 203 switch( vector_remove_peer( &torrent->peer_list->peers[i], peer, 0 ) ) {
222 case 0: continue; 204 case 0: continue;
223 case 2: torrent->peer_list->seed_count[i]--; 205 case 2: torrent->peer_list->seed_count[i]--;
@@ -226,9 +208,9 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
226 } 208 }
227 } else { 209 } else {
228 if( (OT_FLAG(peer_dest) & PEER_FLAG_SEEDING ) && !(OT_FLAG(peer) & PEER_FLAG_SEEDING ) ) 210 if( (OT_FLAG(peer_dest) & PEER_FLAG_SEEDING ) && !(OT_FLAG(peer) & PEER_FLAG_SEEDING ) )
229 torrent->peer_list->seed_count[0]--; 211 torrent->peer_list->seed_count[ base_pool ]--;
230 if( !(OT_FLAG(peer_dest) & PEER_FLAG_SEEDING ) && (OT_FLAG(peer) & PEER_FLAG_SEEDING ) ) 212 if( !(OT_FLAG(peer_dest) & PEER_FLAG_SEEDING ) && (OT_FLAG(peer) & PEER_FLAG_SEEDING ) )
231 torrent->peer_list->seed_count[0]++; 213 torrent->peer_list->seed_count[ base_pool ]++;
232 if( !(OT_FLAG( peer_dest ) & PEER_FLAG_COMPLETED ) && (OT_FLAG( peer ) & PEER_FLAG_COMPLETED ) ) 214 if( !(OT_FLAG( peer_dest ) & PEER_FLAG_COMPLETED ) && (OT_FLAG( peer ) & PEER_FLAG_COMPLETED ) )
233 torrent->peer_list->downloaded++; 215 torrent->peer_list->downloaded++;
234 if( OT_FLAG( peer_dest ) & PEER_FLAG_COMPLETED ) 216 if( OT_FLAG( peer_dest ) & PEER_FLAG_COMPLETED )
@@ -250,22 +232,6 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply
250 char *r = reply; 232 char *r = reply;
251 size_t peer_count, seed_count, index; 233 size_t peer_count, seed_count, index;
252 234
253#ifdef WANT_CLOSED_TRACKER
254 if( torrent == OT_TORRENT_NOT_ON_WHITELIST ) {
255 const char * const notvalid = "d14:failure reason43:This torrent is not served by this tracker.e";
256 memmove( reply, notvalid, sizeof(notvalid));
257 return sizeof(notvalid);
258 }
259#endif
260
261#ifdef WANT_BLACKLIST
262 if( torrent == OT_TORRENT_ON_BLACKLIST ) {
263 const char * const blacklisted = "d14:failure reason29:This torrent is black listed.e";
264 memmove( reply, blacklisted, sizeof(blacklisted));
265 return sizeof(blacklisted);
266 }
267#endif
268
269 for( peer_count = seed_count = index = 0; index < OT_POOLS_COUNT; ++index ) { 235 for( peer_count = seed_count = index = 0; index < OT_POOLS_COUNT; ++index ) {
270 peer_count += torrent->peer_list->peers[index].size; 236 peer_count += torrent->peer_list->peers[index].size;
271 seed_count += torrent->peer_list->seed_count[index]; 237 seed_count += torrent->peer_list->seed_count[index];
@@ -473,8 +439,48 @@ static void add_pool_to_changeset( ot_hash *hash, ot_peer *peers, size_t peer_co
473 changeset_size += r - sizeof( size_t ); 439 changeset_size += r - sizeof( size_t );
474} 440}
475 441
442/* Import Changeset from an external authority
443 format: d4:syncd[..]ee
444 [..]: ( 20:01234567890abcdefghij16:XXXXYYYY )+
445*/
446int add_changeset_to_tracker( ot_byte *data, size_t len ) {
447 ot_hash *hash;
448 ot_byte *end = data + len;
449 size_t peer_count;
450
451 /* We do know, that the string is \n terminated, so it cant
452 overflow */
453 if( byte_diff( data, 8, "d4:syncd" ) ) return -1;
454 data += 8;
455
456 while( 1 ) {
457 if( byte_diff( data, 3, "20:" ) ) {
458 if( byte_diff( data, 2, "ee" ) )
459 return -1;
460 return 0;
461 }
462 data += 3;
463 hash = (ot_hash*)data;
464 data += sizeof( ot_hash );
465
466 /* Scan string length indicator */
467 data += ( len = scan_ulong( (char*)data, &peer_count ) );
468
469 /* If no long was scanned, it is not divisible by 8, it is not
470 followed by a colon or claims to need to much memory, we fail */
471 if( !len || !peer_count || ( peer_count & 7 ) || ( *data++ != ':' ) || ( data + peer_count > end ) )
472 return -1;
473
474 while( peer_count > 0 ) {
475 add_peer_to_torrent( hash, (ot_peer*)data, 1 );
476 data += 8; peer_count -= 8;
477 }
478 }
479 return 0;
480}
481
476/* Proposed output format 482/* Proposed output format
477 d4:syncd20:<info_hash>8*N:(xxxxyy)*Nee 483 d4:syncd20:<info_hash>8*N:(xxxxyyyy)*Nee
478*/ 484*/
479size_t return_changeset_for_tracker( char **reply ) { 485size_t return_changeset_for_tracker( char **reply ) {
480 size_t i, r = 8; 486 size_t i, r = 8;