From 131211b4daf83b7c594337f4e7c71e4711094d71 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Tue, 13 Jan 2009 22:41:17 +0000 Subject: V6 --- Makefile | 5 +-- opentracker.c | 86 ++++++++++++++++++++++++++----------------------- ot_accesslist.c | 43 ++++++++++++++++--------- ot_accesslist.h | 6 ++-- ot_fullscrape.c | 8 ++--- ot_http.c | 52 ++++++++++++------------------ ot_http.h | 2 +- ot_livesync.c | 60 ++++++++++++++++++---------------- ot_livesync.h | 2 +- ot_mutex.c | 8 ++--- ot_mutex.h | 4 +-- ot_stats.c | 34 ++++++++++++------- ot_stats.h | 2 +- ot_udp.c | 28 ++++++++-------- ot_udp.h | 2 +- ot_vector.c | 24 ++++---------- scan_urlencoded_query.c | 17 ---------- scan_urlencoded_query.h | 15 +++------ trackerlogic.c | 47 +++++++++------------------ trackerlogic.h | 55 +++++++++++++++---------------- 20 files changed, 235 insertions(+), 265 deletions(-) diff --git a/Makefile b/Makefile index ca4e71b..41b0d68 100644 --- a/Makefile +++ b/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 diff --git a/opentracker.c b/opentracker.c index 8a4126c..46456dd 100644 --- a/opentracker.c +++ b/opentracker.c @@ -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; diff --git a/ot_accesslist.c b/ot_accesslist.c index 0cb6fe7..304b3f1 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c @@ -8,10 +8,12 @@ #include #include #include +#include /* 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; iseed_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; diff --git a/ot_http.c b/ot_http.c index 8c85689..08ecc13 100644 --- a/ot_http.c +++ b/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%s\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%s\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 diff --git a/ot_http.h b/ot_http.h index 18e8156..ced8160 100644 --- a/ot_http.h +++ b/ot_http.h @@ -19,7 +19,7 @@ struct http_data { array request; io_batch batch; } data; - char ip[4]; + ot_ip6 ip; STRUCT_HTTP_FLAG flag; }; diff --git a/ot_livesync.c b/ot_livesync.c index a47edba..d577f7c 100644 --- a/ot_livesync.c +++ b/ot_livesync.c @@ -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; jsize; ++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= 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 */ diff --git a/ot_livesync.h b/ot_livesync.h index ae9ab55..8e78afb 100644 --- a/ot_livesync.h +++ b/ot_livesync.h @@ -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 diff --git a/ot_mutex.c b/ot_mutex.c index 6edfaef..36de5ff 100644 --- a/ot_mutex.c +++ b/ot_mutex.c @@ -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( ) { diff --git a/ot_mutex.h b/ot_mutex.h index ba5684d..16b25a0 100644 --- a/ot_mutex.h +++ b/ot_mutex.h @@ -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(); diff --git a/ot_stats.c b/ot_stats.c index 31d53e8..30a599c 100644 --- a/ot_stats.c +++ b/ot_stats.c @@ -12,10 +12,12 @@ #include #include #include +#include /* 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( (jcounters[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: diff --git a/ot_stats.h b/ot_stats.h index 287382f..7cb0c06 100644 --- a/ot_stats.h +++ b/ot_stats.h @@ -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 ); diff --git a/ot_udp.c b/ot_udp.c index 81c4d63..2ea76dd 100644 --- a/ot_udp.c +++ b/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; } diff --git a/ot_udp.h b/ot_udp.h index c146392..39356cb 100644 --- a/ot_udp.h +++ b/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 diff --git a/ot_vector.c b/ot_vector.c index 29bdd49..f7481f1 100644 --- a/ot_vector.c +++ b/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; diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c index c3acefc..4a8ff63 100644 --- a/scan_urlencoded_query.c +++ b/scan_urlencoded_query.c @@ -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"; diff --git a/scan_urlencoded_query.h b/scan_urlencoded_query.h index a0b77af..92e3f34 100644 --- a/scan_urlencoded_query.h +++ b/scan_urlencoded_query.h @@ -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 diff --git a/trackerlogic.c b/trackerlogic.c index 38be9f7..5eff5c0 100644 --- a/trackerlogic.c +++ b/trackerlogic.c @@ -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; idata, 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 ); diff --git a/trackerlogic.h b/trackerlogic.h index eb2906b..da8f822 100644 --- a/trackerlogic.h +++ b/trackerlogic.h @@ -11,17 +11,16 @@ #include #include -/* Libowfat */ -#include -#include - -#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 ); -- cgit v1.2.3