Browse Source

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.

dynamic-accesslists
erdgeist 18 years ago
parent
commit
e0a9c2a4aa
  1. 2
      Makefile
  2. 13
      opentracker.c
  3. 24
      scan_urlencoded_query.c
  4. 7
      scan_urlencoded_query.h
  5. 48
      trackerlogic.c
  6. 4
      trackerlogic.h

2
Makefile

@ -1,5 +1,5 @@
CC?=gcc 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 LDFLAGS+=-L../libowfat/ -lowfat -s -lm
HEADERS=trackerlogic.h scan_urlencoded_query.h HEADERS=trackerlogic.h scan_urlencoded_query.h

13
opentracker.c

@ -186,6 +186,17 @@ e400:
break; break;
case -1: /* error */ case -1: /* error */
goto e404; 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: case 4:
if(!byte_diff(data,4,"port")) { if(!byte_diff(data,4,"port")) {
size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); 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."); httperror(h,"500 Internal Server Error","A server error has occured. Please retry later.");
goto bailout; 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 ) if( reply )
reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply ); reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply );
if( !reply || ( reply_size <= 0 ) ) { if( !reply || ( reply_size <= 0 ) ) {

24
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; unsigned char *d = (unsigned char*)deststring;
register unsigned char b, c; register unsigned char b, c;
while ( is_unreserved( c = *s++) ) { while( is_unreserved( c = *s++) ) {
if (c=='%') { if( c=='%') {
if( ( c = scan_fromhex(*s++) ) == 0xff ) return -1; if( ( c = scan_fromhex(*s++) ) == 0xff ) return -1;
if( ( b = scan_fromhex(*s++) ) == 0xff ) return -1; if( ( b = scan_fromhex(*s++) ) == 0xff ) return -1;
c=(c<<4)|b; c=(c<<4)|b;
} }
if(d) *d++ = c; if( d ) *d++ = c;
} }
switch( 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'; } while( (len > 0) && (*data >= '0') && (*data <= '9') ) { --len; *tmp = 10**tmp + *data++-'0'; }
return len; 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;
}

7
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 // data pointer to len chars of string
// len length of chars in data to parse // len length of chars in data to parse
// number number to receive result // 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 ); 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 #endif

48
trackerlogic.c

@ -15,11 +15,19 @@
#include "scan.h" #include "scan.h"
#include "byte.h" #include "byte.h"
// GLOBAL VARIABLES
//
static ot_vector all_torrents[256];
// Helper functions for binary_find // Helper functions for binary_find
// //
int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); } 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 ); } 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, static void *binary_search( const void *key, const void *base,
unsigned long member_count, const unsigned long member_size, unsigned long member_count, const unsigned long member_size,
int (*compar) (const void *, const void *), 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<e){*t++=m[*s>>4];*t++=m[*s++&15];}*t=0;return ths;} char ths[1+2*20];char*to_hex(ot_byte*s){char*m="0123456789ABCDEF";char*e=ths+40;char*t=ths;while(t<e){*t++=m[*s>>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 ) { 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 ); 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( *exactmatch ) return match;
if( vector->size + 1 >= vector->space ) { 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; if( !new_data ) return NULL;
// Adjust pointer if it moved by realloc // Adjust pointer if it moved by realloc
match = match - (ot_byte*)vector->data + new_data; match = match - (ot_byte*)vector->data + new_data;
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 ); MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match );
vector->size++; 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 ) { static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) {
int exactmatch; int exactmatch;
ot_peer *end = ((ot_peer*)vector->data) + vector->size;
ot_peer *match; ot_peer *match;
if( !vector->size ) return 0; if( !vector->size ) return 0;
@ -81,8 +88,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) {
if( !exactmatch ) return 0; if( !exactmatch ) return 0;
exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1; exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1;
MEMMOVE( match, match + 1, ((ot_peer*)vector->data) + vector->size - match - 1 ); MEMMOVE( match, match + 1, end - match - 1 );
vector->size--; 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; 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 ) { static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) {
int exactmatch; int exactmatch;
ot_torrent *end = ((ot_torrent*)vector->data) + vector->size; 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( !exactmatch ) return -1; if( !vector->size ) return 0;
match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), compare_hash, &exactmatch );
if( !exactmatch ) return 0;
free_peerlist( match->peer_list ); free_peerlist( match->peer_list );
MEMMOVE( match, match + 1, end - match - 1 ); MEMMOVE( match, match + 1, end - match - 1 );
vector->size--; if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
if( ( 3*vector->size < vector->space ) && ( vector->space > 1024 ) ) { vector->space /= OT_VECTOR_SHRINK_RATIO;
realloc( vector->data, vector->space >> 1 ); realloc( vector->data, vector->space * sizeof( ot_torrent ) );
vector->space >>= 1;
} }
return 0; return 1;
} }
// Returns 1, if torrent is gone, 0 otherwise // 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; if( !exactmatch ) return;
// Maybe this does the job
if( clean_peerlist( torrent->peer_list ) ) {
vector_remove_torrent( torrents_list, hash );
return;
}
for( i=0; i<OT_POOLS_COUNT; ++i ) for( i=0; i<OT_POOLS_COUNT; ++i )
switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) {
case 0: continue; case 0: continue;
case 2: torrent->peer_list->seed_count[i]--; case 2: torrent->peer_list->seed_count[i]--;
case 1: default: return; case 1: default: return;
} }
clean_peerlist( torrent->peer_list );
} }
void cleanup_torrents( void ) { void cleanup_torrents( void ) {

4
trackerlogic.h

@ -32,6 +32,10 @@ typedef time_t ot_time;
#define OT_POOLS_TIMEOUT 300 #define OT_POOLS_TIMEOUT 300
#define NOW (time(NULL)/OT_POOLS_TIMEOUT) #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 { typedef struct {
void *data; void *data;
size_t size; size_t size;

Loading…
Cancel
Save