diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | opentracker.c | 13 | ||||
-rw-r--r-- | scan_urlencoded_query.c | 24 | ||||
-rw-r--r-- | scan_urlencoded_query.h | 7 | ||||
-rw-r--r-- | trackerlogic.c | 48 | ||||
-rw-r--r-- | trackerlogic.h | 4 |
6 files changed, 77 insertions, 21 deletions
@@ -1,5 +1,5 @@ | |||
1 | CC?=gcc | 1 | CC?=gcc |
2 | CFLAGS+=-I../libowfat -Wall -pipe -Os | 2 | CFLAGS+=-I../libowfat -Wall -pipe -Os # -DWANT_IP_FROM_QUERY_STRING -g -ggdb |
3 | LDFLAGS+=-L../libowfat/ -lowfat -s -lm | 3 | LDFLAGS+=-L../libowfat/ -lowfat -s -lm |
4 | 4 | ||
5 | HEADERS=trackerlogic.h scan_urlencoded_query.h | 5 | 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: | |||
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 | |||
59 | size_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 | ||
18 | size_t scan_fixed_int( char *data, size_t len, int *number ); | 19 | size_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 | ||
25 | size_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 | // | ||
20 | static ot_vector all_torrents[256]; | ||
21 | |||
18 | // Helper functions for binary_find | 22 | // Helper functions for binary_find |
19 | // | 23 | // |
20 | int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); } | 24 | int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); } |
21 | int compare_ip_port( const void *peer1, const void *peer2 ) { return memcmp( peer1, peer2, 6 ); } | 25 | int 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 | // | ||
23 | static void *binary_search( const void *key, const void *base, | 31 | static 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 | // |
49 | 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;} | 57 | 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;} |
50 | 58 | ||
51 | // GLOBAL VARIABLES | ||
52 | // | ||
53 | static ot_vector all_torrents[256]; | ||
54 | 59 | ||
55 | static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int(*compare_func)(const void*, const void*), int *exactmatch ) { | 60 | static 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 | ||
75 | static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { | 81 | static 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 ) { | |||
97 | static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { | 107 | static 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 | ||
266 | void cleanup_torrents( void ) { | 282 | 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; | |||
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 | ||
35 | typedef struct { | 39 | typedef struct { |
36 | void *data; | 40 | void *data; |
37 | size_t size; | 41 | size_t size; |