static void cfgopt_load_value(cfgopt_t *cfg, char *value){ if(!value) return; switch(cfg->type){ case CONFIG_STR: { cfg->val.str = strdup(value); break; } case CONFIG_DEC: case CONFIG_OCT: { int base = cfg->type == CONFIG_DEC ? 0 : 8; if(!cfg->val.num) NEW0(cfg->val.num); *cfg->val.num = strtoul(value, NULL, base); break; } case CONFIG_BOOL: { if(!cfg->val.boolean) NEW0(cfg->val.boolean); *cfg->val.boolean = (bool) strtoul(value, NULL, 0); break; } case CONFIG_IP: { char *ip; MALLOC(ip, 4); if(scan_ip4(value, ip) == 0) ERROR("invalid IPv4 literal: %s", value); cfg->val.ip = ip; break; } case CONFIG_IP6: { char *ip6; MALLOC(ip6, 16); if(scan_ip6(value, ip6) == 0) ERROR("invalid IPv6 literal: %s", value); cfg->val.ip6 = ip6; break; } case CONFIG_MAC: { char *mac; MALLOC(mac, 6); if(scan_mac(value, mac) != 6) ERROR("invalid MAC literal: %s", value); cfg->val.mac = mac; break; } case CONFIG_NONOPT: { if(!cfg->val.nonopt){ cfg->val.nonopt = strdup(value); }else{ size_t new_size = 2 + strlen(cfg->val.nonopt) + strlen(value); REALLOC(cfg->val.nonopt, new_size); strcat(cfg->val.nonopt, " "); strcat(cfg->val.nonopt, value); } break; } default: ERROR("invalid configuration type %d", (int) cfg->type); } }
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 */ if( !(off = scan_ip6( s, ip ) ) ) return 0; s += off; if( *s == 0 || isspace(*s)) return s-src; if( *s == ']' && bracket ) ++s; if( !ip6_isv4mapped(ip)){ if( ( bracket && *(s) != ':' ) || ( *(s) != '.' ) ) return 0; s++; } else { if( *(s++) != ':' ) return 0; } if( !(off = scan_ushort (s, port ) ) ) return 0; return off+s-src; }
size_t scan_ip6if(const char* src,char* ip,uint32* scope_id) { size_t i=scan_ip6(src,ip); *scope_id=0; if (src[i]=='%') { size_t j; char* tmp; for (j=i+1; isalnum(src[j]); ++j) ; if (!src[j]) tmp=(char*)src+i+1; else { tmp=alloca(j-i); byte_copy(tmp,j-(i+1),src+i+1); tmp[j-(i+1)]=0; } if (*tmp) { *scope_id=socket_getifidx(tmp); return j; } } return i; }
int main(int argc,char* argv[]) { static size_t x; x=23; atomic_add(&x,3); printf("%u\n",x); printf("%u\n",atomic_add_return(&x,-3)); printf("%u\n",compare_and_swap(&x,26,17)); printf("%u\n",compare_and_swap(&x,23,17)); #if 0 atomic_add(&x,3); printf("%u\n",x); x=23; atomic_add(&x,3); assert(x==26); atomic_or(&x,1); assert(x==27); atomic_and(&x,-2); assert(x==26); #endif #if 0 iarray a; char* c; iarray_init(&a,sizeof(io_entry)); printf("15 -> %p\n",c=iarray_allocate(&a,15)); printf("23 -> %p\n",c=iarray_allocate(&a,23)); printf("1234567 -> %p\n",c=iarray_allocate(&a,1234567)); printf("23 -> %p\n",iarray_get(&a,23)); #endif #if 0 io_batch* b=iob_new(1234); int64 fd=open("t.c",0); iob_addbuf(b,"fnord",5); iob_addfile_close(b,fd,0,7365); iob_write(1,b,writecb); #endif #if 0 char dest[1024]; unsigned long len; scan_urlencoded2("libstdc++.tar.gz",dest,&len); buffer_putmflush(buffer_1,dest,"\n"); #endif #if 0 static stralloc sa; stralloc_copym(&sa,"foo ","bar ","baz.\n"); write(1,sa.s,sa.len); #endif #if 0 buffer_putmflush(buffer_1,"foo ","bar ","baz.\n"); #endif #if 0 char* c="fnord"; int fd=open_read(c); errmsg_iam(argv[0]); carp("could not open file `",c,"'"); diesys(23,"could not open file `",c,"'"); #endif #if 0 errmsg_warn("could not open file `",c,"'",0); errmsg_warnsys("could not open file `",c,"'",0); #endif #if 0 char buf[100]="/usr/bin/sh"; int len=str_len(buf); assert(byte_rchr(buf,len,'/')==8); assert(byte_rchr(buf,len,'@')==len); assert(byte_rchr(buf,len,'h')==len-1); printf("%d\n",byte_rchr("x",1,'x')); #endif #if 0 char buf[IP6_FMT+100]; int i; char ip[16]; uint32 scope_id; char* s="fec0::1:220:e0ff:fe69:ad92%eth0/64"; char blubip[16]="\0\0\0\0\0\0\0\0\0\0\xff\xff\x7f\0\0\001"; i=scan_ip6if(s,ip,&scope_id); assert(s[i]=='/'); buffer_put(buffer_1,buf,fmt_ip6if(buf,ip,scope_id)); buffer_putnlflush(buffer_1); buffer_put(buffer_1,buf,fmt_ip6ifc(buf,blubip,scope_id)); buffer_putnlflush(buffer_1); scan_ip6("2001:7d0:0:f015:0:0:0:1",ip); buffer_put(buffer_1,buf,fmt_ip6(buf,ip)); buffer_putnlflush(buffer_1); #endif #if 0 char buf[100]; int i; printf("%d\n",i=fmt_pad(buf,"fnord",5,7,10)); buf[i]=0; puts(buf); #endif #if 0 char ip[16]; char buf[32]; printf("%d (expect 2)\n",scan_ip6("::",ip)); printf("%d (expect 3)\n",scan_ip6("::1",ip)); printf("%d (expect 16)\n",scan_ip6("fec0:0:0:ffff::1/0",ip)); printf("%.*s\n",fmt_ip6(buf,ip),buf); #endif #if 0 static stralloc s,t; stralloc_copys(&s,"fnord"); stralloc_copys(&t,"abc"); printf("%d\n",stralloc_diff(&s,&t)); stralloc_copys(&t,"fnor"); printf("%d\n",stralloc_diff(&s,&t)); stralloc_copys(&t,"fnord"); printf("%d\n",stralloc_diff(&s,&t)); stralloc_copys(&t,"fnordh"); printf("%d\n",stralloc_diff(&s,&t)); stralloc_copys(&t,"hausen"); printf("%d\n",stralloc_diff(&s,&t)); #endif #if 0 static stralloc s; stralloc_copys(&s,"fnord"); printf("%d\n",stralloc_diffs(&s,"abc")); printf("%d\n",stralloc_diffs(&s,"fnor")); printf("%d\n",stralloc_diffs(&s,"fnord")); printf("%d\n",stralloc_diffs(&s,"fnordh")); printf("%d\n",stralloc_diffs(&s,"hausen")); #endif #if 0 printf("%d\n",case_starts("fnordhausen","FnOrD")); printf("%d\n",case_starts("fnordhausen","blah")); #endif #if 0 char buf[]="FnOrD"; case_lowers(buf); puts(buf); #endif #if 0 char buf[100]="foo bar baz"; printf("%d (expect 7)\n",byte_rchr(buf,11,' ')); #endif #if 0 unsigned long size; char* buf=mmap_read(argv[1],&size); if (buf) { unsigned int x=fmt_yenc(0,buf,size); unsigned int y; char* tmp=malloc(x+1); y=fmt_yenc(tmp,buf,size); write(1,tmp,x); } #endif #if 0 char buf[100]; char buf2[100]; unsigned int len,len2; buf[fmt_yenc(buf,"http://localhost/~fefe",22)]=0; buffer_puts(buffer_1,buf); buffer_putsflush(buffer_1,"\n"); if ((buf[len2=scan_yenc(buf,buf2,&len)])!='\n') { buffer_putsflush(buffer_2,"parse error!\n"); return 1; } buffer_put(buffer_1,buf2,len2); buffer_putsflush(buffer_1,"\n"); return 0; #endif #if 0 char buf[100]; char buf2[100]; unsigned int len,len2; buf[fmt_base64(buf,"foo:bar",7)]=0; buffer_puts(buffer_1,buf); buffer_putsflush(buffer_1,"\n"); if ((buf[len2=scan_base64(buf,buf2,&len)])!=0) { buffer_putsflush(buffer_2,"parse error!\n"); return 1; } buffer_put(buffer_1,buf2,len2); buffer_putsflush(buffer_1,"\n"); return 0; #endif #if 0 unsigned long size; char* buf=mmap_read(argv[1],&size); if (buf) { unsigned int x=fmt_uuencoded(0,buf,size); unsigned int y; char* tmp=malloc(x+1); y=fmt_uuencoded(tmp,buf,size); write(1,tmp,x); } #endif #if 0 char buf[]="00000000000000000000000000000001"; char ip[16]; if (scan_ip6_flat(buf,ip) != str_len(buf)) buffer_putsflush(buffer_2,"parse error!\n"); #endif #if 0 int fd=open_read("t.c"); buffer b; char buf[1024]; char line[20]; int i; buffer_init(&b,read,fd,buf,1024); i=buffer_getline(&b,line,19); buffer_puts(buffer_1,"getline returned "); buffer_putulong(buffer_1,i); buffer_puts(buffer_1,"\n"); buffer_puts(buffer_1,line); buffer_flush(buffer_1); #endif #if 0 buffer_putulong(buffer_1,23); // buffer_putspace(buffer_1); buffer_putsflush(buffer_1,"\n"); // buffer_flush(buffer_1); #endif #if 0 long a,b,c; char buf[4096]; char buf2[4096]; memcpy(buf,buf2,4096); byte_copy(buf,4096,buf2); rdtscl(a); memcpy(buf,buf2,4096); rdtscl(b); byte_copy(buf,4096,buf2); rdtscl(c); printf("memcpy: %d - byte_copy: %d\n",b-a,c-b); #endif #if 0 char ip[16]; int i; if ((i=scan_ip6(argv[1],ip))) { char buf[128]; buf[fmt_ip6(buf,ip)]=0; puts(buf); } #endif #if 0 char buf[100]; strcpy(buf,"foobarbaz"); buf[fmt_fill(buf,3,5,100)]=0; printf("\"%s\"\n",buf); #endif #if 0 unsigned long len; char *c=mmap_read("/etc/passwd",&len); printf("got map %p of len %lu\n",c,len); #endif #if 0 char c; printf("%d\n",buffer_getc(buffer_0,&c)); printf("%c\n",c); #endif #if 0 char buf[100]="01234567890123456789012345678901234567890123456789"; long a,b,c; #endif #if 0 buf[ip4_fmt(buf,ip4loopback)]=0; buffer_puts(buffer_1small,buf); buffer_flush(buffer_1small); #endif #if 0 buf[0]=0; buf[fmt_8long(buf,0)]=0; puts(buf); rdtscl(a); c=str_len(buf); rdtscl(b); /*byte_zero_djb(buf,j); */ // printf("\n%lu %d\n",b-a,c); #endif #if 0 buffer_puts(buffer_1small,"hello, world\n"); buffer_flush(buffer_1small); #endif #if 0 int s=socket_tcp4(); char ip[4]={127,0,0,1}; int t=socket_connect4(s,ip,80); #endif #if 0 char buf[100]="foo bar baz fnord "; char buf2[100]="foo braz fnord"; long a,b,c; long i=0,j=0,k=0; double d; uint32 l,m,n; stralloc sa={0}; stralloc_copys(&sa,"fnord"); stralloc_catlong0(&sa,-23,5); stralloc_append(&sa,"\n"); printf("%d %d\n",str_equal("fnord","fnord1"),str_equal("fnord1","fnord")); write(1,sa.s,sa.len); printf("%d %d\n",stralloc_starts(&sa,"fnord"),stralloc_starts(&sa,"fnord\na")); l=0xdeadbeef; uint32_pack_big((char*)&m,l); uint32_unpack_big((char*)&m,&n); printf("%x %x %x\n",l,m,n); rdtscl(a); /* i=scan_double("3.1415",&d); */ rdtscl(b); /*byte_zero_djb(buf,j); */ rdtscl(c); printf("%lu %lu\n",b-a,c-b); #endif #if 0 size_t size; char* buf=mmap_read(argv[1],&size); if (buf) { unsigned int x=fmt_urlencoded2(0,buf,size,"x"); unsigned int y; char* tmp=malloc(x+1); y=fmt_urlencoded2(tmp,buf,size,"x"); write(1,tmp,x); } #endif #if 0 printf("%d %d\n",strcmp("foo","bar"),str_diff("foo","bar")); printf("%d %d\n",strcmp("foo","üar"),str_diff("foo","üar")); #endif #if 0 { int16 a; int32 b; int64 c; assert(imult16(4,10000,&a)==0); assert(imult16(-4,10000,&a)==0); assert(imult16(5,10,&a)==1 && a==50); assert(imult16(-3,10000,&a)==1 && a==-30000); assert(imult32(0x40000000,2,&b)==0); assert(imult32(0x3fffffff,2,&b)==1 && b==0x7ffffffe); assert(imult64(0x4000000000000000ll,2,&c)==0); assert(imult64(0x3fffffffffffffffll,2,&c)==1 && c==0x7ffffffffffffffell); } #endif #if 0 stralloc a; printf("%d\n",stralloc_copym(&a,"fnord",", ","foo")); #endif return 0; }
main(int argc,char **argv) { int fakev4=0; unsigned long u; int opt; char *x; int j; int s; int cloop; dns_random_init(seed); close(6); close(7); sig_ignore(sig_pipe); while ((opt = getopt(argc,argv,"46dDvqQhHrRi:p:t:T:l:I:")) != opteof) switch(opt) { case '4': noipv6 = 1; break; case '6': forcev6 = 1; break; case 'd': flagdelay = 1; break; case 'D': flagdelay = 0; break; case 'v': verbosity = 2; break; case 'q': verbosity = 0; break; case 'Q': verbosity = 1; break; case 'l': forcelocal = optarg; break; case 'H': flagremotehost = 0; break; case 'h': flagremotehost = 1; break; case 'R': flagremoteinfo = 0; break; case 'r': flagremoteinfo = 1; break; case 't': scan_ulong(optarg,&itimeout); break; case 'T': j = scan_ulong(optarg,&ctimeout[0]); if (optarg[j] == '+') ++j; scan_ulong(optarg + j,&ctimeout[1]); break; case 'i': if (!scan_ip6(optarg,iplocal)) usage(); break; case 'I': netif=socket_getifidx(optarg); break; case 'p': scan_ulong(optarg,&u); portlocal = u; break; default: usage(); } argv += optind; if (!verbosity) buffer_2->fd = -1; hostname = *argv; if (!hostname) usage(); if (!hostname[0] || str_equal(hostname,"0")) hostname = (noipv6?"127.0.0.1":"::1"); x = *++argv; if (!x) usage(); if (!x[scan_ulong(x,&u)]) portremote = u; else { struct servent *se; se = getservbyname(x,"tcp"); if (!se) strerr_die3x(111,FATAL,"unable to figure out port number for ",x); portremote = ntohs(se->s_port); /* i continue to be amazed at the stupidity of the s_port interface */ } if (!*++argv) usage(); if (!stralloc_copys(&tmp,hostname)) nomem(); if (dns_ip6_qualify(&addresses,&fqdn,&tmp) == -1) strerr_die4sys(111,FATAL,"temporarily unable to figure out IP address for ",hostname,": "); if (addresses.len < 16) strerr_die3x(111,FATAL,"no IP address for ",hostname); if (addresses.len == 16) { ctimeout[0] += ctimeout[1]; ctimeout[1] = 0; } for (cloop = 0;cloop < 2;++cloop) { if (!stralloc_copys(&moreaddresses,"")) nomem(); for (j = 0;j + 16 <= addresses.len;j += 4) { s = socket_tcp6(); if (s == -1) strerr_die2sys(111,FATAL,"unable to create socket: "); if (socket_bind6(s,iplocal,portlocal,netif) == -1) strerr_die2sys(111,FATAL,"unable to bind socket: "); if (timeoutconn6(s,addresses.s + j,portremote,ctimeout[cloop],netif) == 0) goto CONNECTED; close(s); if (!cloop && ctimeout[1] && (errno == error_timeout)) { if (!stralloc_catb(&moreaddresses,addresses.s + j,16)) nomem(); } else { strnum[fmt_ulong(strnum,portremote)] = 0; if (ip6_isv4mapped(addresses.s+j)) ipstr[ip4_fmt(ipstr,addresses.s + j + 12)] = 0; else ipstr[ip6_fmt(ipstr,addresses.s + j)] = 0; strerr_warn5(CONNECT,ipstr," port ",strnum,": ",&strerr_sys); } } if (!stralloc_copy(&addresses,&moreaddresses)) nomem(); } _exit(111); CONNECTED: if (!flagdelay) socket_tcpnodelay(s); /* if it fails, bummer */ if (socket_local6(s,iplocal,&portlocal,&netif) == -1) strerr_die2sys(111,FATAL,"unable to get local address: "); if (!forcev6 && (ip6_isv4mapped(iplocal) || byte_equal(iplocal,16,V6any))) fakev4=1; if (!pathexec_env("PROTO",fakev4?"TCP":"TCP6")) nomem(); strnum[fmt_ulong(strnum,portlocal)] = 0; if (!pathexec_env("TCPLOCALPORT",strnum)) nomem(); if (fakev4) ipstr[ip4_fmt(ipstr,iplocal+12)] = 0; else ipstr[ip6_fmt(ipstr,iplocal)] = 0; if (!pathexec_env("TCPLOCALIP",ipstr)) nomem(); x = forcelocal; if (!x) if (dns_name6(&tmp,iplocal) == 0) { if (!stralloc_0(&tmp)) nomem(); x = tmp.s; } if (!pathexec_env("TCPLOCALHOST",x)) nomem(); if (socket_remote6(s,ipremote,&portremote,&netif) == -1) strerr_die2sys(111,FATAL,"unable to get remote address: "); strnum[fmt_ulong(strnum,portremote)] = 0; if (!pathexec_env("TCPREMOTEPORT",strnum)) nomem(); if (fakev4) ipstr[ip4_fmt(ipstr,ipremote+12)] = 0; else ipstr[ip6_fmt(ipstr,ipremote)] = 0; if (!pathexec_env("TCPREMOTEIP",ipstr)) nomem(); if (verbosity >= 2) strerr_warn4("tcpclient: connected to ",ipstr," port ",strnum,0); x = 0; if (flagremotehost) if (dns_name6(&tmp,ipremote) == 0) { if (!stralloc_0(&tmp)) nomem(); x = tmp.s; } if (!pathexec_env("TCPREMOTEHOST",x)) nomem(); x = 0; if (flagremoteinfo) if (remoteinfo6(&tmp,ipremote,portremote,iplocal,portlocal,itimeout,netif) == 0) { if (!stralloc_0(&tmp)) nomem(); x = tmp.s; } if (!pathexec_env("TCPREMOTEINFO",x)) nomem(); if (fd_move(6,s) == -1) strerr_die2sys(111,FATAL,"unable to set up descriptor 6: "); if (fd_copy(7,6) == -1) strerr_die2sys(111,FATAL,"unable to set up descriptor 7: "); sig_uncatch(sig_pipe); pathexec(argv); strerr_die4sys(111,FATAL,"unable to run ",*argv,": "); }
static int init(char ip[256]) { unsigned long int i; unsigned long int j; int iplen = 0; char* x; #if WINDOWS FIXED_INFO* pFixedInfo; ULONG ulOutBufLen; typedef DWORD (WINAPI get_network_params_fn)(PFIXED_INFO pFixedInfo,PULONG pOutBufLen); static get_network_params_fn* get_network_params; if(get_network_params == 0) { HANDLE iphlpapi = LoadLibraryA("iphlpapi.dll"); if(iphlpapi != INVALID_HANDLE_VALUE) { if((get_network_params = (get_network_params_fn*)GetProcAddress(iphlpapi, "GetNetworkParams")) == 0) return -1; } } #endif x = getenv("DNSCACHEIP"); #if WINDOWS #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) if(!x) { /* Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable */ pFixedInfo = (FIXED_INFO*)MALLOC(sizeof(FIXED_INFO)); if(pFixedInfo) { ulOutBufLen = sizeof(FIXED_INFO); if((*get_network_params)(pFixedInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { FREE(pFixedInfo); pFixedInfo = (FIXED_INFO*)MALLOC(ulOutBufLen); } } if(pFixedInfo) { if((*get_network_params)(pFixedInfo, &ulOutBufLen) == NO_ERROR) { x = pFixedInfo->DnsServerList.IpAddress.String; } } } #endif if(x) while(iplen <= 60) { if(*x == '.') ++x; else { i = scan_ip6(x, ip + iplen); if(!i) break; x += i; iplen += 16; } } if(!iplen) { i = openreadclose("/etc/resolv.conf", &data, 64); if(i == (unsigned long int)-1) return -1; if(i) { if(!stralloc_append(&data, "\n")) return -1; i = 0; for(j = 0; j < data.len; ++j) if(data.s[j] == '\n') { if(byte_equal("nameserver ", 11, data.s + i) || byte_equal("nameserver\t", 11, data.s + i)) { i += 10; while((data.s[i] == ' ') || (data.s[i] == '\t')) ++i; if(iplen <= 60) if(scan_ip6(data.s + i, ip + iplen)) { iplen += 16; } } i = j + 1; } } } if(!iplen) { byte_copy(ip, 16, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"); iplen = 16; } byte_zero(ip + iplen, 256 - iplen); return 0; }
static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, char *read_ptr ) { int numwant, tmp, scanon; unsigned short port = 0; char *write_ptr; ssize_t len; struct http_data *cookie = io_getcookie( sock ); /* 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; ++read_ptr; } #ifdef WANT_IP_FROM_PROXY if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_PROXY ) ) { ot_ip6 proxied_ip; char *fwd = http_header( ws->request, ws->header_size, "x-forwarded-for" ); if( fwd && scan_ip6( fwd, proxied_ip ) ) OT_SETIP( &ws->peer, proxied_ip ); else OT_SETIP( &ws->peer, cookie->ip ); } else #endif OT_SETIP( &ws->peer, cookie->ip ); ws->peer_id = NULL; ws->hash = NULL; OT_SETPORT( &ws->peer, &port ); OT_PEERFLAG( &ws->peer ) = 0; numwant = 50; scanon = 1; 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 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 ); 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; break; case 3: /* matched "event" */ switch( scan_find_keywords( keywords_announce_event, &read_ptr, SCAN_SEARCHPATH_VALUE ) ) { case -1: HTTPERROR_400_PARAM; case 1: /* matched "completed" */ OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_COMPLETED; break; case 2: /* matched "stopped" */ OT_PEERFLAG( &ws->peer ) |= PEER_FLAG_STOPPED; break; default: break; } 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; 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; break; case 6: /* matched "info_hash" */ 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; ws->hash = (ot_hash*)write_ptr; break; #ifdef WANT_IP_FROM_QUERY_STRING case 7: /* matched "ip" */ { char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply+16; len = scan_urlencoded_query( &read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE ); tmp_buf2[len] = 0; if( ( len <= 0 ) || !scan_ip6( tmp_buf2, tmp_buf1 ) ) HTTPERROR_400_PARAM; OT_SETIP( &ws->peer, tmp_buf1 ); } break; #endif #ifdef WANT_FULLLOG_NETWORKS case 8: /* matched "lognet" */ { //if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) { char *tmp_buf = ws->reply; ot_net net; signed short parsed, bits; len = scan_urlencoded_query( &read_ptr, tmp_buf, SCAN_SEARCHPATH_VALUE ); tmp_buf[len] = 0; 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( tmp_buf[parsed++] != '/' ) bits = 128; else { parsed = scan_short( tmp_buf + parsed, &bits ); if( !parsed ) HTTPERROR_400_PARAM; if( ip6_isv4mapped( net.address ) ) bits += 96; } net.bits = bits; loglist_add_network( &net ); return ws->reply_size = sprintf( ws->reply, "Successfully added.\n" ); //} } #endif break; 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; ws->peer_id = write_ptr; break; } } #ifdef WANT_LOG_NUMWANT numwants[numwant]++; #endif /* XXX DEBUG stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ws->reply ); */ /* Scanned whole query string */ if( !ws->hash ) return ws->reply_size = sprintf( ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" ); if( OT_PEERFLAG( &ws->peer ) & PEER_FLAG_STOPPED ) ws->reply_size = remove_peer_from_torrent( FLAG_TCP, ws ); else ws->reply_size = add_peer_to_torrent_and_return_peers( FLAG_TCP, ws, numwant ); stats_issue_event( EVENT_ANNOUNCE, FLAG_TCP, ws->reply_size); return ws->reply_size; }