int setup_tcp_server_socket(const char ip[4], const char ip6[16], u16 port, int backlog) { char sip[FMT_IP6]; int fd; fd = socket_tcp6(); if(fd >= 0) { if(socket_bind6_reuse(fd, ip6, port, 0) == -1) { close(fd); fd = socket_tcp(); if(fd >= 0) { if(-1 == socket_bind4_reuse(fd, ip, port)) ERROR("unable to create server socket: %s", strerror(errno)); else { fmt_ip4(sip, ip); DEBUG("bound TCP socket on %s:%hu", sip, port); } } else { ERROR("unable to create TCP socket: %s", strerror(errno)); } } else { fmt_ip6(sip, ip6); DEBUG("bound TCP socket on [%s]:%hu", sip, port); } if(socket_listen(fd, backlog) == -1) ERROR("listen() failed: %s", strerror(errno)); } else { ERROR("unable to create TCP socket: %s", strerror(errno)); } return fd; }
size_t fmt_ip6c(char *s,const char ip[16]) { if (ip6_isv4mapped(ip)) return fmt_ip4(s,ip+12); else return fmt_ip6(s,ip); }
static size_t stats_return_busy_networks( char * reply, stats_network_node *tree, int amount, int limit ) { ot_ip6 networks[amount]; ot_ip6 node_value; size_t scores[amount]; int i; char * r = reply; memset( scores, 0, sizeof( scores ) ); memset( networks, 0, sizeof( networks ) ); memset( node_value, 0, sizeof( node_value ) ); stats_get_highscore_networks( tree, 0, node_value, scores, networks, amount, limit ); r += sprintf( r, "Networks, limit /%d:\n", limit+STATS_NETWORK_NODE_BITWIDTH ); for( i=amount-1; i>=0; --i) { if( scores[i] ) { r += sprintf( r, "%08zd: ", scores[i] ); #ifdef WANT_V6 r += fmt_ip6c( r, networks[i] ); #else r += fmt_ip4( r, networks[i]); #endif *r++ = '\n'; } } *r++ = '\n'; return r - reply; }
void cfgopt_print(cfgopt_t *cfg){ for(; cfg->type != CONFIG_END ; ++cfg){ switch(cfg->type){ case CONFIG_STR: if(cfg->val.str) DEBUG("key='%s', val='%s'", cfg->key, cfg->val.str); break; case CONFIG_BOOL: if(cfg->val.boolean) DEBUG("key='%s', val=%s", cfg->key, *cfg->val.boolean ? "true" : "false"); break; case CONFIG_DEC: if(cfg->val.num) DEBUG("key='%s', val=%ld", cfg->key, *cfg->val.num); break; case CONFIG_OCT: if(cfg->val.num) DEBUG("key='%s', val=%lo", cfg->key, *cfg->val.num); break; case CONFIG_IP: { char sip[FMT_IP4]; fmt_ip4(sip, cfg->val.ip); DEBUG("key='%s', val=%s", cfg->key, sip); break; } case CONFIG_IP6: { char sip[FMT_IP6]; fmt_ip6(sip, cfg->val.ip); DEBUG("key='%s', val=%s", cfg->key, sip); break; } case CONFIG_MAC: { char smac[FMT_MAC]; fmt_mac(smac, cfg->val.mac); DEBUG("key='%s', val=%s", cfg->key, smac); break; } case CONFIG_NONOPT: if(cfg->val.nonopt) DEBUG("nonopt='%s'", cfg->val.nonopt); break; default: break; } } }
int setup_udp_server_socket(const char ip[4], const char ip6[16], u16 port) { char sip[FMT_IP6]; int fd; fd = socket_udp6(); if(fd >= 0) { if(socket_bind6(fd, ip6, port, 0) == -1) { close(fd); fd = socket_udp(); if(socket_bind4(fd, ip, port) == -1) { ERROR("unable to create server socket: %s", strerror(errno)); } else { fmt_ip4(sip, ip); DEBUG("bound UDP socket on %s:%hu", sip, port); } } else { fmt_ip6(sip, ip6); DEBUG("bound UDP socket on [%s]:%hu", sip, port); } } else { ERROR("unable to create UDP socket: %s", strerror(errno)); } return fd; }
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++; #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++; break; case EVENT_CONNECT: if( proto == FLAG_TCP ) ot_overall_tcp_connects++; else ot_overall_udp_connects++; break; case EVENT_COMPLETED: #ifdef WANT_SYSLOGS if( event_data) { struct ot_workstruct *ws = (struct ot_workstruct *)event_data; char timestring[64]; char hash_hex[42], peerid_hex[42], ip_readable[64]; struct tm time_now; time_t ttt; time( &ttt ); localtime_r( &ttt, &time_now ); strftime( timestring, sizeof( timestring ), "%FT%T%z", &time_now ); to_hex( hash_hex, *ws->hash ); if( ws->peer_id ) to_hex( peerid_hex, (uint8_t*)ws->peer_id ); else { *peerid_hex=0; } #ifdef WANT_V6 ip_readable[ fmt_ip6c( ip_readable, (char*)&ws->peer ) ] = 0; #else ip_readable[ fmt_ip4( ip_readable, (char*)&ws->peer ) ] = 0; #endif syslog( LOG_INFO, "time=%s event=completed info_hash=%s peer_id=%s ip=%s", timestring, hash_hex, peerid_hex, ip_readable ); } #endif ot_overall_completed++; break; case EVENT_SCRAPE: if( proto == FLAG_TCP ) ot_overall_tcp_successfulscrapes++; else ot_overall_udp_successfulscrapes++; case EVENT_FULLSCRAPE: ot_full_scrape_count++; ot_full_scrape_size += event_data; break; 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 ); off += fmt_ip6c( _debug+off, *ip ); off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); write( 2, _debug, off ); ot_full_scrape_request_count++; } 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 ); off += fmt_ip6c(_debug+off, *ip ); off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); write( 2, _debug, off ); ot_full_scrape_request_count++; } break; case EVENT_FAILED: ot_failed_request_counts[event_data]++; break; case EVENT_RENEW: ot_renewed[event_data]++; break; case EVENT_SYNC: ot_overall_sync_count+=event_data; break; case EVENT_BUCKET_LOCKED: ot_overall_stall_count++; break; #ifdef WANT_SPOT_WOODPECKER case EVENT_WOODPECKER: pthread_mutex_lock( &g_woodpeckers_mutex ); stat_increase_network_count( &stats_woodpeckers_tree, 0, event_data ); pthread_mutex_unlock( &g_woodpeckers_mutex ); break; #endif case EVENT_CONNID_MISSMATCH: ++ot_overall_udp_connectionidmissmatches; default: break; } }
int main(int argc,char* argv[]) { unsigned long count=1000; unsigned long interval=10; unsigned long sample=5; int keepalive=0; char ip[16]; uint16 port=80; uint32 scope_id=0; stralloc ips={0}; int s; char* request; int rlen; signal(SIGPIPE,SIG_IGN); if (!geteuid()) { struct rlimit rl; long l; #ifdef RLIMIT_NPROC rl.rlim_cur=RLIM_INFINITY; rl.rlim_max=RLIM_INFINITY; setrlimit(RLIMIT_NPROC,&rl); #endif for (l=0; l<20000; l+=500) { rl.rlim_cur=l; rl.rlim_max=l; if (setrlimit(RLIMIT_NOFILE,&rl)==-1) break; } } for (;;) { int i; int c=getopt(argc,argv,"c:i:s:kb"); if (c==-1) break; switch (c) { case 'k': keepalive=1; break; case 'i': i=scan_ulong(optarg,&interval); if (i==0 || optarg[i]) { buffer_puts(buffer_2,"httpbench: warning: could not parse interval: "); buffer_puts(buffer_2,optarg+i+1); buffer_putsflush(buffer_2,"\n"); } break; case 'c': i=scan_ulong(optarg,&count); if (i==0 || optarg[i]) { buffer_puts(buffer_2,"httpbench: warning: could not parse count: "); buffer_puts(buffer_2,optarg+i+1); buffer_putsflush(buffer_2,"\n"); } break; case 's': i=scan_ulong(optarg,&sample); if (i==0 || optarg[i]) { buffer_puts(buffer_2,"httpbench: warning: could not parse sample size: "); buffer_puts(buffer_2,optarg+i+1); buffer_putsflush(buffer_2,"\n"); } break; case 'b': bindport=10000; break; case '?': usage: buffer_putsflush(buffer_2, "usage: httpbench [-hb] [-c count] [-i interval] [-s sample] url\n" "\n" "\t-h\tprint this help\n" "\t-c n\topen n connections total (default: 1000)\n" "\t-i n\tevery n connections, measure the latency (default: 10)\n" "\t-s n\tlatency == average of time to fetch an URL n times (default: 5)\n" "\t-k\tenable HTTP keep-alive\n" "\t-b\tbind the sockets ourselves, so the OS doesn't choose the ports\n" "Setting the number of connections to 1 measures the throughput\n" "instead of the latency (give URL to a large file).\n"); return 0; } } if (!argv[optind]) goto usage; if (byte_diff(argv[optind],7,"http://")) goto usage; { char* host=argv[optind]+7; int colon=str_chr(host,':'); int slash=str_chr(host,'/'); char* c; if (host[0]=='[') { /* ipv6 IP notation */ int tmp; ++host; --colon; --slash; tmp=str_chr(host,']'); if (host[tmp]==']') host[tmp]=0; if (host[tmp+1]==':') colon=tmp+1; if (colon<tmp+1) colon=tmp+1+str_len(host+tmp+1); } if (colon<slash) { host[colon]=0; c=host+colon+1; if (c[scan_ushort(c,&port)]!='/') goto usage; *c=0; } host[colon]=0; c=host+slash; *c=0; { char* tmp=alloca(str_len(host)+1); tmp[fmt_str(tmp,host)]=0; host=tmp; } *c='/'; { int tmp=str_chr(host,'%'); if (host[tmp]) { host[tmp]=0; scope_id=socket_getifidx(host+tmp+1); if (scope_id==0) { buffer_puts(buffer_2,"httpbench: warning: network interface "); buffer_puts(buffer_2,host+tmp+1); buffer_putsflush(buffer_2," not found.\n"); } } } { stralloc a={0}; stralloc_copys(&a,host); if (dns_ip6(&ips,&a)==-1) { buffer_puts(buffer_2,"httpbench: could not resolve IP: "); buffer_puts(buffer_2,host); buffer_putnlflush(buffer_2); return 1; } } request=malloc(300+str_len(host)+str_len(c)*3); if (!request) panic("malloc"); { int i; i=fmt_str(request,"GET "); i+=fmt_urlencoded(request+i,c,str_len(c)); i+=fmt_str(request+i," HTTP/1.0\r\nHost: "); i+=fmt_str(request+i,host); i+=fmt_str(request+i,":"); i+=fmt_ulong(request+i,port); i+=fmt_str(request+i,"\r\nUser-Agent: httpbench/1.0\r\nConnection: "); i+=fmt_str(request+i,keepalive?"keep-alive":"close"); i+=fmt_str(request+i,"\r\n\r\n"); rlen=i; request[rlen]=0; } } { int i; s=-1; for (i=0; i+16<=ips.len; i+=16) { char buf[IP6_FMT]; int v6=byte_diff(ips.s+i,12,V4mappedprefix); buffer_puts(buffer_1,"connecting to "); buffer_put(buffer_1,buf, v6? fmt_ip6(buf,ips.s+i): fmt_ip4(buf,ips.s+i+12)); buffer_puts(buffer_1," port "); buffer_putulong(buffer_1,port); buffer_putnlflush(buffer_1); s=make_connection(ips.s+i,port,scope_id); if (s!=-1) { byte_copy(ip,16,ips.s+i); break; } } if (s==-1) return 1; } if (write(s,request,rlen)!=rlen) panic("write"); if (readanswer(s,count==1)==-1) exit(1); close(s); if (count==1) return 0; { long i; long j; long err=0; int *socks; socks=malloc(sizeof(int)*count); if (!socks) panic("malloc"); for (i=j=0; i<count; ++i) { struct timeval a,b; long d; if (j==0) { int k,s=0; long x=0,y=0; for (k=0; k<sample; ++k) { if (!keepalive || !k) { gettimeofday(&a,0); s=make_connection(ip,port,scope_id); if (s==-1) panic("make_connection"); gettimeofday(&b,0); d=(b.tv_sec-a.tv_sec)*1000000; d=d+b.tv_usec-a.tv_usec; x+=d; } gettimeofday(&a,0); write(s,request,rlen); if (readanswer(s,0)==-1) { ++err; keepalive=0; } gettimeofday(&b,0); d=(b.tv_sec-a.tv_sec)*1000000; d=d+b.tv_usec-a.tv_usec; y+=d; if (!keepalive) close(s); } if (keepalive) close(s); buffer_puts(buffer_1,"sample "); buffer_putulong(buffer_1,x); buffer_puts(buffer_1," "); buffer_putulong(buffer_1,y/sample); buffer_putnlflush(buffer_1); } ++j; if (j==interval) j=0; gettimeofday(&a,0); socks[i]=make_connection(ip,port,scope_id); if (socks[i]==-1) panic("make_connection"); gettimeofday(&b,0); d=(b.tv_sec-a.tv_sec)*1000000; d=d+b.tv_usec-a.tv_usec; buffer_puts(buffer_1,"clat "); buffer_putulong(buffer_1,d); buffer_putnlflush(buffer_1); } } buffer_flush(buffer_1); return 0; }