Browse Source

clang-format

master
Dirk Engling 7 months ago
parent
commit
7c633c259e
  1. 199
      opentracker.c
  2. 44
      ot_accesslist.c
  3. 3
      ot_accesslist.h
  4. 24
      ot_clean.c
  5. 43
      ot_fullscrape.c
  6. 2
      ot_fullscrape.h
  7. 250
      ot_http.c
  8. 5
      ot_iovec.c
  9. 32
      ot_livesync.c
  10. 11
      ot_mutex.c
  11. 1
      ot_mutex.h
  12. 283
      ot_stats.c
  13. 2
      ot_stats.h
  14. 37
      ot_udp.c
  15. 54
      ot_vector.c
  16. 3
      ot_vector.h
  17. 59
      scan_urlencoded_query.c
  18. 74
      trackerlogic.c
  19. 15
      trackerlogic.h

199
opentracker.c

@ -5,37 +5,37 @@ @@ -5,37 +5,37 @@
$Id$ */
/* System */
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <pthread.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <pwd.h>
#include <ctype.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#ifdef WANT_SYSLOGS
#include <syslog.h>
#endif
/* Libowfat */
#include "socket.h"
#include "byte.h"
#include "io.h"
#include "iob.h"
#include "byte.h"
#include "scan.h"
#include "ip6.h"
#include "scan.h"
#include "socket.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_mutex.h"
#include "ot_http.h"
#include "ot_udp.h"
#include "ot_accesslist.h"
#include "ot_stats.h"
#include "ot_http.h"
#include "ot_livesync.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "ot_udp.h"
#include "trackerlogic.h"
/* Globals */
time_t g_now_seconds;
@ -99,13 +99,15 @@ static void install_signal_handlers( void ) { @@ -99,13 +99,15 @@ static void install_signal_handlers( void ) {
}
static void usage(char *name) {
fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip[/bits]] [-f config] [-s livesyncport]"
fprintf(stderr,
"Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip[/bits]] [-f config] [-s livesyncport]"
#ifdef WANT_ACCESSLIST_BLACK
" [-b blacklistfile]"
#elif defined(WANT_ACCESSLIST_WHITE)
" [-w whitelistfile]"
#endif
"\n", name );
"\n",
name);
}
#define HELPLINE(opt, desc) fprintf(stderr, "\t%-10s%s\n", opt, desc)
@ -145,7 +147,8 @@ static ssize_t header_complete( char * request, ssize_t byte_count ) { @@ -145,7 +147,8 @@ static ssize_t header_complete( char * request, ssize_t byte_count ) {
state = (state >> 2) | ((c << 6) & 0xc0);
else
break;
if( state >= 0xa0 || state == 0x99 ) return i + 1;
if (state >= 0xa0 || state == 0x99)
return i + 1;
}
}
return 0;
@ -253,8 +256,7 @@ static void handle_accept( const int64 serversocket ) { @@ -253,8 +256,7 @@ static void handle_accept( const int64 serversocket ) {
/* Put fd into a non-blocking mode */
io_nonblock(sock);
if( !io_fd( sock ) ||
!( cookie = (struct http_data*)malloc( sizeof(struct http_data) ) ) ) {
if (!io_fd(sock) || !(cookie = (struct http_data *)malloc(sizeof(struct http_data)))) {
io_close(sock);
continue;
}
@ -377,7 +379,8 @@ char * set_config_option( char **option, char *value ) { @@ -377,7 +379,8 @@ char * set_config_option( char **option, char *value ) {
#ifdef _DEBUG
fprintf(stderr, "Setting config option: %s\n", value);
#endif
while( isspace(*value) ) ++value;
while (isspace(*value))
++value;
free(*option);
return *option = strdup(value);
}
@ -385,19 +388,26 @@ char * set_config_option( char **option, char *value ) { @@ -385,19 +388,26 @@ char * set_config_option( char **option, char *value ) {
static int scan_ip6_port(const char *src, ot_ip6 ip, uint16 *port) {
const char *s = src;
int off, bracket = 0;
while( isspace(*s) ) ++s;
if( *s == '[' ) ++s, ++bracket; /* for v6 style notation */
while (isspace(*s))
++s;
if (*s == '[')
++s, ++bracket; /* for v6 style notation */
if (!(off = scan_ip6(s, ip)))
return 0;
s += off;
if( bracket && *s == ']' ) ++s;
if( *s == 0 || isspace(*s)) return s-src;
if (bracket && *s == ']')
++s;
if (*s == 0 || isspace(*s))
return s - src;
if (!ip6_isv4mapped(ip)) {
if( *s != ':' && *s != '.' ) return 0;
if( !bracket && *(s) == ':' ) return 0;
if (*s != ':' && *s != '.')
return 0;
if (!bracket && *(s) == ':')
return 0;
s++;
} else {
if( *(s++) != ':' ) return 0;
if (*(s++) != ':')
return 0;
}
if (!(off = scan_ushort(s, port)))
return 0;
@ -407,7 +417,8 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) { @@ -407,7 +417,8 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) {
static int scan_ip6_net(const char *src, ot_net *net) {
const char *s = src;
int off;
while( isspace(*s) ) ++s;
while (isspace(*s))
++s;
if (!(off = scan_ip6(s, net->address)))
return 0;
s += off;
@ -447,10 +458,12 @@ int parse_configfile( char * config_filename ) { @@ -447,10 +458,12 @@ int parse_configfile( char * config_filename ) {
size_t strl;
/* Skip white spaces */
while(isspace(*p)) ++p;
while (isspace(*p))
++p;
/* Ignore comments and empty lines */
if((*p=='#')||(*p=='\n')||(*p==0)) continue;
if ((*p == '#') || (*p == '\n') || (*p == 0))
continue;
/* consume trailing new lines and spaces */
strl = strlen(p);
@ -464,22 +477,28 @@ int parse_configfile( char * config_filename ) { @@ -464,22 +477,28 @@ int parse_configfile( char * config_filename ) {
set_config_option(&g_serveruser, p + 13);
} else if (!byte_diff(p, 14, "listen.tcp_udp") && isspace(p[14])) {
uint16_t tmpport = 6969;
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;
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_ip6_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_ip6_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;
} else if (!byte_diff(p, 18, "listen.udp.workers") && isspace(p[18])) {
char *value = p + 18;
while( isspace(*value) ) ++value;
while (isspace(*value))
++value;
scan_uint(value, &g_udp_workers);
#ifdef WANT_ACCESSLIST_WHITE
} else if (!byte_diff(p, 16, "access.whitelist") && isspace(p[16])) {
@ -496,25 +515,29 @@ int parse_configfile( char * config_filename ) { @@ -496,25 +515,29 @@ int parse_configfile( char * config_filename ) {
#endif
#ifdef WANT_RESTRICT_STATS
} else if (!byte_diff(p, 12, "access.stats") && isspace(p[12])) {
if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error;
if (!scan_ip6_net(p + 13, &tmpnet))
goto parse_error;
accesslist_bless_net(&tmpnet, OT_PERMISSION_MAY_STAT);
#endif
} else if (!byte_diff(p, 17, "access.stats_path") && isspace(p[17])) {
set_config_option(&g_stats_path, p + 18);
#ifdef WANT_IP_FROM_PROXY
} else if (!byte_diff(p, 12, "access.proxy") && isspace(p[12])) {
if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error;
if (!scan_ip6_net(p + 13, &tmpnet))
goto parse_error;
accesslist_bless_net(&tmpnet, OT_PERMISSION_MAY_PROXY);
#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_ip6_net( p+25, &tmpnet )) goto parse_error;
if (!scan_ip6_net(p + 25, &tmpnet))
goto parse_error;
accesslist_bless_net(&tmpnet, OT_PERMISSION_MAY_LIVESYNC);
} else if (!byte_diff(p, 23, "livesync.cluster.listen") && isspace(p[23])) {
uint16_t tmpport = LIVESYNC_PORT;
if( !scan_ip6_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
@ -551,12 +574,15 @@ void load_state(const char * const state_filename ) { @@ -551,12 +574,15 @@ void load_state(const char * const state_filename ) {
infohash[i] = eger;
}
if( i != (int)sizeof(ot_hash) ) continue;
if (i != (int)sizeof(ot_hash))
continue;
i *= 2;
if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &base ) ) ) continue;
if (inbuf[i++] != ':' || !(consumed = scan_ulonglong(inbuf + i, &base)))
continue;
i += consumed;
if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &downcount ) ) ) continue;
if (inbuf[i++] != ':' || !(consumed = scan_ulonglong(inbuf + i, &downcount)))
continue;
add_torrent_from_saved_state(infohash, base, downcount);
}
@ -592,16 +618,14 @@ int drop_privileges ( const char * const serveruser, const char * const serverdi @@ -592,16 +618,14 @@ int drop_privileges ( const char * const serveruser, const char * const serverdi
fprintf(stderr, "Warning: Could not get password entry for %s. Reverting to uid -2.\n", serveruser);
if (setegid((gid_t)-2) || setgid((gid_t)-2) || setuid((uid_t)-2) || seteuid((uid_t)-2))
panic("Could not set uid to value -2");
}
else {
} else {
if (setegid(pws->pw_gid) || setgid(pws->pw_gid) || setuid(pws->pw_uid) || seteuid(pws->pw_uid))
panic("Could not set uid to specified value");
}
if (geteuid() == 0 || getegid() == 0)
panic("Still running with root privileges?!");
}
else {
} else {
/* Normal user, just chdir() */
if (serverdir && chdir(serverdir)) {
fprintf(stderr, "Could not chroot to %s, because: %s\n", serverdir, strerror(errno));
@ -641,43 +665,82 @@ int main( int argc, char **argv ) { @@ -641,43 +665,82 @@ int main( int argc, char **argv ) {
#endif
while (scanon) {
switch( getopt( argc, argv, ":i:p:A:P:d:u:r:s:f:l:v"
switch (getopt(argc, argv,
":i:p:A:P:d:u:r:s:f:l:v"
#ifdef WANT_ACCESSLIST_BLACK
"b:"
#elif defined(WANT_ACCESSLIST_WHITE)
"w:"
#endif
"h")) {
case -1 : scanon = 0; break;
case -1:
scanon = 0;
break;
case 'i':
if( !scan_ip6( 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;
case 'b':
set_config_option(&g_accesslist_filename, optarg);
break;
#elif defined(WANT_ACCESSLIST_WHITE)
case 'w': set_config_option( &g_accesslist_filename, optarg); break;
case 'w':
set_config_option(&g_accesslist_filename, optarg);
break;
#endif
case 'p':
if( !scan_ushort( optarg, &tmpport)) { usage( argv[0] ); exit( 1 ); }
ot_try_bind( serverip, tmpport, FLAG_TCP ); bound++; break;
if (!scan_ushort(optarg, &tmpport)) {
usage(argv[0]);
exit(1);
}
ot_try_bind(serverip, tmpport, FLAG_TCP);
bound++;
break;
case 'P':
if( !scan_ushort( optarg, &tmpport)) { usage( argv[0] ); exit( 1 ); }
ot_try_bind( serverip, tmpport, FLAG_UDP ); bound++; break;
if (!scan_ushort(optarg, &tmpport)) {
usage(argv[0]);
exit(1);
}
ot_try_bind(serverip, tmpport, FLAG_UDP);
bound++;
break;
#ifdef WANT_SYNC_LIVE
case 's':
if( !scan_ushort( optarg, &tmpport)) { usage( argv[0] ); exit( 1 ); }
livesync_bind_mcast( serverip, tmpport); break;
if (!scan_ushort(optarg, &tmpport)) {
usage(argv[0]);
exit(1);
}
livesync_bind_mcast(serverip, tmpport);
break;
#endif
case 'd': set_config_option( &g_serverdir, optarg ); break;
case 'u': set_config_option( &g_serveruser, optarg ); break;
case 'r': set_config_option( &g_redirecturl, optarg ); break;
case 'l': statefile = optarg; break;
case 'd':
set_config_option(&g_serverdir, optarg);
break;
case 'u':
set_config_option(&g_serveruser, optarg);
break;
case 'r':
set_config_option(&g_redirecturl, optarg);
break;
case 'l':
statefile = optarg;
break;
case 'A':
if( !scan_ip6_net( optarg, &tmpnet )) { usage( argv[0] ); exit( 1 ); }
if (!scan_ip6_net(optarg, &tmpnet)) {
usage(argv[0]);
exit(1);
}
accesslist_bless_net(&tmpnet, 0xffff); /* Allow everything for now */
break;
case 'f': bound += parse_configfile( optarg ); break;
case 'h': help( argv[0] ); exit( 0 );
case 'f':
bound += parse_configfile(optarg);
break;
case 'h':
help(argv[0]);
exit(0);
case 'v': {
char buffer[8192];
stats_return_tracker_version(buffer);
@ -685,7 +748,9 @@ int main( int argc, char **argv ) { @@ -685,7 +748,9 @@ int main( int argc, char **argv ) {
exit(0);
}
default:
case '?': usage( argv[0] ); exit( 1 );
case '?':
usage(argv[0]);
exit(1);
}
}

44
ot_accesslist.c

@ -5,28 +5,28 @@ @@ -5,28 +5,28 @@
/* System */
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#ifdef WANT_DYNAMIC_ACCESSLIST
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
/* Libowfat */
#include "byte.h"
#include "scan.h"
#include "fmt.h"
#include "ip6.h"
#include "mmap.h"
#include "fmt.h"
#include "scan.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_accesslist.h"
#include "ot_vector.h"
#include "trackerlogic.h"
/* GLOBAL VARIABLES */
#ifdef WANT_ACCESSLIST
@ -62,9 +62,7 @@ static ot_accesslist * _Atomic g_accesslist_delete = NULL; @@ -62,9 +62,7 @@ static ot_accesslist * _Atomic g_accesslist_delete = NULL;
#endif
/* Helpers to work on access lists */
static int vector_compare_hash(const void *hash1, const void *hash2 ) {
return memcmp( hash1, hash2, OT_HASH_COMPARE_SIZE );
}
static int vector_compare_hash(const void *hash1, const void *hash2) { return memcmp(hash1, hash2, OT_HASH_COMPARE_SIZE); }
static ot_accesslist *accesslist_free(ot_accesslist *accesslist) {
while (accesslist) {
@ -149,7 +147,8 @@ static void accesslist_readfile( void ) { @@ -149,7 +147,8 @@ static void accesslist_readfile( void ) {
}
/* Find start of next line */
while( read_offs <= map_end && *(read_offs++) != '\n' );
while (read_offs <= map_end && *(read_offs++) != '\n')
;
}
#ifdef _DEBUG
fprintf(stderr, "Added %zd info_hashes to accesslist\n", (size_t)(info_hash - accesslist_new->list));
@ -226,7 +225,8 @@ static void * accesslist_worker( void * args ) { @@ -226,7 +225,8 @@ static void * accesslist_worker( void * args ) {
accesslist_readfile();
/* Wait for signals */
while( sigwait (&signal_mask, &sig) != 0 && sig != SIGHUP );
while (sigwait(&signal_mask, &sig) != 0 && sig != SIGHUP)
;
}
return NULL;
}
@ -403,8 +403,7 @@ void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value @@ -403,8 +403,7 @@ void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value
/* Check each net in vector for overlap */
uint8_t *member = ((uint8_t *)vector->data);
for (i = 0; i < vector->size; ++i) {
if( address_in_net( *(ot_ip6*)member, net ) ||
address_in_net( net->address, (ot_net*)member ) )
if (address_in_net(*(ot_ip6 *)member, net) || address_in_net(net->address, (ot_net *)member))
return 0;
member += member_size;
}
@ -437,8 +436,8 @@ void *get_value_for_net( const ot_ip6 address, const ot_vector *vector, const si @@ -437,8 +436,8 @@ void *get_value_for_net( const ot_ip6 address, const ot_vector *vector, const si
#ifdef WANT_FULLLOG_NETWORKS
static ot_vector g_lognets_list;
ot_log *g_logchain_first, *g_logchain_last;
static pthread_mutex_t g_lognets_list_mutex = PTHREAD_MUTEX_INITIALIZER;
void loglist_add_network(const ot_net *net) {
pthread_mutex_lock(&g_lognets_list_mutex);
set_value_for_net(net, &g_lognets_list, NULL, sizeof(ot_net));
@ -534,11 +533,16 @@ int accesslist_bless_net( ot_net *net, ot_permissions permissions ) { @@ -534,11 +533,16 @@ int accesslist_bless_net( ot_net *net, ot_permissions permissions ) {
off += fmt_long(_debug + off, net->bits);
}
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 & OT_PERMISSION_MAY_PROXY ) off += snprintf( _debug+off, 512-off, " may_proxy" );
if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing" );
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 & OT_PERMISSION_MAY_PROXY)
off += snprintf(_debug + off, 512 - off, " may_proxy");
if (!permissions)
off += snprintf(_debug + off, sizeof(_debug) - off, " nothing");
_debug[off++] = '.';
_debug[off++] = '\n';
(void)write(2, _debug, off);

3
ot_accesslist.h

@ -6,6 +6,8 @@ @@ -6,6 +6,8 @@
#ifndef OT_ACCESSLIST_H__
#define OT_ACCESSLIST_H__
#include "trackerlogic.h"
#if defined(WANT_ACCESSLIST_BLACK) && defined(WANT_ACCESSLIST_WHITE)
#error WANT_ACCESSLIST_BLACK and WANT_ACCESSLIST_WHITE are exclusive.
#endif
@ -53,7 +55,6 @@ void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value @@ -53,7 +55,6 @@ void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value
*/
void *get_value_for_net(const ot_ip6 address, const ot_vector *vector, const size_t member_size);
#ifdef WANT_IP_FROM_PROXY
int proxylist_add_network(const ot_net *proxy, const ot_net *net);
int proxylist_check_network(const ot_ip6 *proxy, const ot_ip6 address /* can be NULL to only check proxy */);

24
ot_clean.c

@ -5,19 +5,19 @@ @@ -5,19 +5,19 @@
/* System */
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>
/* Libowfat */
#include "io.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_mutex.h"
#include "ot_vector.h"
#include "ot_accesslist.h"
#include "ot_clean.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "ot_accesslist.h"
#include "ot_vector.h"
#include "trackerlogic.h"
/* Returns amount of removed peers */
static ssize_t clean_single_bucket(ot_peer *peers, size_t peer_count, size_t peer_size, time_t timedout, int *removed_seeders) {
@ -40,8 +40,7 @@ static ssize_t clean_single_bucket( ot_peer *peers, size_t peer_count, size_t pe @@ -40,8 +40,7 @@ static ssize_t clean_single_bucket( ot_peer *peers, size_t peer_count, size_t pe
OT_PEERTIME(peers, peer_size) = timediff;
memcpy(insert_point, peers, peer_size);
insert_point += peer_size;
} else
if( OT_PEERFLAG_D( peers, peer_size ) & PEER_FLAG_SEEDING )
} else if (OT_PEERFLAG_D(peers, peer_size) & PEER_FLAG_SEEDING)
(*removed_seeders)++;
}
@ -104,8 +103,7 @@ int clean_single_peer_list( ot_peerlist *peer_list, size_t peer_size ) { @@ -104,8 +103,7 @@ int clean_single_peer_list( ot_peerlist *peer_list, size_t peer_size ) {
return 1 if torrent timed out
*/
int clean_single_torrent(ot_torrent *torrent) {
return clean_single_peer_list( torrent->peer_list6, OT_PEER_SIZE6) *
clean_single_peer_list( torrent->peer_list4, OT_PEER_SIZE4);
return clean_single_peer_list(torrent->peer_list6, OT_PEER_SIZE6) * clean_single_peer_list(torrent->peer_list4, OT_PEER_SIZE4);
}
/* Clean up all peers in current bucket, remove timedout pools and
@ -141,12 +139,8 @@ static void * clean_worker( void * args ) { @@ -141,12 +139,8 @@ static void * clean_worker( void * args ) {
}
static pthread_t thread_id;
void clean_init( void ) {
pthread_create( &thread_id, NULL, clean_worker, NULL );
}
void clean_init(void) { pthread_create(&thread_id, NULL, clean_worker, NULL); }
void clean_deinit( void ) {
pthread_cancel( thread_id );
}
void clean_deinit(void) { pthread_cancel(thread_id); }
const char *g_version_clean_c = "$Source$: $Revision$\n";

43
ot_fullscrape.c

@ -6,11 +6,11 @@ @@ -6,11 +6,11 @@
#ifdef WANT_FULLSCRAPE
/* System */
#include <sys/param.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/param.h>
#ifdef WANT_COMPRESSION_GZIP
#include <zlib.h>
#endif
@ -21,10 +21,10 @@ @@ -21,10 +21,10 @@
#include "textcode.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_mutex.h"
#include "ot_iovec.h"
#include "ot_fullscrape.h"
#include "ot_iovec.h"
#include "ot_mutex.h"
#include "trackerlogic.h"
/* Fetch full scrape info for all torrents
Full scrapes usually are huge and one does not want to
@ -43,7 +43,17 @@ static void fullscrape_make_gzip( int taskid, ot_tasktype mode); @@ -43,7 +43,17 @@ static void fullscrape_make_gzip( int taskid, ot_tasktype mode);
/* Converter function from memory to human readable hex strings
XXX - Duplicated from ot_stats. Needs fix. */
static char*to_hex(char*d,uint8_t*s){char*m="0123456789ABCDEF";char *t=d;char*e=d+40;while(d<e){*d++=m[*s>>4];*d++=m[*s++&15];}*d=0;return t;}
static char *to_hex(char *d, uint8_t *s) {
char *m = "0123456789ABCDEF";
char *t = d;
char *e = d + 40;
while (d < e) {
*d++ = m[*s >> 4];
*d++ = m[*s++ & 15];
}
*d = 0;
return t;
}
/* This is the entry point into this worker thread
It grabs tasks from mutex_tasklist and delivers results back
@ -87,22 +97,28 @@ static char * fullscrape_write_one( ot_tasktype mode, char *r, ot_torrent *torre @@ -87,22 +97,28 @@ static char * fullscrape_write_one( ot_tasktype mode, char *r, ot_torrent *torre
case TASK_FULLSCRAPE:
default:
/* push hash as bencoded string */
*r++='2'; *r++='0'; *r++=':';
memcpy( r, hash, sizeof(ot_hash) ); r += sizeof(ot_hash);
*r++ = '2';
*r++ = '0';
*r++ = ':';
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", seed_count, down_count, peer_count - seed_count);
break;
case TASK_FULLSCRAPE_TPB_ASCII:
to_hex( r, *hash ); r+= 2 * sizeof(ot_hash);
to_hex(r, *hash);
r += 2 * sizeof(ot_hash);
r += sprintf(r, ":%zd:%zd\n", seed_count, peer_count - seed_count);
break;
case TASK_FULLSCRAPE_TPB_ASCII_PLUS:
to_hex( r, *hash ); r+= 2 * sizeof(ot_hash);
to_hex(r, *hash);
r += 2 * sizeof(ot_hash);
r += sprintf(r, ":%zd:%zd:%zd\n", seed_count, peer_count - seed_count, down_count);
break;
case TASK_FULLSCRAPE_TPB_BINARY:
memcpy( r, *hash, sizeof(ot_hash) ); r += sizeof(ot_hash);
memcpy(r, *hash, sizeof(ot_hash));
r += sizeof(ot_hash);
*(uint32_t *)(r + 0) = htonl((uint32_t)seed_count);
*(uint32_t *)(r + 4) = htonl((uint32_t)(peer_count - seed_count));
r += 8;
@ -112,7 +128,8 @@ static char * fullscrape_write_one( ot_tasktype mode, char *r, ot_torrent *torre @@ -112,7 +128,8 @@ static char * fullscrape_write_one( ot_tasktype mode, char *r, ot_torrent *torre
r += sprintf(r, ":%zd:%zd\n", seed_count, peer_count - seed_count);
break;
case TASK_FULLSCRAPE_TRACKERSTATE:
to_hex( r, *hash ); r+= 2 * sizeof(ot_hash);
to_hex(r, *hash);
r += 2 * sizeof(ot_hash);
r += sprintf(r, ":%zd:%zd\n", torrent->peer_list6->base, down_count);
break;
}

2
ot_fullscrape.h

@ -8,6 +8,8 @@ @@ -8,6 +8,8 @@
#ifdef WANT_FULLSCRAPE
#include "ot_mutex.h"
void fullscrape_init();
void fullscrape_deinit();
void fullscrape_deliver(int64 sock, ot_tasktype tasktype);

250
ot_http.c

@ -4,31 +4,31 @@ @@ -4,31 +4,31 @@
$id$ */
/* System */
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
/* Libowfat */
#include "byte.h"
#include "array.h"
#include "byte.h"
#include "case.h"
#include "iob.h"
#include "ip6.h"
#include "scan.h"
#include "case.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_mutex.h"
#include "ot_accesslist.h"
#include "ot_fullscrape.h"
#include "ot_http.h"
#include "ot_iovec.h"
#include "scan_urlencoded_query.h"
#include "ot_fullscrape.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "ot_accesslist.h"
#include "scan_urlencoded_query.h"
#include "trackerlogic.h"
#define OT_MAXMULTISCRAPE_COUNT 64
#define OT_BATCH_LIMIT (1024 * 1024 * 16)
@ -37,15 +37,16 @@ extern char *g_redirecturl; @@ -37,15 +37,16 @@ extern char *g_redirecturl;
char *g_stats_path;
ssize_t g_stats_path_len;
enum {
SUCCESS_HTTP_HEADER_LENGTH = 80,
SUCCESS_HTTP_SIZE_OFF = 17 };
enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 };
static void http_senddata(const int64 sock, struct ot_workstruct *ws) {
struct http_data *cookie = io_getcookie(sock);
ssize_t written_size;
if( !cookie ) { io_close(sock); return; }
if (!cookie) {
io_close(sock);
return;
}
/* whoever sends data is not interested in its input-array */
if (ws->keep_alive && ws->header_size != ws->request_size) {
@ -61,7 +62,9 @@ static void http_senddata( const int64 sock, struct ot_workstruct *ws ) { @@ -61,7 +62,9 @@ static void http_senddata( const int64 sock, struct ot_workstruct *ws ) {
written_size = write(sock, ws->reply, ws->reply_size);
if ((written_size < 0) || ((written_size == ws->reply_size) && !ws->keep_alive)) {
array_reset(&cookie->request);
free( cookie ); io_close( sock ); return;
free(cookie);
io_close(sock);
return;
}
if (written_size < ws->reply_size) {
@ -70,7 +73,8 @@ static void http_senddata( const int64 sock, struct ot_workstruct *ws ) { @@ -70,7 +73,8 @@ static void http_senddata( const int64 sock, struct ot_workstruct *ws ) {
if (!(outbuf = malloc(ws->reply_size - written_size))) {
array_reset(&cookie->request);
free(cookie); io_close( sock );
free(cookie);
io_close(sock);
return;
}
@ -85,7 +89,8 @@ static void http_senddata( const int64 sock, struct ot_workstruct *ws ) { @@ -85,7 +89,8 @@ static void http_senddata( const int64 sock, struct ot_workstruct *ws ) {
/* writeable short data sockets just have a tcp timeout */
if (!ws->keep_alive) {
taia_uint( &t, 0 ); io_timeout( sock, t );
taia_uint(&t, 0);
io_timeout(sock, t);
io_dontwantread(sock);
}
io_wantwrite(sock);
@ -110,7 +115,8 @@ ssize_t http_issue_error( const int64 sock, struct ot_workstruct *ws, int code ) @@ -110,7 +115,8 @@ ssize_t http_issue_error( const int64 sock, struct ot_workstruct *ws, int code )
if (code == CODE_HTTPERROR_302)
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, G_OUTBUF_SIZE, "HTTP/1.0 %s\r\nContent-Type: text/html\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\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);
@ -155,7 +161,8 @@ ssize_t http_sendiovecdata( const int64 sock, struct ot_workstruct *ws, int iove @@ -155,7 +161,8 @@ ssize_t http_sendiovecdata( const int64 sock, struct ot_workstruct *ws, int iove
header_size = asprintf(&header, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n%sContent-Length: %zd\r\n\r\n", encoding, size);
else {
if (!(cookie->flag & STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER)) {
header_size = asprintf( &header, "HTTP/1.0 200 OK\r\nContent-Type: application/octet-stream\r\n%sTransfer-Encoding: chunked\r\n\r\n%zx\r\n", encoding, size );
header_size =
asprintf(&header, "HTTP/1.0 200 OK\r\nContent-Type: application/octet-stream\r\n%sTransfer-Encoding: chunked\r\n\r\n%zx\r\n", encoding, size);
cookie->flag |= STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER;
} else
header_size = asprintf(&header, "%zx\r\n", size);
@ -203,29 +210,43 @@ ssize_t http_sendiovecdata( const int64 sock, struct ot_workstruct *ws, int iove @@ -203,29 +210,43 @@ ssize_t http_sendiovecdata( const int64 sock, struct ot_workstruct *ws, int iove
}
/* writeable sockets timeout after 10 minutes */
taia_now( &t ); taia_addsec( &t, &t, OT_CLIENT_TIMEOUT_SEND );
taia_now(&t);
taia_addsec(&t, &t, OT_CLIENT_TIMEOUT_SEND);
io_timeout(sock, t);
io_wantwrite(sock);
return 0;
}
static ssize_t http_handle_stats(const int64 sock, struct ot_workstruct *ws, char *read_ptr) {
static const ot_keywords keywords_main[] =
{ { "mode", 1 }, {"format", 2 }, {"info_hash", 3}, { NULL, -3 } };
static const ot_keywords keywords_mode[] =
{ { "peer", TASK_STATS_PEERS }, { "conn", TASK_STATS_CONNS }, { "scrp", TASK_STATS_SCRAPE }, { "udp4", TASK_STATS_UDP }, { "tcp4", TASK_STATS_TCP },
{ "busy", TASK_STATS_BUSY_NETWORKS }, { "torr", TASK_STATS_TORRENTS }, { "fscr", TASK_STATS_FULLSCRAPE },
{ "s24s", TASK_STATS_SLASH24S }, { "tpbs", TASK_STATS_TPB }, { "herr", TASK_STATS_HTTPERRORS }, { "completed", TASK_STATS_COMPLETED },
{ "top100", TASK_STATS_TOP100 }, { "top10", TASK_STATS_TOP10 }, { "renew", TASK_STATS_RENEW }, { "syncs", TASK_STATS_SYNCS }, { "version", TASK_STATS_VERSION },
{ "everything", TASK_STATS_EVERYTHING }, { "statedump", TASK_FULLSCRAPE_TRACKERSTATE }, { "fulllog", TASK_STATS_FULLLOG },
static const ot_keywords keywords_main[] = {{"mode", 1}, {"format", 2}, {"info_hash", 3}, {NULL, -3}};
static const ot_keywords keywords_mode[] = {{"peer", TASK_STATS_PEERS},
{"conn", TASK_STATS_CONNS},
{"scrp", TASK_STATS_SCRAPE},
{"udp4", TASK_STATS_UDP},
{"tcp4", TASK_STATS_TCP},
{"busy", TASK_STATS_BUSY_NETWORKS},
{"torr", TASK_STATS_TORRENTS},
{"fscr", TASK_STATS_FULLSCRAPE},
{"s24s", TASK_STATS_SLASH24S},
{"tpbs", TASK_STATS_TPB},
{"herr", TASK_STATS_HTTPERRORS},
{"completed", TASK_STATS_COMPLETED},
{"top100", TASK_STATS_TOP100},
{"top10", TASK_STATS_TOP10},
{"renew", TASK_STATS_RENEW},
{"syncs", TASK_STATS_SYNCS},
{"version", TASK_STATS_VERSION},
{"everything", TASK_STATS_EVERYTHING},
{"statedump", TASK_FULLSCRAPE_TRACKERSTATE},
{"fulllog", TASK_STATS_FULLLOG},
{"woodpeckers", TASK_STATS_WOODPECKERS},
#ifdef WANT_LOG_NUMWANT
{"numwants", TASK_STATS_NUMWANTS},
#endif
{NULL, -3}};
static const ot_keywords keywords_format[] =
{ { "bin", TASK_FULLSCRAPE_TPB_BINARY }, { "ben", TASK_FULLSCRAPE }, { "url", TASK_FULLSCRAPE_TPB_URLENCODED },
{ "txt", TASK_FULLSCRAPE_TPB_ASCII }, { "txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS }, { NULL, -3 } };
static const ot_keywords keywords_format[] = {{"bin", TASK_FULLSCRAPE_TPB_BINARY}, {"ben", TASK_FULLSCRAPE},
{"url", TASK_FULLSCRAPE_TPB_URLENCODED}, {"txt", TASK_FULLSCRAPE_TPB_ASCII},
{"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}};
int mode = TASK_STATS_PEERS, scanon = 1, format = 0;
@ -238,22 +259,31 @@ static const ot_keywords keywords_format[] = @@ -238,22 +259,31 @@ static const ot_keywords keywords_format[] =
while (scanon) {
switch (scan_find_keywords(keywords_main, &read_ptr, SCAN_SEARCHPATH_PARAM)) {
case -2: scanon = 0; break; /* TERMINATOR */
case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */
case -3: scan_urlencoded_skipvalue( &read_ptr ); break;
case -2:
scanon = 0;
break; /* TERMINATOR */
case -1:
HTTPERROR_400_PARAM; /* PARSE ERROR */
case -3:
scan_urlencoded_skipvalue(&read_ptr);
break;
case 1: /* matched "mode" */
if( ( mode = scan_find_keywords( keywords_mode, &read_ptr, SCAN_SEARCHPATH_VALUE ) ) <= 0 ) HTTPERROR_400_PARAM;
if ((mode = scan_find_keywords(keywords_mode, &read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0)
HTTPERROR_400_PARAM;
break;
case 2: /* matched "format" */
if( ( format = scan_find_keywords( keywords_format, &read_ptr, SCAN_SEARCHPATH_VALUE ) ) <= 0 ) HTTPERROR_400_PARAM;
if ((format = scan_find_keywords(keywords_format, &read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0)
HTTPERROR_400_PARAM;
break;
case 3: HTTPERROR_400_PARAM; /* If the stats URL was mistakenly added as announce URL, return a 400 */
case 3:
HTTPERROR_400_PARAM; /* If the stats URL was mistakenly added as announce URL, return a 400 */
}
}
#ifdef WANT_FULLSCRAPE
if (mode == TASK_FULLSCRAPE_TRACKERSTATE) {
format = mode; mode = TASK_STATS_TPB;
format = mode;
mode = TASK_STATS_TPB;
}
if (mode == TASK_STATS_TPB) {
@ -274,7 +304,8 @@ static const ot_keywords keywords_format[] = @@ -274,7 +304,8 @@ static const ot_keywords keywords_format[] =
cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED;
/* Clients waiting for us should not easily timeout */
taia_uint( &t, 0 ); io_timeout( sock, t );
taia_uint(&t, 0);
io_timeout(sock, t);
fullscrape_deliver(sock, format);
io_dontwantread(sock);
return ws->reply_size = -2;
@ -285,7 +316,8 @@ static const ot_keywords keywords_format[] = @@ -285,7 +316,8 @@ static const ot_keywords keywords_format[] =
if ((mode & TASK_CLASS_MASK) == TASK_STATS) {
tai6464 t;
/* Complex stats also include expensive memory debugging tools */
taia_uint( &t, 0 ); io_timeout( sock, t );
taia_uint(&t, 0);
io_timeout(sock, t);
stats_deliver(sock, mode);
return ws->reply_size = -2;
}
@ -297,7 +329,10 @@ static const ot_keywords keywords_format[] = @@ -297,7 +329,10 @@ static const ot_keywords keywords_format[] =
#ifdef WANT_MODEST_FULLSCRAPES
static pthread_mutex_t g_modest_fullscrape_mutex = PTHREAD_MUTEX_INITIALIZER;
static ot_vector g_modest_fullscrape_timeouts;
typedef struct { ot_ip6 ip; ot_time last_fullscrape; } ot_scrape_log;
typedef struct {
ot_ip6 ip;
ot_time last_fullscrape;
} ot_scrape_log;
#endif
#ifdef WANT_FULLSCRAPE
@ -348,7 +383,8 @@ static ssize_t http_handle_fullscrape( const int64 sock, struct ot_workstruct *w @@ -348,7 +383,8 @@ static ssize_t http_handle_fullscrape( const int64 sock, struct ot_workstruct *w
/* Pass this task to the worker thread */
cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED;
/* Clients waiting for us should not easily timeout */
taia_uint( &t, 0 ); io_timeout( sock, t );
taia_uint(&t, 0);
io_timeout(sock, t);
fullscrape_deliver(sock, TASK_FULLSCRAPE | format);
io_dontwantread(sock);
return ws->reply_size = -2;
@ -363,16 +399,23 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, c @@ -363,16 +399,23 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, c
/* This is to hack around stupid clients that send "scrape ?info_hash" */
if (read_ptr[-1] != '?') {
while( ( *read_ptr != '?' ) && ( *read_ptr != '\n' ) ) ++read_ptr;
if( *read_ptr == '\n' ) HTTPERROR_400_PARAM;
while ((*read_ptr != '?') && (*read_ptr != '\n'))
++read_ptr;
if (*read_ptr == '\n')
HTTPERROR_400_PARAM;
++read_ptr;
}
while (scanon) {
switch (scan_find_keywords(keywords_scrape, &read_ptr, SCAN_SEARCHPATH_PARAM)) {
case -2: scanon = 0; break; /* TERMINATOR */
default: HTTPERROR_400_PARAM; /* PARSE ERROR */
case -3: scan_urlencoded_skipvalue( &read_ptr ); break;
case -2:
scanon = 0;
break; /* TERMINATOR */
default:
HTTPERROR_400_PARAM; /* PARSE ERROR */
case -3:
scan_urlencoded_skipvalue(&read_ptr);
break;
case 1: /* matched "info_hash" */
/* ignore this, when we have less than 20 bytes */
if (scan_urlencoded_query(&read_ptr, (char *)(multiscrape_buf + numwant++), SCAN_SEARCHPATH_VALUE) != (ssize_t)sizeof(ot_hash))
@ -382,7 +425,8 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, c @@ -382,7 +425,8 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, c
}
/* No info_hash found? Inform user */
if( !numwant ) HTTPERROR_400_PARAM;
if (!numwant)
HTTPERROR_400_PARAM;
/* Limit number of hashes to process */
if (numwant > OT_MAXMULTISCRAPE_COUNT)
@ -403,10 +447,13 @@ static char* http_header( char *data, size_t byte_count, char *header ) { @@ -403,10 +447,13 @@ static char* http_header( char *data, size_t byte_count, char *header ) {
size_t i;
long sl = strlen(header);
for (i = 0; i + sl + 2 < byte_count; ++i) {
if( data[i] != '\n' || data[ i + sl + 1] != ':' ) continue;
if( !case_equalb( data + i + 1, sl, header ) ) continue;
if (data[i] != '\n' || data[i + sl + 1] != ':')
continue;
if (!case_equalb(data + i + 1, sl, header))
continue;
data += i + sl + 2;
while( *data == ' ' || *data == '\t' ) ++data;
while (*data == ' ' || *data == '\t')
++data;
return data;
}
return 0;
@ -420,8 +467,7 @@ static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "even @@ -420,8 +467,7 @@ static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "even
#ifdef WANT_FULLLOG_NETWORKS
{"lognet", 8},
#endif
{ "peer_id", 9 },
{ NULL, -3 } };
{"peer_id", 9}, {NULL, -3}};
static ot_keywords keywords_announce_event[] = {{"completed", 1}, {"stopped", 2}, {NULL, -3}};
static ssize_t http_handle_announce(const int64 sock, struct ot_workstruct *ws, char *read_ptr) {
int numwant, tmp, scanon;
@ -432,8 +478,10 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, @@ -432,8 +478,10 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
/* This is to hack around stupid clients that send "announce ?info_hash" */
if (read_ptr[-1] != '?') {
while( ( *read_ptr != '?' ) && ( *read_ptr != '\n' ) ) ++read_ptr;
if( *read_ptr == '\n' ) HTTPERROR_400_PARAM;
while ((*read_ptr != '?') && (*read_ptr != '\n'))
++read_ptr;
if (*read_ptr == '\n')
HTTPERROR_400_PARAM;
++read_ptr;
}
@ -459,22 +507,33 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, @@ -459,22 +507,33 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
while (scanon) {
switch (scan_find_keywords(keywords_announce, &read_ptr, SCAN_SEARCHPATH_PARAM)) {
case -2: scanon = 0; break; /* TERMINATOR */
case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */
case -3: scan_urlencoded_skipvalue( &read_ptr ); break;
case -2:
scanon = 0;
break; /* TERMINATOR */
case -1:
HTTPERROR_400_PARAM; /* PARSE ERROR */
case -3:
scan_urlencoded_skipvalue(&read_ptr);
break;
case 1: /* matched "port" */
len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE);
if( ( len <= 0 ) || scan_fixed_int( write_ptr, len, &tmp ) || ( tmp > 0xffff ) ) HTTPERROR_400_PARAM;
port = htons( tmp ); OT_SETPORT( &ws->peer, &port );
if ((len <= 0) || scan_fixed_int(write_ptr, len, &tmp) || (tmp > 0xffff))
HTTPERROR_400_PARAM;
port = htons(tmp);
OT_SETPORT(&ws->peer, &port);
break;
case 2: /* matched "left" */
if( ( len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ) ) <= 0 ) HTTPERROR_400_PARAM;
if( scan_fixed_int( write_ptr, len, &tmp ) ) tmp = 0;
if( !tmp ) OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_SEEDING;
if ((len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE)) <= 0)
HTTPERROR_400_PARAM;
if (scan_fixed_int(write_ptr, len, &tmp))
tmp = 0;
if (!tmp)
OT_PEERFLAG(&ws->peer) |= PEER_FLAG_SEEDING;
break;
case 3: /* matched "event" */
switch (scan_find_keywords(keywords_announce_event, &read_ptr, SCAN_SEARCHPATH_VALUE)) {
case -1: HTTPERROR_400_PARAM;
case -1:
HTTPERROR_400_PARAM;
case 1: /* matched "completed" */
OT_PEERFLAG(&ws->peer) |= PEER_FLAG_COMPLETED;
break;
@ -487,19 +546,26 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, @@ -487,19 +546,26 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
break;
case 4: /* matched "numwant" */
len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE);
if( ( len <= 0 ) || scan_fixed_int( write_ptr, len, &numwant ) ) HTTPERROR_400_PARAM;
if( numwant < 0 ) numwant = 50;
if( numwant > 200 ) numwant = 200;
if ((len <= 0) || scan_fixed_int(write_ptr, len, &numwant))
HTTPERROR_400_PARAM;
if (numwant < 0)
numwant = 50;
if (numwant > 200)
numwant = 200;
break;
case 5: /* matched "compact" */
len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE);
if( ( len <= 0 ) || scan_fixed_int( write_ptr, len, &tmp ) ) HTTPERROR_400_PARAM;
if( !tmp ) HTTPERROR_400_COMPACT;
if ((len <= 0) || scan_fixed_int(write_ptr, len, &tmp))
HTTPERROR_400_PARAM;
if (!tmp)
HTTPERROR_400_COMPACT;
break;
case 6: /* matched "info_hash" */
if( ws->hash ) HTTPERROR_400_DOUBLEHASH;
if (ws->hash)
HTTPERROR_400_DOUBLEHASH;
/* ignore this, when we have less than 20 bytes */
if( scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM;
if (scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE) != 20)
HTTPERROR_400_PARAM;
ws->hash = (ot_hash *)write_ptr;
break;
#ifdef WANT_IP_FROM_QUERY_STRING
@ -508,10 +574,10 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, @@ -508,10 +574,10 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
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;
if ((len <= 0) || !scan_ip6(tmp_buf2, tmp_buf1))
HTTPERROR_400_PARAM;
OT_SETIP(&ws->peer, tmp_buf1);
}
break;
} break;
#endif
#ifdef WANT_FULLLOG_NETWORKS
case 8: /* matched "lognet" */
@ -523,18 +589,21 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, @@ -523,18 +589,21 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
len = scan_urlencoded_query(&read_ptr, tmp_buf, SCAN_SEARCHPATH_VALUE);
tmp_buf[len] = 0;
if( len <= 0 ) HTTPERROR_400_PARAM;
if (len <= 0)
HTTPERROR_400_PARAM;
if (*tmp_buf == '-') {
loglist_reset();
return ws->reply_size = sprintf(ws->reply, "Successfully removed.\n");
}
parsed = scan_ip6(tmp_buf, net.address);
if( !parsed ) HTTPERROR_400_PARAM;
if (!parsed)
HTTPERROR_400_PARAM;
if (tmp_buf[parsed++] != '/')
bits = 128;
else {
parsed = scan_short(tmp_buf + parsed, &bits);
if( !parsed ) HTTPERROR_400_PARAM;
if (!parsed)
HTTPERROR_400_PARAM;
if (ip6_isv4mapped(net.address))
bits += 96;
}
@ -542,12 +611,12 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, @@ -542,12 +611,12 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
loglist_add_network(&net);
return ws->reply_size = sprintf(ws->reply, "Successfully added.\n");
//}
}
break;
} break;
#endif
case 9: /* matched "peer_id" */
/* ignore this, when we have less than 20 bytes */
if( scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM;
if (scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE) != 20)
HTTPERROR_400_PARAM;
ws->peer_id = write_ptr;
break;
}
@ -614,10 +683,12 @@ ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) { @@ -614,10 +683,12 @@ ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) {
ws->reply = ws->outbuf + SUCCESS_HTTP_HEADER_LENGTH;
/* This one implicitely tests strlen < 5, too -- remember, it is \n terminated */
if( memcmp( read_ptr, "GET /", 5) ) HTTPERROR_400;
if (memcmp(read_ptr, "GET /", 5))
HTTPERROR_400;
/* Skip leading '/' */
for( read_ptr+=4; *read_ptr == '/'; ++read_ptr);
for (read_ptr += 4; *read_ptr == '/'; ++read_ptr)
;
/* Try to parse the request.
In reality we abandoned requiring the url to be correct. This now
@ -626,8 +697,10 @@ ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) { @@ -626,8 +697,10 @@ ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) {
len = scan_urlencoded_query(&read_ptr, write_ptr = read_ptr, SCAN_PATH);
/* If parsing returned an error, leave with not found */
if( g_redirecturl && ( len == -2 ) ) HTTPERROR_302;
if( len <= 0 ) HTTPERROR_404;
if (g_redirecturl && (len == -2))
HTTPERROR_302;
if (len <= 0)
HTTPERROR_404;
/* This is the hardcore match for announce*/
if ((*write_ptr == 'a') || (*write_ptr == '?'))
@ -649,13 +722,16 @@ ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) { @@ -649,13 +722,16 @@ ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) {
ws->keep_alive = 0;
#ifdef WANT_KEEPALIVE
read_ptr = http_header(ws->request, ws->header_size, "connection");
if( read_ptr && ( *read_ptr == 'K' || *read_ptr == 'k' ) ) ws->keep_alive = 1;
if (read_ptr && (*read_ptr == 'K' || *read_ptr == 'k'))
ws->keep_alive = 1;
#endif
/* If routines handled sending themselves, just return */
if( ws->reply_size == -2 ) return 0;
if (ws->reply_size == -2)
return 0;
/* If routine failed, let http error take over */
if( ws->reply_size <= 0 ) HTTPERROR_500;
if (ws->reply_size <= 0)
HTTPERROR_500;
/* This one is rather ugly, so I take you step by step through it.

5
ot_iovec.c

@ -4,10 +4,10 @@ @@ -4,10 +4,10 @@
$id$ */
/* System */
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
/* Libowfat */
@ -54,7 +54,6 @@ void *iovec_append( int *iovec_entries, struct iovec **iovector, struct iovec *a @@ -54,7 +54,6 @@ void *iovec_append( int *iovec_entries, struct iovec **iovector, struct iovec *a
return new_vec;
}
void iovec_free(int *iovec_entries, struct iovec **iovector) {
int i;
for (i = 0; i < *iovec_entries; ++i)

32
ot_livesync.c

@ -4,25 +4,25 @@ @@ -4,25 +4,25 @@
$id$ */
/* System */
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
/* Libowfat */
#include "socket.h"
#include "ndelay.h"
#include "byte.h"
#include "ip6.h"
#include "ndelay.h"
#include "socket.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_livesync.h"
#include "ot_accesslist.h"
#include "ot_stats.h"
#include "ot_livesync.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "trackerlogic.h"
#ifdef WANT_SYNC_LIVE
@ -142,7 +142,8 @@ static void livesync_handle_peersync( struct ot_workstruct *ws, size_t peer_size @@ -142,7 +142,8 @@ static void livesync_handle_peersync( struct ot_workstruct *ws, size_t peer_size
memcpy(&ws->peer, ws->request + off + sizeof(ot_hash), peer_size);
ws->hash = (ot_hash *)(ws->request + off);
if( !g_opentracker_running ) return;
if (!g_opentracker_running)
return;
if (OT_PEERFLAG(ws->peer) & PEER_FLAG_STOPPED)
remove_peer_from_torrent(FLAG_MCA, ws);
@ -152,9 +153,7 @@ static void livesync_handle_peersync( struct ot_workstruct *ws, size_t peer_size @@ -152,9 +153,7 @@ static void livesync_handle_peersync( struct ot_workstruct *ws, size_t peer_size
off += sizeof(ot_hash) + peer_size;
}
stats_issue_event(EVENT_SYNC, 0,
(ws->request_size - sizeof( g_tracker_id ) - sizeof( uint32_t ) ) /
((ssize_t)sizeof( ot_hash ) + peer_size));
stats_issue_event(EVENT_SYNC, 0, (ws->request_size - sizeof(g_tracker_id) - sizeof(uint32_t)) / ((ssize_t)sizeof(ot_hash) + peer_size));
}
/* Tickle the live sync module from time to time, so no events get
@ -163,15 +162,13 @@ static void livesync_handle_peersync( struct ot_workstruct *ws, size_t peer_size @@ -163,15 +162,13 @@ static void livesync_handle_peersync( struct ot_workstruct *ws, size_t peer_size
void livesync_ticker() {
/* livesync_issue_peersync sets g_next_packet_time */
pthread_mutex_lock(&g_outbuf_mutex);
if( g_now_seconds > g_v6_buf.next_packet_time &&
g_v6_buf.fill > sizeof( g_tracker_id ) + sizeof( uint32_t ) )
if (g_now_seconds > g_v6_buf.next_packet_time && g_v6_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t))
livesync_issue_peersync(&g_v6_buf);
else
pthread_mutex_unlock(&g_outbuf_mutex);
pthread_mutex_lock(&g_outbuf_mutex);
if( g_now_seconds > g_v4_buf.next_packet_time &&
g_v4_buf.fill > sizeof( g_tracker_id ) + sizeof( uint32_t ) )
if (g_now_seconds > g_v4_buf.next_packet_time && g_v4_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t))
livesync_issue_peersync(&g_v4_buf);
else
pthread_mutex_unlock(&g_outbuf_mutex);
@ -199,7 +196,8 @@ void livesync_tell( struct ot_workstruct *ws ) { @@ -199,7 +196,8 @@ void livesync_tell( struct ot_workstruct *ws ) {
static void *livesync_worker(void *args) {
struct ot_workstruct ws;
ot_ip6 in_ip; uint16_t in_port;
ot_ip6 in_ip;
uint16_t in_port;
(void)args;

11
ot_mutex.c

@ -16,10 +16,10 @@ @@ -16,10 +16,10 @@
#include "uint32.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_iovec.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "trackerlogic.h"
/* #define MTX_DBG( STRING ) fprintf( stderr, STRING ) */
#define MTX_DBG(STRING)
@ -37,9 +37,7 @@ ot_vector *mutex_bucket_lock( int bucket ) { @@ -37,9 +37,7 @@ ot_vector *mutex_bucket_lock( int bucket ) {
return all_torrents + bucket;
}
ot_vector *mutex_bucket_lock_by_hash( ot_hash const hash ) {
return mutex_bucket_lock( uint32_read_big( (const char*)hash ) >> OT_BUCKET_COUNT_SHIFT );
}
ot_vector *mutex_bucket_lock_by_hash(ot_hash const hash) { return mutex_bucket_lock(uint32_read_big((const char *)hash) >> OT_BUCKET_COUNT_SHIFT); }
void mutex_bucket_unlock(int bucket, int delta_torrentcount) {
pthread_mutex_unlock(bucket_mutex + bucket);
@ -50,9 +48,7 @@ void mutex_bucket_unlock_by_hash( ot_hash const hash, int delta_torrentcount ) { @@ -50,9 +48,7 @@ void mutex_bucket_unlock_by_hash( ot_hash const hash, int delta_torrentcount ) {
mutex_bucket_unlock(uint32_read_big((char *)hash) >> OT_BUCKET_COUNT_SHIFT, delta_torrentcount);
}
size_t mutex_get_torrent_count( ) {
return g_torrent_count;
}
size_t mutex_get_torrent_count() { return g_torrent_count; }
/* TaskQueue Magic */
@ -223,7 +219,6 @@ int mutex_workqueue_pushchunked(ot_taskid taskid, struct iovec *iovec) { @@ -223,7 +219,6 @@ int mutex_workqueue_pushchunked(ot_taskid taskid, struct iovec *iovec) {
return task ? 0 : -1;
}
int64 mutex_workqueue_popresult(int *iovec_entries, struct iovec **iovec, int *is_partial) {
struct ot_task **task;
int64 sock = -1;

1
ot_mutex.h

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
#define OT_MUTEX_H__
#include <sys/uio.h>
#include "trackerlogic.h"
void mutex_init(void);
void mutex_deinit(void);

283
ot_stats.c

@ -4,16 +4,16 @@ @@ -4,16 +4,16 @@
$id$ */
/* System */
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <inttypes.h>
#ifdef WANT_SYSLOGS
#include <syslog.h>
#endif
@ -25,11 +25,11 @@ @@ -25,11 +25,11 @@
#include "ip6.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_mutex.h"
#include "ot_accesslist.h"
#include "ot_iovec.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "ot_accesslist.h"
#include "trackerlogic.h"
#ifndef NO_FULLSCRAPE_LOGGING
#define LOG_TO_STDERR(...) fprintf(stderr, __VA_ARGS__)
@ -42,21 +42,23 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype @@ -42,21 +42,23 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype
#define OT_STATS_TMPSIZE 8192
/* Clumsy counters... to be rethought */
static unsigned long long ot_overall_tcp_connections = 0;
static unsigned long long ot_overall_udp_connections = 0;
static unsigned long long ot_overall_tcp_successfulannounces = 0;
static unsigned long long ot_overall_udp_successfulannounces = 0;
static unsigned long long ot_overall_tcp_successfulscrapes = 0;
static unsigned long long ot_overall_udp_successfulscrapes = 0;
static unsigned long long ot_overall_udp_connectionidmissmatches = 0;
static unsigned long long ot_overall_tcp_connects = 0;
static unsigned long long ot_overall_udp_connects = 0;
static unsigned long long ot_overall_completed = 0;
static unsigned long long ot_full_scrape_count = 0;
static unsigned long long ot_full_scrape_request_count = 0;
static unsigned long long ot_full_scrape_size = 0;
static unsigned long long ot_overall_tcp_connections;
static unsigned long long ot_overall_udp_connections;
static unsigned long long ot_overall_tcp_successfulannounces;
static unsigned long long ot_overall_udp_successfulannounces;
static unsigned long long ot_overall_tcp_successfulscrapes;
static unsigned long long ot_overall_udp_successfulscrapes;
static unsigned long long ot_overall_udp_connectionidmissmatches;
static unsigned long long ot_overall_tcp_connects;
static unsigned long long ot_overall_udp_connects;
static unsigned long long ot_overall_completed;
static unsigned long long ot_full_scrape_count;
static unsigned long long ot_full_scrape_request_count;
static unsigned long long ot_full_scrape_size;
static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT];
static char * ot_failed_request_names[] = { "302 Redirect", "400 Parse Error", "400 Invalid Parameter", "400 Invalid Parameter (compact=0)", "400 Not Modest", "402 Payment Required", "403 Access Denied", "404 Not found", "500 Internal Server Error" };
static char *ot_failed_request_names[] = {
"302 Redirect", "400 Parse Error", "400 Invalid Parameter", "400 Invalid Parameter (compact=0)", "400 Not Modest",
"402 Payment Required", "403 Access Denied", "404 Not found", "500 Internal Server Error"};
static unsigned long long ot_renewed[OT_PEER_TIMEOUT];
static unsigned long long ot_overall_sync_count;
static unsigned long long ot_overall_stall_count;
@ -130,11 +132,13 @@ static int stats_shift_down_network_count( stats_network_node **node, int depth, @@ -130,11 +132,13 @@ static int stats_shift_down_network_count( stats_network_node **node, int depth,
return rest;
}
static size_t stats_get_highscore_networks( stats_network_node *node, int depth, ot_ip6 node_value, size_t *scores, ot_ip6 *networks, int network_count, int limit ) {
static size_t stats_get_highscore_networks(stats_network_node *node, int depth, ot_ip6 node_value, size_t *scores, ot_ip6 *networks, int network_count,
int limit) {
size_t score = 0;
int i;
if( !node ) return 0;
if (!node)
return 0;
if (depth < limit) {
for (i = 0; i < STATS_NETWORK_NODE_COUNT; ++i)
@ -170,10 +174,12 @@ static size_t stats_get_highscore_networks( stats_network_node *node, int depth, @@ -170,10 +174,12 @@ static size_t stats_get_highscore_networks( stats_network_node *node, int depth,
score += node_score;
if( node_score <= scores[0] ) continue;
if (node_score <= scores[0])
continue;
__STR(node_value, depth, i);
while( j < network_count && node_score > scores[j] ) ++j;
while (j < network_count && node_score > scores[j])
++j;
--j;
memcpy(scores, scores + 1, j * sizeof(*scores));
@ -294,9 +300,22 @@ static int torrent_statter( ot_torrent *torrent, uintptr_t data ) { @@ -294,9 +300,22 @@ static int torrent_statter( ot_torrent *torrent, uintptr_t data ) {
}
/* Converter function from memory to human readable hex strings */
static char*to_hex(char*d,uint8_t*s){char*m="0123456789ABCDEF";char *t=d;char*e=d+40;while(d<e){*d++=m[*s>>4];*d++=m[*s++&15];}*d=0;return t;}
static char *to_hex(char *d, uint8_t *s) {
char *m = "0123456789ABCDEF";
char *t = d;
char *e = d + 40;
while (d < e) {
*d++ = m[*s >> 4];
*d++ = m[*s++ & 15];
}
*d = 0;
return t;
}
typedef struct { size_t val; ot_hash hash; } ot_record;
typedef struct {
size_t val;
ot_hash hash;
} ot_record;
/* Fetches stats from tracker */
size_t stats_top_txt(char *reply, int amount) {
@ -351,72 +370,42 @@ size_t stats_top_txt( char * reply, int amount ) { @@ -351,72 +370,42 @@ size_t stats_top_txt( char * reply, int amount ) {
return r - reply;
}
static unsigned long events_per_time( unsigned long long events, time_t t ) {
return events / ( (unsigned int)t ? (unsigned int)t : 1 );
}
static unsigned long events_per_time(unsigned long long events, time_t t) { return events / ((unsigned int)t ? (unsigned int)t : 1); }
static size_t stats_connections_mrtg(char *reply) {
ot_time t = time(NULL) - ot_start_time;
return sprintf( reply,
"%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.",
return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.",
ot_overall_tcp_connections + ot_overall_udp_connections,
ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects,
(int)t,
(int)(t / 3600),
ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects, (int)t, (int)(t / 3600),
events_per_time(ot_overall_tcp_connections + ot_overall_udp_connections, t),
events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t )
);
events_per_time(ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects, t));
}
static size_t stats_udpconnections_mrtg(char *reply) {
ot_time t = time(NULL) - ot_start_time;
return sprintf( reply,
"%llu\n%llu\n%i seconds (%i hours)\nopentracker udp4 stats, %lu conns/s :: %lu success/s.",
ot_overall_udp_connections,
ot_overall_udp_successfulannounces+ot_overall_udp_connects,
(int)t,
(int)(t / 3600),
events_per_time( ot_overall_udp_connections, t ),
events_per_time( ot_overall_udp_successfulannounces+ot_overall_udp_connects, t )
);
return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker udp4 stats, %lu conns/s :: %lu success/s.", ot_overall_udp_connections,
ot_overall_udp_successfulannounces + ot_overall_udp_connects, (int)t, (int)(t / 3600), events_per_time(ot_overall_udp_connections, t),
events_per_time(ot_overall_udp_successfulannounces + ot_overall_udp_connects, t));
}
static size_t stats_tcpconnections_mrtg(char *reply) {
time_t t = time(NULL) - ot_start_time;
return sprintf( reply,
"%llu\n%llu\n%i seconds (%i hours)\nopentracker tcp4 stats, %lu conns/s :: %lu success/s.",
ot_overall_tcp_connections,
ot_overall_tcp_successfulannounces,
(int)t,
(int)(t / 3600),
events_per_time( ot_overall_tcp_connections, t ),
events_per_time( ot_overall_tcp_successfulannounces, t )
);
return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker tcp4 stats, %lu conns/s :: %lu success/s.", ot_overall_tcp_connections,
ot_overall_tcp_successfulannounces, (int)t, (int)(t / 3600), events_per_time(ot_overall_tcp_connections, t),
events_per_time(ot_overall_tcp_successfulannounces, t));
}
static size_t stats_scrape_mrtg(char *reply) {
time_t t = time(NULL) - ot_start_time;
return sprintf( reply,
"%llu\n%llu\n%i seconds (%i hours)\nopentracker scrape stats, %lu scrape/s (tcp and udp)",
ot_overall_tcp_successfulscrapes,
ot_overall_udp_successfulscrapes,
(int)t,
(int)(t / 3600),
events_per_time( (ot_overall_tcp_successfulscrapes+ot_overall_udp_successfulscrapes), t )
);
return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker scrape stats, %lu scrape/s (tcp and udp)", ot_overall_tcp_successfulscrapes,
ot_overall_udp_successfulscrapes, (int)t, (int)(t / 3600),
events_per_time((ot_overall_tcp_successfulscrapes + ot_overall_udp_successfulscrapes), t));
}
static size_t stats_fullscrapes_mrtg(char *reply) {
ot_time t = time(NULL) - ot_start_time;
return sprintf( reply,
"%llu\n%llu\n%i seconds (%i hours)\nopentracker full scrape stats, %lu conns/s :: %lu bytes/s.",
ot_full_scrape_count * 1000,
ot_full_scrape_size,
(int)t,
(int)(t / 3600),
events_per_time( ot_full_scrape_count, t ),
events_per_time( ot_full_scrape_size, t )
);
return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker full scrape stats, %lu conns/s :: %lu bytes/s.", ot_full_scrape_count * 1000,
ot_full_scrape_size, (int)t, (int)(t / 3600), events_per_time(ot_full_scrape_count, t), events_per_time(ot_full_scrape_size, t));
}
static size_t stats_peers_mrtg(char *reply) {
@ -424,29 +413,19 @@ static size_t stats_peers_mrtg( char * reply ) { @@ -424,29 +413,19 @@ static size_t stats_peers_mrtg( char * reply ) {
iterate_all_torrents(torrent_statter, (uintptr_t)&stats);
return sprintf( reply, "%llu\n%llu\nopentracker serving %llu torrents\nopentracker",
stats.peer_count,
stats.seed_count,
stats.torrent_count
);
return sprintf(reply, "%llu\n%llu\nopentracker serving %llu torrents\nopentracker", stats.peer_count, stats.seed_count, stats.torrent_count);
}
static size_t stats_torrents_mrtg( char * reply )
{
static size_t stats_torrents_mrtg(char *reply) {
size_t torrent_count = mutex_get_torrent_count();
return sprintf( reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker",
torrent_count,
(size_t)0,
torrent_count
);
return sprintf(reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", torrent_count, (size_t)0, torrent_count);
}
static size_t stats_httperrors_txt(char *reply) {
return sprintf( reply, "302 RED %llu\n400 ... %llu\n400 PAR %llu\n400 COM %llu\n403 IP %llu\n404 INV %llu\n500 SRV %llu\n",
ot_failed_request_counts[0], ot_failed_request_counts[1], ot_failed_request_counts[2],
ot_failed_request_counts[3], ot_failed_request_counts[4], ot_failed_request_counts[5],
ot_failed_request_counts[6] );
return sprintf(reply, "302 RED %llu\n400 ... %llu\n400 PAR %llu\n400 COM %llu\n403 IP %llu\n404 INV %llu\n500 SRV %llu\n", ot_failed_request_counts[0],
ot_failed_request_counts[1], ot_failed_request_counts[2], ot_failed_request_counts[3], ot_failed_request_counts[4],
ot_failed_request_counts[5], ot_failed_request_counts[6]);
}
static size_t stats_return_renew_bucket(char *reply) {
@ -460,28 +439,16 @@ static size_t stats_return_renew_bucket( char * reply ) { @@ -460,28 +439,16 @@ static size_t stats_return_renew_bucket( char * reply ) {
static size_t stats_return_sync_mrtg(char *reply) {
ot_time t = time(NULL) - ot_start_time;
return sprintf( reply,
"%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.",
ot_overall_sync_count,
0LL,
(int)t,
(int)(t / 3600),
events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ),
events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t )
);
return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", ot_overall_sync_count, 0LL, (int)t,
(int)(t / 3600), events_per_time(ot_overall_tcp_connections + ot_overall_udp_connections, t),
events_per_time(ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects, t));
}
static size_t stats_return_completed_mrtg(char *reply) {
ot_time t = time(NULL) - ot_start_time;
return sprintf( reply,
"%llu\n%llu\n%i seconds (%i hours)\nopentracker, %lu completed/h.",
ot_overall_completed,
0LL,
(int)t,
(int)(t / 3600),
events_per_time( ot_overall_completed, t / 3600 )
);
return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker, %lu completed/h.", ot_overall_completed, 0LL, (int)t, (int)(t / 3600),
events_per_time(ot_overall_completed, t / 3600));
}
#ifdef WANT_LOG_NUMWANT
@ -505,7 +472,8 @@ static void stats_return_fulllog( int *iovec_entries, struct iovec **iovector, c @@ -505,7 +472,8 @@ static void stats_return_fulllog( int *iovec_entries, struct iovec **iovector, c
while (loglist) {
if (r + (loglist->size + 64) >= re) {
r = iovec_fix_increase_or_free(iovec_entries, iovector, r, 32 * OT_STATS_TMPSIZE);
if( !r ) return;
if (!r)
return;
re = r + 32 * OT_STATS_TMPSIZE;
}
r += sprintf(r, "%08ld: ", loglist->time);
@ -537,7 +505,9 @@ static size_t stats_return_everything( char * reply ) { @@ -537,7 +505,9 @@ static size_t stats_return_everything( char * reply ) {
r += sprintf(r, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
r += sprintf(r, "<stats>\n");
r += sprintf(r, " <tracker_id>%" PRIu32 "</tracker_id>\n", g_tracker_id);
r += sprintf( r, " <version>\n" ); r += stats_return_tracker_version( r ); r += sprintf( r, " </version>\n" );
r += sprintf(r, " <version>\n");
r += stats_return_tracker_version(r);
r += sprintf(r, " </version>\n");
r += sprintf(r, " <uptime>%llu</uptime>\n", (unsigned long long)(time(NULL) - ot_start_time));
r += sprintf(r, " <torrents>\n");
r += sprintf(r, " <count_mutex>%zd</count_mutex>\n", mutex_get_torrent_count());
@ -547,8 +517,13 @@ static size_t stats_return_everything( char * reply ) { @@ -547,8 +517,13 @@ static size_t stats_return_everything( char * reply ) {
r += sprintf(r, " <seeds>\n <count>%llu</count>\n </seeds>\n", stats.seed_count);
r += sprintf(r, " <completed>\n <count>%llu</count>\n </completed>\n", ot_overall_completed);
r += sprintf(r, " <connections>\n");
r += sprintf( r, " <tcp>\n <accept>%llu</accept>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n </tcp>\n", ot_overall_tcp_connections, ot_overall_tcp_successfulannounces, ot_overall_tcp_successfulscrapes );
r += sprintf( r, " <udp>\n <overall>%llu</overall>\n <connect>%llu</connect>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n <missmatch>%llu</missmatch>\n </udp>\n", ot_overall_udp_connections, ot_overall_udp_connects, ot_overall_udp_successfulannounces, ot_overall_udp_successfulscrapes, ot_overall_udp_connectionidmissmatches );
r += sprintf(r, " <tcp>\n <accept>%llu</accept>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n </tcp>\n",
ot_overall_tcp_connections, ot_overall_tcp_successfulannounces, ot_overall_tcp_successfulscrapes);
r += sprintf(
r,
" <udp>\n <overall>%llu</overall>\n <connect>%llu</connect>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n <missmatch>%llu</missmatch>\n </udp>\n",
ot_overall_udp_connections, ot_overall_udp_connects, ot_overall_udp_successfulannounces, ot_overall_udp_successfulscrapes,
ot_overall_udp_connectionidmissmatches);
r += sprintf(r, " <livesync>\n <count>%llu</count>\n </livesync>\n", ot_overall_sync_count);
r += sprintf(r, " </connections>\n");
r += sprintf(r, " <debug>\n");
@ -566,15 +541,13 @@ static size_t stats_return_everything( char * reply ) { @@ -566,15 +541,13 @@ static size_t stats_return_everything( char * reply ) {
return r - reply;
}
extern const char
*g_version_opentracker_c, *g_version_accesslist_c, *g_version_clean_c, *g_version_fullscrape_c, *g_version_http_c,
*g_version_iovec_c, *g_version_mutex_c, *g_version_stats_c, *g_version_udp_c, *g_version_vector_c,
*g_version_scan_urlencoded_query_c, *g_version_trackerlogic_c, *g_version_livesync_c, *g_version_rijndael_c;
extern const char *g_version_opentracker_c, *g_version_accesslist_c, *g_version_clean_c, *g_version_fullscrape_c, *g_version_http_c, *g_version_iovec_c,
*g_version_mutex_c, *g_version_stats_c, *g_version_udp_c, *g_version_vector_c, *g_version_scan_urlencoded_query_c, *g_version_trackerlogic_c,
*g_version_livesync_c, *g_version_rijndael_c;
size_t stats_return_tracker_version(char *reply) {
return sprintf( reply, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
g_version_opentracker_c, g_version_accesslist_c, g_version_clean_c, g_version_fullscrape_c, g_version_http_c,
g_version_iovec_c, g_version_mutex_c, g_version_stats_c, g_version_udp_c, g_version_vector_c,
return sprintf(reply, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", g_version_opentracker_c, g_version_accesslist_c, g_version_clean_c, g_version_fullscrape_c,
g_version_http_c, g_version_iovec_c, g_version_mutex_c, g_version_stats_c, g_version_udp_c, g_version_vector_c,
g_version_scan_urlencoded_query_c, g_version_trackerlogic_c, g_version_livesync_c, g_version_rijndael_c);
}
@ -619,22 +592,38 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype @@ -619,22 +592,38 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype
return;
switch (mode & TASK_TASK_MASK) {
case TASK_STATS_TORRENTS: r += stats_torrents_mrtg( r ); break;
case TASK_STATS_PEERS: r += stats_peers_mrtg( r ); break;
case TASK_STATS_SLASH24S: r += stats_slash24s_txt( r, 128 ); break;
case TASK_STATS_TOP10: r += stats_top_txt( r, 10 ); break;
case TASK_STATS_TORRENTS:
r += stats_torrents_mrtg(r);
break;
case TASK_STATS_PEERS:
r += stats_peers_mrtg(r);
break;
case TASK_STATS_SLASH24S:
r += stats_slash24s_txt(r, 128);
break;
case TASK_STATS_TOP10:
r += stats_top_txt(r, 10);
break;
case TASK_STATS_TOP100:
r = iovec_fix_increase_or_free(iovec_entries, iovector, r, 4 * OT_STATS_TMPSIZE);
if( !r ) return;
r += stats_top_txt( r, 100 ); break;
case TASK_STATS_EVERYTHING: r = iovec_fix_increase_or_free( iovec_entries, iovector, r, OT_STATS_TMPSIZE + 64 * OT_PEER_TIMEOUT );
if( !r ) return;
r += stats_return_everything( r ); break;
if (!r)
return;
r += stats_top_txt(r, 100);
break;
case TASK_STATS_EVERYTHING:
r = iovec_fix_increase_or_free(iovec_entries, iovector, r, OT_STATS_TMPSIZE + 64 * OT_PEER_TIMEOUT);
if (!r)
return;
r += stats_return_everything(r);
break;
#ifdef WANT_SPOT_WOODPECKER
case TASK_STATS_WOODPECKERS: r += stats_return_woodpeckers( r, 128 ); break;
case TASK_STATS_WOODPECKERS:
r += stats_return_woodpeckers(r, 128);
break;
#endif
#ifdef WANT_FULLLOG_NETWORKS
case TASK_STATS_FULLLOG: stats_return_fulllog( iovec_entries, iovector, r );
case TASK_STATS_FULLLOG:
stats_return_fulllog(iovec_entries, iovector, r);
return;
#endif
default:
@ -647,16 +636,25 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype @@ -647,16 +636,25 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype
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++;
if (proto == FLAG_TCP)
ot_overall_tcp_connections++;
else
ot_overall_udp_connections++;
#ifdef WANT_LOG_NETWORKS
stat_increase_network_count(&stats_network_counters_root, 0, event_data);
#endif
break;
case EVENT_ANNOUNCE:
if( proto == FLAG_TCP ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++;
if (proto == FLAG_TCP)
ot_overall_tcp_successfulannounces++;
else
ot_overall_udp_successfulannounces++;
break;
case EVENT_CONNECT:
if( proto == FLAG_TCP ) ot_overall_tcp_connects++; else ot_overall_udp_connects++;
if (proto == FLAG_TCP)
ot_overall_tcp_connects++;
else
ot_overall_udp_connects++;
break;
case EVENT_COMPLETED:
#ifdef WANT_SYSLOGS
@ -689,14 +687,16 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event @@ -689,14 +687,16 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event
ot_overall_completed++;
break;
case EVENT_SCRAPE:
if( proto == FLAG_TCP ) ot_overall_tcp_successfulscrapes++; else ot_overall_udp_successfulscrapes++;
if (proto == FLAG_TCP)
ot_overall_tcp_successfulscrapes++;
else
ot_overall_udp_successfulscrapes++;
break;
case EVENT_FULLSCRAPE:
ot_full_scrape_count++;
ot_full_scrape_size += event_data;
break;
case EVENT_FULLSCRAPE_REQUEST:
{
case EVENT_FULLSCRAPE_REQUEST: {
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);
@ -704,10 +704,8 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event @@ -704,10 +704,8 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event
off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n");
(void)write(2, _debug, off);
ot_full_scrape_request_count++;
}
break;
case EVENT_FULLSCRAPE_REQUEST_GZIP:
{
} break;
case EVENT_FULLSCRAPE_REQUEST_GZIP: {
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);
@ -715,8 +713,7 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event @@ -715,8 +713,7 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event
off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n");
(void)write(2, _debug, off);
ot_full_scrape_request_count++;
}
break;
} break;
case EVENT_FAILED:
ot_failed_request_counts[event_data]++;
break;
@ -767,9 +764,7 @@ static void * stats_worker( void * args ) { @@ -767,9 +764,7 @@ static void * stats_worker( void * args ) {
return NULL;
}
void stats_deliver( int64 sock, int tasktype ) {
mutex_workqueue_pushtask( sock, tasktype );
}
void stats_deliver(int64 sock, int tasktype) { mutex_workqueue_pushtask(sock, tasktype); }
static pthread_t thread_id;
void stats_init() {

2
ot_stats.h

@ -6,6 +6,8 @@ @@ -6,6 +6,8 @@
#ifndef OT_STATS_H__
#define OT_STATS_H__
#include "trackerlogic.h"
typedef enum {
EVENT_ACCEPT,
EVENT_READ,

37
ot_udp.c

@ -4,22 +4,22 @@ @@ -4,22 +4,22 @@
$id$ */
/* System */
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Libowfat */
#include "socket.h"
#include "io.h"
#include "ip6.h"
#include "socket.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_udp.h"
#include "ot_stats.h"
#include "ot_rijndael.h"
#include "ot_stats.h"
#include "ot_udp.h"
#include "trackerlogic.h"
#if 0
static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff };
@ -63,7 +63,8 @@ static void udp_make_connectionid( uint32_t connid[2], const ot_ip6 remoteip, in @@ -63,7 +63,8 @@ static void udp_make_connectionid( uint32_t connid[2], const ot_ip6 remoteip, in
}
memcpy(plain, remoteip, sizeof(plain));
for( i=0; i<4; ++i ) plain[i] ^= g_key_of_the_hour[age];
for (i = 0; i < 4; ++i)
plain[i] ^= g_key_of_the_hour[age];
rijndaelEncrypt128(g_rijndael_round_key, (uint8_t *)remoteip, (uint8_t *)crypt);
connid[0] = crypt[0] ^ crypt[1];
connid[1] = crypt[2] ^ crypt[3];
@ -81,7 +82,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { @@ -81,7 +82,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
size_t byte_count, scrape_count;
byte_count = socket_recv6(serversocket, ws->inbuf, G_INBUF_SIZE, remoteip, &remoteport, &scopeid);
if( !byte_count ) return 0;
if (!byte_count)
return 0;
stats_issue_event(EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip);
stats_issue_event(EVENT_READ, FLAG_UDP, byte_count);
@ -112,7 +114,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { @@ -112,7 +114,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
udp_make_connectionid(connid, remoteip, 1);
if (inpacket[0] != connid[0] || inpacket[1] != connid[1]) {
const size_t s = sizeof("Connection ID missmatch.");
outpacket[0] = htonl( 3 ); outpacket[1] = inpacket[3];
outpacket[0] = htonl(3);
outpacket[1] = inpacket[3];
memcpy(&outpacket[2], "Connection ID missmatch.", s);
socket_send6(serversocket, ws->outbuf, 8 + s, remoteip, remoteport, 0);
stats_issue_event(EVENT_CONNID_MISSMATCH, FLAG_UDP, 8 + s);
@ -151,9 +154,14 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { @@ -151,9 +154,14 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
OT_PEERFLAG(ws->peer) = 0;
switch (event) {
case 1: OT_PEERFLAG( ws->peer ) |= PEER_FLAG_COMPLETED; break;
case 3: OT_PEERFLAG( ws->peer ) |= PEER_FLAG_STOPPED; break;
default: break;
case 1:
OT_PEERFLAG(ws->peer) |= PEER_FLAG_COMPLETED;
break;
case 3:
OT_PEERFLAG(ws->peer) |= PEER_FLAG_STOPPED;
break;
default:
break;
}
if (!left)
@ -169,7 +177,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { @@ -169,7 +177,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) {
/* Limit amount of peers to OT_MAX_PEERS_UDP */
uint32_t numwant = ntohl(inpacket[92 / 4]);
size_t max_peers = ip6_isv4mapped(remoteip) ? OT_MAX_PEERS_UDP4 : OT_MAX_PEERS_UDP6;
if (numwant > max_peers) numwant = max_peers;
if (numwant > max_peers)
numwant = max_peers;
ws->reply = ws->outbuf + 8;
ws->reply_size = 8 + add_peer_to_torrent_and_return_peers(FLAG_UDP, ws, numwant);

54
ot_vector.c

@ -4,33 +4,27 @@ @@ -4,33 +4,27 @@
$id$ */
/* System */
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stdint.h>
#include <stddef.h>
/* Opentracker */
#include "trackerlogic.h"
#include "ot_vector.h"
/* Libowfat */
#include "uint32.h"
#include "uint16.h"
#include "uint32.h"
static int vector_compare_peer6(const void *peer1, const void *peer2 ) {
return memcmp( peer1, peer2, OT_PEER_COMPARE_SIZE6 );
}
static int vector_compare_peer4(const void *peer1, const void *peer2 ) {
return memcmp( peer1, peer2, OT_PEER_COMPARE_SIZE4 );
}
static int vector_compare_peer6(const void *peer1, const void *peer2) { return memcmp(peer1, peer2, OT_PEER_COMPARE_SIZE6); }
static int vector_compare_peer4(const void *peer1, const void *peer2) { return memcmp(peer1, peer2, OT_PEER_COMPARE_SIZE4); }
/* This function gives us a binary search that returns a pointer, even if
no exact match is found. In that case it sets exactmatch 0 and gives
calling functions the chance to insert data
*/
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 ) {
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 interval = member_count;
while (interval) {
@ -54,7 +48,8 @@ void *binary_search( const void * const key, const void * base, const size_t mem @@ -54,7 +48,8 @@ void *binary_search( const void * const key, const void * base, const size_t mem
static uint8_t vector_hash_peer(ot_peer const *peer, size_t compare_size, int bucket_count) {
unsigned int hash = 5381;
uint8_t *p = (uint8_t *)peer;
while( compare_size-- ) hash += (hash<<5) + *(p++);
while (compare_size--)
hash += (hash << 5) + *(p++);
return hash % bucket_count;
}
@ -68,12 +63,14 @@ static uint8_t vector_hash_peer( ot_peer const *peer, size_t compare_size, int b @@ -68,12 +63,14 @@ static uint8_t vector_hash_peer( ot_peer const *peer, size_t compare_size, int b
void *vector_find_or_insert(ot_vector *vector, void *key, size_t member_size, size_t compare_size, int *exactmatch) {
uint8_t *match = binary_search(key, vector->data, vector->size, member_size, compare_size, exactmatch);
if( *exactmatch ) return match;
if (*exactmatch)
return match;
if (vector->size + 1 > vector->space) {
size_t new_space = vector->space ? OT_VECTOR_GROW_RATIO * vector->space : OT_VECTOR_MIN_MEMBERS;
uint8_t *new_data = realloc(vector->data, new_space * member_size);
if( !new_data ) return NULL;
if (!new_data)
return NULL;
/* Adjust pointer if it moved by realloc */
match = new_data + (match - (uint8_t *)vector->data);
@ -96,7 +93,8 @@ ot_peer *vector_find_or_insert_peer( ot_vector *vector, ot_peer const *peer, siz @@ -96,7 +93,8 @@ ot_peer *vector_find_or_insert_peer( ot_vector *vector, ot_peer const *peer, siz
vector = ((ot_vector *)vector->data) + vector_hash_peer(peer, compare_size, vector->size);
match = binary_search(peer, vector->data, vector->size, peer_size, compare_size, exactmatch);
if( *exactmatch ) return match;
if (*exactmatch)
return match;
/* This is the amount of bytes that needs to be pushed backwards by peer_size bytes to make room for new peer */
end = (ot_peer *)vector->data + vector->size * peer_size;
@ -107,7 +105,8 @@ ot_peer *vector_find_or_insert_peer( ot_vector *vector, ot_peer const *peer, siz @@ -107,7 +105,8 @@ ot_peer *vector_find_or_insert_peer( ot_vector *vector, ot_peer const *peer, siz
size_t new_space = vector->space ? OT_VECTOR_GROW_RATIO * vector->space : OT_VECTOR_MIN_MEMBERS;
ot_peer *new_data = realloc(vector->data, new_space * peer_size);
if( !new_data ) return NULL;
if (!new_data)
return NULL;
/* Adjust pointer if it moved by realloc */
match = new_data + offset;
@ -132,7 +131,8 @@ int vector_remove_peer( ot_vector *vector, ot_peer const *peer, size_t peer_size @@ -132,7 +131,8 @@ int vector_remove_peer( ot_vector *vector, ot_peer const *peer, size_t peer_size
ot_peer *match, *end;
size_t compare_size = OT_PEER_COMPARE_SIZE_FROM_PEER_SIZE(peer_size);
if( !vector->size ) return 0;
if (!vector->size)
return 0;
/* If space is zero but size is set, we're dealing with a list of vector->size buckets */
if (vector->space < vector->size)
@ -140,7 +140,8 @@ int vector_remove_peer( ot_vector *vector, ot_peer const *peer, size_t peer_size @@ -140,7 +140,8 @@ int vector_remove_peer( ot_vector *vector, ot_peer const *peer, size_t peer_size
end = ((ot_peer *)vector->data) + peer_size * vector->size;
match = (ot_peer *)binary_search(peer, vector->data, vector->size, peer_size, compare_size, &exactmatch);
if( !exactmatch ) return 0;
if (!exactmatch)
return 0;
was_seeder = (OT_PEERFLAG_D(match, peer_size) & PEER_FLAG_SEEDING) ? 2 : 1;
memmove(match, match + peer_size, end - match - peer_size);
@ -153,7 +154,8 @@ int vector_remove_peer( ot_vector *vector, ot_peer const *peer, size_t peer_size @@ -153,7 +154,8 @@ int vector_remove_peer( ot_vector *vector, ot_peer const *peer, size_t peer_size
void vector_remove_torrent(ot_vector *vector, ot_torrent *match) {
ot_torrent *end = ((ot_torrent *)vector->data) + vector->size;
if( !vector->size ) return;
if (!vector->size)
return;
/* If this is being called after a unsuccessful malloc() for peer_list
in add_peer_to_torrent, match->peer_list actually might be NULL */
@ -177,8 +179,7 @@ void vector_clean_list( ot_vector * vector, int num_buckets ) { @@ -177,8 +179,7 @@ void vector_clean_list( ot_vector * vector, int num_buckets ) {
void vector_redistribute_buckets(ot_peerlist *peer_list, size_t peer_size) {
int tmp, bucket, bucket_size_new, num_buckets_new, num_buckets_old = 1;
ot_vector *bucket_list_new, *bucket_list_old = &peer_list->peers;
int (*sort_func)(const void *, const void *) =
peer_size == OT_PEER_SIZE6 ? &vector_compare_peer6 : &vector_compare_peer4;
int (*sort_func)(const void *, const void *) = peer_size == OT_PEER_SIZE6 ? &vector_compare_peer6 : &vector_compare_peer4;
if (OT_PEERLIST_HASBUCKETS(peer_list)) {
num_buckets_old = peer_list->peers.size;
@ -205,7 +206,8 @@ void vector_redistribute_buckets( ot_peerlist * peer_list, size_t peer_size ) { @@ -205,7 +206,8 @@ void vector_redistribute_buckets( ot_peerlist * peer_list, size_t peer_size ) {
/* Assume near perfect distribution */
bucket_list_new = malloc(num_buckets_new * sizeof(ot_vector));
if( !bucket_list_new) return;
if (!bucket_list_new)
return;
bzero(bucket_list_new, num_buckets_new * sizeof(ot_vector));
tmp = peer_list->peer_count / num_buckets_new;
@ -231,7 +233,8 @@ void vector_redistribute_buckets( ot_peerlist * peer_list, size_t peer_size ) { @@ -231,7 +233,8 @@ void vector_redistribute_buckets( ot_peerlist * peer_list, size_t peer_size ) {
bucket_dest += vector_hash_peer(peers_old, OT_PEER_COMPARE_SIZE_FROM_PEER_SIZE(peer_size), num_buckets_new);
if (bucket_dest->size + 1 > bucket_dest->space) {
void *tmp = realloc(bucket_dest->data, peer_size * OT_VECTOR_GROW_RATIO * bucket_dest->space);
if( !tmp ) return vector_clean_list( bucket_list_new, num_buckets_new );
if (!tmp)
return vector_clean_list(bucket_list_new, num_buckets_new);
bucket_dest->data = tmp;
bucket_dest->space *= OT_VECTOR_GROW_RATIO;
}
@ -272,8 +275,7 @@ void vector_fixup_peers( ot_vector * vector, size_t peer_size ) { @@ -272,8 +275,7 @@ void vector_fixup_peers( ot_vector * vector, size_t peer_size ) {
return;
}
while( ( vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) &&
( vector->space >= OT_VECTOR_SHRINK_RATIO * OT_VECTOR_MIN_MEMBERS ) ) {
while ((vector->size * OT_VECTOR_SHRINK_THRESH < vector->space) && (vector->space >= OT_VECTOR_SHRINK_RATIO * OT_VECTOR_MIN_MEMBERS)) {
vector->space /= OT_VECTOR_SHRINK_RATIO;
need_fix++;
}

3
ot_vector.h

@ -21,8 +21,7 @@ typedef struct { @@ -21,8 +21,7 @@ typedef struct {
size_t space;
} ot_vector;
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 );
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);
void *vector_find_or_insert(ot_vector *vector, void *key, size_t member_size, size_t compare_size, int *exactmatch);
ot_peer *vector_find_or_insert_peer(ot_vector *vector, ot_peer const *peer, size_t peer_size, int *exactmatch);

59
scan_urlencoded_query.c

@ -45,9 +45,13 @@ static const unsigned char is_unreserved[256] = { @@ -45,9 +45,13 @@ static const unsigned char is_unreserved[256] = {
/* Do a fast nibble to hex representation conversion */
static unsigned char fromhex(unsigned char x) {
x-='0'; if( x<=9) return x;
x&=~0x20; x-='A'-'0';
if( x<6 ) return x+10;
x -= '0';
if (x <= 9)
return x;
x &= ~0x20;
x -= 'A' - '0';
if (x < 6)
return x + 10;
return 0xff;
}
@ -58,11 +62,13 @@ void scan_urlencoded_skipvalue( char **string ) { @@ -58,11 +62,13 @@ void scan_urlencoded_skipvalue( char **string ) {
/* Since we are asked to skip the 'value', we assume to stop at
terminators for a 'value' string position */
while( ( f = is_unreserved[ *s++ ] ) & SCAN_SEARCHPATH_VALUE );
while ((f = is_unreserved[*s++]) & SCAN_SEARCHPATH_VALUE)
;
/* If we stopped at a hard terminator like \0 or \n, make the
next scan_urlencoded_query encounter it again */
if( f & SCAN_SEARCHPATH_TERMINATOR ) --s;
if (f & SCAN_SEARCHPATH_TERMINATOR)
--s;
*string = (char *)s;
}
@ -71,8 +77,10 @@ int scan_find_keywords( const ot_keywords * keywords, char **string, SCAN_SEARCH @@ -71,8 +77,10 @@ int scan_find_keywords( const ot_keywords * keywords, char **string, SCAN_SEARCH
char *deststring = *string;
ssize_t match_length = scan_urlencoded_query(string, deststring, flags);
if( match_length < 0 ) return match_length;
if( match_length == 0 ) return -3;
if (match_length < 0)
return match_length;
if (match_length == 0)
return -3;
while (keywords->key) {
if (!strncmp(keywords->key, deststring, match_length) && !keywords->key[match_length])
@ -96,8 +104,10 @@ ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_F @@ -96,8 +104,10 @@ ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_F
/* When encountering an url escaped character, try to decode */
if (c == '%') {
if( ( b = fromhex(*s++) ) == 0xff ) return -1;
if( ( c = fromhex(*s++) ) == 0xff ) return -1;
if ((b = fromhex(*s++)) == 0xff)
return -1;
if ((c = fromhex(*s++)) == 0xff)
return -1;
c |= (b << 4);
}
@ -106,22 +116,30 @@ ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_F @@ -106,22 +116,30 @@ ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_F
}
switch (c) {
case 0: case '\r': case '\n': case ' ':
case 0:
case '\r':
case '\n':
case ' ':
/* If we started scanning on a hard terminator, indicate we've finished */
if( d == (unsigned char*)deststring ) return -2;
if (d == (unsigned char *)deststring)
return -2;
/* Else make the next call to scan_urlencoded_param encounter it again */
--s;
break;
case '?':
if( flags != SCAN_PATH ) return -1;
if (flags != SCAN_PATH)
return -1;
break;
case '=':
if( flags != SCAN_SEARCHPATH_PARAM ) return -1;
if (flags != SCAN_SEARCHPATH_PARAM)
return -1;
break;
case '&':
if( flags == SCAN_PATH ) return -1;
if( flags == SCAN_SEARCHPATH_PARAM ) --s;
if (flags == SCAN_PATH)
return -1;
if (flags == SCAN_SEARCHPATH_PARAM)
--s;
break;
default:
return -1;
@ -134,9 +152,14 @@ ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_F @@ -134,9 +152,14 @@ ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_F
ssize_t scan_fixed_int(char *data, size_t len, int *tmp) {
int minus = 0;
*tmp = 0;
if( *data == '-' ) --len, ++data, ++minus;
while( (len > 0) && (*data >= '0') && (*data <= '9') ) { --len; *tmp = 10**tmp + *data++-'0'; }
if( minus ) *tmp = -*tmp;
if (*data == '-')
--len, ++data, ++minus;
while ((len > 0) && (*data >= '0') && (*data <= '9')) {
--len;
*tmp = 10 * *tmp + *data++ - '0';
}
if (minus)
*tmp = -*tmp;
return len;
}

74
trackerlogic.c

@ -4,31 +4,31 @@ @@ -4,31 +4,31 @@
$id$ */
/* System */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* Libowfat */
#include "array.h"
#include "byte.h"
#include "io.h"
#include "iob.h"
#include "ip6.h"
#include "array.h"
/* Opentracker */
#include "trackerlogic.h"
#include "ot_vector.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "ot_clean.h"
#include "ot_http.h"
#include "ot_accesslist.h"
#include "ot_clean.h"
#include "ot_fullscrape.h"
#include "ot_http.h"
#include "ot_livesync.h"
#include "ot_mutex.h"
#include "ot_stats.h"
#include "ot_vector.h"
#include "trackerlogic.h"
/* Forward declaration */
size_t return_peers_for_torrent(struct ot_workstruct *ws, ot_torrent *torrent, size_t amount, char *reply, PROTO_FLAG proto);
@ -59,8 +59,7 @@ void add_torrent_from_saved_state( ot_hash const hash, ot_time base, size_t down @@ -59,8 +59,7 @@ void add_torrent_from_saved_state( ot_hash const hash, ot_time base, size_t down
byte_zero(torrent, sizeof(ot_torrent));
memcpy(torrent->hash, hash, sizeof(ot_hash));
if( !( torrent->peer_list6 = malloc( sizeof (ot_peerlist) ) ) ||
!( torrent->peer_list4 = malloc( sizeof (ot_peerlist) ) ) ) {
if (!(torrent->peer_list6 = malloc(sizeof(ot_peerlist))) || !(torrent->peer_list4 = malloc(sizeof(ot_peerlist)))) {
vector_remove_torrent(torrents_list, torrent);
return mutex_bucket_unlock_by_hash(hash, 0);
}
@ -105,8 +104,7 @@ size_t add_peer_to_torrent_and_return_peers( PROTO_FLAG proto, struct ot_workstr @@ -105,8 +104,7 @@ size_t add_peer_to_torrent_and_return_peers( PROTO_FLAG proto, struct ot_workstr
byte_zero(torrent, sizeof(ot_torrent));
memcpy(torrent->hash, *ws->hash, sizeof(ot_hash));
if( !( torrent->peer_list6 = malloc( sizeof (ot_peerlist) ) ) ||
!( torrent->peer_list4 = malloc( sizeof (ot_peerlist) ) ) ) {
if (!(torrent->peer_list6 = malloc(sizeof(ot_peerlist))) || !(torrent->peer_list4 = malloc(sizeof(ot_peerlist)))) {
vector_remove_torrent(torrents_list, torrent);
mutex_bucket_unlock_by_hash(*ws->hash, 0);
return 0;
@ -242,7 +240,10 @@ static size_t return_peers_selection( struct ot_workstruct *ws, ot_peerlist *pee @@ -242,7 +240,10 @@ static size_t return_peers_selection( struct ot_workstruct *ws, ot_peerlist *pee
/* Make fixpoint arithmetic as exact as possible */
#define MAXPRECBIT (1 << (8 * sizeof(int) - 3))
while( !(shifted_pc & MAXPRECBIT ) ) { shifted_pc <<= 1; shift++; }
while (!(shifted_pc & MAXPRECBIT)) {
shifted_pc <<= 1;
shift++;
}
shifted_step = shifted_pc / amount;
#undef MAXPRECBIT
@ -254,8 +255,7 @@ static size_t return_peers_selection( struct ot_workstruct *ws, ot_peerlist *pee @@ -254,8 +255,7 @@ static size_t return_peers_selection( struct ot_workstruct *ws, ot_peerlist *pee
ot_peer *peer;
/* This is the aliased, non shifted range, next value may fall into */
unsigned int diff = ( ( ( amount + 1 ) * shifted_step ) >> shift ) -
( ( amount * shifted_step ) >> shift );
unsigned int diff = (((amount + 1) * shifted_step) >> shift) - ((amount * shifted_step) >> shift);
bucket_offset += 1 + nrand48(ws->rand48_state) % diff;
while (bucket_offset >= bucket_list[bucket_index].size) {
@ -341,7 +341,8 @@ static size_t return_peers_for_torrent_tcp( struct ot_workstruct * ws, ot_torren @@ -341,7 +341,8 @@ static size_t return_peers_for_torrent_tcp( struct ot_workstruct * ws, ot_torren
++amount_v4;
}
r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie12:min intervali%ie", seed_count, down_count, peer_count, erval, erval/2 );
r +=
sprintf(r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie12:min intervali%ie", seed_count, down_count, peer_count, erval, erval / 2);
if (amount_v4) {
r += sprintf(r, PEERS_BENCODED4 "%zd:", OT_PEER_COMPARE_SIZE4 * amount_v4);
@ -394,8 +395,7 @@ size_t return_udp_scrape_for_torrent( ot_hash const hash, char *reply ) { @@ -394,8 +395,7 @@ size_t return_udp_scrape_for_torrent( ot_hash const hash, char *reply ) {
} else {
r[0] = htonl(torrent->peer_list6->seed_count + torrent->peer_list4->seed_count);
r[1] = htonl(torrent->peer_list6->down_count + torrent->peer_list4->down_count);
r[2] = htonl( torrent->peer_list6->peer_count + torrent->peer_list4->peer_count -
torrent->peer_list6->seed_count - torrent->peer_list4->seed_count);
r[2] = htonl(torrent->peer_list6->peer_count + torrent->peer_list4->peer_count - torrent->peer_list6->seed_count - torrent->peer_list4->seed_count);
}
}
mutex_bucket_unlock_by_hash(hash, delta_torrentcount);
@ -420,19 +420,21 @@ size_t return_tcp_scrape_for_torrent( ot_hash const *hash_list, int amount, char @@ -420,19 +420,21 @@ size_t return_tcp_scrape_for_torrent( ot_hash const *hash_list, int amount, char
vector_remove_torrent(torrents_list, torrent);
delta_torrentcount = -1;
} else {
*r++='2';*r++='0';*r++=':';
memcpy( r, hash, sizeof(ot_hash) ); r+=sizeof(ot_hash);
r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee",
torrent->peer_list6->seed_count + torrent->peer_list4->seed_count,
*r++ = '2';
*r++ = '0';
*r++ = ':';
memcpy(r, hash, sizeof(ot_hash));
r += sizeof(ot_hash);
r += sprintf(r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", torrent->peer_list6->seed_count + torrent->peer_list4->seed_count,
torrent->peer_list6->down_count + torrent->peer_list4->down_count,
torrent->peer_list6->peer_count + torrent->peer_list4->peer_count -
torrent->peer_list6->seed_count - torrent->peer_list4->seed_count);
torrent->peer_list6->peer_count + torrent->peer_list4->peer_count - torrent->peer_list6->seed_count - torrent->peer_list4->seed_count);
}
}
mutex_bucket_unlock_by_hash(*hash, delta_torrentcount);
}
*r++ = 'e'; *r++ = 'e';
*r++ = 'e';
*r++ = 'e';
return r - reply;
}
@ -456,19 +458,22 @@ size_t remove_peer_from_torrent( PROTO_FLAG proto, struct ot_workstruct *ws ) { @@ -456,19 +458,22 @@ size_t remove_peer_from_torrent( PROTO_FLAG proto, struct ot_workstruct *ws ) {
if (exactmatch) {
peer_list = peer_size == OT_PEER_SIZE6 ? torrent->peer_list6 : torrent->peer_list4;
switch (vector_remove_peer(&peer_list->peers, peer_src, peer_size)) {
case 2: peer_list->seed_count--; /* Intentional fallthrough */
case 1: peer_list->peer_count--; /* Intentional fallthrough */
default: break;
case 2:
peer_list->seed_count--; /* Intentional fallthrough */
case 1:
peer_list->peer_count--; /* Intentional fallthrough */
default:
break;
}
peer_count = torrent->peer_list6->peer_count + torrent->peer_list4->peer_count;
seed_count = torrent->peer_list6->seed_count + torrent->peer_list4->seed_count;
}
if (proto == FLAG_TCP) {
int erval = OT_CLIENT_REQUEST_INTERVAL_RANDOM;
ws->reply_size = sprintf( ws->reply, "d8:completei%zde10:incompletei%zde8:intervali%ie12:min intervali%ie%s0:e", seed_count, peer_count - seed_count, erval, erval / 2, peer_size == OT_PEER_SIZE6 ? PEERS_BENCODED6 : PEERS_BENCODED4 );
ws->reply_size = sprintf(ws->reply, "d8:completei%zde10:incompletei%zde8:intervali%ie12:min intervali%ie%s0:e", seed_count, peer_count - seed_count, erval,
erval / 2, peer_size == OT_PEER_SIZE6 ? PEERS_BENCODED6 : PEERS_BENCODED4);
}
/* Handle UDP reply */
@ -496,7 +501,8 @@ void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data @@ -496,7 +501,8 @@ void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data
break;
mutex_bucket_unlock(bucket, 0);
if( !g_opentracker_running ) return;
if (!g_opentracker_running)
return;
}
}

15
trackerlogic.h

@ -6,11 +6,11 @@ @@ -6,11 +6,11 @@
#ifndef OT_TRACKERLOGIC_H__
#define OT_TRACKERLOGIC_H__
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#if defined(__linux__) && defined(WANT_ARC4RANDOM)
#include <bsd/stdlib.h>
@ -22,8 +22,10 @@ @@ -22,8 +22,10 @@
typedef uint8_t ot_hash[20];
typedef time_t ot_time;
typedef char ot_ip6[16];
typedef struct { ot_ip6 address; int bits; }
ot_net;
typedef struct {
ot_ip6 address;
int bits;
} ot_net;
/* List of peers should fit in a single UDP packet (around 1200 bytes) */
#define OT_MAX_PEERS_UDP6 66
#define OT_MAX_PEERS_UDP4 200
@ -44,7 +46,8 @@ typedef struct { ot_ip6 address; int bits; } @@ -44,7 +46,8 @@ typedef struct { ot_ip6 address; int bits; }
#define OT_TORRENT_TIMEOUT_HOURS 24
#define OT_TORRENT_TIMEOUT (60 * OT_TORRENT_TIMEOUT_HOURS)
#define OT_CLIENT_REQUEST_INTERVAL_RANDOM ( OT_CLIENT_REQUEST_INTERVAL - OT_CLIENT_REQUEST_VARIATION/2 + (int)( nrand48(ws->rand48_state) % OT_CLIENT_REQUEST_VARIATION ) )
#define OT_CLIENT_REQUEST_INTERVAL_RANDOM \
(OT_CLIENT_REQUEST_INTERVAL - OT_CLIENT_REQUEST_VARIATION / 2 + (int)(nrand48(ws->rand48_state) % OT_CLIENT_REQUEST_VARIATION))
/* If WANT_MODEST_FULLSCRAPES is on, ip addresses may not
fullscrape more frequently than this amount in seconds */

Loading…
Cancel
Save