mirror of
git://erdgeist.org/opentracker
synced 2025-04-01 02:52:57 +08:00
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.
This commit is contained in:
parent
f40b373c3b
commit
e0a9c2a4aa
2
Makefile
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
|
||||||
|
@ -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 ) ) {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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 ) {
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user