diff options
| author | erdgeist <> | 2008-10-04 05:40:51 +0000 |
|---|---|---|
| committer | erdgeist <> | 2008-10-04 05:40:51 +0000 |
| commit | e534db03c6877f8ac0559f63840e9a00e9bd43bf (patch) | |
| tree | 811181b9b39d0484e28eb25cbb9f2eea094978e2 /trackerlogic.c | |
| parent | 8cbfc8602c73e55770f3c06d8ea42758b22a0401 (diff) | |
added live sync code
added a config file parser
added tracker id
changed WANT_CLOSED_TRACKER and WANT_BLACKLIST into WANT_ACCESS_WHITE and WANT_ACCESS_BLACK
changed WANT_TRACKER_SYNC to WANT_SYNC_BATCH and added WANT_SYNC_LIVE
added an option to switch off fullscrapes
cleaned up many internal hardcoded values, like PROTO_FLAG,
Diffstat (limited to 'trackerlogic.c')
| -rw-r--r-- | trackerlogic.c | 70 |
1 files changed, 48 insertions, 22 deletions
diff --git a/trackerlogic.c b/trackerlogic.c index 37bb878..bff3a3c 100644 --- a/trackerlogic.c +++ b/trackerlogic.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <unistd.h> | 14 | #include <unistd.h> |
| 15 | #include <time.h> | 15 | #include <time.h> |
| 16 | #include <math.h> | 16 | #include <math.h> |
| 17 | #include <errno.h> | ||
| 17 | 18 | ||
| 18 | /* Libowfat */ | 19 | /* Libowfat */ |
| 19 | #include "scan.h" | 20 | #include "scan.h" |
| @@ -28,19 +29,20 @@ | |||
| 28 | #include "ot_accesslist.h" | 29 | #include "ot_accesslist.h" |
| 29 | #include "ot_fullscrape.h" | 30 | #include "ot_fullscrape.h" |
| 30 | #include "ot_sync.h" | 31 | #include "ot_sync.h" |
| 32 | #include "ot_livesync.h" | ||
| 31 | 33 | ||
| 32 | void free_peerlist( ot_peerlist *peer_list ) { | 34 | void free_peerlist( ot_peerlist *peer_list ) { |
| 33 | size_t i; | 35 | size_t i; |
| 34 | for( i=0; i<OT_POOLS_COUNT; ++i ) | 36 | for( i=0; i<OT_POOLS_COUNT; ++i ) |
| 35 | if( peer_list->peers[i].data ) | 37 | if( peer_list->peers[i].data ) |
| 36 | free( peer_list->peers[i].data ); | 38 | free( peer_list->peers[i].data ); |
| 37 | #ifdef WANT_TRACKER_SYNC | 39 | #ifdef WANT_SYNC_BATCH |
| 38 | free( peer_list->changeset.data ); | 40 | free( peer_list->changeset.data ); |
| 39 | #endif | 41 | #endif |
| 40 | free( peer_list ); | 42 | free( peer_list ); |
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC_PARAM( int from_changeset ) ) { | 45 | ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_SYNC_PARAM( int from_changeset ) ) { |
| 44 | int exactmatch; | 46 | int exactmatch; |
| 45 | ot_torrent *torrent; | 47 | ot_torrent *torrent; |
| 46 | ot_peer *peer_dest; | 48 | ot_peer *peer_dest; |
| @@ -58,6 +60,11 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC | |||
| 58 | return NULL; | 60 | return NULL; |
| 59 | } | 61 | } |
| 60 | 62 | ||
| 63 | #ifdef WANT_SYNC_LIVE | ||
| 64 | if( !from_changeset ) | ||
| 65 | livesync_tell( hash, peer, PEER_FLAG_LEECHING ); | ||
| 66 | #endif | ||
| 67 | |||
| 61 | if( !exactmatch ) { | 68 | if( !exactmatch ) { |
| 62 | /* Create a new torrent entry, then */ | 69 | /* Create a new torrent entry, then */ |
| 63 | memmove( &torrent->hash, hash, sizeof( ot_hash ) ); | 70 | memmove( &torrent->hash, hash, sizeof( ot_hash ) ); |
| @@ -79,7 +86,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC | |||
| 79 | if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED ) | 86 | if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED ) |
| 80 | OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED; | 87 | OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED; |
| 81 | 88 | ||
| 82 | #ifdef WANT_TRACKER_SYNC | 89 | #ifdef WANT_SYNC |
| 83 | if( from_changeset ) { | 90 | if( from_changeset ) { |
| 84 | /* Check, whether peer already is in current pool, do nothing if so */ | 91 | /* Check, whether peer already is in current pool, do nothing if so */ |
| 85 | peer_pool = &torrent->peer_list->peers[0]; | 92 | peer_pool = &torrent->peer_list->peers[0]; |
| @@ -148,7 +155,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC | |||
| 148 | * RANDOM may return huge values | 155 | * RANDOM may return huge values |
| 149 | * does not yet check not to return self | 156 | * does not yet check not to return self |
| 150 | */ | 157 | */ |
| 151 | size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, int is_tcp ) { | 158 | size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, PROTO_FLAG proto ) { |
| 152 | char *r = reply; | 159 | char *r = reply; |
| 153 | int exactmatch; | 160 | int exactmatch; |
| 154 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 161 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); |
| @@ -164,7 +171,7 @@ size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, int | |||
| 164 | if( peer_list->peer_count < amount ) | 171 | if( peer_list->peer_count < amount ) |
| 165 | amount = peer_list->peer_count; | 172 | amount = peer_list->peer_count; |
| 166 | 173 | ||
| 167 | if( is_tcp ) | 174 | if( proto == FLAG_TCP ) |
| 168 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie5:peers%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount ); | 175 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie5:peers%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount ); |
| 169 | else { | 176 | else { |
| 170 | *(uint32_t*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 177 | *(uint32_t*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
| @@ -204,7 +211,7 @@ size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, int | |||
| 204 | r += 6; | 211 | r += 6; |
| 205 | } | 212 | } |
| 206 | } | 213 | } |
| 207 | if( is_tcp ) | 214 | if( proto == FLAG_TCP ) |
| 208 | *r++ = 'e'; | 215 | *r++ = 'e'; |
| 209 | 216 | ||
| 210 | mutex_bucket_unlock_by_hash( hash ); | 217 | mutex_bucket_unlock_by_hash( hash ); |
| @@ -263,23 +270,33 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl | |||
| 263 | return r - reply; | 270 | return r - reply; |
| 264 | } | 271 | } |
| 265 | 272 | ||
| 266 | size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ) { | 273 | size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) { |
| 267 | int exactmatch; | 274 | int exactmatch; |
| 268 | size_t index; | 275 | size_t index; |
| 269 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 276 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); |
| 270 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); | 277 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); |
| 271 | ot_peerlist *peer_list; | 278 | ot_peerlist *peer_list; |
| 272 | 279 | ||
| 280 | #ifdef WANT_SYNC_LIVE | ||
| 281 | if( proto != FLAG_MCA ) | ||
| 282 | livesync_tell( hash, peer, PEER_FLAG_STOPPED ); | ||
| 283 | #endif | ||
| 284 | |||
| 273 | if( !exactmatch ) { | 285 | if( !exactmatch ) { |
| 274 | mutex_bucket_unlock_by_hash( hash ); | 286 | mutex_bucket_unlock_by_hash( hash ); |
| 275 | 287 | ||
| 276 | if( is_tcp ) | 288 | if( proto == FLAG_TCP ) |
| 277 | return sprintf( reply, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 289 | return sprintf( reply, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
| 278 | 290 | ||
| 279 | /* Create fake packet to satisfy parser on the other end */ | 291 | /* Create fake packet to satisfy parser on the other end */ |
| 280 | ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 292 | if( proto == FLAG_UDP ) { |
| 281 | ((uint32_t*)reply)[3] = ((uint32_t*)reply)[4] = 0; | 293 | ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
| 282 | return (size_t)20; | 294 | ((uint32_t*)reply)[3] = ((uint32_t*)reply)[4] = 0; |
| 295 | return (size_t)20; | ||
| 296 | } | ||
| 297 | |||
| 298 | if( proto == FLAG_MCA ) | ||
| 299 | return 0; | ||
| 283 | } | 300 | } |
| 284 | 301 | ||
| 285 | peer_list = torrent->peer_list; | 302 | peer_list = torrent->peer_list; |
| @@ -296,37 +313,46 @@ size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int | |||
| 296 | 313 | ||
| 297 | exit_loop: | 314 | exit_loop: |
| 298 | 315 | ||
| 299 | if( is_tcp ) { | 316 | if( proto == FLAG_TCP ) { |
| 300 | size_t reply_size = sprintf( reply, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers0:e", peer_list->seed_count, peer_list->peer_count - peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 317 | size_t reply_size = sprintf( reply, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers0:e", peer_list->seed_count, peer_list->peer_count - peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
| 301 | mutex_bucket_unlock_by_hash( hash ); | 318 | mutex_bucket_unlock_by_hash( hash ); |
| 302 | return reply_size; | 319 | return reply_size; |
| 303 | } | 320 | } |
| 304 | 321 | ||
| 305 | /* else { Handle UDP reply */ | 322 | /* Handle UDP reply */ |
| 306 | ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 323 | if( proto == FLAG_TCP ) { |
| 307 | ((uint32_t*)reply)[3] = htonl( peer_list->peer_count - peer_list->seed_count ); | 324 | ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
| 308 | ((uint32_t*)reply)[4] = htonl( peer_list->seed_count); | 325 | ((uint32_t*)reply)[3] = htonl( peer_list->peer_count - peer_list->seed_count ); |
| 326 | ((uint32_t*)reply)[4] = htonl( peer_list->seed_count); | ||
| 327 | } | ||
| 309 | 328 | ||
| 310 | mutex_bucket_unlock_by_hash( hash ); | 329 | mutex_bucket_unlock_by_hash( hash ); |
| 311 | return (size_t)20; | 330 | return (size_t)20; |
| 312 | } | 331 | } |
| 313 | 332 | ||
| 333 | void exerr( char * message ) { | ||
| 334 | fprintf( stderr, "%s\n", message ); | ||
| 335 | exit( 111 ); | ||
| 336 | } | ||
| 337 | |||
| 314 | int trackerlogic_init( const char * const serverdir ) { | 338 | int trackerlogic_init( const char * const serverdir ) { |
| 315 | if( serverdir && chdir( serverdir ) ) { | 339 | if( serverdir && chdir( serverdir ) ) { |
| 316 | fprintf( stderr, "Could not chdir() to %s\n", serverdir ); | 340 | fprintf( stderr, "Could not chdir() to %s, because %s\n", serverdir, strerror(errno) ); |
| 317 | return -1; | 341 | return -1; |
| 318 | } | 342 | } |
| 319 | 343 | ||
| 320 | srandom( time(NULL) ); | 344 | srandom( time(NULL) ); |
| 321 | 345 | g_tracker_id = random(); | |
| 346 | |||
| 322 | /* Initialise background worker threads */ | 347 | /* Initialise background worker threads */ |
| 323 | mutex_init( ); | 348 | mutex_init( ); |
| 324 | clean_init( ); | 349 | clean_init( ); |
| 325 | fullscrape_init( ); | 350 | fullscrape_init( ); |
| 326 | #ifdef WANT_TRACKER_SYNC | 351 | accesslist_init( ); |
| 352 | livesync_init( ); | ||
| 327 | sync_init( ); | 353 | sync_init( ); |
| 328 | #endif | ||
| 329 | stats_init( ); | 354 | stats_init( ); |
| 355 | |||
| 330 | return 0; | 356 | return 0; |
| 331 | } | 357 | } |
| 332 | 358 | ||
| @@ -349,9 +375,9 @@ void trackerlogic_deinit( void ) { | |||
| 349 | 375 | ||
| 350 | /* Deinitialise background worker threads */ | 376 | /* Deinitialise background worker threads */ |
| 351 | stats_deinit( ); | 377 | stats_deinit( ); |
| 352 | #ifdef WANT_TRACKER_SYNC | ||
| 353 | sync_deinit( ); | 378 | sync_deinit( ); |
| 354 | #endif | 379 | livesync_init( ); |
| 380 | accesslist_init( ); | ||
| 355 | fullscrape_deinit( ); | 381 | fullscrape_deinit( ); |
| 356 | clean_deinit( ); | 382 | clean_deinit( ); |
| 357 | mutex_deinit( ); | 383 | mutex_deinit( ); |
