summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opentracker.c55
-rw-r--r--trackerlogic.c23
2 files changed, 35 insertions, 43 deletions
diff --git a/opentracker.c b/opentracker.c
index 4d65564..d22a3b2 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -10,7 +10,6 @@
10#include "array.h" 10#include "array.h"
11#include "case.h" 11#include "case.h"
12#include "fmt.h" 12#include "fmt.h"
13#include "iob.h"
14#include "str.h" 13#include "str.h"
15#include <string.h> 14#include <string.h>
16#include <sys/types.h> 15#include <sys/types.h>
@@ -32,8 +31,9 @@ unsigned long const OT_CLIENT_TIMEOUT_CHECKINTERVAL = 5;
32static unsigned int ot_overall_connections = 0; 31static unsigned int ot_overall_connections = 0;
33static time_t ot_start_time; 32static time_t ot_start_time;
34static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80; 33static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80;
35static char reply[8192]; 34static const unsigned int SUCCESS_HTTP_SIZE_OFF = 17;
36static size_t reply_size; 35// To always have space for error messages
36static char static_reply[8192];
37 37
38static void carp(const char* routine) { 38static void carp(const char* routine) {
39 buffer_puts(buffer_2,routine); 39 buffer_puts(buffer_2,routine);
@@ -49,7 +49,6 @@ static void panic(const char* routine) {
49 49
50struct http_data { 50struct http_data {
51 array r; 51 array r;
52 io_batch iob;
53 unsigned long ip; 52 unsigned long ip;
54}; 53};
55 54
@@ -66,23 +65,24 @@ int header_complete(struct http_data* r) {
66} 65}
67 66
68// whoever sends data is not interested in its input-array 67// whoever sends data is not interested in its input-array
69void senddata(int64 s,struct http_data* h) { 68void senddata(int64 s, struct http_data* h, char *buffer, size_t size ) {
70 size_t written_size; 69 size_t written_size;
71 70
72 if( h ) array_reset(&h->r); 71 if( h ) array_reset(&h->r);
73 written_size = write( s, reply, reply_size ); 72 written_size = write( s, buffer, size );
74 if( ( written_size < 0 ) || ( written_size == reply_size ) ) { 73 if( ( written_size < 0 ) || ( written_size == size ) ) {
75 free(h); io_close( s ); 74 free(h); io_close( s );
76 } else { 75 } else {
76 // here we would take a copy of the buffer and remember it
77 fprintf( stderr, "Should have handled this.\n" ); 77 fprintf( stderr, "Should have handled this.\n" );
78 free(h); io_close( s ); 78 free(h); io_close( s );
79 } 79 }
80} 80}
81 81
82void httperror(int64 s,struct http_data* h,const char* title,const char* message) { 82void httperror(int64 s,struct http_data* h,const char* title,const char* message) {
83 reply_size = sprintf( reply, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n", 83 size_t reply_size = sprintf( static_reply, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n",
84 title, strlen(message)+strlen(title)+16-4,title+4); 84 title, strlen(message)+strlen(title)+16-4,title+4);
85 senddata(s,h); 85 senddata(s,h,static_reply,reply_size);
86} 86}
87 87
88// bestimmten http parameter auslesen und adresse zurueckgeben 88// bestimmten http parameter auslesen und adresse zurueckgeben
@@ -114,10 +114,9 @@ void httpresponse(int64 s,struct http_data* h)
114 ot_hash *hash = NULL; 114 ot_hash *hash = NULL;
115 int numwant, tmp, scanon; 115 int numwant, tmp, scanon;
116 unsigned short port = htons(6881); 116 unsigned short port = htons(6881);
117 size_t reply_size = 0;
117 118
118 reply_size = 0;
119 array_cat0(&h->r); 119 array_cat0(&h->r);
120
121 c = array_start(&h->r); 120 c = array_start(&h->r);
122 121
123 if (byte_diff(c,4,"GET ")) { 122 if (byte_diff(c,4,"GET ")) {
@@ -170,7 +169,7 @@ e400_param:
170 return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes."); 169 return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes.");
171 170
172 // Enough for http header + whole scrape string 171 // Enough for http header + whole scrape string
173 if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + reply ) ) <= 0 ) 172 if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
174 goto e500; 173 goto e500;
175 break; 174 break;
176 case 8: 175 case 8:
@@ -262,14 +261,14 @@ e400_param:
262 261
263 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) { 262 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
264 remove_peer_from_torrent( hash, &peer ); 263 remove_peer_from_torrent( hash, &peer );
265 MEMMOVE( reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 ); 264 MEMMOVE( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 );
266 } else { 265 } else {
267 torrent = add_peer_to_torrent( hash, &peer ); 266 torrent = add_peer_to_torrent( hash, &peer );
268 if( !torrent ) { 267 if( !torrent ) {
269e500: 268e500:
270 return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later."); 269 return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later.");
271 } 270 }
272 if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply ) ) <= 0 ) 271 if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 )
273 goto e500; 272 goto e500;
274 } 273 }
275 break; 274 break;
@@ -278,7 +277,7 @@ e500:
278 goto e404; 277 goto e404;
279 { 278 {
280 unsigned long seconds_elapsed = time( NULL ) - ot_start_time; 279 unsigned long seconds_elapsed = time( NULL ) - ot_start_time;
281 reply_size = sprintf( reply + SUCCESS_HTTP_HEADER_LENGTH, 280 reply_size = sprintf( static_reply + SUCCESS_HTTP_HEADER_LENGTH,
282 "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.", 281 "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.",
283 ot_overall_connections, ot_overall_connections, seconds_elapsed, 282 ot_overall_connections, ot_overall_connections, seconds_elapsed,
284 seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) ); 283 seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) );
@@ -290,12 +289,14 @@ e404:
290 } 289 }
291 290
292 if( reply_size ) { 291 if( reply_size ) {
293 MEMMOVE( reply, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: X \r\n\r\n", SUCCESS_HTTP_HEADER_LENGTH ); 292 size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size );
294 fmt_ulonglong( reply+59, (long long)reply_size ); 293 reply_size += 1 + sprintf( static_reply + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size );
294 static_reply[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n';
295 senddata( s, h, static_reply + reply_off, reply_size );
296 } else {
297 if( h ) array_reset(&h->r);
298 free( h ); io_close( s );
295 } 299 }
296 reply_size += SUCCESS_HTTP_HEADER_LENGTH;
297 io_dontwantread(s);
298 senddata(s,h);
299} 300}
300 301
301void graceful( int s ) { 302void graceful( int s ) {
@@ -462,20 +463,6 @@ allparsed:
462 } 463 }
463 } 464 }
464 } 465 }
465
466 while ((i=io_canwrite())!=-1) {
467 struct http_data* h=io_getcookie(i);
468
469 int64 r=iob_send(i,&h->iob);
470 if (r==-1)
471 io_eagain(i);
472 else
473 if ((r<=0)||(h->iob.bytesleft==0)) {
474 iob_reset(&h->iob);
475 free(h);
476 io_close(i);
477 }
478 }
479 } 466 }
480 return 0; 467 return 0;
481} 468}
diff --git a/trackerlogic.c b/trackerlogic.c
index c69da43..85e8156 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -75,10 +75,10 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_
75 if( !new_data ) return NULL; 75 if( !new_data ) return NULL;
76 76
77 // Adjust pointer if it moved by realloc 77 // Adjust pointer if it moved by realloc
78 match = match - (ot_byte*)vector->data + new_data; 78 match = new_data + (match - (ot_byte*)vector->data);
79 79
80 vector->data = new_data; 80 vector->data = new_data;
81 vector->space = new_space;; 81 vector->space = new_space;
82 } 82 }
83 MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); 83 MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match );
84 vector->size++; 84 vector->size++;
@@ -94,11 +94,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) {
94 match = BINARY_FIND( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch ); 94 match = BINARY_FIND( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
95 95
96 if( !exactmatch ) return 0; 96 if( !exactmatch ) return 0;
97 exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1; 97 exactmatch = ( OT_FLAG( match ) & PEER_FLAG_SEEDING ) ? 2 : 1;
98 MEMMOVE( match, match + 1, end - match - 1 ); 98 MEMMOVE( match, match + 1, sizeof(ot_peer) * ( end - match - 1 ) );
99 if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { 99 if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
100 vector->space /= OT_VECTOR_SHRINK_RATIO; 100 vector->space /= OT_VECTOR_SHRINK_RATIO;
101 realloc( vector->data, vector->space * sizeof( ot_peer ) ); 101 vector->data = realloc( vector->data, vector->space * sizeof( ot_peer ) );
102 } 102 }
103 return exactmatch; 103 return exactmatch;
104} 104}
@@ -120,11 +120,15 @@ static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) {
120 match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); 120 match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
121 121
122 if( !exactmatch ) return 0; 122 if( !exactmatch ) return 0;
123 free_peerlist( match->peer_list ); 123
124 MEMMOVE( match, match + 1, end - match - 1 ); 124 // If this is being called after a unsuccessful malloc() for peer_list
125 // in add_peer_to_torrent, match->peer_list actually might be NULL
126 if( match->peer_list) free_peerlist( match->peer_list );
127
128 MEMMOVE( match, match + 1, sizeof(ot_torrent) * ( end - match - 1 ) );
125 if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { 129 if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
126 vector->space /= OT_VECTOR_SHRINK_RATIO; 130 vector->space /= OT_VECTOR_SHRINK_RATIO;
127 realloc( vector->data, vector->space * sizeof( ot_torrent ) ); 131 vector->data = realloc( vector->data, vector->space * sizeof( ot_torrent ) );
128 } 132 }
129 return 1; 133 return 1;
130} 134}
@@ -175,12 +179,13 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
175 179
176 if( !exactmatch ) { 180 if( !exactmatch ) {
177 // Create a new torrent entry, then 181 // Create a new torrent entry, then
182 MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) );
183
178 torrent->peer_list = malloc( sizeof (ot_peerlist) ); 184 torrent->peer_list = malloc( sizeof (ot_peerlist) );
179 if( !torrent->peer_list ) { 185 if( !torrent->peer_list ) {
180 vector_remove_torrent( torrents_list, hash ); 186 vector_remove_torrent( torrents_list, hash );
181 return NULL; 187 return NULL;
182 } 188 }
183 MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) );
184 189
185 byte_zero( torrent->peer_list, sizeof( ot_peerlist )); 190 byte_zero( torrent->peer_list, sizeof( ot_peerlist ));
186 torrent->peer_list->base = NOW; 191 torrent->peer_list->base = NOW;