From 62a9b0253280d5ef9636bcee5e26c3a288d0a9ec Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Fri, 8 Dec 2006 21:36:26 +0000 Subject: Should work now *cough* *cough* --- opentracker.c | 61 +++++++++++++++++++++++++++++++++++++++------------------- trackerlogic.c | 24 ++++++++++++----------- trackerlogic.h | 14 ++++++++------ 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/opentracker.c b/opentracker.c index 8313d90..d46858d 100644 --- a/opentracker.c +++ b/opentracker.c @@ -97,15 +97,20 @@ const char* http_header(struct http_data* r,const char* h) if (*c==' ' || *c=='\t') ++c; return c; } - return 0; + return 0; } + return 0; } void httpresponse(struct http_data* h,int64 s) { - char *c, *d, *data; + char *c, *d, *data, *reply = NULL; struct ot_peer peer; + ot_torrent torrent; ot_hash *hash = NULL; + unsigned long numwant; + int compact; + size_t reply_size = 0; array_cat0(&h->r); @@ -128,10 +133,6 @@ e400: while (c[1]=='/') ++c; switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) { - case 0: -e404: - httperror(h,"404 Not Found","No such file or directory."); - goto bailout; case 6: /* scrape ? */ if (!byte_diff(c,6,"scrape")) goto e404; @@ -142,6 +143,8 @@ e404: byte_copy( peer.ip, 4, h->ip ); peer.port = 6881; + numwant = 50; + compact = 1; while( 1 ) { switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { @@ -158,24 +161,42 @@ e404: /* scan int */ c; else if(!byte_diff(c,7,"compact")) /* scan flag */ c; - break; - case 9: /* info_hash= */ - if(!byte_diff(c,9,"info_hash")) { - /* ignore this, when we have less than 20 bytes */ - switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) - case -1: - httperror(h,"404 Not Found","No such file or directory."); - goto bailout; - case 20: - hash = (ot_hash*)data; /* Fall through intended */ - default: - continue; + break; + case 9: + if(byte_diff(c,9,"info_hash")) + continue; + /* ignore this, when we have less than 20 bytes */ + switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) { + case -1: + goto e404; + case 20: + hash = (ot_hash*)data; /* Fall through intended */ + default: + continue; } - break; + default: + continue; } } + + /* Scanned whole query string */ + if( !hash || ( compact == 0 ) ) goto e404; + torrent = add_peer_to_torrent( hash, &peer ); + if( !torrent ) { +e500: + httperror(h,"500 Internal Server Error","A server error has occured. Please retry later."); + goto bailout; + } + reply = malloc( numwant*6+10 ); + if( reply ) + reply_size = return_peers_for_torrent( torrent, numwant, reply ); + if( !reply || reply_size < 0 ) { + if( reply ) free( reply ); + goto e500; + } break; default: /* neither scrape nor announce */ +e404: httperror(h,"404 Not Found","No such file or directory."); goto bailout; } @@ -190,7 +211,7 @@ e404: c+=fmt_httpdate(c,s.st_mtime); */ c+=fmt_str(c,"\r\nConnection: close\r\n\r\n"); iob_addbuf(&h->iob,h->hdrbuf,c - h->hdrbuf); - iob_addbuf(&h->iob,tracker_answer, tracker_answer_size); + if( reply && reply_size ) iob_addbuf(&h->iob,reply, reply_size ); bailout: io_dontwantread(s); diff --git a/trackerlogic.c b/trackerlogic.c index 6274c41..ab1f419 100644 --- a/trackerlogic.c +++ b/trackerlogic.c @@ -54,7 +54,7 @@ ot_byte *scratch_space = 0; #define TESTSET( i ) (scratch_space[index]) #define RANDOM random() -ot_torrent add_peer_to_torrent( ot_hash hash, ot_peer peer ) { +ot_torrent add_peer_to_torrent( ot_hash *hash, ot_peer peer ) { ot_torrent torrent; ot_peer peer_dest; int exactmatch; @@ -66,7 +66,7 @@ ot_torrent add_peer_to_torrent( ot_hash hash, ot_peer peer ) { // Create a new torrent entry, then MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) ); - torrent->peer_list = map_file( to_hex( hash ) ); + torrent->peer_list = map_file( to_hex( *hash ) ); torrent->peer_count = 0; torrent->seed_count = 0; } @@ -106,8 +106,9 @@ inline int TESTVALIDPEER( ot_peer p ) { return p->death > NOW; } // * it is not guaranteed to see all peers, so no assumptions on active seeders/peers may be done // * since compact format cannot handle v6 addresses, it must be enabled by OT_COMPACT_ONLY // -void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply ) { +size_t return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply ) { register ot_peer peer_base = torrent->peer_list; + char *r = reply; unsigned long peer_count = torrent->peer_count; unsigned long selected_count = 0, invalid_count = 0; unsigned long index = 0; @@ -132,9 +133,9 @@ void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *r index = 0; #ifndef OT_COMPACT_ONLY - reply += FORMAT_FIXED_STRING( reply, "d5:peersl" ); + r += FORMAT_FIXED_STRING( r, "d5:peersl" ); #else - reply += FORMAT_FORMAT_STRING( reply, "d5:peers%li:",6*selected_count ); + r += FORMAT_FORMAT_STRING( r, "d5:peers%li:",6*selected_count ); #endif while( selected_count-- ) { @@ -142,11 +143,11 @@ void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *r while( !TESTSELECTED( index ) ) ++index; peer = peer_base + index; #ifdef OT_COMPACT_ONLY - MEMMOVE( reply, &peer->ip, 4 ); - MEMMOVE( reply+4, &peer->port, 2 ); - reply += 6; + MEMMOVE( r, &peer->ip, 4 ); + MEMMOVE( r+4, &peer->port, 2 ); + r += 6; #else - reply += FORMAT_FORMAT_STRING( reply, "d2:ip%d:%s7:peer id20:%20c4:porti%ie", + r += FORMAT_FORMAT_STRING( r, "d2:ip%d:%s7:peer id20:%20c4:porti%ie", peer->flags & PEER_IP_LENGTH_MASK, peer->ip, peer->id, @@ -154,10 +155,11 @@ void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *r #endif } #ifndef OT_COMPACT_ONLY - reply += FORMAT_FIXED_STRING( reply, "ee" ); + r += FORMAT_FIXED_STRING( r, "ee" ); #else - reply += FORMAT_FIXED_STRING( reply, "e" ); + r += FORMAT_FIXED_STRING( r, "e" ); #endif + return r - reply; } // Compacts a torrents peer list diff --git a/trackerlogic.h b/trackerlogic.h index 03ed577..ad18cba 100644 --- a/trackerlogic.h +++ b/trackerlogic.h @@ -1,6 +1,8 @@ #ifndef __TRACKERLOGIC_H__ #define __TRACKERLOGIC_H__ +#include + /* Should be called BYTE, WORD, DWORD - but some OSs already have that and there's no #iftypedef */ /* They mark memory used as data instead of integer or human readable string - they should be cast before used as integer/text */ @@ -12,8 +14,8 @@ typedef unsigned long ot_time; typedef ot_byte ot_hash[20]; typedef ot_byte ot_ip[ 4/*0*/ ]; // tunables -const unsigned long OT_TIMEOUT = 2700; -const unsigned long OT_HUGE_FILESIZE = 1024*1024*256; // Thats 256MB per file, enough for 204800 peers of 128 bytes +static const unsigned long OT_TIMEOUT = 2700; +static const unsigned long OT_HUGE_FILESIZE = 1024*1024*256; // Thats 256MB per file, enough for 204800 peers of 128 bytes // We will not service v6, yes #define OT_COMPACT_ONLY @@ -35,8 +37,8 @@ typedef struct ot_peer { ot_time death; ot_byte flags; } *ot_peer; -ot_byte PEER_FLAG_SEEDING = 0x80; -ot_byte PEER_IP_LENGTH_MASK = 0x3f; +static const ot_byte PEER_FLAG_SEEDING = 0x80; +static const ot_byte PEER_IP_LENGTH_MASK = 0x3f; typedef struct { ot_hash hash; @@ -64,8 +66,8 @@ void *binary_search( const void *key, const void *base, int init_logic( char *chdir_directory ); void deinit_logic( ); -ot_torrent add_peer_to_torrent( ot_hash hash, ot_peer peer ); -void return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply ); +ot_torrent add_peer_to_torrent( ot_hash *hash, ot_peer peer ); +size_t return_peers_for_torrent( ot_torrent torrent, unsigned long amount, char *reply ); void heal_torrent( ot_torrent torrent ); #endif -- cgit v1.2.3