From 74a7fbd6fe88a9bed988d5987b6b24dd12edeb04 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Tue, 9 Jan 2007 06:30:37 +0000 Subject: Fixed a bug where I didn't replace new buffer pointer after realloc. Fixed a bug where I didnt copy enough memory when shrinking vectors. Now save some extra bytes in header. --- opentracker.c | 55 +++++++++++++++++++++---------------------------------- trackerlogic.c | 23 ++++++++++++++--------- 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 @@ #include "array.h" #include "case.h" #include "fmt.h" -#include "iob.h" #include "str.h" #include #include @@ -32,8 +31,9 @@ unsigned long const OT_CLIENT_TIMEOUT_CHECKINTERVAL = 5; static unsigned int ot_overall_connections = 0; static time_t ot_start_time; static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80; -static char reply[8192]; -static size_t reply_size; +static const unsigned int SUCCESS_HTTP_SIZE_OFF = 17; +// To always have space for error messages +static char static_reply[8192]; static void carp(const char* routine) { buffer_puts(buffer_2,routine); @@ -49,7 +49,6 @@ static void panic(const char* routine) { struct http_data { array r; - io_batch iob; unsigned long ip; }; @@ -66,23 +65,24 @@ int header_complete(struct http_data* r) { } // whoever sends data is not interested in its input-array -void senddata(int64 s,struct http_data* h) { +void senddata(int64 s, struct http_data* h, char *buffer, size_t size ) { size_t written_size; if( h ) array_reset(&h->r); - written_size = write( s, reply, reply_size ); - if( ( written_size < 0 ) || ( written_size == reply_size ) ) { + written_size = write( s, buffer, size ); + if( ( written_size < 0 ) || ( written_size == size ) ) { free(h); io_close( s ); } else { + // here we would take a copy of the buffer and remember it fprintf( stderr, "Should have handled this.\n" ); free(h); io_close( s ); } } void httperror(int64 s,struct http_data* h,const char* title,const char* message) { - reply_size = sprintf( reply, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n%s\n", + 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%s\n", title, strlen(message)+strlen(title)+16-4,title+4); - senddata(s,h); + senddata(s,h,static_reply,reply_size); } // bestimmten http parameter auslesen und adresse zurueckgeben @@ -114,10 +114,9 @@ void httpresponse(int64 s,struct http_data* h) ot_hash *hash = NULL; int numwant, tmp, scanon; unsigned short port = htons(6881); + size_t reply_size = 0; - reply_size = 0; array_cat0(&h->r); - c = array_start(&h->r); if (byte_diff(c,4,"GET ")) { @@ -170,7 +169,7 @@ e400_param: return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes."); // Enough for http header + whole scrape string - if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + reply ) ) <= 0 ) + if( ( reply_size = return_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 ) goto e500; break; case 8: @@ -262,14 +261,14 @@ e400_param: if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) { remove_peer_from_torrent( hash, &peer ); - MEMMOVE( reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 ); + MEMMOVE( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "d15:warning message4:Okaye", reply_size = 26 ); } else { torrent = add_peer_to_torrent( hash, &peer ); if( !torrent ) { e500: return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later."); } - if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + reply ) ) <= 0 ) + if( ( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_reply ) ) <= 0 ) goto e500; } break; @@ -278,7 +277,7 @@ e500: goto e404; { unsigned long seconds_elapsed = time( NULL ) - ot_start_time; - reply_size = sprintf( reply + SUCCESS_HTTP_HEADER_LENGTH, + reply_size = sprintf( static_reply + SUCCESS_HTTP_HEADER_LENGTH, "%d\n%d\nUp: %ld seconds (%ld hours)\nPretuned by german engineers, currently handling %li connections per second.", ot_overall_connections, ot_overall_connections, seconds_elapsed, seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) ); @@ -290,12 +289,14 @@ e404: } if( reply_size ) { - MEMMOVE( reply, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: X \r\n\r\n", SUCCESS_HTTP_HEADER_LENGTH ); - fmt_ulonglong( reply+59, (long long)reply_size ); + size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size ); + 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 ); + static_reply[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n'; + senddata( s, h, static_reply + reply_off, reply_size ); + } else { + if( h ) array_reset(&h->r); + free( h ); io_close( s ); } - reply_size += SUCCESS_HTTP_HEADER_LENGTH; - io_dontwantread(s); - senddata(s,h); } void graceful( int s ) { @@ -462,20 +463,6 @@ allparsed: } } } - - while ((i=io_canwrite())!=-1) { - struct http_data* h=io_getcookie(i); - - int64 r=iob_send(i,&h->iob); - if (r==-1) - io_eagain(i); - else - if ((r<=0)||(h->iob.bytesleft==0)) { - iob_reset(&h->iob); - free(h); - io_close(i); - } - } } return 0; } 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_ if( !new_data ) return NULL; // Adjust pointer if it moved by realloc - match = match - (ot_byte*)vector->data + new_data; + match = new_data + (match - (ot_byte*)vector->data); vector->data = new_data; - vector->space = new_space;; + vector->space = new_space; } MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); vector->size++; @@ -94,11 +94,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { match = BINARY_FIND( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch ); if( !exactmatch ) return 0; - exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1; - MEMMOVE( match, match + 1, end - match - 1 ); + exactmatch = ( OT_FLAG( match ) & PEER_FLAG_SEEDING ) ? 2 : 1; + MEMMOVE( match, match + 1, sizeof(ot_peer) * ( end - match - 1 ) ); 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 ) ); + vector->data = realloc( vector->data, vector->space * sizeof( ot_peer ) ); } return exactmatch; } @@ -120,11 +120,15 @@ static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( !exactmatch ) return 0; - free_peerlist( match->peer_list ); - MEMMOVE( match, match + 1, end - match - 1 ); + + // If this is being called after a unsuccessful malloc() for peer_list + // in add_peer_to_torrent, match->peer_list actually might be NULL + if( match->peer_list) free_peerlist( match->peer_list ); + + MEMMOVE( match, match + 1, sizeof(ot_torrent) * ( end - match - 1 ) ); 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_torrent ) ); + vector->data = realloc( vector->data, vector->space * sizeof( ot_torrent ) ); } return 1; } @@ -175,12 +179,13 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) { if( !exactmatch ) { // Create a new torrent entry, then + MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) ); + torrent->peer_list = malloc( sizeof (ot_peerlist) ); if( !torrent->peer_list ) { vector_remove_torrent( torrents_list, hash ); return NULL; } - MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) ); byte_zero( torrent->peer_list, sizeof( ot_peerlist )); torrent->peer_list->base = NOW; -- cgit v1.2.3