mirror of
git://erdgeist.org/opentracker
synced 2025-01-26 22:56:26 +00:00
V6
This commit is contained in:
parent
779d6c235f
commit
131211b4da
5
Makefile
5
Makefile
@ -19,6 +19,8 @@ LIBOWFAT_LIBRARY=$(PREFIX)/libowfat
|
||||
|
||||
BINDIR?=$(PREFIX)/bin
|
||||
|
||||
#FEATURES+=-DWANT_V6
|
||||
|
||||
#FEATURES+=-DWANT_ACCESSLIST_BLACK
|
||||
#FEATURES+=-DWANT_ACCESSLIST_WHITE
|
||||
|
||||
@ -31,13 +33,12 @@ BINDIR?=$(PREFIX)/bin
|
||||
FEATURES+=-DWANT_FULLSCRAPE
|
||||
|
||||
#FEATURES+=-D_DEBUG_HTTPERROR
|
||||
#FEATURES+=-D_DEBUG_PEERID
|
||||
|
||||
OPTS_debug=-D_DEBUG -g -ggdb # -pg -fprofile-arcs -ftest-coverage
|
||||
OPTS_production=-Os
|
||||
|
||||
CFLAGS+=-I$(LIBOWFAT_HEADERS) -Wall -pipe -Wextra #-ansi -pedantic
|
||||
LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread -lz
|
||||
LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread -lpthread -lz
|
||||
|
||||
BINARY =opentracker
|
||||
HEADERS=trackerlogic.h scan_urlencoded_query.h ot_mutex.h ot_stats.h ot_vector.h ot_clean.h ot_udp.h ot_iovec.h ot_fullscrape.h ot_accesslist.h ot_http.h ot_livesync.h
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "iob.h"
|
||||
#include "byte.h"
|
||||
#include "scan.h"
|
||||
#include "ip4.h"
|
||||
#include "ip6.h"
|
||||
|
||||
/* Opentracker */
|
||||
#include "trackerlogic.h"
|
||||
@ -108,7 +108,7 @@ static ssize_t handle_read( const int64 clientsocket, struct ot_workstruct *ws )
|
||||
struct http_data* h = io_getcookie( clientsocket );
|
||||
ssize_t l;
|
||||
|
||||
if( ( l = io_tryread( clientsocket, ws->inbuf, ws->inbuf_size ) ) <= 0 ) {
|
||||
if( ( l = io_tryread( clientsocket, ws->inbuf, G_INBUF_SIZE ) ) <= 0 ) {
|
||||
handle_dead( clientsocket );
|
||||
return 0;
|
||||
}
|
||||
@ -152,28 +152,28 @@ static void handle_write( const int64 clientsocket ) {
|
||||
|
||||
static void handle_accept( const int64 serversocket ) {
|
||||
struct http_data *h;
|
||||
unsigned char ip[4];
|
||||
ot_ip6 ip;
|
||||
uint16 port;
|
||||
tai6464 t;
|
||||
int64 i;
|
||||
|
||||
while( ( i = socket_accept4( serversocket, (char*)ip, &port) ) != -1 ) {
|
||||
while( ( i = socket_accept6( serversocket, ip, &port, NULL ) ) != -1 ) {
|
||||
|
||||
/* Put fd into a non-blocking mode */
|
||||
io_nonblock( i );
|
||||
|
||||
if( !io_fd( i ) ||
|
||||
!( h = (struct http_data*)malloc( sizeof( struct http_data ) ) ) ) {
|
||||
!( h = (struct http_data*)malloc( sizeof(struct http_data) ) ) ) {
|
||||
io_close( i );
|
||||
continue;
|
||||
}
|
||||
io_setcookie( i, h );
|
||||
io_wantread( i );
|
||||
|
||||
memset( h, 0, sizeof( struct http_data ) );
|
||||
WRITE32(h->ip,0,READ32(ip,0));
|
||||
memset(h, 0, sizeof( struct http_data ) );
|
||||
memcpy(h->ip,ip,sizeof(ot_ip6));
|
||||
|
||||
stats_issue_event( EVENT_ACCEPT, FLAG_TCP, ntohl(*(uint32_t*)ip));
|
||||
stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip);
|
||||
|
||||
/* That breaks taia encapsulation. But there is no way to take system
|
||||
time this often in FreeBSD and libowfat does not allow to set unix time */
|
||||
@ -193,20 +193,14 @@ static void server_mainloop( ) {
|
||||
int iovec_entries;
|
||||
|
||||
/* Initialize our "thread local storage" */
|
||||
ws.inbuf = malloc( THREAD_INBUF_SIZE );
|
||||
ws.outbuf = malloc( THREAD_OUTBUF_SIZE );
|
||||
ws.inbuf = malloc( G_INBUF_SIZE );
|
||||
ws.outbuf = malloc( G_OUTBUF_SIZE );
|
||||
#ifdef _DEBUG_HTTPERROR
|
||||
ws.debugbuf= malloc( THREAD_INBUF_SIZE );
|
||||
ws.debugbuf= malloc( G_INBUF_SIZE );
|
||||
#endif
|
||||
if( !ws.inbuf || !ws.outbuf )
|
||||
panic( "Initializing worker failed" );
|
||||
|
||||
ws.inbuf_size = THREAD_INBUF_SIZE;
|
||||
ws.outbuf_size = THREAD_OUTBUF_SIZE;
|
||||
#ifdef _DEBUG_HTTPERROR
|
||||
ws.debugbuf_size= THREAD_INBUF_SIZE;
|
||||
#endif
|
||||
|
||||
for( ; ; ) {
|
||||
int64 i;
|
||||
|
||||
@ -217,7 +211,7 @@ static void server_mainloop( ) {
|
||||
if( (intptr_t)cookie == FLAG_TCP )
|
||||
handle_accept( i );
|
||||
else if( (intptr_t)cookie == FLAG_UDP )
|
||||
handle_udp4( i, &ws );
|
||||
handle_udp6( i, &ws );
|
||||
else
|
||||
handle_read( i, &ws );
|
||||
}
|
||||
@ -241,17 +235,20 @@ static void server_mainloop( ) {
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t ot_try_bind( char ip[4], uint16_t port, PROTO_FLAG proto ) {
|
||||
int64 s = proto == FLAG_TCP ? socket_tcp4( ) : socket_udp4( );
|
||||
static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) {
|
||||
int64 s = proto == FLAG_TCP ? socket_tcp6( ) : socket_udp6( );
|
||||
|
||||
#ifdef _DEBUG
|
||||
char *protos[] = {"TCP","UDP","UDP mcast"};
|
||||
uint8_t *_ip = (uint8_t *)ip;
|
||||
fprintf( stderr, "Binding socket type %s to address %d.%d.%d.%d:%d...", protos[proto],_ip[0],_ip[1],_ip[2],_ip[3],port);
|
||||
char _debug[512];
|
||||
int off = snprintf( _debug, sizeof(_debug), "Binding socket type %s to address [", protos[proto] );
|
||||
off += fmt_ip6( _debug+off, ip);
|
||||
off += snprintf( _debug + off, sizeof(_debug)-off, "]:%d...", port);
|
||||
fputs( _debug, stderr );
|
||||
#endif
|
||||
|
||||
if( socket_bind4_reuse( s, ip, port ) == -1 )
|
||||
panic( "socket_bind4_reuse" );
|
||||
|
||||
if( socket_bind6_reuse( s, ip, port, 0 ) == -1 )
|
||||
panic( "socket_bind6_reuse" );
|
||||
|
||||
if( ( proto == FLAG_TCP ) && ( socket_listen( s, SOMAXCONN) == -1 ) )
|
||||
panic( "socket_listen" );
|
||||
@ -279,16 +276,22 @@ char * set_config_option( char **option, char *value ) {
|
||||
return *option = strdup( value );
|
||||
}
|
||||
|
||||
static int scan_ip4_port( const char *src, char *ip, uint16 *port ) {
|
||||
static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) {
|
||||
const char *s = src;
|
||||
int off;
|
||||
int off, bracket = 0;
|
||||
while( isspace(*s) ) ++s;
|
||||
if( !(off = scan_ip4( s, ip ) ) )
|
||||
if( *s == '[' ) ++s, ++bracket; /* for v6 style notation */
|
||||
if( !(off = scan_ip6( s, ip ) ) )
|
||||
return 0;
|
||||
s += off;
|
||||
if( *s == 0 || isspace(*s)) return s-src;
|
||||
if( *(s++) != ':' )
|
||||
return 0;
|
||||
if( *s == ']' && bracket ) ++s;
|
||||
if( !ip6_isv4mapped(ip)){
|
||||
if( ( bracket && *(s) != ':' ) || ( *(s) != '.' ) ) return 0;
|
||||
s++;
|
||||
} else {
|
||||
if( *(s++) != ':' ) return 0;
|
||||
}
|
||||
if( !(off = scan_ushort (s, port ) ) )
|
||||
return 0;
|
||||
return off+s-src;
|
||||
@ -296,7 +299,8 @@ static int scan_ip4_port( const char *src, char *ip, uint16 *port ) {
|
||||
|
||||
int parse_configfile( char * config_filename ) {
|
||||
FILE * accesslist_filehandle;
|
||||
char inbuf[512], tmpip[4];
|
||||
char inbuf[512];
|
||||
ot_ip6 tmpip;
|
||||
int bound = 0;
|
||||
|
||||
accesslist_filehandle = fopen( config_filename, "r" );
|
||||
@ -324,17 +328,17 @@ int parse_configfile( char * config_filename ) {
|
||||
set_config_option( &g_serverdir, p+16 );
|
||||
} else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) {
|
||||
uint16_t tmpport = 6969;
|
||||
if( !scan_ip4_port( p+15, tmpip, &tmpport )) goto parse_error;
|
||||
if( !scan_ip6_port( p+15, tmpip, &tmpport )) goto parse_error;
|
||||
ot_try_bind( tmpip, tmpport, FLAG_TCP ); ++bound;
|
||||
ot_try_bind( tmpip, tmpport, FLAG_UDP ); ++bound;
|
||||
} else if(!byte_diff(p,10,"listen.tcp" ) && isspace(p[10])) {
|
||||
uint16_t tmpport = 6969;
|
||||
if( !scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error;
|
||||
if( !scan_ip6_port( p+11, tmpip, &tmpport )) goto parse_error;
|
||||
ot_try_bind( tmpip, tmpport, FLAG_TCP );
|
||||
++bound;
|
||||
} else if(!byte_diff(p, 10, "listen.udp" ) && isspace(p[10])) {
|
||||
uint16_t tmpport = 6969;
|
||||
if( !scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error;
|
||||
if( !scan_ip6_port( p+11, tmpip, &tmpport )) goto parse_error;
|
||||
ot_try_bind( tmpip, tmpport, FLAG_UDP );
|
||||
++bound;
|
||||
#ifdef WANT_ACCESSLIST_WHITE
|
||||
@ -346,18 +350,18 @@ int parse_configfile( char * config_filename ) {
|
||||
#endif
|
||||
#ifdef WANT_RESTRICT_STATS
|
||||
} else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) {
|
||||
if( !scan_ip4( p+13, tmpip )) goto parse_error;
|
||||
if( !scan_ip6( p+13, tmpip )) goto parse_error;
|
||||
accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT );
|
||||
#endif
|
||||
} else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) {
|
||||
set_config_option( &g_redirecturl, p+21 );
|
||||
#ifdef WANT_SYNC_LIVE
|
||||
} else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) {
|
||||
if( !scan_ip4( p+25, tmpip )) goto parse_error;
|
||||
if( !scan_ip6( p+25, tmpip )) goto parse_error;
|
||||
accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC );
|
||||
} else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) {
|
||||
uint16_t tmpport = LIVESYNC_PORT;
|
||||
if( !scan_ip4_port( p+24, tmpip, &tmpport )) goto parse_error;
|
||||
if( !scan_ip6_port( p+24, tmpip, &tmpport )) goto parse_error;
|
||||
livesync_bind_mcast( tmpip, tmpport );
|
||||
#endif
|
||||
} else
|
||||
@ -411,10 +415,12 @@ int drop_privileges (const char * const serverdir) {
|
||||
}
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
char serverip[4] = {0,0,0,0}, tmpip[4];
|
||||
ot_ip6 serverip, tmpip;
|
||||
int bound = 0, scanon = 1;
|
||||
uint16_t tmpport;
|
||||
|
||||
memset( serverip, 0, sizeof(ot_ip6) );
|
||||
|
||||
while( scanon ) {
|
||||
switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:v"
|
||||
#ifdef WANT_ACCESSLIST_BLACK
|
||||
@ -425,7 +431,7 @@ while( scanon ) {
|
||||
"h" ) ) {
|
||||
case -1 : scanon = 0; break;
|
||||
case 'i':
|
||||
if( !scan_ip4( optarg, serverip )) { usage( argv[0] ); exit( 1 ); }
|
||||
if( !scan_ip6( optarg, serverip )) { usage( argv[0] ); exit( 1 ); }
|
||||
break;
|
||||
#ifdef WANT_ACCESSLIST_BLACK
|
||||
case 'b': set_config_option( &g_accesslist_filename, optarg); break;
|
||||
@ -446,7 +452,7 @@ while( scanon ) {
|
||||
case 'd': set_config_option( &g_serverdir, optarg ); break;
|
||||
case 'r': set_config_option( &g_redirecturl, optarg ); break;
|
||||
case 'A':
|
||||
if( !scan_ip4( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); }
|
||||
if( !scan_ip6( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); }
|
||||
accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */
|
||||
break;
|
||||
case 'f': bound += parse_configfile( optarg ); break;
|
||||
|
@ -8,10 +8,12 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Libowfat */
|
||||
#include "byte.h"
|
||||
#include "scan.h"
|
||||
#include "ip6.h"
|
||||
|
||||
/* Opentracker */
|
||||
#include "trackerlogic.h"
|
||||
@ -32,14 +34,14 @@ void accesslist_deinit( void ) {
|
||||
accesslist_reset( );
|
||||
}
|
||||
|
||||
static int accesslist_addentry( ot_hash *infohash ) {
|
||||
static int accesslist_addentry( ot_hash infohash ) {
|
||||
int eger;
|
||||
void *insert = vector_find_or_insert( &accesslist, infohash, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &eger );
|
||||
|
||||
if( !insert )
|
||||
return -1;
|
||||
|
||||
memmove( insert, infohash, OT_HASH_COMPARE_SIZE );
|
||||
memcpy( insert, infohash, OT_HASH_COMPARE_SIZE );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -64,7 +66,7 @@ static void accesslist_readfile( int foo ) {
|
||||
/* We do ignore anything that is not of the form "^[:xdigit:]{40}[^:xdigit:].*" */
|
||||
while( fgets( inbuf, sizeof(inbuf), accesslist_filehandle ) ) {
|
||||
int i;
|
||||
for( i=0; i<20; ++i ) {
|
||||
for( i=0; i<(int)sizeof(ot_hash); ++i ) {
|
||||
int eger = 16 * scan_fromhex( inbuf[ 2*i ] ) + scan_fromhex( inbuf[ 1 + 2*i ] );
|
||||
if( eger < 0 )
|
||||
continue;
|
||||
@ -74,13 +76,13 @@ static void accesslist_readfile( int foo ) {
|
||||
continue;
|
||||
|
||||
/* Append accesslist to accesslist vector */
|
||||
accesslist_addentry( &infohash );
|
||||
accesslist_addentry( infohash );
|
||||
}
|
||||
|
||||
fclose( accesslist_filehandle );
|
||||
}
|
||||
|
||||
int accesslist_hashisvalid( ot_hash *hash ) {
|
||||
int accesslist_hashisvalid( ot_hash hash ) {
|
||||
int exactmatch;
|
||||
binary_search( hash, accesslist.data, accesslist.size, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &exactmatch );
|
||||
|
||||
@ -102,30 +104,39 @@ void accesslist_init( ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t g_adminip_addresses[OT_ADMINIP_MAX];
|
||||
static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX];
|
||||
static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX];
|
||||
static unsigned int g_adminip_count = 0;
|
||||
|
||||
int accesslist_blessip( char *ip, ot_permissions permissions ) {
|
||||
int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) {
|
||||
if( g_adminip_count >= OT_ADMINIP_MAX )
|
||||
return -1;
|
||||
WRITE32(g_adminip_addresses + g_adminip_count,0,READ32(ip,0));
|
||||
|
||||
memcpy(g_adminip_addresses + g_adminip_count,ip,sizeof(ot_ip6));
|
||||
g_adminip_permissions[ g_adminip_count++ ] = permissions;
|
||||
|
||||
#ifdef _DEBUG
|
||||
uint8_t *_ip = (uint8_t*)ip;
|
||||
fprintf( stderr, "Blessing ip address %d.%d.%d.%d with:", _ip[0], _ip[1], _ip[2], _ip[3]);
|
||||
if( permissions & OT_PERMISSION_MAY_STAT ) fputs( " may_fetch_stats", stderr );
|
||||
if( permissions & OT_PERMISSION_MAY_LIVESYNC ) fputs( " may_sync_live", stderr );
|
||||
if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) fputs( " may_fetch_fullscrapes", stderr );
|
||||
if( !permissions ) fputs(" nothing.\n", stderr); else fputs(".\n", stderr );
|
||||
{
|
||||
char _debug[512];
|
||||
int off = snprintf( _debug, sizeof(_debug), "Blessing ip address " );
|
||||
off += fmt_ip6(_debug+off, ip );
|
||||
|
||||
if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" );
|
||||
if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" );
|
||||
if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" );
|
||||
if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing\n" );
|
||||
_debug[off++] = '.';
|
||||
write( 2, _debug, off );
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int accesslist_isblessed( char *ip, ot_permissions permissions ) {
|
||||
int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ) {
|
||||
unsigned int i;
|
||||
for( i=0; i<g_adminip_count; ++i )
|
||||
if( !memcmp( g_adminip_addresses + i, ip, 4) && ( g_adminip_permissions[ i ] & permissions ) )
|
||||
if( !memcmp( g_adminip_addresses + i, ip, sizeof(ot_ip6)) && ( g_adminip_permissions[ i ] & permissions ) )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define WANT_ACCESSLIST
|
||||
void accesslist_init( );
|
||||
void accesslist_deinit( );
|
||||
int accesslist_hashisvalid( ot_hash *hash );
|
||||
int accesslist_hashisvalid( ot_hash hash );
|
||||
|
||||
extern char *g_accesslist_filename;
|
||||
|
||||
@ -30,7 +30,7 @@ typedef enum {
|
||||
OT_PERMISSION_MAY_LIVESYNC = 0x4
|
||||
} ot_permissions;
|
||||
|
||||
int accesslist_blessip( char * ip, ot_permissions permissions );
|
||||
int accesslist_isblessed( char * ip, ot_permissions permissions );
|
||||
int accesslist_blessip( ot_ip6 ip, ot_permissions permissions );
|
||||
int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions );
|
||||
|
||||
#endif
|
||||
|
@ -115,7 +115,7 @@ static int fullscrape_increase( int *iovec_entries, struct iovec **iovector,
|
||||
}
|
||||
|
||||
static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) {
|
||||
int bucket,i;
|
||||
int bucket;
|
||||
char *r, *re;
|
||||
#ifdef WANT_COMPRESSION_GZIP
|
||||
char compress_buffer[OT_SCRAPE_MAXENTRYLEN];
|
||||
@ -165,17 +165,17 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tas
|
||||
|
||||
/* push hash as bencoded string */
|
||||
*r++='2'; *r++='0'; *r++=':';
|
||||
for(i=0;i<20;i+=4) WRITE32(r,i,READ32(hash,i)); r+=20;
|
||||
memcpy( r, hash, sizeof(ot_hash) ); r += sizeof(ot_hash);
|
||||
/* push rest of the scrape string */
|
||||
r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count );
|
||||
|
||||
break;
|
||||
case TASK_FULLSCRAPE_TPB_ASCII:
|
||||
to_hex( r, *hash ); r+=40;
|
||||
to_hex( r, *hash ); r+= 2 * sizeof(ot_hash);
|
||||
r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count );
|
||||
break;
|
||||
case TASK_FULLSCRAPE_TPB_BINARY:
|
||||
for(i=0;i<20;i+=4) WRITE32(r,i,READ32(hash,i)); r+=20;
|
||||
memcpy( r, *hash, sizeof(ot_hash) ); r += sizeof(ot_hash);
|
||||
*(uint32_t*)(r+0) = htonl( (uint32_t) peer_list->seed_count );
|
||||
*(uint32_t*)(r+4) = htonl( (uint32_t)( peer_list->peer_count-peer_list->seed_count) );
|
||||
r+=8;
|
||||
|
52
ot_http.c
52
ot_http.c
@ -15,6 +15,7 @@
|
||||
#include "byte.h"
|
||||
#include "array.h"
|
||||
#include "iob.h"
|
||||
#include "ip6.h"
|
||||
|
||||
/* Opentracker */
|
||||
#include "trackerlogic.h"
|
||||
@ -34,11 +35,6 @@ enum {
|
||||
SUCCESS_HTTP_HEADER_LENGTH_CONTENT_ENCODING = 32,
|
||||
SUCCESS_HTTP_SIZE_OFF = 17 };
|
||||
|
||||
#ifdef _DEBUG_PEERID
|
||||
size_t g_this_peerid_len = 0;
|
||||
char *g_this_peerid_data = NULL;
|
||||
#endif
|
||||
|
||||
static void http_senddata( const int64 client_socket, struct ot_workstruct *ws ) {
|
||||
struct http_data *h = io_getcookie( client_socket );
|
||||
ssize_t written_size;
|
||||
@ -63,7 +59,7 @@ static void http_senddata( const int64 client_socket, struct ot_workstruct *ws )
|
||||
}
|
||||
|
||||
iob_reset( &h->data.batch );
|
||||
memmove( outbuf, ws->reply + written_size, ws->reply_size - written_size );
|
||||
memcpy( outbuf, ws->reply + written_size, ws->reply_size - written_size );
|
||||
iob_addbuf_free( &h->data.batch, outbuf, ws->reply_size - written_size );
|
||||
h->flag |= STRUCT_HTTP_FLAG_IOB_USED;
|
||||
|
||||
@ -89,9 +85,9 @@ ssize_t http_issue_error( const int64 client_socket, struct ot_workstruct *ws, i
|
||||
|
||||
ws->reply = ws->outbuf;
|
||||
if( code == CODE_HTTPERROR_302 )
|
||||
ws->reply_size = snprintf( ws->reply, ws->outbuf_size, "HTTP/1.0 302 Found\r\nContent-Length: 0\r\nLocation: %s\r\n\r\n", g_redirecturl );
|
||||
ws->reply_size = snprintf( ws->reply, G_OUTBUF_SIZE, "HTTP/1.0 302 Found\r\nContent-Length: 0\r\nLocation: %s\r\n\r\n", g_redirecturl );
|
||||
else
|
||||
ws->reply_size = snprintf( ws->reply, ws->outbuf_size, "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(title)+16-4,title+4);
|
||||
ws->reply_size = snprintf( ws->reply, G_OUTBUF_SIZE, "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(title)+16-4,title+4);
|
||||
|
||||
#ifdef _DEBUG_HTTPERROR
|
||||
fprintf( stderr, "DEBUG: invalid request was: %s\n", ws->debugbuf );
|
||||
@ -245,13 +241,13 @@ static ssize_t http_handle_fullscrape( const int64 client_socket, struct ot_work
|
||||
if( strstr( ws->request, "gzip" ) ) {
|
||||
h->flag |= STRUCT_HTTP_FLAG_GZIP;
|
||||
format = TASK_FLAG_GZIP;
|
||||
stats_issue_event( EVENT_FULLSCRAPE_REQUEST_GZIP, *(int*)h->ip, 0 );
|
||||
stats_issue_event( EVENT_FULLSCRAPE_REQUEST_GZIP, 0, (uintptr_t)h->ip );
|
||||
} else
|
||||
#endif
|
||||
stats_issue_event( EVENT_FULLSCRAPE_REQUEST, *(int*)h->ip, 0 );
|
||||
stats_issue_event( EVENT_FULLSCRAPE_REQUEST, 0, (uintptr_t)h->ip );
|
||||
|
||||
#ifdef _DEBUG_HTTPERROR
|
||||
write( 2, ws->debugbuf, ws->debugbuf_size );
|
||||
write( 2, ws->debugbuf, G_DEBUGBUF_SIZE );
|
||||
#endif
|
||||
|
||||
/* Pass this task to the worker thread */
|
||||
@ -263,6 +259,7 @@ write( 2, ws->debugbuf, ws->debugbuf_size );
|
||||
return ws->reply_size = -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t http_handle_scrape( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) {
|
||||
static const ot_keywords keywords_scrape[] = { { "info_hash", 1 }, { NULL, -3 } };
|
||||
|
||||
@ -306,9 +303,6 @@ static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "even
|
||||
#ifdef WANT_IP_FROM_QUERY_STRING
|
||||
{ "ip", 7 },
|
||||
#endif
|
||||
#ifdef _DEBUG_PEERID
|
||||
{ "peer_id", 8 },
|
||||
#endif
|
||||
{ NULL, -3 } };
|
||||
static ot_keywords keywords_announce_event[] = { { "completed", 1 }, { "stopped", 2 }, { NULL, -3 } };
|
||||
static ssize_t http_handle_announce( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) {
|
||||
@ -332,10 +326,6 @@ static ssize_t http_handle_announce( const int64 client_socket, struct ot_workst
|
||||
numwant = 50;
|
||||
scanon = 1;
|
||||
|
||||
#ifdef _DEBUG_PEERID
|
||||
ws->peer_id = NULL;
|
||||
#endif
|
||||
|
||||
while( scanon ) {
|
||||
switch( scan_find_keywords(keywords_announce, &read_ptr, SCAN_SEARCHPATH_PARAM ) ) {
|
||||
case -2: scanon = 0; break; /* TERMINATOR */
|
||||
@ -383,16 +373,14 @@ static ssize_t http_handle_announce( const int64 client_socket, struct ot_workst
|
||||
break;
|
||||
#ifdef WANT_IP_FROM_QUERY_STRING
|
||||
case 7: /* matched "ip" */
|
||||
len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE );
|
||||
if( ( len <= 0 ) || scan_fixed_ip( write_ptr, len, (unsigned char*)/*tmp*/ws->reply ) ) HTTPERROR_400_PARAM;
|
||||
OT_SETIP( &peer, /*tmp*/ws->reply );
|
||||
{
|
||||
char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply+16;
|
||||
len = scan_urlencoded_query( &read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE );
|
||||
tmp_buf2[len] = 0;
|
||||
if( ( len <= 0 ) || scan_ip6( tmp_buf2, tmp_buf1 ) ) HTTPERROR_400_PARAM;
|
||||
OT_SETIP( &peer, tmp_buf1 );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef _DEBUG_PEERID
|
||||
case 8: /* matched "peer_id" */
|
||||
ws->peer_id_size = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE );
|
||||
ws->peer_id = ws->peer_id_size > 0 ? write_ptr : 0;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -402,9 +390,9 @@ static ssize_t http_handle_announce( const int64 client_socket, struct ot_workst
|
||||
return ws->reply_size = sprintf( ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" );
|
||||
|
||||
if( OT_PEERFLAG( &peer ) & PEER_FLAG_STOPPED )
|
||||
ws->reply_size = remove_peer_from_torrent( hash, &peer, ws->reply, FLAG_TCP );
|
||||
ws->reply_size = remove_peer_from_torrent( *hash, &peer, ws->reply, FLAG_TCP );
|
||||
else
|
||||
ws->reply_size = add_peer_to_torrent_and_return_peers(hash, &peer, FLAG_TCP, numwant, ws->reply );
|
||||
ws->reply_size = add_peer_to_torrent_and_return_peers( *hash, &peer, FLAG_TCP, numwant, ws->reply );
|
||||
|
||||
if( !ws->reply_size ) HTTPERROR_500;
|
||||
|
||||
@ -418,9 +406,9 @@ ssize_t http_handle_request( const int64 client_socket, struct ot_workstruct *ws
|
||||
|
||||
#ifdef _DEBUG_HTTPERROR
|
||||
reply_off = ws->request_size;
|
||||
if( ws->request_size >= (ssize_t)ws->debugbuf_size )
|
||||
reply_off = ws->debugbuf_size - 1;
|
||||
memmove( ws->debugbuf, ws->request, reply_off );
|
||||
if( ws->request_size >= G_DEBUGBUF_SIZE )
|
||||
reply_off = G_DEBUGBUF_SIZE - 1;
|
||||
memcpy( ws->debugbuf, ws->request, reply_off );
|
||||
ws->debugbuf[ reply_off ] = 0;
|
||||
#endif
|
||||
|
||||
|
@ -19,7 +19,7 @@ struct http_data {
|
||||
array request;
|
||||
io_batch batch;
|
||||
} data;
|
||||
char ip[4];
|
||||
ot_ip6 ip;
|
||||
STRUCT_HTTP_FLAG flag;
|
||||
};
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "socket.h"
|
||||
#include "ndelay.h"
|
||||
#include "byte.h"
|
||||
#include "ip6.h"
|
||||
|
||||
/* Opentracker */
|
||||
#include "trackerlogic.h"
|
||||
@ -88,14 +89,14 @@ void livesync_init( ) {
|
||||
|
||||
/* Prepare outgoing peers buffer */
|
||||
g_peerbuffer_pos = g_peerbuffer_start;
|
||||
memmove( g_peerbuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
memcpy( g_peerbuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
uint32_pack_big( (char*)g_peerbuffer_pos + sizeof( g_tracker_id ), OT_SYNC_PEER);
|
||||
g_peerbuffer_pos += sizeof( g_tracker_id ) + sizeof( uint32_t);
|
||||
|
||||
#ifdef WANT_SYNC_SCRAPE
|
||||
/* Prepare outgoing scrape buffer */
|
||||
g_scrapebuffer_pos = g_scrapebuffer_start;
|
||||
memmove( g_scrapebuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
memcpy( g_scrapebuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
uint32_pack_big( (char*)g_scrapebuffer_pos + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_TELL);
|
||||
g_scrapebuffer_pos += sizeof( g_tracker_id ) + sizeof( uint32_t);
|
||||
|
||||
@ -116,8 +117,13 @@ void livesync_deinit() {
|
||||
pthread_cancel( thread_id );
|
||||
}
|
||||
|
||||
void livesync_bind_mcast( char *ip, uint16_t port) {
|
||||
void livesync_bind_mcast( ot_ip6 ip, uint16_t port) {
|
||||
char tmpip[4] = {0,0,0,0};
|
||||
char *v4ip;
|
||||
|
||||
if( !ip6_isv4mapped(ip))
|
||||
exerr("v6 mcast support not yet available.");
|
||||
v4ip = ip+12;
|
||||
|
||||
if( g_socket_in != -1 )
|
||||
exerr("Error: Livesync listen ip specified twice.");
|
||||
@ -129,12 +135,12 @@ void livesync_bind_mcast( char *ip, uint16_t port) {
|
||||
if( socket_bind4_reuse( g_socket_in, tmpip, port ) == -1 )
|
||||
exerr("Error: Cant bind live sync incoming socket." );
|
||||
|
||||
if( socket_mcjoin4( g_socket_in, groupip_1, ip ) )
|
||||
if( socket_mcjoin4( g_socket_in, groupip_1, v4ip ) )
|
||||
exerr("Error: Cant make live sync incoming socket join mcast group.");
|
||||
|
||||
if( ( g_socket_out = socket_udp4()) < 0)
|
||||
exerr("Error: Cant create live sync outgoing socket." );
|
||||
if( socket_bind4_reuse( g_socket_out, ip, port ) == -1 )
|
||||
if( socket_bind4_reuse( g_socket_out, v4ip, port ) == -1 )
|
||||
exerr("Error: Cant bind live sync outgoing socket." );
|
||||
|
||||
socket_mcttl4(g_socket_out, 1);
|
||||
@ -160,9 +166,9 @@ static void livesync_handle_peersync( ssize_t datalen ) {
|
||||
if( !g_opentracker_running ) return;
|
||||
|
||||
if( OT_PEERFLAG(peer) & PEER_FLAG_STOPPED )
|
||||
remove_peer_from_torrent(hash, peer, NULL, FLAG_MCA );
|
||||
remove_peer_from_torrent( *hash, peer, NULL, FLAG_MCA );
|
||||
else
|
||||
add_peer_to_torrent( hash, peer, FLAG_MCA );
|
||||
add_peer_to_torrent( *hash, peer, FLAG_MCA );
|
||||
|
||||
off += sizeof( ot_hash ) + sizeof( ot_peer );
|
||||
}
|
||||
@ -175,7 +181,7 @@ void livesync_issue_beacon( ) {
|
||||
size_t torrent_count = mutex_get_torrent_count();
|
||||
uint8_t beacon[ sizeof(g_tracker_id) + sizeof(uint32_t) + sizeof( uint64_t ) ];
|
||||
|
||||
memmove( beacon, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
memcpy( beacon, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_BEACON);
|
||||
uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ) + sizeof(uint32_t), (uint32_t)((uint64_t)(torrent_count)>>32) );
|
||||
uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ) + 2 * sizeof(uint32_t), (uint32_t)torrent_count );
|
||||
@ -202,7 +208,7 @@ void livesync_handle_beacon( ssize_t datalen ) {
|
||||
|
||||
if( torrent_count_remote > g_inquire_remote_count ) {
|
||||
g_inquire_remote_count = torrent_count_remote;
|
||||
memmove( &g_inquire_remote_host, g_inbuffer, sizeof( g_tracker_id ) );
|
||||
memcpy( &g_inquire_remote_host, g_inbuffer, sizeof( g_tracker_id ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,9 +216,9 @@ void livesync_handle_beacon( ssize_t datalen ) {
|
||||
void livesync_issue_inquire( ) {
|
||||
uint8_t inquire[ sizeof(g_tracker_id) + sizeof(uint32_t) + sizeof(g_tracker_id)];
|
||||
|
||||
memmove( inquire, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
memcpy( inquire, &g_tracker_id, sizeof( g_tracker_id ) );
|
||||
uint32_pack_big( (char*)inquire + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_INQUIRE);
|
||||
memmove( inquire + sizeof(g_tracker_id) + sizeof(uint32_t), &g_inquire_remote_host, sizeof( g_tracker_id ) );
|
||||
memcpy( inquire + sizeof(g_tracker_id) + sizeof(uint32_t), &g_inquire_remote_host, sizeof( g_tracker_id ) );
|
||||
|
||||
socket_send4(g_socket_out, (char*)inquire, sizeof(inquire), groupip_1, LIVESYNC_PORT);
|
||||
}
|
||||
@ -239,7 +245,7 @@ void livesync_issue_tell( ) {
|
||||
unsigned int j;
|
||||
for( j=0; j<torrents_list->size; ++j ) {
|
||||
ot_torrent *torrent = (ot_torrent*)(torrents_list->data) + j;
|
||||
memmove(g_scrapebuffer_pos, torrent->hash, sizeof(ot_hash));
|
||||
memcpy(g_scrapebuffer_pos, torrent->hash, sizeof(ot_hash));
|
||||
g_scrapebuffer_pos += sizeof(ot_hash);
|
||||
uint32_pack_big( (char*)g_scrapebuffer_pos , (uint32_t)(g_now_minutes - torrent->peer_list->base ));
|
||||
uint32_pack_big( (char*)g_scrapebuffer_pos + 4, (uint32_t)((uint64_t)(torrent->peer_list->down_count)>>32) );
|
||||
@ -268,29 +274,29 @@ void livesync_handle_tell( ssize_t datalen ) {
|
||||
/* Some instance is in progress of telling. Our inquiry was successful.
|
||||
Don't ask again until we see next beacon. */
|
||||
g_next_inquire_time = 0;
|
||||
|
||||
|
||||
/* Don't cause any new inquiries during another tracker's tell */
|
||||
if( g_next_beacon_time - g_now_seconds < LIVESYNC_BEACON_INTERVAL )
|
||||
g_next_beacon_time = g_now_seconds + LIVESYNC_BEACON_INTERVAL;
|
||||
|
||||
while( off + sizeof(ot_hash) + 12 <= (size_t)datalen ) {
|
||||
ot_hash *hash = (ot_hash*)(g_inbuffer+off);
|
||||
ot_vector *torrents_list = mutex_bucket_lock_by_hash(hash);
|
||||
ot_vector *torrents_list = mutex_bucket_lock_by_hash(*hash);
|
||||
size_t down_count_remote;
|
||||
int exactmatch;
|
||||
ot_torrent * torrent = vector_find_or_insert(torrents_list, hash, sizeof(ot_hash), OT_HASH_COMPARE_SIZE, &exactmatch);
|
||||
if( !torrent ) {
|
||||
mutex_bucket_unlock_by_hash( hash, 0 );
|
||||
mutex_bucket_unlock_by_hash( *hash, 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !exactmatch ) {
|
||||
/* Create a new torrent entry, then */
|
||||
int i; for(i=0;i<20;i+=4) WRITE32(&torrent->hash,i,READ32(hash,i));
|
||||
memcpy( &torrent->hash, hash, sizeof(ot_hash));
|
||||
|
||||
if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) {
|
||||
vector_remove_torrent( torrents_list, torrent );
|
||||
mutex_bucket_unlock_by_hash( hash, 0 );
|
||||
mutex_bucket_unlock_by_hash( *hash, 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -298,8 +304,8 @@ void livesync_handle_tell( ssize_t datalen ) {
|
||||
torrent->peer_list->base = g_now_minutes - uint32_read_big((char*)g_inbuffer+off+sizeof(ot_hash));
|
||||
}
|
||||
|
||||
down_count_remote = (size_t)(((uint64_t)uint32_read_big((char*)g_inbuffer+off+sizeof( ot_hash ) + sizeof(uint32_t))) << 32);
|
||||
down_count_remote |= (size_t) uint32_read_big((char*)g_inbuffer+off+sizeof( ot_hash ) + 2 * sizeof(uint32_t));
|
||||
down_count_remote = (size_t)(((uint64_t)uint32_read_big((char*)g_inbuffer+off+sizeof(ot_hash ) + sizeof(uint32_t))) << 32);
|
||||
down_count_remote |= (size_t) uint32_read_big((char*)g_inbuffer+off+sizeof(ot_hash ) + 2 * sizeof(uint32_t));
|
||||
|
||||
if( down_count_remote > torrent->peer_list->down_count )
|
||||
torrent->peer_list->down_count = down_count_remote;
|
||||
@ -319,7 +325,7 @@ void livesync_handle_tell( ssize_t datalen ) {
|
||||
stuck when there's not enough traffic to fill udp packets fast
|
||||
enough */
|
||||
void livesync_ticker( ) {
|
||||
|
||||
|
||||
/* livesync_issue_peersync sets g_next_packet_time */
|
||||
if( g_now_seconds > g_next_packet_time &&
|
||||
g_peerbuffer_pos > g_peerbuffer_start + sizeof( g_tracker_id ) )
|
||||
@ -350,21 +356,19 @@ void livesync_ticker( ) {
|
||||
}
|
||||
|
||||
/* Inform live sync about whats going on. */
|
||||
void livesync_tell( ot_hash * const info_hash, const ot_peer * const peer ) {
|
||||
unsigned int i;
|
||||
for(i=0;i<sizeof(ot_hash)/4;i+=4) WRITE32(g_peerbuffer_pos,i,READ32(info_hash,i));
|
||||
void livesync_tell( ot_hash const info_hash, const ot_peer * const peer ) {
|
||||
|
||||
WRITE32(g_peerbuffer_pos,sizeof(ot_hash) ,READ32(peer,0));
|
||||
WRITE32(g_peerbuffer_pos,sizeof(ot_hash)+4,READ32(peer,4));
|
||||
memcpy( g_peerbuffer_pos, info_hash, sizeof(ot_hash) );
|
||||
memcpy( g_peerbuffer_pos+sizeof(ot_hash), peer, sizeof(ot_peer) );
|
||||
|
||||
g_peerbuffer_pos += sizeof(ot_hash)+8;
|
||||
g_peerbuffer_pos += sizeof(ot_hash)+sizeof(ot_peer);
|
||||
|
||||
if( g_peerbuffer_pos >= g_peerbuffer_highwater )
|
||||
livesync_issue_peersync();
|
||||
}
|
||||
|
||||
static void * livesync_worker( void * args ) {
|
||||
uint8_t in_ip[4]; uint16_t in_port;
|
||||
ot_ip6 in_ip; uint16_t in_port;
|
||||
ssize_t datalen;
|
||||
|
||||
(void)args;
|
||||
@ -375,7 +379,7 @@ static void * livesync_worker( void * args ) {
|
||||
/* Expect at least tracker id and packet type */
|
||||
if( datalen <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) )
|
||||
continue;
|
||||
if( !accesslist_isblessed((char*)in_ip, OT_PERMISSION_MAY_LIVESYNC))
|
||||
if( !accesslist_isblessed(in_ip, OT_PERMISSION_MAY_LIVESYNC))
|
||||
continue;
|
||||
if( !memcmp( g_inbuffer, &g_tracker_id, sizeof( g_tracker_id ) ) ) {
|
||||
/* TODO: log packet coming from ourselves */
|
||||
|
@ -86,7 +86,7 @@ void livesync_deinit();
|
||||
void livesync_bind_mcast( char *ip, uint16_t port );
|
||||
|
||||
/* Inform live sync about whats going on. */
|
||||
void livesync_tell( ot_hash * const info_hash, const ot_peer * const peer );
|
||||
void livesync_tell( ot_hash const info_hash, const ot_peer * const peer );
|
||||
|
||||
/* Tickle the live sync module from time to time, so no events get
|
||||
stuck when there's not enough traffic to fill udp packets fast
|
||||
|
@ -80,8 +80,8 @@ ot_vector *mutex_bucket_lock( int bucket ) {
|
||||
return all_torrents + bucket;
|
||||
}
|
||||
|
||||
ot_vector *mutex_bucket_lock_by_hash( ot_hash *hash ) {
|
||||
int bucket = uint32_read_big( (char*)*hash ) >> OT_BUCKET_COUNT_SHIFT;
|
||||
ot_vector *mutex_bucket_lock_by_hash( ot_hash hash ) {
|
||||
int bucket = uint32_read_big( (char*)hash ) >> OT_BUCKET_COUNT_SHIFT;
|
||||
|
||||
/* Can block */
|
||||
mutex_bucket_lock( bucket );
|
||||
@ -96,8 +96,8 @@ void mutex_bucket_unlock( int bucket, int delta_torrentcount ) {
|
||||
pthread_mutex_unlock( &bucket_mutex );
|
||||
}
|
||||
|
||||
void mutex_bucket_unlock_by_hash( ot_hash *hash, int delta_torrentcount ) {
|
||||
mutex_bucket_unlock( uint32_read_big( (char*)*hash ) >> OT_BUCKET_COUNT_SHIFT, delta_torrentcount );
|
||||
void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) {
|
||||
mutex_bucket_unlock( uint32_read_big( (char*)hash ) >> OT_BUCKET_COUNT_SHIFT, delta_torrentcount );
|
||||
}
|
||||
|
||||
size_t mutex_get_torrent_count( ) {
|
||||
|
@ -12,10 +12,10 @@ void mutex_init( );
|
||||
void mutex_deinit( );
|
||||
|
||||
ot_vector *mutex_bucket_lock( int bucket );
|
||||
ot_vector *mutex_bucket_lock_by_hash( ot_hash *hash );
|
||||
ot_vector *mutex_bucket_lock_by_hash( ot_hash hash );
|
||||
|
||||
void mutex_bucket_unlock( int bucket, int delta_torrentcount );
|
||||
void mutex_bucket_unlock_by_hash( ot_hash *hash, int delta_torrentcount );
|
||||
void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount );
|
||||
|
||||
size_t mutex_get_torrent_count();
|
||||
|
||||
|
34
ot_stats.c
34
ot_stats.c
@ -12,10 +12,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Libowfat */
|
||||
#include "byte.h"
|
||||
#include "io.h"
|
||||
#include "ip6.h"
|
||||
|
||||
/* Opentracker */
|
||||
#include "trackerlogic.h"
|
||||
@ -132,8 +134,8 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, u
|
||||
while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j;
|
||||
--j;
|
||||
|
||||
memmove( scores, scores + 1, j * sizeof( *scores ) );
|
||||
memmove( networks, networks + 1, j * sizeof( *networks ) );
|
||||
memcpy( scores, scores + 1, j * sizeof( *scores ) );
|
||||
memcpy( networks, networks + 1, j * sizeof( *networks ) );
|
||||
scores[ j ] = node->counters[ i ];
|
||||
networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) );
|
||||
}
|
||||
@ -176,13 +178,13 @@ size_t stats_top10_txt( char * reply ) {
|
||||
ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list;
|
||||
int idx = 9; while( (idx >= 0) && ( peer_list->peer_count > top10c[idx].val ) ) --idx;
|
||||
if ( idx++ != 9 ) {
|
||||
memmove( top10c + idx + 1, top10c + idx, ( 9 - idx ) * sizeof( ot_record ) );
|
||||
memcpy( top10c + idx + 1, top10c + idx, ( 9 - idx ) * sizeof( ot_record ) );
|
||||
top10c[idx].val = peer_list->peer_count;
|
||||
top10c[idx].torrent = (ot_torrent*)(torrents_list->data) + j;
|
||||
}
|
||||
idx = 9; while( (idx >= 0) && ( peer_list->seed_count > top10s[idx].val ) ) --idx;
|
||||
if ( idx++ != 9 ) {
|
||||
memmove( top10s + idx + 1, top10s + idx, ( 9 - idx ) * sizeof( ot_record ) );
|
||||
memcpy( top10s + idx + 1, top10s + idx, ( 9 - idx ) * sizeof( ot_record ) );
|
||||
top10s[idx].val = peer_list->seed_count;
|
||||
top10s[idx].torrent = (ot_torrent*)(torrents_list->data) + j;
|
||||
}
|
||||
@ -269,7 +271,7 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh )
|
||||
while( ( insert_pos >= 0 ) && ( count[j] > slash24s[ 2 * insert_pos ] ) )
|
||||
--insert_pos;
|
||||
++insert_pos;
|
||||
memmove( slash24s + 2 * ( insert_pos + 1 ), slash24s + 2 * ( insert_pos ), 2 * sizeof( uint32_t ) * ( amount - insert_pos - 1 ) );
|
||||
memcpy( slash24s + 2 * ( insert_pos + 1 ), slash24s + 2 * ( insert_pos ), 2 * sizeof( uint32_t ) * ( amount - insert_pos - 1 ) );
|
||||
slash24s[ 2 * insert_pos ] = count[j];
|
||||
slash24s[ 2 * insert_pos + 1 ] = ( i << NUM_TOPBITS ) + j;
|
||||
if( slash24s[ 2 * amount - 2 ] > thresh )
|
||||
@ -537,7 +539,7 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype
|
||||
iovec_fixlast( iovec_entries, iovector, r );
|
||||
}
|
||||
|
||||
void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data ) {
|
||||
void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event_data ) {
|
||||
switch( event ) {
|
||||
case EVENT_ACCEPT:
|
||||
if( proto == FLAG_TCP ) ot_overall_tcp_connections++; else ot_overall_udp_connections++;
|
||||
@ -559,16 +561,24 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_
|
||||
break;
|
||||
case EVENT_FULLSCRAPE_REQUEST:
|
||||
{
|
||||
uint8_t ip[4]; *(uint32_t*)ip = (uint32_t)proto; /* ugly hack to transfer ip to stats */
|
||||
LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE\n", (unsigned int)(g_now_seconds - ot_start_time)/60, ip[0], ip[1], ip[2], ip[3] );
|
||||
ot_full_scrape_request_count++;
|
||||
ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */
|
||||
char _debug[512];
|
||||
int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 );
|
||||
off += fmt_ip6( _debug+off, *ip );
|
||||
off += snprintf( _debug, sizeof(_debug)-off, " - FULL SCRAPE\n" );
|
||||
write( 2, _debug, off );
|
||||
ot_full_scrape_request_count++;
|
||||
}
|
||||
break;
|
||||
case EVENT_FULLSCRAPE_REQUEST_GZIP:
|
||||
{
|
||||
uint8_t ip[4]; *(uint32_t*)ip = (uint32_t)proto; /* ugly hack to transfer ip to stats */
|
||||
LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE GZIP\n", (unsigned int)(g_now_seconds - ot_start_time)/60, ip[0], ip[1], ip[2], ip[3] );
|
||||
ot_full_scrape_request_count++;
|
||||
ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */
|
||||
char _debug[512];
|
||||
int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 );
|
||||
off += fmt_ip6(_debug+off, *ip );
|
||||
off += snprintf( _debug, sizeof(_debug)-off, " - FULL SCRAPE\n" );
|
||||
write( 2, _debug, off );
|
||||
ot_full_scrape_request_count++;
|
||||
}
|
||||
break;
|
||||
case EVENT_FAILED:
|
||||
|
@ -32,7 +32,7 @@ enum {
|
||||
CODE_HTTPERROR_COUNT
|
||||
};
|
||||
|
||||
void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data );
|
||||
void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event_data );
|
||||
void stats_deliver( int64 socket, int tasktype );
|
||||
size_t return_stats_for_tracker( char *reply, int mode, int format );
|
||||
size_t stats_return_tracker_version( char *reply );
|
||||
|
28
ot_udp.c
28
ot_udp.c
@ -19,15 +19,15 @@
|
||||
|
||||
static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff };
|
||||
|
||||
static void udp_make_connectionid( uint32_t * connid, const char * remoteip ) {
|
||||
static void udp_make_connectionid( uint32_t * connid, const ot_ip6 remoteip ) {
|
||||
/* Touch unused variable */
|
||||
(void)remoteip;
|
||||
|
||||
/* Use a static secret for now */
|
||||
memmove( connid, g_static_connid, 8 );
|
||||
memcpy( connid, g_static_connid, 8 );
|
||||
}
|
||||
|
||||
static int udp_test_connectionid( const uint32_t * const connid, const char * remoteip ) {
|
||||
static int udp_test_connectionid( const uint32_t * const connid, const ot_ip6 remoteip ) {
|
||||
/* Touch unused variable */
|
||||
(void)remoteip;
|
||||
|
||||
@ -36,19 +36,19 @@ static int udp_test_connectionid( const uint32_t * const connid, const char * re
|
||||
}
|
||||
|
||||
/* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */
|
||||
void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) {
|
||||
void handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
|
||||
ot_peer peer;
|
||||
ot_hash *hash = NULL;
|
||||
char remoteip[4];
|
||||
ot_ip6 remoteip;
|
||||
uint32_t *inpacket = (uint32_t*)ws->inbuf;
|
||||
uint32_t *outpacket = (uint32_t*)ws->outbuf;
|
||||
uint32_t numwant, left, event;
|
||||
uint32_t numwant, left, event, scopeid;
|
||||
uint16_t port, remoteport;
|
||||
size_t r, r_out;
|
||||
|
||||
r = socket_recv4( serversocket, ws->inbuf, ws->inbuf_size, remoteip, &remoteport);
|
||||
r = socket_recv6( serversocket, ws->inbuf, G_INBUF_SIZE, remoteip, &remoteport, &scopeid );
|
||||
|
||||
stats_issue_event( EVENT_ACCEPT, FLAG_UDP, ntohl(*(uint32_t*)remoteip) );
|
||||
stats_issue_event( EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip );
|
||||
stats_issue_event( EVENT_READ, FLAG_UDP, r );
|
||||
|
||||
/* Minimum udp tracker packet size, also catches error */
|
||||
@ -65,7 +65,7 @@ void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) {
|
||||
outpacket[1] = inpacket[3];
|
||||
udp_make_connectionid( outpacket + 2, remoteip );
|
||||
|
||||
socket_send4( serversocket, ws->outbuf, 16, remoteip, remoteport );
|
||||
socket_send6( serversocket, ws->outbuf, 16, remoteip, remoteport, 0 );
|
||||
stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 );
|
||||
break;
|
||||
case 1: /* This is an announce action */
|
||||
@ -103,11 +103,11 @@ void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) {
|
||||
outpacket[1] = inpacket[12/4];
|
||||
|
||||
if( OT_PEERFLAG( &peer ) & PEER_FLAG_STOPPED ) /* Peer is gone. */
|
||||
r = remove_peer_from_torrent( hash, &peer, ws->outbuf, FLAG_UDP );
|
||||
r = remove_peer_from_torrent( *hash, &peer, ws->outbuf, FLAG_UDP );
|
||||
else
|
||||
r = 8 + add_peer_to_torrent_and_return_peers( hash, &peer, FLAG_UDP, numwant, ((char*)outpacket) + 8 );
|
||||
r = 8 + add_peer_to_torrent_and_return_peers( *hash, &peer, FLAG_UDP, numwant, ((char*)outpacket) + 8 );
|
||||
|
||||
socket_send4( serversocket, ws->outbuf, r, remoteip, remoteport );
|
||||
socket_send6( serversocket, ws->outbuf, r, remoteip, remoteport, 0 );
|
||||
stats_issue_event( EVENT_ANNOUNCE, FLAG_UDP, r );
|
||||
break;
|
||||
|
||||
@ -119,9 +119,9 @@ void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) {
|
||||
outpacket[1] = inpacket[12/4];
|
||||
|
||||
for( r_out = 0; ( r_out * 20 < r - 16) && ( r_out <= 74 ); r_out++ )
|
||||
return_udp_scrape_for_torrent( (ot_hash*)( ((char*)inpacket) + 16 + 20 * r_out ), ((char*)outpacket) + 8 + 12 * r_out );
|
||||
return_udp_scrape_for_torrent( *(ot_hash*)( ((char*)inpacket) + 16 + 20 * r_out ), ((char*)outpacket) + 8 + 12 * r_out );
|
||||
|
||||
socket_send4( serversocket, ws->outbuf, 8 + 12 * r_out, remoteip, remoteport );
|
||||
socket_send6( serversocket, ws->outbuf, 8 + 12 * r_out, remoteip, remoteport, 0 );
|
||||
stats_issue_event( EVENT_SCRAPE, FLAG_UDP, r );
|
||||
break;
|
||||
}
|
||||
|
2
ot_udp.h
2
ot_udp.h
@ -6,6 +6,6 @@
|
||||
#ifndef __OT_UDP_H__
|
||||
#define __OT_UDP_H__
|
||||
|
||||
void handle_udp4( int64 serversocket, struct ot_workstruct *ws );
|
||||
void handle_udp6( int64 serversocket, struct ot_workstruct *ws );
|
||||
|
||||
#endif
|
||||
|
24
ot_vector.c
24
ot_vector.c
@ -17,9 +17,7 @@
|
||||
#include "uint16.h"
|
||||
|
||||
static int vector_compare_peer(const void *peer1, const void *peer2 ) {
|
||||
int32_t cmp = READ32(peer2,0) - READ32(peer1,0);
|
||||
if (cmp == 0) cmp = READ16(peer2,4) - READ16(peer1,4);
|
||||
return cmp;
|
||||
return memcmp( peer1, peer2, OT_PEER_COMPARE_SIZE );
|
||||
}
|
||||
|
||||
/* This function gives us a binary search that returns a pointer, even if
|
||||
@ -30,19 +28,14 @@ static int vector_compare_peer(const void *peer1, const void *peer2 ) {
|
||||
*/
|
||||
void *binary_search( const void * const key, const void * base, const size_t member_count, const size_t member_size,
|
||||
size_t compare_size, int *exactmatch ) {
|
||||
size_t offs, mc = member_count;
|
||||
size_t mc = member_count;
|
||||
int8_t *lookat = ((int8_t*)base) + member_size * (mc >> 1);
|
||||
int32_t key_cache = READ32(key,0);
|
||||
*exactmatch = 1;
|
||||
|
||||
while( mc ) {
|
||||
int32_t cmp = READ32(lookat,0) - key_cache;
|
||||
if (cmp == 0) {
|
||||
for( offs = 4; cmp == 0 && offs < compare_size; offs += 4 )
|
||||
cmp = READ32(lookat,offs) - READ32(key,offs);
|
||||
if( cmp == 0 )
|
||||
return (void *)lookat;
|
||||
}
|
||||
int32_t cmp = memcmp( lookat, key, compare_size );
|
||||
if( cmp == 0 )
|
||||
return (void *)lookat;
|
||||
|
||||
if (cmp < 0) {
|
||||
base = (void*)(lookat + member_size);
|
||||
@ -60,13 +53,10 @@ void *binary_search( const void * const key, const void * base, const size_t mem
|
||||
ot_peer *binary_search_peer( const ot_peer * const peer, const ot_peer * base, const size_t member_count, int *exactmatch ) {
|
||||
size_t mc = member_count;
|
||||
const ot_peer *lookat = base + (mc >> 1);
|
||||
int32_t low = READ32(peer,0);
|
||||
int16_t high = READ16(peer,4);
|
||||
*exactmatch = 1;
|
||||
|
||||
while( mc ) {
|
||||
int32_t cmp = READ32(lookat,0) - low;
|
||||
if(cmp == 0) cmp = READ16(lookat,4) - high;
|
||||
int32_t cmp = memcmp(lookat,peer,OT_PEER_COMPARE_SIZE );
|
||||
if(cmp == 0) return (ot_peer*)lookat;
|
||||
|
||||
if (cmp < 0) {
|
||||
@ -84,7 +74,7 @@ ot_peer *binary_search_peer( const ot_peer * const peer, const ot_peer * base, c
|
||||
|
||||
|
||||
static uint8_t vector_hash_peer( ot_peer *peer, int bucket_count ) {
|
||||
unsigned int hash = 5381, i = 6;
|
||||
unsigned int hash = 5381, i = OT_PEER_COMPARE_SIZE;
|
||||
uint8_t *p = (uint8_t*)peer;
|
||||
while( i-- ) hash += (hash<<5) + *(p++);
|
||||
return hash % bucket_count;
|
||||
|
@ -140,21 +140,4 @@ ssize_t scan_fixed_int( char *data, size_t len, int *tmp ) {
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] ) {
|
||||
int u, i;
|
||||
|
||||
for( i=0; i<4; ++i ) {
|
||||
ssize_t j = scan_fixed_int( data, len, &u );
|
||||
if( j == (ssize_t)len ) return len;
|
||||
ip[i] = u;
|
||||
data += len - j;
|
||||
len = j;
|
||||
if ( i<3 ) {
|
||||
if( !len || *data != '.') return -1;
|
||||
--len; ++data;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *g_version_scan_urlencoded_query_c = "$Source$: $Revision$\n";
|
||||
|
@ -46,17 +46,10 @@ int scan_find_keywords( const ot_keywords * keywords, char **string, SCAN_SEARCH
|
||||
void scan_urlencoded_skipvalue( char **string );
|
||||
|
||||
/* data pointer to len chars of string
|
||||
len length of chars in data to parse
|
||||
number number to receive result
|
||||
returns number of bytes not parsed, mostly !=0 means fail
|
||||
*/
|
||||
len length of chars in data to parse
|
||||
number number to receive result
|
||||
returns number of bytes not parsed, mostly !=0 means fail
|
||||
*/
|
||||
ssize_t scan_fixed_int( char *data, size_t len, int *number );
|
||||
|
||||
/* data pointer to len chars of string
|
||||
len length of chars in data to parse
|
||||
ip buffer to receive result
|
||||
returns number of bytes not parsed, mostly !=0 means fail
|
||||
*/
|
||||
ssize_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] );
|
||||
|
||||
#endif
|
||||
|
@ -41,12 +41,7 @@ void free_peerlist( ot_peerlist *peer_list ) {
|
||||
free( peer_list );
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_PEERID
|
||||
extern size_t g_this_peerid_len;
|
||||
extern char *g_this_peerid_data;
|
||||
#endif
|
||||
|
||||
size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ) {
|
||||
size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ) {
|
||||
int exactmatch, delta_torrentcount = 0;
|
||||
size_t reply_size;
|
||||
ot_torrent *torrent;
|
||||
@ -66,7 +61,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO
|
||||
|
||||
if( !exactmatch ) {
|
||||
/* Create a new torrent entry, then */
|
||||
int i; for(i=0;i<20;i+=4) WRITE32(&torrent->hash,i,READ32(hash,i));
|
||||
memcpy( torrent->hash, hash, sizeof(ot_hash) );
|
||||
|
||||
if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) {
|
||||
vector_remove_torrent( torrents_list, torrent );
|
||||
@ -114,16 +109,6 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO
|
||||
} else {
|
||||
stats_issue_event( EVENT_RENEW, 0, OT_PEERTIME( peer_dest ) );
|
||||
|
||||
#ifdef _DEBUG_PEERID
|
||||
if( OT_PEERTIME( peer_dest ) < 2 ) {
|
||||
uint8_t *_ip = (uint8_t*)peer_dest;
|
||||
int i;
|
||||
for( i=0;i<20;++i)printf("%02X",(*hash)[i]);
|
||||
if( g_this_peerid_data ) g_this_peerid_data[g_this_peerid_len] = 0;
|
||||
printf( " %d.%d.%d.%d:%d\t%d %02X %s\n", _ip[0], _ip[1], _ip[2], _ip[3], OT_PEERTIME( peer_dest ), *(uint16_t*)( ((char*)peer_dest)+4 ), OT_PEERFLAG(peer_dest), g_this_peerid_data ? g_this_peerid_data : "-" );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WANT_SYNC_LIVE
|
||||
/* Won't live sync peers that come back too fast. Only exception:
|
||||
fresh "completed" reports */
|
||||
@ -144,7 +129,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO
|
||||
OT_PEERFLAG( peer ) |= PEER_FLAG_COMPLETED;
|
||||
}
|
||||
|
||||
*(uint64_t*)(peer_dest) = *(uint64_t*)(peer);
|
||||
*peer_dest = *peer;
|
||||
#ifdef WANT_SYNC
|
||||
if( proto == FLAG_MCA ) {
|
||||
mutex_bucket_unlock_by_hash( hash, delta_torrentcount );
|
||||
@ -153,7 +138,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO
|
||||
#endif
|
||||
|
||||
reply_size = return_peers_for_torrent( torrent, amount, reply, proto );
|
||||
mutex_bucket_unlock_by_hash( &torrent->hash, delta_torrentcount );
|
||||
mutex_bucket_unlock_by_hash( torrent->hash, delta_torrentcount );
|
||||
return reply_size;
|
||||
}
|
||||
|
||||
@ -171,9 +156,9 @@ static size_t return_peers_all( ot_peerlist *peer_list, char *reply ) {
|
||||
ot_peer * peers = (ot_peer*)bucket_list[bucket].data;
|
||||
size_t peer_count = bucket_list[bucket].size;
|
||||
while( peer_count-- ) {
|
||||
WRITE32(r,0,READ32(peers,0));
|
||||
WRITE16(r,4,READ16(peers++,4));
|
||||
r+=6;
|
||||
memcpy(r,peers,OT_PEER_COMPARE_SIZE);
|
||||
peers+=sizeof(ot_peer);
|
||||
r+=OT_PEER_COMPARE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,9 +201,8 @@ static size_t return_peers_selection( ot_peerlist *peer_list, size_t amount, cha
|
||||
bucket_index = ( bucket_index + 1 ) % num_buckets;
|
||||
}
|
||||
peer = ((ot_peer*)bucket_list[bucket_index].data) + bucket_offset;
|
||||
WRITE32(r,0,READ32(peer,0));
|
||||
WRITE16(r,4,READ16(peer,4));
|
||||
r+=6;
|
||||
memcpy(r,peer,OT_PEER_COMPARE_SIZE);
|
||||
r+=OT_PEER_COMPARE_SIZE;
|
||||
}
|
||||
return r - reply;
|
||||
}
|
||||
@ -236,7 +220,7 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply
|
||||
|
||||
if( proto == FLAG_TCP ) {
|
||||
int erval = OT_CLIENT_REQUEST_INTERVAL_RANDOM;
|
||||
r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie12:min intervali%ie5:peers%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, erval, erval/2, 6*amount );
|
||||
r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie12:min intervali%ie5:peers" PEERS6 "%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, erval, erval/2, OT_PEER_COMPARE_SIZE*amount );
|
||||
} else {
|
||||
*(uint32_t*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM );
|
||||
*(uint32_t*)(r+4) = htonl( peer_list->peer_count );
|
||||
@ -258,7 +242,7 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply
|
||||
}
|
||||
|
||||
/* Fetches scrape info for a specific torrent */
|
||||
size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ) {
|
||||
size_t return_udp_scrape_for_torrent( ot_hash hash, char *reply ) {
|
||||
int exactmatch, delta_torrentcount = 0;
|
||||
ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash );
|
||||
ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
|
||||
@ -292,7 +276,7 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl
|
||||
|
||||
for( i=0; i<amount; ++i ) {
|
||||
ot_hash *hash = hash_list + i;
|
||||
ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash );
|
||||
ot_vector *torrents_list = mutex_bucket_lock_by_hash( *hash );
|
||||
ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
|
||||
|
||||
if( exactmatch ) {
|
||||
@ -300,14 +284,13 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl
|
||||
vector_remove_torrent( torrents_list, torrent );
|
||||
delta_torrentcount = -1;
|
||||
} else {
|
||||
int j;
|
||||
*r++='2';*r++='0';*r++=':';
|
||||
for(j=0;j<20;j+=4) WRITE32(r,j,READ32(hash,j)); r += 20;
|
||||
memcpy( r, hash, sizeof(ot_hash) ); r+=sizeof(ot_hash);
|
||||
r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee",
|
||||
torrent->peer_list->seed_count, torrent->peer_list->down_count, torrent->peer_list->peer_count-torrent->peer_list->seed_count );
|
||||
}
|
||||
}
|
||||
mutex_bucket_unlock_by_hash( hash, delta_torrentcount );
|
||||
mutex_bucket_unlock_by_hash( *hash, delta_torrentcount );
|
||||
}
|
||||
|
||||
*r++ = 'e'; *r++ = 'e';
|
||||
@ -315,7 +298,7 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl
|
||||
}
|
||||
|
||||
static ot_peerlist dummy_list;
|
||||
size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) {
|
||||
size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) {
|
||||
int exactmatch;
|
||||
size_t reply_size = 0;
|
||||
ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash );
|
||||
|
@ -11,17 +11,16 @@
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Libowfat */
|
||||
#include <uint16.h>
|
||||
#include <uint32.h>
|
||||
|
||||
#define READ16(addr,offs) ((int16_t)uint16_read((offs)+(uint8_t*)(addr)))
|
||||
#define READ32(addr,offs) ((int32_t)uint32_read((offs)+(uint8_t*)(addr)))
|
||||
#define WRITE16(addr,offs,val) uint16_pack((offs)+(uint8_t*)(addr),(val))
|
||||
#define WRITE32(addr,offs,val) uint32_pack((offs)+(uint8_t*)(addr),(val))
|
||||
|
||||
typedef uint8_t ot_hash[20];
|
||||
typedef time_t ot_time;
|
||||
typedef char ot_ip6[16];
|
||||
#ifdef WANT_V6
|
||||
#define OT_IP_SIZE 16
|
||||
#define PEERS6 "6"
|
||||
#else
|
||||
#define OT_IP_SIZE 4
|
||||
#define PEERS6 ""
|
||||
#endif
|
||||
|
||||
/* Some tracker behaviour tunable */
|
||||
#define OT_CLIENT_TIMEOUT 30
|
||||
@ -60,7 +59,7 @@ extern uint32_t g_tracker_id;
|
||||
typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA } PROTO_FLAG;
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[8];
|
||||
uint8_t data[OT_IP_SIZE+2+2];
|
||||
} ot_peer;
|
||||
static const uint8_t PEER_FLAG_SEEDING = 0x80;
|
||||
static const uint8_t PEER_FLAG_COMPLETED = 0x40;
|
||||
@ -68,12 +67,17 @@ static const uint8_t PEER_FLAG_STOPPED = 0x20;
|
||||
static const uint8_t PEER_FLAG_FROM_SYNC = 0x10;
|
||||
static const uint8_t PEER_FLAG_LEECHING = 0x00;
|
||||
|
||||
#define OT_SETIP(peer,ip) WRITE32((peer),0,READ32((ip),0))
|
||||
#define OT_SETPORT(peer,port) WRITE16((peer),4,READ16((port),0))
|
||||
#define OT_PEERFLAG(peer) (((uint8_t*)(peer))[6])
|
||||
#define OT_PEERTIME(peer) (((uint8_t*)(peer))[7])
|
||||
#ifdef WANT_V6
|
||||
#define OT_SETIP(peer,ip) memcpy((peer),(ip),(OT_IP_SIZE))
|
||||
#else
|
||||
#define OT_SETIP(peer,ip) memcpy((peer),(((uint8_t*)ip)+12),(OT_IP_SIZE))
|
||||
#endif
|
||||
#define OT_SETPORT(peer,port) memcpy(((uint8_t*)(peer))+(OT_IP_SIZE),(port),2)
|
||||
#define OT_PEERFLAG(peer) (((uint8_t*)(peer))[(OT_IP_SIZE)+2])
|
||||
#define OT_PEERTIME(peer) (((uint8_t*)(peer))[(OT_IP_SIZE)+3])
|
||||
|
||||
#define OT_HASH_COMPARE_SIZE (sizeof(ot_hash))
|
||||
#define OT_PEER_COMPARE_SIZE ((OT_IP_SIZE)+2)
|
||||
|
||||
struct ot_peerlist;
|
||||
typedef struct ot_peerlist ot_peerlist;
|
||||
@ -98,16 +102,13 @@ struct ot_peerlist {
|
||||
|
||||
struct ot_workstruct {
|
||||
/* Thread specific, static */
|
||||
#define THREAD_INBUF_SIZE 8192
|
||||
char *inbuf;
|
||||
size_t inbuf_size;
|
||||
#define THREAD_OUTBUF_SIZE 8192
|
||||
#define G_INBUF_SIZE 8192
|
||||
char *outbuf;
|
||||
size_t outbuf_size;
|
||||
#define G_OUTBUF_SIZE 8192
|
||||
#ifdef _DEBUG_HTTPERROR
|
||||
#define THREAD_DEBUGBUF_SIZE 8192
|
||||
char *debugbuf;
|
||||
size_t debugbuf_size;
|
||||
#define G_DEBUGBUF_SIZE 8192
|
||||
#endif
|
||||
|
||||
/* HTTP specific, non static */
|
||||
@ -115,10 +116,6 @@ struct ot_workstruct {
|
||||
ssize_t request_size;
|
||||
char *reply;
|
||||
ssize_t reply_size;
|
||||
#ifdef _DEBUG_PEERID
|
||||
char *peer_id;
|
||||
ssize_t peer_id_size;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@ -135,6 +132,10 @@ struct ot_workstruct {
|
||||
#define WANT_SYNC_PARAM( param )
|
||||
#endif
|
||||
|
||||
#if defined WANT_V6 && defined WANT_LOG_NETWORKS
|
||||
#undef WANT_LOG_NETWORKS
|
||||
#endif
|
||||
|
||||
void trackerlogic_init( );
|
||||
void trackerlogic_deinit( void );
|
||||
void exerr( char * message );
|
||||
@ -142,10 +143,10 @@ void exerr( char * message );
|
||||
/* add_peer_to_torrent does only release the torrent bucket if from_sync is set,
|
||||
otherwise it is released in return_peers_for_torrent */
|
||||
#define add_peer_to_torrent(hash,peer,proto) add_peer_to_torrent_and_return_peers(hash,peer,proto,0,NULL)
|
||||
size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply );
|
||||
size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto );
|
||||
size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply );
|
||||
size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO_FLAG proto );
|
||||
size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply );
|
||||
size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply );
|
||||
size_t return_udp_scrape_for_torrent( ot_hash hash, char *reply );
|
||||
|
||||
/* Helper, before it moves to its own object */
|
||||
void free_peerlist( ot_peerlist *peer_list );
|
||||
|
Loading…
x
Reference in New Issue
Block a user