diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | opentracker.c | 122 | ||||
| -rw-r--r-- | trackerlogic.c | 20 |
3 files changed, 63 insertions, 81 deletions
| @@ -3,7 +3,7 @@ FEATURES=#-DWANT_IP_FROM_QUERY_STRING -DWANT_BLACKLIST -DWANT_CLOSED_TRACKER -D_ | |||
| 3 | #DEBUG_OPTS=-g -ggdb -pg # -fprofile-arcs -ftest-coverage | 3 | #DEBUG_OPTS=-g -ggdb -pg # -fprofile-arcs -ftest-coverage |
| 4 | DEBUG_OPTS=-s -Os | 4 | DEBUG_OPTS=-s -Os |
| 5 | CFLAGS+=-I../libowfat -Wall -pipe # -pedantic -ansi | 5 | CFLAGS+=-I../libowfat -Wall -pipe # -pedantic -ansi |
| 6 | LDFLAGS+=-L../libowfat/ -lowfat -lm | 6 | LDFLAGS+=-L../libowfat/ -lowfat |
| 7 | 7 | ||
| 8 | HEADERS=trackerlogic.h scan_urlencoded_query.h | 8 | HEADERS=trackerlogic.h scan_urlencoded_query.h |
| 9 | SOURCES=opentracker.c trackerlogic.c scan_urlencoded_query.c | 9 | SOURCES=opentracker.c trackerlogic.c scan_urlencoded_query.c |
diff --git a/opentracker.c b/opentracker.c index 00b73a3..54fb80f 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -33,7 +33,8 @@ static time_t ot_start_time; | |||
| 33 | static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; | 33 | static const size_t SUCCESS_HTTP_HEADER_LENGTH = 80; |
| 34 | static const size_t SUCCESS_HTTP_SIZE_OFF = 17; | 34 | static const size_t SUCCESS_HTTP_SIZE_OFF = 17; |
| 35 | /* To always have space for error messages ;) */ | 35 | /* To always have space for error messages ;) */ |
| 36 | static char static_scratch[8192]; | 36 | static char static_inbuf[8192]; |
| 37 | static char static_outbuf[8192*4]; | ||
| 37 | 38 | ||
| 38 | #ifdef _DEBUG_HTTPERROR | 39 | #ifdef _DEBUG_HTTPERROR |
| 39 | static char debug_request[8192]; | 40 | static char debug_request[8192]; |
| @@ -51,12 +52,11 @@ struct http_data { | |||
| 51 | 52 | ||
| 52 | int main( int argc, char **argv ); | 53 | int main( int argc, char **argv ); |
| 53 | 54 | ||
| 54 | static int httpheader_complete( struct http_data *h ); | 55 | static void httperror( const int64 s, const char *title, const char *message ); |
| 55 | static void httperror( const int64 s, struct http_data *h, const char *title, const char *message ); | 56 | static void httpresponse( const int64 s, char *data ); |
| 56 | static void httpresponse( const int64 s, struct http_data *h); | ||
| 57 | 57 | ||
| 58 | static void sendmallocdata( const int64 s, struct http_data *h, char *buffer, const size_t size ); | 58 | static void sendmallocdata( const int64 s, char *buffer, const size_t size ); |
| 59 | static void senddata( const int64 s, struct http_data *h, char *buffer, const size_t size ); | 59 | static void senddata( const int64 s, char *buffer, const size_t size ); |
| 60 | 60 | ||
| 61 | static void server_mainloop( const int64 serversocket ); | 61 | static void server_mainloop( const int64 serversocket ); |
| 62 | static void handle_timeouted( void ); | 62 | static void handle_timeouted( void ); |
| @@ -71,11 +71,11 @@ static void carp( const char *routine ); | |||
| 71 | static void panic( const char *routine ); | 71 | static void panic( const char *routine ); |
| 72 | static void graceful( int s ); | 72 | static void graceful( int s ); |
| 73 | 73 | ||
| 74 | #define HTTPERROR_400 return httperror( s, h, "400 Invalid Request", "This server only understands GET." ) | 74 | #define HTTPERROR_400 return httperror( s, "400 Invalid Request", "This server only understands GET." ) |
| 75 | #define HTTPERROR_400_PARAM return httperror( s, h, "400 Invalid Request", "Invalid parameter" ) | 75 | #define HTTPERROR_400_PARAM return httperror( s, "400 Invalid Request", "Invalid parameter" ) |
| 76 | #define HTTPERROR_400_COMPACT return httperror( s, h, "400 Invalid Request", "This server only delivers compact results." ) | 76 | #define HTTPERROR_400_COMPACT return httperror( s, "400 Invalid Request", "This server only delivers compact results." ) |
| 77 | #define HTTPERROR_404 return httperror( s, h, "404 Not Found", "No such file or directory." ) | 77 | #define HTTPERROR_404 return httperror( s, "404 Not Found", "No such file or directory." ) |
| 78 | #define HTTPERROR_500 return httperror( s, h, "500 Internal Server Error", "A server error has occured. Please retry later." ) | 78 | #define HTTPERROR_500 return httperror( s, "500 Internal Server Error", "A server error has occured. Please retry later." ) |
| 79 | 79 | ||
| 80 | /* End of prototypes */ | 80 | /* End of prototypes */ |
| 81 | 81 | ||
| @@ -91,33 +91,23 @@ static void panic( const char *routine ) { | |||
| 91 | exit( 111 ); | 91 | exit( 111 ); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static int httpheader_complete( struct http_data *h ) { | 94 | static void httperror( const int64 s, const char *title, const char *message ) { |
| 95 | size_t l = array_bytes( &h->request ), i; | 95 | size_t reply_size = sprintf( static_outbuf, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n", |
| 96 | const char* c = array_start( &h->request ); | ||
| 97 | |||
| 98 | for( i=0; i+1<l; ++i) { | ||
| 99 | if( c[i]=='\n' && c[i+1]=='\n') return i+2; | ||
| 100 | if( i+3<l && c[i]=='\r' && c[i+1]=='\n' && c[i+2]=='\r' && c[i+3]=='\n' ) return i+4; | ||
| 101 | } | ||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | static void httperror( const int64 s, struct http_data *h, const char *title, const char *message ) { | ||
| 106 | size_t reply_size = sprintf( static_scratch, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n", | ||
| 107 | title, strlen(message)+strlen(title)+16-4,title+4); | 96 | title, strlen(message)+strlen(title)+16-4,title+4); |
| 108 | #ifdef _DEBUG_HTTPERROR | 97 | #ifdef _DEBUG_HTTPERROR |
| 109 | fprintf( stderr, "DEBUG: invalid request was: %s\n", debug_request ); | 98 | fprintf( stderr, "DEBUG: invalid request was: %s\n", debug_request ); |
| 110 | #endif | 99 | #endif |
| 111 | senddata(s,h,static_scratch,reply_size); | 100 | senddata(s,static_outbuf,reply_size); |
| 112 | } | 101 | } |
| 113 | 102 | ||
| 114 | static void sendmallocdata( const int64 s, struct http_data *h, char *buffer, size_t size ) { | 103 | static void sendmallocdata( const int64 s, char *buffer, size_t size ) { |
| 115 | tai6464 t; | 104 | struct http_data *h = io_getcookie( s ); |
| 116 | char *header; | 105 | char *header; |
| 117 | size_t header_size; | 106 | size_t header_size; |
| 107 | tai6464 t; | ||
| 118 | 108 | ||
| 119 | if( !h ) | 109 | if( !h ) |
| 120 | return free( buffer); | 110 | return free( buffer ); |
| 121 | array_reset( &h->request ); | 111 | array_reset( &h->request ); |
| 122 | 112 | ||
| 123 | header = malloc( SUCCESS_HTTP_HEADER_LENGTH ); | 113 | header = malloc( SUCCESS_HTTP_HEADER_LENGTH ); |
| @@ -133,12 +123,13 @@ static void sendmallocdata( const int64 s, struct http_data *h, char *buffer, si | |||
| 133 | iob_addbuf_free( &h->batch, buffer, size ); | 123 | iob_addbuf_free( &h->batch, buffer, size ); |
| 134 | 124 | ||
| 135 | /* writeable sockets just have a tcp timeout */ | 125 | /* writeable sockets just have a tcp timeout */ |
| 136 | taia_uint(&t,0); io_timeout( s, t ); | 126 | taia_uint( &t, 0 ); io_timeout( s, t ); |
| 137 | io_dontwantread( s ); | 127 | io_dontwantread( s ); |
| 138 | io_wantwrite( s ); | 128 | io_wantwrite( s ); |
| 139 | } | 129 | } |
| 140 | 130 | ||
| 141 | static void senddata( const int64 s, struct http_data *h, char *buffer, size_t size ) { | 131 | static void senddata( const int64 s, char *buffer, size_t size ) { |
| 132 | struct http_data *h = io_getcookie( s ); | ||
| 142 | size_t written_size; | 133 | size_t written_size; |
| 143 | 134 | ||
| 144 | /* whoever sends data is not interested in its input-array */ | 135 | /* whoever sends data is not interested in its input-array */ |
| @@ -168,8 +159,8 @@ static void senddata( const int64 s, struct http_data *h, char *buffer, size_t s | |||
| 168 | } | 159 | } |
| 169 | } | 160 | } |
| 170 | 161 | ||
| 171 | static void httpresponse( const int64 s, struct http_data *h) { | 162 | static void httpresponse( const int64 s, char *data ) { |
| 172 | char *c, *data, *reply; | 163 | char *c, *reply; |
| 173 | ot_peer peer; | 164 | ot_peer peer; |
| 174 | ot_torrent *torrent; | 165 | ot_torrent *torrent; |
| 175 | ot_hash *hash = NULL; | 166 | ot_hash *hash = NULL; |
| @@ -178,22 +169,19 @@ static void httpresponse( const int64 s, struct http_data *h) { | |||
| 178 | time_t t; | 169 | time_t t; |
| 179 | size_t reply_size = 0, reply_off; | 170 | size_t reply_size = 0, reply_off; |
| 180 | 171 | ||
| 181 | array_cat0( &h->request ); | ||
| 182 | c = array_start( &h->request ); | ||
| 183 | |||
| 184 | #ifdef _DEBUG_HTTPERROR | 172 | #ifdef _DEBUG_HTTPERROR |
| 185 | memcpy( debug_request, array_start( &h->request ), array_bytes( &h->request ) ); | 173 | memcpy( debug_request, data, sizeof( debug_request ) ); |
| 186 | #endif | 174 | #endif |
| 187 | 175 | ||
| 188 | if( byte_diff( c, 4, "GET ") ) HTTPERROR_400; | 176 | /* This one implicitely tests strlen < 5, too -- remember, it is \n terminated */ |
| 177 | if( byte_diff( data, 5, "GET /") ) HTTPERROR_400; | ||
| 189 | 178 | ||
| 190 | c+=4; | 179 | /* Query string MUST terminate with SP -- we know that theres at least a '\n' where this search terminates */ |
| 191 | for( data = c; *data!=' ' && *data != '\t' && *data != '\n' && *data != '\r'; ++data ) ; | 180 | for( c = data + 5; *c!=' ' && *c != '\t' && *c != '\n' && *c != '\r'; ++c ) ; |
| 181 | if( *c != ' ' ) HTTPERROR_400; | ||
| 192 | 182 | ||
| 193 | if( *data != ' ' ) HTTPERROR_400; | 183 | /* Skip leading '/' */ |
| 194 | *data = 0; | 184 | for( c = data+4; *c == '/'; ++c); |
| 195 | if( c[0] != '/' ) HTTPERROR_404; | ||
| 196 | while( *c == '/' ) ++c; | ||
| 197 | 185 | ||
| 198 | switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) { | 186 | switch( scan_urlencoded_query( &c, data = c, SCAN_PATH ) ) { |
| 199 | case 4: /* sync ? */ | 187 | case 4: /* sync ? */ |
| @@ -222,7 +210,7 @@ static void httpresponse( const int64 s, struct http_data *h) { | |||
| 222 | if( !hash ) HTTPERROR_400_PARAM; | 210 | if( !hash ) HTTPERROR_400_PARAM; |
| 223 | if( ( reply_size = return_sync_for_torrent( hash, &reply ) ) <= 0 ) HTTPERROR_500; | 211 | if( ( reply_size = return_sync_for_torrent( hash, &reply ) ) <= 0 ) HTTPERROR_500; |
| 224 | 212 | ||
| 225 | return sendmallocdata( s, h, reply, reply_size ); | 213 | return sendmallocdata( s, reply, reply_size ); |
| 226 | case 5: /* stats ? */ | 214 | case 5: /* stats ? */ |
| 227 | if( byte_diff(data,5,"stats")) HTTPERROR_404; | 215 | if( byte_diff(data,5,"stats")) HTTPERROR_404; |
| 228 | scanon = 1; | 216 | scanon = 1; |
| @@ -250,7 +238,7 @@ static void httpresponse( const int64 s, struct http_data *h) { | |||
| 250 | } | 238 | } |
| 251 | 239 | ||
| 252 | /* Enough for http header + whole scrape string */ | 240 | /* Enough for http header + whole scrape string */ |
| 253 | if( ( reply_size = return_stats_for_tracker( SUCCESS_HTTP_HEADER_LENGTH + static_scratch, mode ) ) <= 0 ) HTTPERROR_500; | 241 | if( ( reply_size = return_stats_for_tracker( SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, mode ) ) <= 0 ) HTTPERROR_500; |
| 254 | 242 | ||
| 255 | break; | 243 | break; |
| 256 | case 6: /* scrape ? */ | 244 | case 6: /* scrape ? */ |
| @@ -279,18 +267,18 @@ SCRAPE_WORKAROUND: | |||
| 279 | /* Scanned whole query string, no hash means full scrape... you might want to limit that */ | 267 | /* Scanned whole query string, no hash means full scrape... you might want to limit that */ |
| 280 | if( !hash ) { | 268 | if( !hash ) { |
| 281 | if( ( reply_size = return_fullscrape_for_tracker( &reply ) ) <= 0 ) HTTPERROR_500; | 269 | if( ( reply_size = return_fullscrape_for_tracker( &reply ) ) <= 0 ) HTTPERROR_500; |
| 282 | return sendmallocdata( s, h, reply, reply_size ); | 270 | return sendmallocdata( s, reply, reply_size ); |
| 283 | } | 271 | } |
| 284 | 272 | ||
| 285 | /* Enough for http header + whole scrape string */ | 273 | /* Enough for http header + whole scrape string */ |
| 286 | if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_scratch ) ) <= 0 ) HTTPERROR_500; | 274 | if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) <= 0 ) HTTPERROR_500; |
| 287 | break; | 275 | break; |
| 288 | case 8: | 276 | case 8: |
| 289 | if( byte_diff(data,8,"announce")) HTTPERROR_404; | 277 | if( byte_diff(data,8,"announce")) HTTPERROR_404; |
| 290 | 278 | ||
| 291 | ANNOUNCE_WORKAROUND: | 279 | ANNOUNCE_WORKAROUND: |
| 292 | 280 | ||
| 293 | OT_SETIP( &peer, h->ip); | 281 | OT_SETIP( &peer, ((struct http_data*)io_getcookie( s ))->ip); |
| 294 | OT_SETPORT( &peer, &port ); | 282 | OT_SETPORT( &peer, &port ); |
| 295 | OT_FLAG( &peer ) = 0; | 283 | OT_FLAG( &peer ) = 0; |
| 296 | numwant = 50; | 284 | numwant = 50; |
| @@ -369,10 +357,10 @@ ANNOUNCE_WORKAROUND: | |||
| 369 | 357 | ||
| 370 | if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) { | 358 | if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) { |
| 371 | remove_peer_from_torrent( hash, &peer ); | 359 | remove_peer_from_torrent( hash, &peer ); |
| 372 | reply_size = sprintf( static_scratch + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 360 | reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
| 373 | } else { | 361 | } else { |
| 374 | torrent = add_peer_to_torrent( hash, &peer ); | 362 | torrent = add_peer_to_torrent( hash, &peer ); |
| 375 | if( !torrent || ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_scratch ) ) <= 0 ) HTTPERROR_500; | 363 | if( !torrent || ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) <= 0 ) HTTPERROR_500; |
| 376 | } | 364 | } |
| 377 | ot_overall_successfulannounces++; | 365 | ot_overall_successfulannounces++; |
| 378 | break; | 366 | break; |
| @@ -383,7 +371,7 @@ ANNOUNCE_WORKAROUND: | |||
| 383 | if( byte_diff(data,11,"mrtg_scrape")) HTTPERROR_404; | 371 | if( byte_diff(data,11,"mrtg_scrape")) HTTPERROR_404; |
| 384 | 372 | ||
| 385 | t = time( NULL ) - ot_start_time; | 373 | t = time( NULL ) - ot_start_time; |
| 386 | reply_size = sprintf( static_scratch + SUCCESS_HTTP_HEADER_LENGTH, | 374 | reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, |
| 387 | "%i\n%i\nUp: %i seconds (%i hours)\nPretuned by german engineers, currently handling %i connections per second.", | 375 | "%i\n%i\nUp: %i seconds (%i hours)\nPretuned by german engineers, currently handling %i connections per second.", |
| 388 | ot_overall_connections, ot_overall_successfulannounces, (int)t, (int)(t / 3600), (int)ot_overall_connections / ( (int)t ? (int)t : 1 ) ); | 376 | ot_overall_connections, ot_overall_successfulannounces, (int)t, (int)(t / 3600), (int)ot_overall_connections / ( (int)t ? (int)t : 1 ) ); |
| 389 | break; | 377 | break; |
| @@ -403,16 +391,16 @@ ANNOUNCE_WORKAROUND: | |||
| 403 | plus dynamic space needed to expand our Content-Length value. We reserve SUCCESS_HTTP_SIZE_OFF for it expansion and calculate | 391 | plus dynamic space needed to expand our Content-Length value. We reserve SUCCESS_HTTP_SIZE_OFF for it expansion and calculate |
| 404 | the space NOT needed to expand in reply_off | 392 | the space NOT needed to expand in reply_off |
| 405 | */ | 393 | */ |
| 406 | reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_scratch, 0, "%zd", reply_size ); | 394 | reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_outbuf, 0, "%zd", reply_size ); |
| 407 | 395 | ||
| 408 | /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete | 396 | /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete |
| 409 | packet size is increased by size of header plus one byte '\n', we will copy over '\0' in next step */ | 397 | packet size is increased by size of header plus one byte '\n', we will copy over '\0' in next step */ |
| 410 | reply_size += 1 + sprintf( static_scratch + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size ); | 398 | reply_size += 1 + sprintf( static_outbuf + reply_off, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", reply_size ); |
| 411 | 399 | ||
| 412 | /* 3. Finally we join both blocks neatly */ | 400 | /* 3. Finally we join both blocks neatly */ |
| 413 | static_scratch[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n'; | 401 | static_outbuf[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n'; |
| 414 | 402 | ||
| 415 | senddata( s, h, static_scratch + reply_off, reply_size ); | 403 | senddata( s, static_outbuf + reply_off, reply_size ); |
| 416 | } | 404 | } |
| 417 | 405 | ||
| 418 | static void graceful( int s ) { | 406 | static void graceful( int s ) { |
| @@ -463,7 +451,7 @@ static void handle_read( const int64 clientsocket ) { | |||
| 463 | struct http_data* h = io_getcookie( clientsocket ); | 451 | struct http_data* h = io_getcookie( clientsocket ); |
| 464 | size_t l; | 452 | size_t l; |
| 465 | 453 | ||
| 466 | if( ( l = io_tryread( clientsocket, static_scratch, sizeof static_scratch ) ) <= 0 ) { | 454 | if( ( l = io_tryread( clientsocket, static_inbuf, sizeof static_inbuf ) ) <= 0 ) { |
| 467 | if( h ) { | 455 | if( h ) { |
| 468 | array_reset( &h->request ); | 456 | array_reset( &h->request ); |
| 469 | free( h ); | 457 | free( h ); |
| @@ -472,24 +460,30 @@ static void handle_read( const int64 clientsocket ) { | |||
| 472 | return; | 460 | return; |
| 473 | } | 461 | } |
| 474 | 462 | ||
| 475 | array_catb( &h->request, static_scratch, l ); | ||
| 476 | |||
| 477 | #ifdef _DEBUG_HTTPERROR | 463 | #ifdef _DEBUG_HTTPERROR |
| 478 | memcpy( debug_request, "500!\0", 5 ); | 464 | memcpy( debug_request, "500!\0", 5 ); |
| 479 | #endif | 465 | #endif |
| 480 | 466 | ||
| 467 | /* If we get the whole request in one packet, handle it without copying */ | ||
| 468 | if( !array_start( &h->request ) ) { | ||
| 469 | if( memchr( static_inbuf, '\n', l ) ) | ||
| 470 | return httpresponse( clientsocket, static_inbuf ); | ||
| 471 | return array_catb( &h->request, static_inbuf, l ); | ||
| 472 | } | ||
| 473 | |||
| 474 | array_catb( &h->request, static_inbuf, l ); | ||
| 475 | |||
| 481 | if( array_failed( &h->request ) ) | 476 | if( array_failed( &h->request ) ) |
| 482 | httperror( clientsocket, h, "500 Server Error", "Request too long."); | 477 | httperror( clientsocket, "500 Server Error", "Request too long."); |
| 483 | else if( array_bytes( &h->request ) > 8192 ) | 478 | else if( array_bytes( &h->request ) > 8192 ) |
| 484 | httperror( clientsocket, h, "500 request too long", "You sent too much headers"); | 479 | httperror( clientsocket, "500 request too long", "You sent too much headers"); |
| 485 | else if( ( l = httpheader_complete( h ) ) ) | 480 | else if( memchr( array_start( &h->request ), '\n', array_length( &h->request, 1 ) ) ) |
| 486 | httpresponse( clientsocket, h); | 481 | httpresponse( clientsocket, array_start( &h->request ) ); |
| 487 | } | 482 | } |
| 488 | 483 | ||
| 489 | static void handle_write( const int64 clientsocket ) { | 484 | static void handle_write( const int64 clientsocket ) { |
| 490 | struct http_data* h=io_getcookie( clientsocket ); | 485 | struct http_data* h=io_getcookie( clientsocket ); |
| 491 | if( !h ) return; | 486 | if( !h || ( iob_send( clientsocket, &h->batch ) <= 0 ) ) { |
| 492 | if( iob_send( clientsocket, &h->batch ) <= 0 ) { | ||
| 493 | iob_reset( &h->batch ); | 487 | iob_reset( &h->batch ); |
| 494 | io_close( clientsocket ); | 488 | io_close( clientsocket ); |
| 495 | free( h ); | 489 | free( h ); |
diff --git a/trackerlogic.c b/trackerlogic.c index b1d7349..f4c61d3 100644 --- a/trackerlogic.c +++ b/trackerlogic.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <math.h> | 14 | #include <math.h> |
| 15 | #include <glob.h> | 15 | #include <glob.h> |
| 16 | 16 | ||
| 17 | #include <assert.h> | ||
| 18 | #include <errno.h> | 17 | #include <errno.h> |
| 19 | #include "scan.h" | 18 | #include "scan.h" |
| 20 | #include "byte.h" | 19 | #include "byte.h" |
| @@ -207,16 +206,11 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) { | |||
| 207 | if( OT_FLAG(peer) & PEER_FLAG_SEEDING ) | 206 | if( OT_FLAG(peer) & PEER_FLAG_SEEDING ) |
| 208 | torrent->peer_list->seed_count[0]++; | 207 | torrent->peer_list->seed_count[0]++; |
| 209 | 208 | ||
| 210 | assert( torrent->peer_list->seed_count[0] <= torrent->peer_list->peers[0].size ); | ||
| 211 | |||
| 212 | for( i=1; i<OT_POOLS_COUNT; ++i ) { | 209 | for( i=1; i<OT_POOLS_COUNT; ++i ) { |
| 213 | switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { | 210 | switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { |
| 214 | case 0: continue; | 211 | case 0: continue; |
| 215 | case 2: torrent->peer_list->seed_count[i]--; | 212 | case 2: torrent->peer_list->seed_count[i]--; |
| 216 | case 1: default: | 213 | case 1: default: return torrent; |
| 217 | assert( torrent->peer_list->seed_count[i] >= 0 ); | ||
| 218 | assert( torrent->peer_list->seed_count[i] <= torrent->peer_list->peers[i].size ); | ||
| 219 | return torrent; | ||
| 220 | } | 214 | } |
| 221 | } | 215 | } |
| 222 | } else { | 216 | } else { |
| @@ -225,9 +219,6 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) { | |||
| 225 | if( !(OT_FLAG(peer_dest) & PEER_FLAG_SEEDING ) && (OT_FLAG(peer) & PEER_FLAG_SEEDING ) ) | 219 | if( !(OT_FLAG(peer_dest) & PEER_FLAG_SEEDING ) && (OT_FLAG(peer) & PEER_FLAG_SEEDING ) ) |
| 226 | torrent->peer_list->seed_count[0]++; | 220 | torrent->peer_list->seed_count[0]++; |
| 227 | memmove( peer_dest, peer, sizeof( ot_peer ) ); | 221 | memmove( peer_dest, peer, sizeof( ot_peer ) ); |
| 228 | |||
| 229 | assert( torrent->peer_list->seed_count[0] >= 0 ); | ||
| 230 | assert( torrent->peer_list->seed_count[0] <= torrent->peer_list->peers[0].size ); | ||
| 231 | } | 222 | } |
| 232 | 223 | ||
| 233 | return torrent; | 224 | return torrent; |
| @@ -463,10 +454,7 @@ void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ) { | |||
| 463 | switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { | 454 | switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { |
| 464 | case 0: continue; | 455 | case 0: continue; |
| 465 | case 2: torrent->peer_list->seed_count[i]--; | 456 | case 2: torrent->peer_list->seed_count[i]--; |
| 466 | case 1: default: | 457 | case 1: default: return; |
| 467 | assert( torrent->peer_list->seed_count[i] >= 0 ); | ||
| 468 | assert( torrent->peer_list->seed_count[i] <= torrent->peer_list->peers[i].size ); | ||
| 469 | return; | ||
| 470 | } | 458 | } |
| 471 | } | 459 | } |
| 472 | 460 | ||
| @@ -476,10 +464,10 @@ int init_logic( const char * const serverdir ) { | |||
| 476 | return -1; | 464 | return -1; |
| 477 | } | 465 | } |
| 478 | 466 | ||
| 479 | srandom( time(NULL)); | 467 | srandom( time(NULL) ); |
| 480 | 468 | ||
| 481 | /* Initialize control structures */ | 469 | /* Initialize control structures */ |
| 482 | byte_zero( all_torrents, sizeof (all_torrents)); | 470 | byte_zero( all_torrents, sizeof (all_torrents) ); |
| 483 | 471 | ||
| 484 | return 0; | 472 | return 0; |
| 485 | } | 473 | } |
