diff options
| author | erdgeist <> | 2007-01-09 06:30:37 +0000 |
|---|---|---|
| committer | erdgeist <> | 2007-01-09 06:30:37 +0000 |
| commit | 74a7fbd6fe88a9bed988d5987b6b24dd12edeb04 (patch) | |
| tree | 338890110742f0ac923d0bc43f0a487ede0a0951 | |
| parent | 8ecfe9a36fafff55b8e6112f709e5ce62a5547f5 (diff) | |
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.
| -rw-r--r-- | opentracker.c | 55 | ||||
| -rw-r--r-- | 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 @@ | |||
| 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; | |||
| 32 | static unsigned int ot_overall_connections = 0; | 31 | static unsigned int ot_overall_connections = 0; |
| 33 | static time_t ot_start_time; | 32 | static time_t ot_start_time; |
| 34 | static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80; | 33 | static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80; |
| 35 | static char reply[8192]; | 34 | static const unsigned int SUCCESS_HTTP_SIZE_OFF = 17; |
| 36 | static size_t reply_size; | 35 | // To always have space for error messages |
| 36 | static char static_reply[8192]; | ||
| 37 | 37 | ||
| 38 | static void carp(const char* routine) { | 38 | static 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 | ||
| 50 | struct http_data { | 50 | struct 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 |
| 69 | void senddata(int64 s,struct http_data* h) { | 68 | void 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 | ||
| 82 | void httperror(int64 s,struct http_data* h,const char* title,const char* message) { | 82 | void 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 ) { |
| 269 | e500: | 268 | e500: |
| 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 | ||
| 301 | void graceful( int s ) { | 302 | void 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; |
