Browse Source

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.

master
Dirk Engling 16 years ago
parent
commit
f5f4c3e2ce
  1. 55
      opentracker.c
  2. 23
      trackerlogic.c

55
opentracker.c

@ -10,7 +10,6 @@
#include "array.h"
#include "case.h"
#include "fmt.h"
#include "iob.h"
#include "str.h"
#include <string.h>
#include <sys/types.h>
@ -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<title>%s</title>\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<title>%s</title>\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;
}

23
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;

Loading…
Cancel
Save