diff options
author | erdgeist <> | 2007-03-27 16:09:03 +0000 |
---|---|---|
committer | erdgeist <> | 2007-03-27 16:09:03 +0000 |
commit | 33774078ab5a3c37ded0c7cdf0324bafc690625f (patch) | |
tree | a27c4d8e809bf5316e39aab0a7cb5f45c8aa75dd | |
parent | b38104b9862a57271567c3dcb7e004addbe70ffc (diff) |
Added inbound part of sync. This also meant to remove the black/whitelisting as we did by now. A more scalable way to blacklist will follow.
-rw-r--r-- | opentracker.c | 91 | ||||
-rw-r--r-- | trackerlogic.c | 110 | ||||
-rw-r--r-- | trackerlogic.h | 12 |
3 files changed, 114 insertions, 99 deletions
diff --git a/opentracker.c b/opentracker.c index 7be1421..0ddce0c 100644 --- a/opentracker.c +++ b/opentracker.c | |||
@@ -56,6 +56,7 @@ struct http_data { | |||
56 | io_batch batch; | 56 | io_batch batch; |
57 | }; | 57 | }; |
58 | unsigned char ip[4]; | 58 | unsigned char ip[4]; |
59 | int blessed; | ||
59 | }; | 60 | }; |
60 | 61 | ||
61 | /* Prototypes */ | 62 | /* Prototypes */ |
@@ -87,6 +88,7 @@ static void graceful( int s ); | |||
87 | #define HTTPERROR_400 return httperror( s, "400 Invalid Request", "This server only understands GET." ) | 88 | #define HTTPERROR_400 return httperror( s, "400 Invalid Request", "This server only understands GET." ) |
88 | #define HTTPERROR_400_PARAM return httperror( s, "400 Invalid Request", "Invalid parameter" ) | 89 | #define HTTPERROR_400_PARAM return httperror( s, "400 Invalid Request", "Invalid parameter" ) |
89 | #define HTTPERROR_400_COMPACT return httperror( s, "400 Invalid Request", "This server only delivers compact results." ) | 90 | #define HTTPERROR_400_COMPACT return httperror( s, "400 Invalid Request", "This server only delivers compact results." ) |
91 | #define HTTPERROR_403_IP return httperror( s, "403 Access Denied", "Your ip address is not allowed to administrate this server." ) | ||
90 | #define HTTPERROR_404 return httperror( s, "404 Not Found", "No such file or directory." ) | 92 | #define HTTPERROR_404 return httperror( s, "404 Not Found", "No such file or directory." ) |
91 | #define HTTPERROR_500 return httperror( s, "500 Internal Server Error", "A server error has occured. Please retry later." ) | 93 | #define HTTPERROR_500 return httperror( s, "500 Internal Server Error", "A server error has occured. Please retry later." ) |
92 | 94 | ||
@@ -173,6 +175,7 @@ static void senddata( const int64 s, char *buffer, size_t size ) { | |||
173 | } | 175 | } |
174 | 176 | ||
175 | static void httpresponse( const int64 s, char *data ) { | 177 | static void httpresponse( const int64 s, char *data ) { |
178 | struct http_data* h = io_getcookie( s ); | ||
176 | char *c, *reply; | 179 | char *c, *reply; |
177 | ot_peer peer; | 180 | ot_peer peer; |
178 | ot_torrent *torrent; | 181 | ot_torrent *torrent; |
@@ -198,11 +201,48 @@ static void httpresponse( const int64 s, char *data ) { | |||
198 | for( c = data+4; *c == '/'; ++c); | 201 | for( c = data+4; *c == '/'; ++c); |
199 | 202 | ||
200 | switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) { | 203 | switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) { |
204 | |||
205 | /****************************** | ||
206 | * S Y N C * | ||
207 | ******************************/ | ||
201 | case 4: /* sync ? */ | 208 | case 4: /* sync ? */ |
202 | if( byte_diff( data, 4, "sync") ) HTTPERROR_404; | 209 | if( byte_diff( data, 4, "sync") ) HTTPERROR_404; |
203 | if( !( reply_size = return_changeset_for_tracker( &reply ) ) ) HTTPERROR_500; | 210 | if( !h->blessed ) HTTPERROR_403_IP; |
204 | return sendmallocdata( s, reply, reply_size ); | 211 | |
212 | mode = SYNC_OUT; | ||
213 | scanon = 1; | ||
205 | 214 | ||
215 | while( scanon ) { | ||
216 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { | ||
217 | case -2: scanon = 0; break; /* TERMINATOR */ | ||
218 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ | ||
219 | default: scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); break; | ||
220 | case 9: | ||
221 | if(byte_diff(data,9,"changeset")) { | ||
222 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | ||
223 | continue; | ||
224 | } | ||
225 | /* ignore this, when we dont at least see "d4:syncdee" */ | ||
226 | if( ( len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) < 10 ) HTTPERROR_400_PARAM; | ||
227 | if( add_changeset_to_tracker( (ot_byte*)data, len ) ) HTTPERROR_400_PARAM; | ||
228 | mode = SYNC_IN; | ||
229 | break; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | if( mode == SYNC_OUT ) { | ||
234 | if( !( reply_size = return_changeset_for_tracker( &reply ) ) ) HTTPERROR_500; | ||
235 | return sendmallocdata( s, reply, reply_size ); | ||
236 | } | ||
237 | |||
238 | /* Simple but proof for now */ | ||
239 | reply = "OK"; | ||
240 | reply_size = 2; | ||
241 | |||
242 | break; | ||
243 | /****************************** | ||
244 | * S T A T S * | ||
245 | ******************************/ | ||
206 | case 5: /* stats ? */ | 246 | case 5: /* stats ? */ |
207 | if( byte_diff(data,5,"stats")) HTTPERROR_404; | 247 | if( byte_diff(data,5,"stats")) HTTPERROR_404; |
208 | scanon = 1; | 248 | scanon = 1; |
@@ -260,8 +300,11 @@ static void httpresponse( const int64 s, char *data ) { | |||
260 | if( !( reply_size = return_stats_for_tracker( SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, mode ) ) ) HTTPERROR_500; | 300 | if( !( reply_size = return_stats_for_tracker( SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, mode ) ) ) HTTPERROR_500; |
261 | break; | 301 | break; |
262 | } | 302 | } |
263 | |||
264 | break; | 303 | break; |
304 | |||
305 | /****************************** | ||
306 | * S C R A P E * | ||
307 | ******************************/ | ||
265 | case 6: /* scrape ? */ | 308 | case 6: /* scrape ? */ |
266 | if( byte_diff( data, 6, "scrape") ) HTTPERROR_404; | 309 | if( byte_diff( data, 6, "scrape") ) HTTPERROR_404; |
267 | 310 | ||
@@ -280,7 +323,7 @@ SCRAPE_WORKAROUND: | |||
280 | } | 323 | } |
281 | /* ignore this, when we have less than 20 bytes */ | 324 | /* ignore this, when we have less than 20 bytes */ |
282 | if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM; | 325 | if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM; |
283 | hash = (ot_hash*)data; /* Fall through intended */ | 326 | hash = (ot_hash*)data; |
284 | break; | 327 | break; |
285 | } | 328 | } |
286 | } | 329 | } |
@@ -297,6 +340,9 @@ SCRAPE_WORKAROUND: | |||
297 | 340 | ||
298 | ot_overall_tcp_successfulannounces++; | 341 | ot_overall_tcp_successfulannounces++; |
299 | break; | 342 | break; |
343 | /****************************** | ||
344 | * A N N O U N C E * | ||
345 | ******************************/ | ||
300 | case 8: | 346 | case 8: |
301 | if( byte_diff( data, 8, "announce" ) ) HTTPERROR_404; | 347 | if( byte_diff( data, 8, "announce" ) ) HTTPERROR_404; |
302 | 348 | ||
@@ -384,7 +430,7 @@ ANNOUNCE_WORKAROUND: | |||
384 | remove_peer_from_torrent( hash, &peer ); | 430 | remove_peer_from_torrent( hash, &peer ); |
385 | reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 431 | reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
386 | } else { | 432 | } else { |
387 | torrent = add_peer_to_torrent( hash, &peer ); | 433 | torrent = add_peer_to_torrent( hash, &peer, 0 ); |
388 | if( !torrent || !( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, 1 ) ) ) HTTPERROR_500; | 434 | if( !torrent || !( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, 1 ) ) ) HTTPERROR_500; |
389 | } | 435 | } |
390 | ot_overall_tcp_successfulannounces++; | 436 | ot_overall_tcp_successfulannounces++; |
@@ -438,12 +484,6 @@ static void graceful( int s ) { | |||
438 | 484 | ||
439 | static void usage( char *name ) { | 485 | static void usage( char *name ) { |
440 | fprintf( stderr, "Usage: %s [-i serverip] [-p serverport] [-d serverdirectory]" | 486 | fprintf( stderr, "Usage: %s [-i serverip] [-p serverport] [-d serverdirectory]" |
441 | #ifdef WANT_CLOSED_TRACKER | ||
442 | " [-oc]" | ||
443 | #endif | ||
444 | #ifdef WANT_BLACKLIST | ||
445 | " [-bB]" | ||
446 | #endif | ||
447 | "\n", name ); | 487 | "\n", name ); |
448 | } | 488 | } |
449 | 489 | ||
@@ -453,23 +493,6 @@ static void help( char *name ) { | |||
453 | "\t-p serverport\tspecify tcp port to bind to (default: 6969, you may specify more than one)\n" | 493 | "\t-p serverport\tspecify tcp port to bind to (default: 6969, you may specify more than one)\n" |
454 | "\t-P serverport\tspecify udp port to bind to (default: 6969, you may specify more than one)\n" | 494 | "\t-P serverport\tspecify udp port to bind to (default: 6969, you may specify more than one)\n" |
455 | "\t-d serverdir\tspecify directory containing white- or black listed torrent info_hashes (default: \".\")\n" | 495 | "\t-d serverdir\tspecify directory containing white- or black listed torrent info_hashes (default: \".\")\n" |
456 | #ifdef WANT_CLOSED_TRACKER | ||
457 | "\t-o\t\tmake tracker an open tracker, e.g. do not check for white list (default: off)\n" | ||
458 | "\t-c\t\tmake tracker a closed tracker, e.g. check each announced torrent against white list (default: on)\n" | ||
459 | #endif | ||
460 | #ifdef WANT_BLACKLIST | ||
461 | "\t-b\t\tmake tracker check its black list, e.g. check each announced torrent against black list (default: on)\n" | ||
462 | "\t-B\t\tmake tracker check its black list, e.g. check each announced torrent against black list (default: off)\n" | ||
463 | #endif | ||
464 | #ifdef WANT_CLOSED_TRACKER | ||
465 | "\n* To white list a torrent, touch a file inside serverdir with info_hash hex string.\n" | ||
466 | #endif | ||
467 | #ifdef WANT_BLACKLIST | ||
468 | #ifndef WANT_CLOSED_TRACKER | ||
469 | "\n" | ||
470 | #endif | ||
471 | "* To white list a torrent, touch a file inside serverdir with info_hash hex string, preprended by '-'.\n" | ||
472 | #endif | ||
473 | "\nExample: ./opentracker -i 127.0.0.1 -p 6969 -P 6969 -i 10.1.1.23 -p 2710 -p 80\n" | 496 | "\nExample: ./opentracker -i 127.0.0.1 -p 6969 -P 6969 -i 10.1.1.23 -p 2710 -p 80\n" |
474 | ); | 497 | ); |
475 | } | 498 | } |
@@ -503,7 +526,7 @@ static void handle_read( const int64 clientsocket ) { | |||
503 | if( array_failed( &h->request ) ) | 526 | if( array_failed( &h->request ) ) |
504 | return httperror( clientsocket, "500 Server Error", "Request too long."); | 527 | return httperror( clientsocket, "500 Server Error", "Request too long."); |
505 | 528 | ||
506 | if( array_bytes( &h->request ) > 8192 ) | 529 | if( ( !h->blessed ) && ( array_bytes( &h->request ) > 8192 ) ) |
507 | return httperror( clientsocket, "500 request too long", "You sent too much headers"); | 530 | return httperror( clientsocket, "500 request too long", "You sent too much headers"); |
508 | 531 | ||
509 | if( memchr( array_start( &h->request ), '\n', array_length( &h->request, 1 ) ) ) | 532 | if( memchr( array_start( &h->request ), '\n', array_length( &h->request, 1 ) ) ) |
@@ -626,7 +649,7 @@ static void handle_udp4( int64 serversocket ) { | |||
626 | outpacket[3] = outpacket[4] = 0; | 649 | outpacket[3] = outpacket[4] = 0; |
627 | r = 20; | 650 | r = 20; |
628 | } else { | 651 | } else { |
629 | torrent = add_peer_to_torrent( hash, &peer ); | 652 | torrent = add_peer_to_torrent( hash, &peer, 0 ); |
630 | if( !torrent ) | 653 | if( !torrent ) |
631 | return; /* XXX maybe send error */ | 654 | return; /* XXX maybe send error */ |
632 | 655 | ||
@@ -719,14 +742,6 @@ int main( int argc, char **argv ) { | |||
719 | case 'P': ot_try_bind( serverip, (uint16)atol( optarg ), 0 ); break; | 742 | case 'P': ot_try_bind( serverip, (uint16)atol( optarg ), 0 ); break; |
720 | case 'd': serverdir = optarg; break; | 743 | case 'd': serverdir = optarg; break; |
721 | case 'h': help( argv[0] ); exit( 0 ); | 744 | case 'h': help( argv[0] ); exit( 0 ); |
722 | #ifdef WANT_CLOSED_TRACKER | ||
723 | case 'o': g_closedtracker = 0; break; | ||
724 | case 'c': g_closedtracker = 1; break; | ||
725 | #endif | ||
726 | #ifdef WANT_BLACKLIST | ||
727 | case 'b': g_check_blacklist = 1; break; | ||
728 | case 'B': g_check_blacklist = 0; break; | ||
729 | #endif | ||
730 | default: | 745 | default: |
731 | case '?': usage( argv[0] ); exit( 1 ); | 746 | case '?': usage( argv[0] ); exit( 1 ); |
732 | } | 747 | } |
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 */ |
27 | static ot_vector all_torrents[256]; | 23 | static ot_vector all_torrents[256]; |
28 | static ot_vector changeset; | 24 | static ot_vector changeset; |
29 | size_t changeset_size = 0; | 25 | size_t changeset_size = 0; |
30 | time_t last_clean_time = 0; | 26 | time_t last_clean_time = 0; |
31 | 27 | ||
32 | #ifdef WANT_CLOSED_TRACKER | ||
33 | int g_closedtracker = 1; | ||
34 | static ot_torrent* const OT_TORRENT_NOT_ON_WHITELIST = (ot_torrent*)1; | ||
35 | #endif | ||
36 | |||
37 | #ifdef WANT_BLACKLIST | ||
38 | int g_check_blacklist = 1; | ||
39 | static 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 | ||
165 | ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) { | 151 | ot_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 | */ | ||
446 | int 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 | */ |
479 | size_t return_changeset_for_tracker( char **reply ) { | 485 | size_t return_changeset_for_tracker( char **reply ) { |
480 | size_t i, r = 8; | 486 | size_t i, r = 8; |
diff --git a/trackerlogic.h b/trackerlogic.h index dfd5047..4fa48eb 100644 --- a/trackerlogic.h +++ b/trackerlogic.h | |||
@@ -84,16 +84,10 @@ typedef struct { | |||
84 | int init_logic( const char * const serverdir ); | 84 | int init_logic( const char * const serverdir ); |
85 | void deinit_logic( void ); | 85 | void deinit_logic( void ); |
86 | 86 | ||
87 | #ifdef WANT_CLOSED_TRACKER | 87 | enum { STATS_MRTG, STATS_TOP5, STATS_DMEM, STATS_TCP, STATS_UDP, SYNC_IN, SYNC_OUT }; |
88 | extern int g_closedtracker; | ||
89 | #endif | ||
90 | #ifdef WANT_BLACKLIST | ||
91 | extern int g_check_blacklist; | ||
92 | #endif | ||
93 | |||
94 | enum { STATS_MRTG, STATS_TOP5, STATS_DMEM, STATS_TCP, STATS_UDP }; | ||
95 | 88 | ||
96 | ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ); | 89 | ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changeset ); |
90 | int add_changeset_to_tracker( ot_byte *data, size_t len ); | ||
97 | size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp ); | 91 | size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp ); |
98 | size_t return_fullscrape_for_tracker( char **reply ); | 92 | size_t return_fullscrape_for_tracker( char **reply ); |
99 | size_t return_tcp_scrape_for_torrent( ot_hash *hash, char *reply ); | 93 | size_t return_tcp_scrape_for_torrent( ot_hash *hash, char *reply ); |