mirror of
https://erdgeist.org/gitweb/opentracker
synced 2024-05-10 07:54:50 +00:00
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.
This commit is contained in:
@ -10,7 +10,6 @@
|
|||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "case.h"
|
#include "case.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "iob.h"
|
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.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 unsigned int ot_overall_connections = 0;
|
||||||
static time_t ot_start_time;
|
static time_t ot_start_time;
|
||||||
static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80;
|
static const unsigned int SUCCESS_HTTP_HEADER_LENGTH = 80;
|
||||||
static char reply[8192];
|
static const unsigned int SUCCESS_HTTP_SIZE_OFF = 17;
|
||||||
static size_t reply_size;
|
// To always have space for error messages
|
||||||
|
static char static_reply[8192];
|
||||||
|
|
||||||
static void carp(const char* routine) {
|
static void carp(const char* routine) {
|
||||||
buffer_puts(buffer_2,routine);
|
buffer_puts(buffer_2,routine);
|
||||||
@ -49,7 +49,6 @@ static void panic(const char* routine) {
|
|||||||
|
|
||||||
struct http_data {
|
struct http_data {
|
||||||
array r;
|
array r;
|
||||||
io_batch iob;
|
|
||||||
unsigned long ip;
|
unsigned long ip;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,23 +65,24 @@ int header_complete(struct http_data* r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// whoever sends data is not interested in its input-array
|
// 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;
|
size_t written_size;
|
||||||
|
|
||||||
if( h ) array_reset(&h->r);
|
if( h ) array_reset(&h->r);
|
||||||
written_size = write( s, reply, reply_size );
|
written_size = write( s, buffer, size );
|
||||||
if( ( written_size < 0 ) || ( written_size == reply_size ) ) {
|
if( ( written_size < 0 ) || ( written_size == size ) ) {
|
||||||
free(h); io_close( s );
|
free(h); io_close( s );
|
||||||
} else {
|
} else {
|
||||||
|
// here we would take a copy of the buffer and remember it
|
||||||
fprintf( stderr, "Should have handled this.\n" );
|
fprintf( stderr, "Should have handled this.\n" );
|
||||||
free(h); io_close( s );
|
free(h); io_close( s );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void httperror(int64 s,struct http_data* h,const char* title,const char* message) {
|
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);
|
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
|
// bestimmten http parameter auslesen und adresse zurueckgeben
|
||||||
@ -114,10 +114,9 @@ void httpresponse(int64 s,struct http_data* h)
|
|||||||
ot_hash *hash = NULL;
|
ot_hash *hash = NULL;
|
||||||
int numwant, tmp, scanon;
|
int numwant, tmp, scanon;
|
||||||
unsigned short port = htons(6881);
|
unsigned short port = htons(6881);
|
||||||
|
size_t reply_size = 0;
|
||||||
|
|
||||||
reply_size = 0;
|
|
||||||
array_cat0(&h->r);
|
array_cat0(&h->r);
|
||||||
|
|
||||||
c = array_start(&h->r);
|
c = array_start(&h->r);
|
||||||
|
|
||||||
if (byte_diff(c,4,"GET ")) {
|
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.");
|
return httperror(s,h,"400 Invalid Request","This server only serves specific scrapes.");
|
||||||
|
|
||||||
// Enough for http header + whole scrape string
|
// 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;
|
goto e500;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
@ -262,14 +261,14 @@ e400_param:
|
|||||||
|
|
||||||
if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
|
if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
|
||||||
remove_peer_from_torrent( hash, &peer );
|
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 {
|
} else {
|
||||||
torrent = add_peer_to_torrent( hash, &peer );
|
torrent = add_peer_to_torrent( hash, &peer );
|
||||||
if( !torrent ) {
|
if( !torrent ) {
|
||||||
e500:
|
e500:
|
||||||
return httperror(s,h,"500 Internal Server Error","A server error has occured. Please retry later.");
|
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;
|
goto e500;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -278,7 +277,7 @@ e500:
|
|||||||
goto e404;
|
goto e404;
|
||||||
{
|
{
|
||||||
unsigned long seconds_elapsed = time( NULL ) - ot_start_time;
|
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.",
|
"%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,
|
ot_overall_connections, ot_overall_connections, seconds_elapsed,
|
||||||
seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) );
|
seconds_elapsed / 3600, ot_overall_connections / ( seconds_elapsed ? seconds_elapsed : 1 ) );
|
||||||
@ -290,12 +289,14 @@ e404:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( reply_size ) {
|
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 );
|
size_t reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( static_reply, 0, "%zd", reply_size );
|
||||||
fmt_ulonglong( reply+59, (long long)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 ) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -75,10 +75,10 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_
|
|||||||
if( !new_data ) return NULL;
|
if( !new_data ) return NULL;
|
||||||
|
|
||||||
// Adjust pointer if it moved by realloc
|
// 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->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 );
|
MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match );
|
||||||
vector->size++;
|
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 );
|
match = BINARY_FIND( peer, vector->data, vector->size, sizeof( ot_peer ), OT_PEER_COMPARE_SIZE, &exactmatch );
|
||||||
|
|
||||||
if( !exactmatch ) return 0;
|
if( !exactmatch ) return 0;
|
||||||
exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1;
|
exactmatch = ( OT_FLAG( match ) & PEER_FLAG_SEEDING ) ? 2 : 1;
|
||||||
MEMMOVE( match, match + 1, end - match - 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 ) ) {
|
if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
|
||||||
vector->space /= OT_VECTOR_SHRINK_RATIO;
|
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;
|
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 );
|
match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
|
||||||
|
|
||||||
if( !exactmatch ) return 0;
|
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 ) ) {
|
if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) {
|
||||||
vector->space /= OT_VECTOR_SHRINK_RATIO;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -175,12 +179,13 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
|
|||||||
|
|
||||||
if( !exactmatch ) {
|
if( !exactmatch ) {
|
||||||
// Create a new torrent entry, then
|
// Create a new torrent entry, then
|
||||||
|
MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) );
|
||||||
|
|
||||||
torrent->peer_list = malloc( sizeof (ot_peerlist) );
|
torrent->peer_list = malloc( sizeof (ot_peerlist) );
|
||||||
if( !torrent->peer_list ) {
|
if( !torrent->peer_list ) {
|
||||||
vector_remove_torrent( torrents_list, hash );
|
vector_remove_torrent( torrents_list, hash );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
MEMMOVE( &torrent->hash, hash, sizeof( ot_hash ) );
|
|
||||||
|
|
||||||
byte_zero( torrent->peer_list, sizeof( ot_peerlist ));
|
byte_zero( torrent->peer_list, sizeof( ot_peerlist ));
|
||||||
torrent->peer_list->base = NOW;
|
torrent->peer_list->base = NOW;
|
||||||
|
Reference in New Issue
Block a user