From e0a9c2a4aa4fc6b648ae20071c35797c4a103e42 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Wed, 3 Jan 2007 05:11:48 +0000 Subject: Added option to get ip from query string + parser, fixed two bugs concerning grow/shrink of vectors. Now cleans up a torrent BEFORE trying to remove a peer -> this may remove peer already and must be done anyway. --- Makefile | 2 +- opentracker.c | 13 ++++++++++++- scan_urlencoded_query.c | 24 +++++++++++++++++++++--- scan_urlencoded_query.h | 7 +++++++ trackerlogic.c | 48 ++++++++++++++++++++++++++++++++---------------- trackerlogic.h | 4 ++++ 6 files changed, 77 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 7d7d15d..19163cc 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC?=gcc -CFLAGS+=-I../libowfat -Wall -pipe -Os +CFLAGS+=-I../libowfat -Wall -pipe -Os # -DWANT_IP_FROM_QUERY_STRING -g -ggdb LDFLAGS+=-L../libowfat/ -lowfat -s -lm HEADERS=trackerlogic.h scan_urlencoded_query.h diff --git a/opentracker.c b/opentracker.c index a1f0311..680caa4 100644 --- a/opentracker.c +++ b/opentracker.c @@ -186,6 +186,17 @@ e400: 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 e404; + 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 ); @@ -263,7 +274,7 @@ e500: httperror(h,"500 Internal Server Error","A server error has occured. Please retry later."); goto bailout; } - reply = malloc( SUCCESS_HTTP_HEADER_LENGTH + numwant*6 + 128 ); // http header + peerlist + seeder, peers and lametta 80 + n*6+81 a.t.m. + reply = malloc( SUCCESS_HTTP_HEADER_LENGTH + numwant * 6 + 128 ); // http header + peerlist + seeder, peers and lametta 80 + n*6+81 a.t.m. if( reply ) reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply ); if( !reply || ( reply_size <= 0 ) ) { diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c index 7bd5ee1..a21ec04 100644 --- a/scan_urlencoded_query.c +++ b/scan_urlencoded_query.c @@ -18,13 +18,13 @@ size_t scan_urlencoded_query(char **string, char *deststring, int flags) { unsigned char *d = (unsigned char*)deststring; register unsigned char b, c; - while ( is_unreserved( c = *s++) ) { - if (c=='%') { + while( is_unreserved( c = *s++) ) { + if( c=='%') { if( ( c = scan_fromhex(*s++) ) == 0xff ) return -1; if( ( b = scan_fromhex(*s++) ) == 0xff ) return -1; c=(c<<4)|b; } - if(d) *d++ = c; + if( d ) *d++ = c; } switch( c ) { @@ -55,3 +55,21 @@ size_t scan_fixed_int( char *data, size_t len, int *tmp ) { while( (len > 0) && (*data >= '0') && (*data <= '9') ) { --len; *tmp = 10**tmp + *data++-'0'; } return len; } + +size_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] ) { + int u, i; + + for( i=0; i<4; ++i ) { + register unsigned int j; + j = scan_fixed_int( data, len, &u ); + if( j == len ) return len; + ip[i] = u; + data += len - j; + len = j; + if ( i<3 ) { + if( !len || *data != '.') return -1; + --len; ++data; + } + } + return len; +} diff --git a/scan_urlencoded_query.h b/scan_urlencoded_query.h index c87dbee..5cc6630 100644 --- a/scan_urlencoded_query.h +++ b/scan_urlencoded_query.h @@ -15,6 +15,13 @@ 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 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 +size_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] ); + #endif diff --git a/trackerlogic.c b/trackerlogic.c index ece3261..762ad69 100644 --- a/trackerlogic.c +++ b/trackerlogic.c @@ -15,11 +15,19 @@ #include "scan.h" #include "byte.h" +// GLOBAL VARIABLES +// +static ot_vector all_torrents[256]; + // Helper functions for binary_find // int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); } int compare_ip_port( const void *peer1, const void *peer2 ) { return memcmp( peer1, peer2, 6 ); } +// 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 (*compar) (const void *, const void *), @@ -48,9 +56,6 @@ static void *binary_search( const void *key, const void *base, // char ths[1+2*20];char*to_hex(ot_byte*s){char*m="0123456789ABCDEF";char*e=ths+40;char*t=ths;while(t>4];*t++=m[*s++&15];}*t=0;return ths;} -// GLOBAL VARIABLES -// -static ot_vector all_torrents[256]; static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int(*compare_func)(const void*, const void*), int *exactmatch ) { ot_byte *match = BINARY_FIND( key, vector->data, vector->size, member_size, compare_func, exactmatch ); @@ -58,14 +63,15 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_ if( *exactmatch ) return match; if( vector->size + 1 >= vector->space ) { - ot_byte *new_data = realloc( vector->data, vector->space ? 2 * vector->space : 1024 ); + size_t new_space = vector->space ? OT_VECTOR_GROW_RATIO * vector->space : OT_VECTOR_MIN_MEMBERS; + ot_byte *new_data = realloc( vector->data, new_space * member_size ); if( !new_data ) return NULL; // Adjust pointer if it moved by realloc match = match - (ot_byte*)vector->data + new_data; vector->data = new_data; - vector->space = vector->space ? vector->space * 2 : 1024; + vector->space = new_space;; } MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); vector->size++; @@ -74,6 +80,7 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { int exactmatch; + ot_peer *end = ((ot_peer*)vector->data) + vector->size; ot_peer *match; if( !vector->size ) return 0; @@ -81,8 +88,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { if( !exactmatch ) return 0; exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1; - MEMMOVE( match, match + 1, ((ot_peer*)vector->data) + vector->size - match - 1 ); - vector->size--; + MEMMOVE( match, match + 1, end - match - 1 ); + if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { + vector->space /= OT_VECTOR_SHRINK_RATIO; + realloc( vector->data, vector->space * sizeof( ot_peer ) ); + } return exactmatch; } @@ -97,17 +107,19 @@ static void free_peerlist( ot_peerlist *peer_list ) { static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { int exactmatch; ot_torrent *end = ((ot_torrent*)vector->data) + vector->size; - ot_torrent *match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), compare_hash, &exactmatch ); + ot_torrent *match; + + if( !vector->size ) return 0; + match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), compare_hash, &exactmatch ); - if( !exactmatch ) return -1; + if( !exactmatch ) return 0; free_peerlist( match->peer_list ); MEMMOVE( match, match + 1, end - match - 1 ); - vector->size--; - if( ( 3*vector->size < vector->space ) && ( vector->space > 1024 ) ) { - realloc( vector->data, vector->space >> 1 ); - vector->space >>= 1; + if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { + vector->space /= OT_VECTOR_SHRINK_RATIO; + realloc( vector->data, vector->space * sizeof( ot_torrent ) ); } - return 0; + return 1; } // Returns 1, if torrent is gone, 0 otherwise @@ -253,14 +265,18 @@ void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ) { if( !exactmatch ) return; + // Maybe this does the job + if( clean_peerlist( torrent->peer_list ) ) { + vector_remove_torrent( torrents_list, hash ); + return; + } + for( i=0; ipeer_list->peers[i], peer ) ) { case 0: continue; case 2: torrent->peer_list->seed_count[i]--; case 1: default: return; } - - clean_peerlist( torrent->peer_list ); } void cleanup_torrents( void ) { diff --git a/trackerlogic.h b/trackerlogic.h index a5dce7c..7fcc73d 100644 --- a/trackerlogic.h +++ b/trackerlogic.h @@ -32,6 +32,10 @@ typedef time_t ot_time; #define OT_POOLS_TIMEOUT 300 #define NOW (time(NULL)/OT_POOLS_TIMEOUT) +#define OT_VECTOR_MIN_MEMBERS 128 +#define OT_VECTOR_GROW_RATIO 2 +#define OT_VECTOR_SHRINK_THRESH 3 +#define OT_VECTOR_SHRINK_RATIO 2 typedef struct { void *data; size_t size; -- cgit v1.2.3