summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--opentracker.c13
-rw-r--r--scan_urlencoded_query.c24
-rw-r--r--scan_urlencoded_query.h7
-rw-r--r--trackerlogic.c48
-rw-r--r--trackerlogic.h4
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 @@
1CC?=gcc 1CC?=gcc
2CFLAGS+=-I../libowfat -Wall -pipe -Os 2CFLAGS+=-I../libowfat -Wall -pipe -Os # -DWANT_IP_FROM_QUERY_STRING -g -ggdb
3LDFLAGS+=-L../libowfat/ -lowfat -s -lm 3LDFLAGS+=-L../libowfat/ -lowfat -s -lm
4 4
5HEADERS=trackerlogic.h scan_urlencoded_query.h 5HEADERS=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:
186 break; 186 break;
187 case -1: /* error */ 187 case -1: /* error */
188 goto e404; 188 goto e404;
189#ifdef WANT_IP_FROM_QUERY_STRING
190 case 2:
191 if(!byte_diff(data,2,"ip")) {
192 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
193 unsigned char ip[4];
194 if( ( len <= 0 ) || scan_fixed_ip( data, len, ip ) ) goto e404;
195 OT_SETIP ( &peer, ip );
196 } else
197 scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE );
198 break;
199#endif
189 case 4: 200 case 4:
190 if(!byte_diff(data,4,"port")) { 201 if(!byte_diff(data,4,"port")) {
191 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ); 202 size_t len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE );
@@ -263,7 +274,7 @@ e500:
263 httperror(h,"500 Internal Server Error","A server error has occured. Please retry later."); 274 httperror(h,"500 Internal Server Error","A server error has occured. Please retry later.");
264 goto bailout; 275 goto bailout;
265 } 276 }
266 reply = malloc( SUCCESS_HTTP_HEADER_LENGTH + numwant*6 + 128 ); // http header + peerlist + seeder, peers and lametta 80 + n*6+81 a.t.m. 277 reply = malloc( SUCCESS_HTTP_HEADER_LENGTH + numwant * 6 + 128 ); // http header + peerlist + seeder, peers and lametta 80 + n*6+81 a.t.m.
267 if( reply ) 278 if( reply )
268 reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply ); 279 reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply );
269 if( !reply || ( reply_size <= 0 ) ) { 280 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) {
18 unsigned char *d = (unsigned char*)deststring; 18 unsigned char *d = (unsigned char*)deststring;
19 register unsigned char b, c; 19 register unsigned char b, c;
20 20
21 while ( is_unreserved( c = *s++) ) { 21 while( is_unreserved( c = *s++) ) {
22 if (c=='%') { 22 if( c=='%') {
23 if( ( c = scan_fromhex(*s++) ) == 0xff ) return -1; 23 if( ( c = scan_fromhex(*s++) ) == 0xff ) return -1;
24 if( ( b = scan_fromhex(*s++) ) == 0xff ) return -1; 24 if( ( b = scan_fromhex(*s++) ) == 0xff ) return -1;
25 c=(c<<4)|b; 25 c=(c<<4)|b;
26 } 26 }
27 if(d) *d++ = c; 27 if( d ) *d++ = c;
28 } 28 }
29 29
30 switch( c ) { 30 switch( c ) {
@@ -55,3 +55,21 @@ size_t scan_fixed_int( char *data, size_t len, int *tmp ) {
55 while( (len > 0) && (*data >= '0') && (*data <= '9') ) { --len; *tmp = 10**tmp + *data++-'0'; } 55 while( (len > 0) && (*data >= '0') && (*data <= '9') ) { --len; *tmp = 10**tmp + *data++-'0'; }
56 return len; 56 return len;
57} 57}
58
59size_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] ) {
60 int u, i;
61
62 for( i=0; i<4; ++i ) {
63 register unsigned int j;
64 j = scan_fixed_int( data, len, &u );
65 if( j == len ) return len;
66 ip[i] = u;
67 data += len - j;
68 len = j;
69 if ( i<3 ) {
70 if( !len || *data != '.') return -1;
71 --len; ++data;
72 }
73 }
74 return len;
75}
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);
15// data pointer to len chars of string 15// data pointer to len chars of string
16// len length of chars in data to parse 16// len length of chars in data to parse
17// number number to receive result 17// number number to receive result
18// returns number of bytes not parsed, mostly !=0 means fail
18size_t scan_fixed_int( char *data, size_t len, int *number ); 19size_t scan_fixed_int( char *data, size_t len, int *number );
19 20
21// data pointer to len chars of string
22// len length of chars in data to parse
23// ip buffer to receive result
24// returns number of bytes not parsed, mostly !=0 means fail
25size_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] );
26
20#endif 27#endif
diff --git a/trackerlogic.c b/trackerlogic.c
index ece3261..762ad69 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -15,11 +15,19 @@
15#include "scan.h" 15#include "scan.h"
16#include "byte.h" 16#include "byte.h"
17 17
18// GLOBAL VARIABLES
19//
20static ot_vector all_torrents[256];
21
18// Helper functions for binary_find 22// Helper functions for binary_find
19// 23//
20int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); } 24int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); }
21int compare_ip_port( const void *peer1, const void *peer2 ) { return memcmp( peer1, peer2, 6 ); } 25int compare_ip_port( const void *peer1, const void *peer2 ) { return memcmp( peer1, peer2, 6 ); }
22 26
27// This function gives us a binary search that returns a pointer, even if
28// no exact match is found. In that case it sets exactmatch 0 and gives
29// calling functions the chance to insert data
30//
23static void *binary_search( const void *key, const void *base, 31static void *binary_search( const void *key, const void *base,
24 unsigned long member_count, const unsigned long member_size, 32 unsigned long member_count, const unsigned long member_size,
25 int (*compar) (const void *, const void *), 33 int (*compar) (const void *, const void *),
@@ -48,9 +56,6 @@ static void *binary_search( const void *key, const void *base,
48// 56//
49char 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;} 57char 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;}
50 58
51// GLOBAL VARIABLES
52//
53static ot_vector all_torrents[256];
54 59
55static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int(*compare_func)(const void*, const void*), int *exactmatch ) { 60static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int(*compare_func)(const void*, const void*), int *exactmatch ) {
56 ot_byte *match = BINARY_FIND( key, vector->data, vector->size, member_size, compare_func, exactmatch ); 61 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_
58 if( *exactmatch ) return match; 63 if( *exactmatch ) return match;
59 64
60 if( vector->size + 1 >= vector->space ) { 65 if( vector->size + 1 >= vector->space ) {
61 ot_byte *new_data = realloc( vector->data, vector->space ? 2 * vector->space : 1024 ); 66 size_t new_space = vector->space ? OT_VECTOR_GROW_RATIO * vector->space : OT_VECTOR_MIN_MEMBERS;
67 ot_byte *new_data = realloc( vector->data, new_space * member_size );
62 if( !new_data ) return NULL; 68 if( !new_data ) return NULL;
63 69
64 // Adjust pointer if it moved by realloc 70 // Adjust pointer if it moved by realloc
65 match = match - (ot_byte*)vector->data + new_data; 71 match = match - (ot_byte*)vector->data + new_data;
66 72
67 vector->data = new_data; 73 vector->data = new_data;
68 vector->space = vector->space ? vector->space * 2 : 1024; 74 vector->space = new_space;;
69 } 75 }
70 MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); 76 MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match );
71 vector->size++; 77 vector->size++;
@@ -74,6 +80,7 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_
74 80
75static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { 81static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) {
76 int exactmatch; 82 int exactmatch;
83 ot_peer *end = ((ot_peer*)vector->data) + vector->size;
77 ot_peer *match; 84 ot_peer *match;
78 85
79 if( !vector->size ) return 0; 86 if( !vector->size ) return 0;
@@ -81,8 +88,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) {
81 88
82 if( !exactmatch ) return 0; 89 if( !exactmatch ) return 0;
83 exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1; 90 exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1;
84 MEMMOVE( match, match + 1, ((ot_peer*)vector->data) + vector->size - match - 1 ); 91 MEMMOVE( match, match + 1, end - match - 1 );
85 vector->size--; 92 if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
93 vector->space /= OT_VECTOR_SHRINK_RATIO;
94 realloc( vector->data, vector->space * sizeof( ot_peer ) );
95 }
86 return exactmatch; 96 return exactmatch;
87} 97}
88 98
@@ -97,17 +107,19 @@ static void free_peerlist( ot_peerlist *peer_list ) {
97static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { 107static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) {
98 int exactmatch; 108 int exactmatch;
99 ot_torrent *end = ((ot_torrent*)vector->data) + vector->size; 109 ot_torrent *end = ((ot_torrent*)vector->data) + vector->size;
100 ot_torrent *match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), compare_hash, &exactmatch ); 110 ot_torrent *match;
111
112 if( !vector->size ) return 0;
113 match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), compare_hash, &exactmatch );
101 114
102 if( !exactmatch ) return -1; 115 if( !exactmatch ) return 0;
103 free_peerlist( match->peer_list ); 116 free_peerlist( match->peer_list );
104 MEMMOVE( match, match + 1, end - match - 1 ); 117 MEMMOVE( match, match + 1, end - match - 1 );
105 vector->size--; 118 if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
106 if( ( 3*vector->size < vector->space ) && ( vector->space > 1024 ) ) { 119 vector->space /= OT_VECTOR_SHRINK_RATIO;
107 realloc( vector->data, vector->space >> 1 ); 120 realloc( vector->data, vector->space * sizeof( ot_torrent ) );
108 vector->space >>= 1;
109 } 121 }
110 return 0; 122 return 1;
111} 123}
112 124
113// Returns 1, if torrent is gone, 0 otherwise 125// Returns 1, if torrent is gone, 0 otherwise
@@ -253,14 +265,18 @@ void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ) {
253 265
254 if( !exactmatch ) return; 266 if( !exactmatch ) return;
255 267
268 // Maybe this does the job
269 if( clean_peerlist( torrent->peer_list ) ) {
270 vector_remove_torrent( torrents_list, hash );
271 return;
272 }
273
256 for( i=0; i<OT_POOLS_COUNT; ++i ) 274 for( i=0; i<OT_POOLS_COUNT; ++i )
257 switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { 275 switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) {
258 case 0: continue; 276 case 0: continue;
259 case 2: torrent->peer_list->seed_count[i]--; 277 case 2: torrent->peer_list->seed_count[i]--;
260 case 1: default: return; 278 case 1: default: return;
261 } 279 }
262
263 clean_peerlist( torrent->peer_list );
264} 280}
265 281
266void cleanup_torrents( void ) { 282void 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;
32#define OT_POOLS_TIMEOUT 300 32#define OT_POOLS_TIMEOUT 300
33#define NOW (time(NULL)/OT_POOLS_TIMEOUT) 33#define NOW (time(NULL)/OT_POOLS_TIMEOUT)
34 34
35#define OT_VECTOR_MIN_MEMBERS 128
36#define OT_VECTOR_GROW_RATIO 2
37#define OT_VECTOR_SHRINK_THRESH 3
38#define OT_VECTOR_SHRINK_RATIO 2
35typedef struct { 39typedef struct {
36 void *data; 40 void *data;
37 size_t size; 41 size_t size;