From 805e46450cfa9400e30fd124c893dda18e050f2b Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Thu, 11 Jan 2007 01:06:10 +0000 Subject: [PATCH] Documentation improved, some reindenting (again), variable types checked, unnecessary defines removed --- Makefile | 2 +- opentracker.c | 402 ++++++++++++++++++++-------------------- scan_urlencoded_query.c | 16 +- scan_urlencoded_query.h | 29 +-- trackerlogic.c | 125 +++++++------ trackerlogic.h | 32 ++-- 6 files changed, 304 insertions(+), 302 deletions(-) diff --git a/Makefile b/Makefile index b6d7d7e..65937c6 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC?=gcc FEATURES=-DWANT_IP_FROM_QUERY_STRING #-DWANT_BLACKLIST -DWANT_CLOSED_TRACKER #DEBUG_OPTS=-g -ggdb -pg # -fprofile-arcs -ftest-coverage DEBUG_OPTS=-s -Os -CFLAGS+=-I../libowfat -Wall -pipe +CFLAGS+=-I../libowfat -Wall -pipe # -pedantic -ansi LDFLAGS+=-L../libowfat/ -lowfat -lm HEADERS=trackerlogic.h scan_urlencoded_query.h diff --git a/opentracker.c b/opentracker.c index ac09089..f4b5e21 100644 --- a/opentracker.c +++ b/opentracker.c @@ -6,8 +6,8 @@ #include "socket.h" #include "io.h" #include "buffer.h" -#include "ip6.h" #include "array.h" +#include "byte.h" #include "case.h" #include "fmt.h" #include "str.h" @@ -25,14 +25,14 @@ #include "trackerlogic.h" #include "scan_urlencoded_query.h" -unsigned long const OT_CLIENT_TIMEOUT = 15; -unsigned long const OT_CLIENT_TIMEOUT_CHECKINTERVAL = 5; +unsigned int const OT_CLIENT_TIMEOUT = 15; +unsigned int const OT_CLIENT_TIMEOUT_CHECKINTERVAL = 5; static unsigned int ot_overall_connections = 0; static time_t ot_start_time; -static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80; -static const unsigned int SUCCESS_HTTP_SIZE_OFF = 17; -// To always have space for error messages +static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; +static const size_t SUCCESS_HTTP_SIZE_OFF = 17; +/* To always have space for error messages ;) */ static char static_reply[8192]; static void carp(const char* routine) { @@ -49,13 +49,12 @@ static void panic(const char* routine) { struct http_data { array r; - unsigned long ip; + unsigned char ip[4]; }; int header_complete(struct http_data* r) { - long l = array_bytes(&r->r); + int l = array_bytes(&r->r), i; const char* c = array_start(&r->r); - long i; for (i=0; i+1r); - long sl = strlen(h); - const char* c = array_start(&r->r); - - for (i=0; i+sl+2r); + int sl = strlen(h); + const char* c = array_start(&r->r); + + for (i=0; i+sl+2r); - c = array_start(&h->r); - - if (byte_diff(c,4,"GET ")) { + char *c, *data; + ot_peer peer; + ot_torrent *torrent; + ot_hash *hash = NULL; + int numwant, tmp, scanon; + unsigned short port = htons(6881); + size_t reply_size = 0; + + array_cat0(&h->r); + c = array_start(&h->r); + + if (byte_diff(c,4,"GET ")) { e400: - return httperror(s,h,"400 Invalid Request","This server only understands GET."); - } - - c+=4; - for (data=c; *data!=' '&&*data!='\t'&&*data!='\n'&&*data!='\r'; ++data) ; - - if (*data!=' ') goto e400; - *data=0; - if (c[0]!='/') goto e404; - while (*c=='/') ++c; + return httperror(s,h,"400 Invalid Request","This server only understands GET."); + } - switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) - { - case 6: /* scrape ? */ - if (byte_diff(data,6,"scrape")) + c+=4; + for (data=c; *data!=' '&&*data!='\t'&&*data!='\n'&&*data!='\r'; ++data) ; + + if (*data!=' ') goto e400; + *data=0; + if (c[0]!='/') goto e404; + while (*c=='/') ++c; + + switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) { + case 6: /* scrape ? */ + if (byte_diff(data,6,"scrape")) + goto e404; + scanon = 1; + + while( scanon ) { + switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { + case -2: /* terminator */ + scanon = 0; + break; + case -1: /* error */ goto e404; - scanon = 1; - - while( scanon ) { - switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { - case -2: /* terminator */ - scanon = 0; - break; - case -1: /* error */ - goto e404; - case 9: - if(byte_diff(data,9,"info_hash")) { - scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); - continue; - } - /* ignore this, when we have less than 20 bytes */ - if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) { -e400_param: - return httperror(s,h,"400 Invalid Request","Invalid parameter"); - } - hash = (ot_hash*)data; /* Fall through intended */ - break; - default: + case 9: + if(byte_diff(data,9,"info_hash")) { scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); - break; + continue; + } + /* ignore this, when we have less than 20 bytes */ + if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) { +e400_param: + return httperror(s,h,"400 Invalid Request","Invalid parameter"); } + hash = (ot_hash*)data; /* Fall through intended */ + break; + default: + scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); + break; } + } - /* Scanned whole query string, wo */ - if( !hash ) - return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes."); - - // Enough for http header + whole scrape string - if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 ) - goto e500; - break; - case 8: - if( byte_diff(data,8,"announce")) + /* Scanned whole query string, wo */ + if( !hash ) + return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes."); + + /* Enough for http header + whole scrape string */ + if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 ) + goto e500; + break; + case 8: + if( byte_diff(data,8,"announce")) + goto e404; + + OT_SETIP( &peer, h->ip); + OT_SETPORT( &peer, &port ); + OT_FLAG( &peer ) = 0; + numwant = 50; + scanon = 1; + + while( scanon ) { + switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { + case -2: /* terminator */ + scanon = 0; + break; + case -1: /* error */ goto e404; - - OT_SETIP( &peer, &h->ip); - OT_SETPORT( &peer, &port ); - OT_FLAG( &peer ) = 0; - numwant = 50; - scanon = 1; - - while( scanon ) { - switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { - case -2: /* terminator */ - scanon = 0; - break; - case -1: /* error */ - goto e404; #ifdef WANT_IP_FROM_QUERY_STRING - case 2: - if(!byte_diff(data,2,"ip")) { - size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); - unsigned char ip[4]; - if( ( len <= 0 ) || scan_fixed_ip( data, len, ip ) ) goto e400_param; - OT_SETIP ( &peer, ip ); - } else - scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); - break; + case 2: + if(!byte_diff(data,2,"ip")) { + size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); + unsigned char ip[4]; + if( ( len <= 0 ) || scan_fixed_ip( data, len, ip ) ) goto e400_param; + OT_SETIP ( &peer, ip ); + } else + scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); + break; #endif - case 4: - if(!byte_diff(data,4,"port")) { - size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); - if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) || ( tmp > 0xffff ) ) goto e400_param; - port = htons( tmp ); OT_SETPORT ( &peer, &port ); - } else if(!byte_diff(data,4,"left")) { - size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); - if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param; - if( !tmp ) OT_FLAG( &peer ) |= PEER_FLAG_SEEDING; - } else - scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); - break; - case 5: - if(byte_diff(data,5,"event")) - scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); - else switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) { - case -1: - goto e400_param; - case 7: - if(!byte_diff(data,7,"stopped")) OT_FLAG( &peer ) |= PEER_FLAG_STOPPED; - break; - case 9: - if(!byte_diff(data,9,"complete")) OT_FLAG( &peer ) |= PEER_FLAG_COMPLETED; - default: // Fall through intended - break; - } - break; + case 4: + if(!byte_diff(data,4,"port")) { + size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); + if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) || ( tmp > 0xffff ) ) goto e400_param; + port = htons( tmp ); OT_SETPORT ( &peer, &port ); + } else if(!byte_diff(data,4,"left")) { + size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); + if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param; + if( !tmp ) OT_FLAG( &peer ) |= PEER_FLAG_SEEDING; + } else + scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); + break; + case 5: + if(byte_diff(data,5,"event")) + scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); + else switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) { + case -1: + goto e400_param; case 7: - if(!byte_diff(data,7,"numwant")) { - size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); - if( ( len <= 0 ) || scan_fixed_int( data, len, &numwant ) ) goto e400_param; - if( numwant > 200 ) numwant = 200; - } else if(!byte_diff(data,7,"compact")) { - size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); - if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param; - if( !tmp ) - return httperror(s,h,"400 Invalid Request","This server only delivers compact results."); - } else - scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); + if(!byte_diff(data,7,"stopped")) OT_FLAG( &peer ) |= PEER_FLAG_STOPPED; break; case 9: - if(byte_diff(data,9,"info_hash")) { - scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); - continue; - } - /* ignore this, when we have less than 20 bytes */ - if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) - goto e400; - hash = (ot_hash*)data; + if(!byte_diff(data,9,"complete")) OT_FLAG( &peer ) |= PEER_FLAG_COMPLETED; + default: /* Fall through intended */ break; - default: + } + break; + case 7: + if(!byte_diff(data,7,"numwant")) { + size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); + if( ( len <= 0 ) || scan_fixed_int( data, len, &numwant ) ) goto e400_param; + if( numwant > 200 ) numwant = 200; + } else if(!byte_diff(data,7,"compact")) { + size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); + if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) goto e400_param; + if( !tmp ) + return httperror(s,h,"400 Invalid Request","This server only delivers compact results."); + } else scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); - break; + break; + case 9: + if(byte_diff(data,9,"info_hash")) { + scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); + continue; } + /* ignore this, when we have less than 20 bytes */ + if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) + goto e400; + hash = (ot_hash*)data; + break; + default: + scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); + break; } + } - /* Scanned whole query string */ - if( !hash ) goto e400; + /* Scanned whole query string */ + if( !hash ) goto e400; - if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) { - remove_peer_from_torrent( hash, &peer ); - MEMMOVE( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 ); - } else { - torrent = add_peer_to_torrent( hash, &peer ); - if( !torrent ) { + if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) { + remove_peer_from_torrent( hash, &peer ); + memmove( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 ); + } else { + torrent = add_peer_to_torrent( hash, &peer ); + if( !torrent ) { e500: - return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later."); - } - if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 ) - goto e500; + return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later."); } - break; - case 11: - if( byte_diff(data,11,"mrtg_scrape")) - goto e404; - { - unsigned long seconds_elapsed = time( NULL ) - ot_start_time; - reply_size = sprintf( static_reply + SUCCESS_HTTP_HEADER_LENGTH, - "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.", - ot_overall_connections, ot_overall_connections, seconds_elapsed, - seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) ); - } - break; - default: /* neither *scrape nor announce */ -e404: - return httperror(s,h,"404 Not Found","No such file or directory."); + if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 ) + goto e500; } - - if( reply_size ) { - size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size ); - reply_size += 1 + sprintf( static_reply + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size ); - static_reply[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n'; - senddata( s, h, static_reply + reply_off, reply_size ); - } else { - if( h ) array_reset(&h->r); - free( h ); io_close( s ); + break; + case 11: + if( byte_diff(data,11,"mrtg_scrape")) + goto e404; + { + time_t seconds_elapsed = time( NULL ) - ot_start_time; + reply_size = sprintf( static_reply + SUCCESS_HTTP_HEADER_LENGTH, + "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.", + ot_overall_connections, ot_overall_connections, seconds_elapsed, + seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) ); } + break; + default: /* neither *scrape nor announce */ +e404: + return httperror(s,h,"404 Not Found","No such file or directory."); + } + + if( reply_size ) { + /* This one is rather ugly, so I take you step by step through it. + + 1. In order to avoid having two buffers, one for header and one for content, we allow all above functions from trackerlogic to + write to a fixed location, leaving SUCCESS_HTTP_HEADER_LENGTH bytes in our static buffer, which is enough for the static string + plus dynamic space needed to expand our Content-Length value. We reserve SUCCESS_HTTP_SIZE_OFF for it expansion and calculate + the space NOT needed to expand in reply_off + */ + size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size ); + + /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete + packet size is increased by size of header plus one byte '\n', we will copy over '\0' in next step */ + reply_size += 1 + sprintf( static_reply + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size ); + + /* 3. Finally we join both blocks neatly */ + static_reply[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n'; + + senddata( s, h, static_reply + reply_off, reply_size ); + } else { + if( h ) array_reset(&h->r); + free( h ); io_close( s ); + } } void graceful( int s ) { @@ -346,10 +352,10 @@ void help( char *name ) { int main( int argc, char **argv ) { int s=socket_tcp4(); tai6464 t, next_timeout_check; - unsigned long ip; char *serverip = NULL; char *serverdir = "."; uint16 port = 6969; + unsigned char ip[4]; while( 1 ) { switch( getopt(argc,argv,":i:p:d:ocbBh") ) { @@ -412,16 +418,16 @@ allparsed: } while( ( i = io_canread() ) != -1 ) { - if( i == s ) { // ist es der serversocket? + if( i == s ) { int n; - while( ( n = socket_accept4( s, (void*)&ip, &port) ) != -1 ) { + while( ( n = socket_accept4( s, (char*)ip, &port) ) != -1 ) { if( io_fd( n ) ) { struct http_data* h=(struct http_data*)malloc(sizeof(struct http_data)); io_wantread(n); if (h) { byte_zero(h,sizeof(struct http_data)); - h->ip=ip; + memmove(h->ip,ip,sizeof(ip)); taia_now(&t); taia_addsec(&t,&t,OT_CLIENT_TIMEOUT); io_timeout(n,t); @@ -437,7 +443,7 @@ allparsed: else carp("socket_accept4"); } else { - char buf[8192]; + /* unsigned (sic!) */ char buf[8192]; struct http_data* h=io_getcookie(i); int l=io_tryread(i,buf,sizeof buf); diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c index ec145f9..223a4ad 100644 --- a/scan_urlencoded_query.c +++ b/scan_urlencoded_query.c @@ -4,15 +4,15 @@ #include "scan.h" #include "scan_urlencoded_query.h" -// Idea is to do a in place replacement or guarantee at least -// strlen( string ) bytes in deststring -// watch http://www.ietf.org/rfc/rfc2396.txt -// unreserved = alphanum | mark -// mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" -// we add '%' to the matrix to not stop at encoded chars. - +/* Idea is to do a in place replacement or guarantee at least + strlen( string ) bytes in deststring + watch http://www.ietf.org/rfc/rfc2396.txt + unreserved = alphanum | mark + mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" + we add '%' to the matrix to not stop at encoded chars. +*/ static const unsigned char reserved_matrix[] = { 0xA2, 0x63, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x47}; -inline int is_unreserved( unsigned char c ) { +static int is_unreserved( unsigned char c ) { if( ( c <= 32 ) || ( c >= 127 ) ) return 0; return 1&(reserved_matrix[(c-32)>>3]>>(c&7)); } diff --git a/scan_urlencoded_query.h b/scan_urlencoded_query.h index 83f9be0..7663278 100644 --- a/scan_urlencoded_query.h +++ b/scan_urlencoded_query.h @@ -8,23 +8,26 @@ #define SCAN_SEARCHPATH_PARAM 1 #define SCAN_SEARCHPATH_VALUE 2 -// string pointer to source, pointer to after terminator on return -// deststring pointer to destination -// flags determines, what to parse -// returns number of valid converted characters in deststring -// or -1 for parse error +/* string pointer to source, pointer to after terminator on return + deststring pointer to destination + flags determines, what to parse + returns number of valid converted characters in deststring + or -1 for parse error +*/ size_t scan_urlencoded_query(char **string, char *deststring, int flags); -// data pointer to len chars of string -// len length of chars in data to parse -// number number to receive result -// returns number of bytes not parsed, mostly !=0 means fail +/* data pointer to len chars of string + len length of chars in data to parse + number number to receive result + returns number of bytes not parsed, mostly !=0 means fail +*/ size_t scan_fixed_int( char *data, size_t len, int *number ); -// data pointer to len chars of string -// len length of chars in data to parse -// ip buffer to receive result -// returns number of bytes not parsed, mostly !=0 means fail +/* data pointer to len chars of string + len length of chars in data to parse + ip buffer to receive result + returns number of bytes not parsed, mostly !=0 means fail +*/ size_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] ); #endif diff --git a/trackerlogic.c b/trackerlogic.c index 85e8156..2b8ffaf 100644 --- a/trackerlogic.c +++ b/trackerlogic.c @@ -22,8 +22,7 @@ #include #endif -// GLOBAL VARIABLES -// +/* GLOBAL VARIABLES */ static ot_vector all_torrents[256]; #ifdef WANT_CLOSED_TRACKER @@ -36,36 +35,37 @@ int g_check_blacklist = 1; static ot_torrent* const OT_TORRENT_ON_BLACKLIST = (ot_torrent*)2; #endif -// This function gives us a binary search that returns a pointer, even if -// no exact match is found. In that case it sets exactmatch 0 and gives -// calling functions the chance to insert data -// -static void *binary_search( const void *key, const void *base, unsigned long member_count, const unsigned long member_size, - int compare_size, int *exactmatch ) { +/* This function gives us a binary search that returns a pointer, even if + no exact match is found. In that case it sets exactmatch 0 and gives + calling functions the chance to insert data +*/ +static void *binary_search( const void * const key, const void * base, const size_t member_count, const size_t member_size, + size_t compare_size, int *exactmatch ) { + size_t mc = member_count; ot_byte *lookat = ((ot_byte*)base) + member_size * (member_count >> 1); *exactmatch = 1; - while( member_count ) { + while( mc ) { int cmp = memcmp( lookat, key, compare_size); if (cmp == 0) return (void *)lookat; if (cmp < 0) { base = (void*)(lookat + member_size); - --member_count; + --mc; } - member_count >>= 1; - lookat = ((ot_byte*)base) + member_size * (member_count >> 1); + mc >>= 1; + lookat = ((ot_byte*)base) + member_size * (mc >> 1); } *exactmatch = 0; return (void*)lookat; } -// Converter function from memory to human readable hex strings -// * definitely not thread safe!!! -// +/* Converter function from memory to human readable hex strings + - definitely not thread safe!!! +*/ char ths[2+2*20]="-";char*to_hex(ot_byte*s){char*m="0123456789ABCDEF";char*e=ths+41;char*t=ths+1;while(t>4];*t++=m[*s++&15];}*t=0;return ths+1;} static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int compare_size, int *exactmatch ) { - ot_byte *match = BINARY_FIND( key, vector->data, vector->size, member_size, compare_size, exactmatch ); + ot_byte *match = binary_search( key, vector->data, vector->size, member_size, compare_size, exactmatch ); if( *exactmatch ) return match; @@ -74,13 +74,13 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_ ot_byte *new_data = realloc( vector->data, new_space * member_size ); if( !new_data ) return NULL; - // Adjust pointer if it moved by realloc + /* Adjust pointer if it moved by realloc */ match = new_data + (match - (ot_byte*)vector->data); vector->data = new_data; vector->space = new_space; } - MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); + memmove( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); vector->size++; return match; } @@ -91,11 +91,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { ot_peer *match; if( !vector->size ) return 0; - match = BINARY_FIND( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch ); + match = binary_search( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch ); if( !exactmatch ) return 0; exactmatch = ( OT_FLAG( match ) & PEER_FLAG_SEEDING ) ? 2 : 1; - MEMMOVE( match, match + 1, sizeof(ot_peer) * ( end - match - 1 ) ); + memmove( match, match + 1, sizeof(ot_peer) * ( end - match - 1 ) ); if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { vector->space /= OT_VECTOR_SHRINK_RATIO; vector->data = realloc( vector->data, vector->space * sizeof( ot_peer ) ); @@ -117,15 +117,15 @@ static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { ot_torrent *match; if( !vector->size ) return 0; - match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); + match = binary_search( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( !exactmatch ) return 0; - // If this is being called after a unsuccessful malloc() for peer_list - // in add_peer_to_torrent, match->peer_list actually might be NULL + /* If this is being called after a unsuccessful malloc() for peer_list + in add_peer_to_torrent, match->peer_list actually might be NULL */ if( match->peer_list) free_peerlist( match->peer_list ); - MEMMOVE( match, match + 1, sizeof(ot_torrent) * ( end - match - 1 ) ); + memmove( match, match + 1, sizeof(ot_torrent) * ( end - match - 1 ) ); if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { vector->space /= OT_VECTOR_SHRINK_RATIO; vector->data = realloc( vector->data, vector->space * sizeof( ot_torrent ) ); @@ -133,22 +133,21 @@ static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { return 1; } -// Returns 1, if torrent is gone, 0 otherwise +/* Returns 1, if torrent is gone, 0 otherwise */ static int clean_peerlist( ot_peerlist *peer_list ) { - long timedout = NOW-peer_list->base; - int i; + int i, timedout = (int)( NOW - peer_list->base ); if( !timedout ) return 0; if( timedout > OT_POOLS_COUNT ) timedout = OT_POOLS_COUNT; - for( i=OT_POOLS_COUNT-timedout; ipeers[i].data); - MEMMOVE( peer_list->peers + timedout, peer_list->peers, sizeof( ot_vector ) * (OT_POOLS_COUNT-timedout) ); + memmove( peer_list->peers + timedout, peer_list->peers, sizeof( ot_vector ) * (OT_POOLS_COUNT-timedout) ); byte_zero( peer_list->peers, sizeof( ot_vector ) * timedout ); - MEMMOVE( peer_list->seed_count + timedout, peer_list->seed_count, sizeof( unsigned long ) * (OT_POOLS_COUNT-timedout) ); - byte_zero( peer_list->seed_count, sizeof( unsigned long ) * timedout ); + memmove( peer_list->seed_count + timedout, peer_list->seed_count, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout) ); + byte_zero( peer_list->seed_count, sizeof( size_t ) * timedout ); peer_list->base = NOW; return timedout == OT_POOLS_COUNT; @@ -178,8 +177,8 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) { if( !torrent ) return NULL; if( !exactmatch ) { - // Create a new torrent entry, then - MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) ); + /* Create a new torrent entry, then */ + memmove( &torrent->hash, hash, sizeof( ot_hash ) ); torrent->peer_list = malloc( sizeof (ot_peerlist) ); if( !torrent->peer_list ) { @@ -195,11 +194,11 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) { peer_pool = &torrent->peer_list->peers[0]; peer_dest = vector_find_or_insert( peer_pool, (void*)peer, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch ); - // If we hadn't had a match in current pool, create peer there and - // remove it from all older pools + /* If we hadn't had a match in current pool, create peer there and + remove it from all older pools */ if( !exactmatch ) { int i; - MEMMOVE( peer_dest, peer, sizeof( ot_peer ) ); + memmove( peer_dest, peer, sizeof( ot_peer ) ); if( OT_FLAG(peer) & PEER_FLAG_SEEDING ) torrent->peer_list->seed_count[0]++; for( i=1; i= peer_count ) { wert--; pool_offset--; } - while( pool_offset >= torrent->peer_list->peers[pool_index].size ) { pool_offset -= torrent->peer_list->peers[pool_index].size; pool_index++; } - MEMMOVE( r, ((ot_peer*)torrent->peer_list->peers[pool_index].data) + pool_offset, 6 ); + memmove( r, ((ot_peer*)torrent->peer_list->peers[pool_index].data) + pool_offset, 6 ); r += 6; } *r++ = 'e'; @@ -275,12 +273,12 @@ size_t return_peers_for_torrent( ot_torrent *torrent, unsigned long amount, char return r - reply; } -// Fetches scrape info for a specific torrent +/* Fetches scrape info for a specific torrent */ size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) { char *r = reply; int exactmatch, peers = 0, seeds = 0, i; ot_vector *torrents_list = &all_torrents[*hash[0]]; - ot_torrent *torrent = BINARY_FIND( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); + ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( !exactmatch ) return 0; clean_peerlist( torrent->peer_list ); @@ -290,8 +288,8 @@ size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) { seeds += torrent->peer_list->seed_count[i]; } - MEMMOVE( r, "d5:filesd20:", 12 ); MEMMOVE( r+12, hash, 20 ); - r += FORMAT_FORMAT_STRING( r+32, "d8:completei%de10:downloadedi%lde10:incompletei%deeee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 32; + memmove( r, "d5:filesd20:", 12 ); memmove( r+12, hash, 20 ); + r += sprintf( r+32, "d8:completei%de10:downloadedi%de10:incompletei%deeee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 32; return r - reply; } @@ -299,11 +297,11 @@ size_t return_scrape_for_torrent( ot_hash *hash, char *reply ) { void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ) { int exactmatch, i; ot_vector *torrents_list = &all_torrents[*hash[0]]; - ot_torrent *torrent = BINARY_FIND( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); + ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( !exactmatch ) return; - // Maybe this does the job + /* Maybe this does the job */ if( clean_peerlist( torrent->peer_list ) ) { #ifdef WANT_CLOSED_TRACKER if( !g_closedtracker ) @@ -332,7 +330,7 @@ int init_logic( char *serverdir ) { srandom( time(NULL)); - // Initialize control structures + /* Initialize control structures */ byte_zero( all_torrents, sizeof (all_torrents)); return 0; @@ -340,7 +338,8 @@ int init_logic( char *serverdir ) { void deinit_logic( ) { int i, j; - // Free all torrents... + + /* Free all torrents... */ for(i=0; i<256; ++i ) { if( all_torrents[i].size ) { ot_torrent *torrents_list = (ot_torrent*)all_torrents[i].data; diff --git a/trackerlogic.h b/trackerlogic.h index 812cfce..178f8db 100644 --- a/trackerlogic.h +++ b/trackerlogic.h @@ -18,18 +18,12 @@ typedef ot_byte ot_hash[20]; typedef ot_dword ot_ip; typedef time_t ot_time; -#define MEMMOVE memmove -#define BZERO bzero -#define FORMAT_FIXED_STRING sprintf -#define FORMAT_FORMAT_STRING sprintf -#define BINARY_FIND binary_search +/* We maintain a list of 256 pointers to sorted list of ot_torrent structs + Sort key is, of course, its hash */ -// We maintain a list of 256 pointers to sorted list of ot_torrent structs -// Sort key is, of course, its hash - -// This list points to 9 pools of peers each grouped in five-minute-intervals -// thus achieving a timeout of 2700s or 45 minutes -// These pools are sorted by its binary content +/* This list points to 9 pools of peers each grouped in five-minute-intervals + thus achieving a timeout of 2700s or 45 minutes + These pools are sorted by its binary content */ #define OT_POOLS_COUNT 9 #define OT_POOLS_TIMEOUT 300 @@ -52,8 +46,8 @@ static const ot_byte PEER_FLAG_SEEDING = 0x80; static const ot_byte PEER_FLAG_COMPLETED = 0x40; static const ot_byte PEER_FLAG_STOPPED = 0x20; -#define OT_SETIP( peer, ip ) MEMMOVE((peer),(ip),4); -#define OT_SETPORT( peer, port ) MEMMOVE(((ot_byte*)peer)+4,(port),2); +#define OT_SETIP( peer, ip ) memmove((peer),(ip),4); +#define OT_SETPORT( peer, port ) memmove(((ot_byte*)peer)+4,(port),2); #define OT_FLAG(peer) (((ot_byte*)(peer))[6]) #define OT_PEER_COMPARE_SIZE ((size_t)6) @@ -61,8 +55,8 @@ static const ot_byte PEER_FLAG_STOPPED = 0x20; typedef struct { ot_time base; - unsigned long seed_count[ OT_POOLS_COUNT ]; - unsigned long downloaded; + size_t seed_count[ OT_POOLS_COUNT ]; + unsigned int downloaded; ot_vector peers[ OT_POOLS_COUNT ]; } ot_peerlist; @@ -71,9 +65,9 @@ typedef struct { ot_peerlist *peer_list; } ot_torrent; -// -// Exported functions -// +/* + Exported functions +*/ int init_logic( char *serverdir ); void deinit_logic( ); @@ -86,7 +80,7 @@ extern int g_check_blacklist; #endif 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 ); +size_t return_peers_for_torrent( ot_torrent *torrent, unsigned int amount, char *reply ); size_t return_scrape_for_torrent( ot_hash *hash, char *reply ); void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ); void cleanup_torrents( void );