void every_minute(int32_t counter) { static int broadcast_count; uint32_t now = (uint32_t)time(NULL); int32_t i,n,numnodes,len; char ipaddr[64],_cmd[MAX_JSON_FIELD]; uint8_t finalbuf[MAX_JSON_FIELD]; struct coin_info *cp; struct nodestats *stats,**nodes; struct pserver_info *pserver; if ( Finished_init == 0 ) return; now = (uint32_t)time(NULL); cp = get_coin_info("BTCD"); if ( cp == 0 ) return; //printf("<<<<<<<<<<<<< EVERY_MINUTE\n"); refresh_buckets(cp->srvNXTACCTSECRET); if ( broadcast_count == 0 ) { p2p_publishpacket(0,0); update_Kbuckets(get_nodestats(cp->srvpubnxtbits),cp->srvpubnxtbits,cp->myipaddr,0,0,0); nodes = (struct nodestats **)copy_all_DBentries(&numnodes,NODESTATS_DATA); if ( nodes != 0 ) { now = (uint32_t)time(NULL); for (i=0; i<numnodes; i++) { expand_ipbits(ipaddr,nodes[i]->ipbits); printf("(%llu %d %s) ",(long long)nodes[i]->nxt64bits,nodes[i]->lastcontact-now,ipaddr); if ( gen_pingstr(_cmd,1) > 0 ) { len = construct_tokenized_req((char *)finalbuf,_cmd,cp->srvNXTACCTSECRET); send_packet(!prevent_queueing("ping"),nodes[i]->ipbits,0,finalbuf,len); pserver = get_pserver(0,ipaddr,0,0); send_kademlia_cmd(0,pserver,"ping",cp->srvNXTACCTSECRET,0,0); p2p_publishpacket(pserver,0); } free(nodes[i]); } free(nodes); } printf("numnodes.%d\n",numnodes); } if ( (broadcast_count % 10) == 0 ) { for (i=n=0; i<Num_in_whitelist; i++) { expand_ipbits(ipaddr,SuperNET_whitelist[i]); pserver = get_pserver(0,ipaddr,0,0); if ( ismyipaddr(ipaddr) == 0 && ((stats= get_nodestats(pserver->nxt64bits)) == 0 || broadcast_count == 0 || (now - stats->lastcontact) > NODESTATS_EXPIRATION) ) send_kademlia_cmd(0,pserver,"ping",cp->srvNXTACCTSECRET,0,0), n++; } if ( Debuglevel > 0 ) printf("PINGED.%d\n",n); } broadcast_count++; }
uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) { uint32_t tmpind; char ipaddr[64]; struct iguana_iAddr checkiA; if ( rwflag == 0 ) { memset(iA,0,sizeof(*iA)); if ( iguana_kvread(coin,coin->iAddrs,0,iA,&ind) != 0 ) { //printf("read[%d] %x -> status.%d\n",ind,iA->ipbits,iA->status); return(ind); } else printf("error getting pkhash[%u] when %d\n",ind,coin->numiAddrs); } else { expand_ipbits(ipaddr,iA->ipbits); tmpind = ind; if ( iguana_kvwrite(coin,coin->iAddrs,&iA->ipbits,iA,&tmpind) != 0 ) { if ( tmpind != ind ) printf("warning: tmpind.%d != ind.%d for %s\n",tmpind,ind,ipaddr); //printf("iA[%d] wrote status.%d\n",ind,iA->status); if ( iguana_kvread(coin,coin->iAddrs,0,&checkiA,&tmpind) != 0 ) { if ( memcmp(&checkiA,iA,sizeof(checkiA)) != 0 ) printf("compare error tmpind.%d != ind.%d\n",tmpind,ind); } return(iA->ipbits); } else printf("error kvwrite (%s) ind.%d tmpind.%d\n",ipaddr,ind,tmpind); } printf("iA[%d] error rwflag.%d\n",ind,rwflag); return(0); }
uint32_t iguana_ipbits2ind(struct iguana_info *coin,struct iguana_iAddr *iA,uint32_t ipbits,int32_t createflag) { uint32_t ind = -1; char ipaddr[64]; expand_ipbits(ipaddr,ipbits); //printf("ipbits.%x %s to ind\n",ipbits,ipaddr); memset(iA,0,sizeof(*iA)); if ( iguana_kvread(coin,coin->iAddrs,&ipbits,iA,&ind) == 0 ) { if ( createflag == 0 ) return(0); ind = -1; iA->ipbits = ipbits; if ( iguana_kvwrite(coin,coin->iAddrs,&ipbits,iA,&ind) == 0 ) { printf("iguana_addr: cant save.(%s)\n",ipaddr); return(0); } else { iA->ind = ind; coin->numiAddrs = ind+1; if ( iguana_rwiAddrind(coin,1,iA,ind) == 0 ) printf("error iAddr.%d: created %x %s\n",ind,ipbits,ipaddr); } } iA->ind = ind; return(ind); }
void iguana_acceptloop(void *args) { struct iguana_peer *addr; struct iguana_info *coin = args; struct pollfd pfd; int32_t sock; struct iguana_accept *ptr; uint16_t port = coin->chain->portp2p; socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t i,ipbits; while ( (coin->bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) sleep(5); printf(">>>>>>>>>>>>>>>> iguana_bindloop 127.0.0.1:%d bind sock.%d\n",port,coin->bindsock); printf("START ACCEPTING\n"); while ( coin->bindsock >= 0 ) { memset(&pfd,0,sizeof(pfd)); pfd.fd = coin->bindsock; pfd.events = POLLIN; if ( poll(&pfd,1,100) <= 0 ) continue; clilen = sizeof(cli_addr); printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); sock = accept(coin->bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { printf("ERROR on accept bindsock.%d errno.%d (%s)\n",coin->bindsock,errno,strerror(errno)); continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(ipaddr,ipbits); printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); for (i=0; i<IGUANA_MAXPEERS; i++) { if ( coin->peers.active[i].ipbits == (uint32_t)ipbits && coin->peers.active[i].usock >= 0 ) { printf("found existing peer.(%s) in slot[%d]\n",ipaddr,i); iguana_iAkill(coin,&coin->peers.active[i],0); sleep(1); } } /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { }*/ if ( (addr= iguana_peerslot(coin,ipbits,0)) == 0 ) { ptr = mycalloc('a',1,sizeof(*ptr)); strcpy(ptr->ipaddr,ipaddr); ptr->ipbits = ipbits; ptr->sock = sock; ptr->port = coin->chain->portp2p; printf("queue PENDING ACCEPTS\n"); queue_enqueue("acceptQ",&coin->acceptQ,&ptr->DL,0); } else { printf("LAUNCH DEDICATED THREAD for %s\n",ipaddr); addr->usock = sock; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); //iguana_dedicatedloop(coin,addr); } } }
void expand_epbits(char *endpoint,struct endpoint epbits) { char ipaddr[64]; if ( epbits.ipbits != 0 ) expand_ipbits(ipaddr,epbits.ipbits); else strcpy(ipaddr,"*"); sprintf(endpoint,"%s://%s:%d",nn_transports[epbits.transport],ipaddr,epbits.port); }
void iguana_gotaddr(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgaddress *A) { char ipaddr[64]; uint32_t ipbits; iguana_rwnum(0,&A->ip[12],sizeof(uint32_t),&ipbits); expand_ipbits(ipaddr,ipbits); iguana_possible_peer(coin,ipaddr); //printf("gotaddr.(%s)\n",ipaddr); }
void set_pNXT_privacyServer(uint64_t privacyServer) { if ( Global_pNXT != 0 && privacyServer != 0 ) { char tmp[32]; expand_ipbits(tmp,(uint32_t)privacyServer); printf("SETTING PRIVACY SERVER IPADDR.(%s)\n",tmp); Global_pNXT->privacyServer = privacyServer; } }
uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) { char checkaddr[64]; uint32_t ipbits,ind,now = (uint32_t)time(NULL); int32_t i; struct iguana_iAddr iA; struct iguana_kvitem item; if ( ipaddr != 0 ) { //printf("Q possible peer.(%s)\n",ipaddr); queue_enqueue("possibleQ",&coin->possibleQ,queueitem(ipaddr),1); return((uint32_t)time(NULL)); } else if ( (ipaddr= queue_dequeue(&coin->possibleQ,1)) == 0 ) return((uint32_t)time(NULL)); #ifdef IGUANA_DISABLEPEERS if ( strcmp(ipaddr,"127.0.0.1") != 0 ) { free_queueitem(ipaddr); return((uint32_t)time(NULL)); } #endif //printf("possible peer.(%s)\n",ipaddr); for (i=0; i<coin->MAXPEERS; i++) if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) { free_queueitem(ipaddr); return((uint32_t)time(NULL)); } if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) { if ( (ipbits= (uint32_t)calc_ipbits(ipaddr)) != 0 ) { expand_ipbits(checkaddr,ipbits); if ( strcmp(checkaddr,ipaddr) == 0 ) { if ( (ind= iguana_ipbits2ind(coin,&iA,ipbits,1)) > 0 && iA.status != IGUANA_PEER_CONNECTING && iA.status != IGUANA_PEER_READY ) { if ( (iA.lastconnect == 0 || iA.lastkilled == 0) || (iA.numconnects > 0 && iA.lastconnect > (now - IGUANA_RECENTPEER)) || iA.lastkilled < now-600 ) { iA.status = IGUANA_PEER_ELIGIBLE; if ( iguana_rwiAddrind(coin,1,&iA,ind) == 0 ) printf("error updating status for (%s)\n",ipaddr); else if ( coin->peers.numconnected < coin->MAXPEERS ) { memset(&item,0,sizeof(item)); item.hh.itemind = ind; iguana_kvconnectiterator(coin,coin->iAddrs,&item,0,&iA.ipbits,&iA,sizeof(iA)); } } } } else printf("reject ipaddr.(%s)\n",ipaddr); } } free_queueitem(ipaddr); return((uint32_t)time(NULL)); }
void iguana_gotaddr(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgaddress *A) { char ipaddr[64],ipport[64]; uint32_t ipbits; uint16_t port; iguana_rwnum(0,&A->ip[12],sizeof(uint32_t),&ipbits); iguana_rwnum(0,(void *)&A->port,sizeof(uint16_t),&port); expand_ipbits(ipaddr,ipbits); if ( port != 0 ) sprintf(ipport,"%s:%d",ipaddr,port); iguana_possible_peer(coin,ipport); //printf("gotaddr.(%s:%d)\n",ipaddr,port); }
uint64_t get_pNXT_privacyServer(int32_t *activeflagp,char *secret) { uint64_t privacyServer; privacyServer = calc_privacyServer(Global_pNXT->privacyServer_ipaddr,atoi(Global_pNXT->privacyServer_port)); *activeflagp = Global_pNXT->privacyServer == privacyServer; char tmp[32]; expand_ipbits(tmp,(uint32_t)privacyServer); strcpy(secret,Global_pNXT->NXTACCTSECRET); memset(Global_pNXT->NXTACCTSECRET,0,sizeof(Global_pNXT->NXTACCTSECRET)); //printf("pNXT ipaddr.(%s) %llx %s\n",Global_pNXT->privacyServer_ipaddr,(long long)privacyServer,tmp); return(privacyServer); }
int32_t expire_nodestats(struct nodestats *stats,uint32_t now) { if ( stats->lastcontact != 0 && (now - stats->lastcontact) > NODESTATS_EXPIRATION ) { char ipaddr[64]; expand_ipbits(ipaddr,stats->ipbits); printf("expire_nodestats %s | %u %u %d\n",ipaddr,now,stats->lastcontact,now - stats->lastcontact); stats->gotencrypted = stats->modified = 0; //stats->sentmilli = 0; stats->expired = 1; return(1); } return(0); }
int32_t iguana_pendingaccept(struct iguana_info *coin) { struct iguana_accept *ptr; char ipaddr[64]; struct iguana_peer *addr; if ( (ptr= queue_dequeue(&coin->acceptQ,0)) != 0 ) { if ( (addr= iguana_peerslot(coin,ptr->ipbits,0)) != 0 ) { expand_ipbits(ipaddr,ptr->ipbits); printf("iguana_pendingaccept LAUNCH DEDICATED THREAD for %s\n",ipaddr); addr->usock = ptr->sock; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); myfree(ptr,sizeof(*ptr)); return(1); } else queue_enqueue("requeue_acceptQ",&coin->acceptQ,&ptr->DL,0); } return(0); }
int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t spacesize) { int32_t i,iter,n,max,sendlen; uint64_t x; struct iguana_peer *tmpaddr,tmp; char ipaddr[65]; if ( coin->peers == 0 ) return(0); sendlen = 0; max = (IGUANA_MINPEERS + IGUANA_MAXPEERS) / 2; if ( max > coin->peers->numranked ) max = coin->peers->numranked; x = 0; sendlen = iguana_rwvarint(1,&space[sendlen],&x); for (iter=0; iter<2; iter++) { for (i=n=0; i<max; i++) { if ( (tmpaddr= coin->peers->ranked[i]) != 0 && ((iter == 0 && tmpaddr->supernet != 0) || (iter == 1 && tmpaddr->supernet == 0)) && tmpaddr->ipbits != 0 ) { tmp = *tmpaddr; iguana_rwnum(1,&tmp.A.ip[12],sizeof(uint32_t),&tmp.ipbits); expand_ipbits(ipaddr,tmp.ipbits); if ( tmp.A.port == 0 ) { ((uint8_t *)&tmp.A.port)[0] = ((uint8_t *)&coin->chain->portp2p)[1]; ((uint8_t *)&tmp.A.port)[1] = ((uint8_t *)&coin->chain->portp2p)[0]; } //printf("(%s:%02x%02x).%04x ",ipaddr,((uint8_t *)&tmp.A.port)[0],((uint8_t *)&tmp.A.port)[1],(int32_t)tmp.protover); sendlen += iguana_rwaddr(1,&space[sendlen],&tmp.A,CADDR_TIME_VERSION); x++; if ( x == 0xf8 ) break; } } } iguana_rwvarint(1,space,&x); //for (i=0; i<sendlen; i++) // printf("%02x",space[i]); //printf(" %p addrrequest: sendlen.%d x.%d\n",space,sendlen,(int32_t)x); if ( x == 0 ) return(-1); return(sendlen); }
void *iguana_kvconnectiterator(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) { struct iguana_iAddr *iA = value; char ipaddr[64]; int32_t i; struct iguana_peer *addr = 0; if ( iA->ipbits != 0 && iguana_numthreads(1 << IGUANA_CONNTHREAD) < IGUANA_MAXCONNTHREADS && iA->status != IGUANA_PEER_READY && iA->status != IGUANA_PEER_CONNECTING ) { //printf("%x\n",iA->ipbits); expand_ipbits(ipaddr,iA->ipbits); portable_mutex_lock(&coin->peers_mutex); for (i=0; i<coin->MAXPEERS; i++) { addr = &coin->peers.active[i]; if ( addr->pending != 0 || addr->ipbits == iA->ipbits || strcmp(ipaddr,addr->ipaddr) == 0 ) { portable_mutex_unlock(&coin->peers_mutex); return(0); } if ( addr->ipbits == 0 ) { iguana_initpeer(coin,addr,iA->ipbits); break; } } portable_mutex_unlock(&coin->peers_mutex); if ( addr != 0 ) { //printf("status.%d addr.%p possible peer.(%s) (%s).%x %u threads %d %d %d %d\n",iA->status,addr,ipaddr,addr->ipaddr,addr->ipbits,addr->pending,iguana_numthreads(0),iguana_numthreads(1),iguana_numthreads(2),iguana_numthreads(3)); iA->status = IGUANA_PEER_CONNECTING; if ( iguana_rwiAddrind(coin,1,iA,item->hh.itemind) > 0 ) { //printf("iguana_startconnection.(%s) status.%d\n",ipaddr,IGUANA_PEER_CONNECTING); iguana_launch("connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); } } else printf("no open peer slots left\n"); } return(0); }
void SuperNET_idler(uv_idle_t *handle) { static int counter; static double lastattempt,lastclock; double millis; void *up; struct udp_queuecmd *qp; struct write_req_t *wr,*firstwr = 0; int32_t flag; char *jsonstr,*retstr,**ptrs; if ( Finished_init == 0 ) return; millis = milliseconds();//((double)uv_hrtime() / 1000000); if ( millis > (lastattempt + APISLEEP) ) { lastattempt = millis; #ifdef TIMESCRAMBLE while ( (wr= queue_dequeue(&sendQ)) != 0 ) { if ( wr == firstwr ) { //queue_enqueue(&sendQ,wr); process_sendQ_item(wr); if ( Debuglevel > 2 ) printf("SuperNET_idler: reached firstwr.%p\n",firstwr); break; } if ( wr->queuetime == 0 || wr->queuetime > lastattempt ) { process_sendQ_item(wr); // free(wr); libuv does this break; } if ( firstwr == 0 ) firstwr = wr; queue_enqueue(&sendQ,wr); } if ( Debuglevel > 2 && queue_size(&sendQ) != 0 ) printf("sendQ size.%d\n",queue_size(&sendQ)); #else #endif flag = 1; while ( flag != 0 ) { flag = 0; if ( (qp= queue_dequeue(&udp_JSON)) != 0 ) { //printf("process qp argjson.%p\n",qp->argjson); char previpaddr[64]; expand_ipbits(previpaddr,qp->previpbits); jsonstr = SuperNET_json_commands(Global_mp,previpaddr,qp->argjson,qp->tokenized_np->H.U.NXTaddr,qp->valid,qp->decoded); //printf("free qp (%s) argjson.%p\n",jsonstr,qp->argjson); if ( jsonstr != 0 ) free(jsonstr); free(qp->decoded); free_json(qp->argjson); free(qp); flag++; } else if ( (ptrs= queue_dequeue(&JSON_Q)) != 0 ) { char *call_SuperNET_JSON(char *JSONstr); jsonstr = ptrs[0]; if ( Debuglevel > 2 ) printf("dequeue JSON_Q.(%s)\n",jsonstr); if ( (retstr= call_SuperNET_JSON(jsonstr)) == 0 ) retstr = clonestr("{\"result\":null}"); ptrs[1] = retstr; if ( ptrs[2] != 0 ) queue_GUIpoll(ptrs); flag++; } } if ( process_storageQ() != 0 ) { //printf("processed storage\n"); } } #ifndef TIMESCRAMBLE while ( (wr= queue_dequeue(&sendQ)) != 0 ) { //printf("sendQ size.%d\n",queue_size(&sendQ)); process_sendQ_item(wr); } #endif while ( (up= queue_dequeue(&UDP_Q)) != 0 ) process_udpentry(up); if ( millis > (lastclock + 1000) ) { poll_pricedbs(); every_second(counter); retstr = findaddress(0,0,0,0,0,0,0,0,0,0); if ( retstr != 0 ) { printf("findaddress completed (%s)\n",retstr); free(retstr); } if ( (counter % 60) == 17 ) { every_minute(counter/60); update_Allnodes(); poll_telepods("BTCD"); poll_telepods("BTC"); } counter++; lastclock = millis; } usleep(APISLEEP * 1000); }
void iguana_acceptloop(void *args) { struct iguana_peer *addr; struct iguana_info *coin = args; struct pollfd pfd; int32_t sock; struct iguana_accept *ptr; uint16_t port = coin->chain->portp2p; socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t i,ipbits,flag; if ( coin->peers == 0 ) return; while ( (coin->bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) { if ( coin->peers->localaddr != 0 ) { printf("another daemon running, no need to have iguana accept connections\n"); return; } //if ( port != IGUANA_RPCPORT ) // return; sleep(5); } printf(">>>>>>>>>>>>>>>> iguana_bindloop 127.0.0.1:%d bind sock.%d\n",port,coin->bindsock); printf("START ACCEPTING\n"); while ( coin->bindsock >= 0 ) { memset(&pfd,0,sizeof(pfd)); pfd.fd = coin->bindsock; pfd.events = POLLIN; if ( poll(&pfd,1,100) <= 0 ) continue; clilen = sizeof(cli_addr); //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,coin->bindsock); sock = accept(coin->bindsock,(struct sockaddr *)&cli_addr,&clilen); if ( sock < 0 ) { printf("ERROR on accept bindsock.%d errno.%d (%s)\n",coin->bindsock,errno,strerror(errno)); continue; } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(ipaddr,ipbits); printf("incoming (%s:%u)\n",ipaddr,cli_addr.sin_port); for (i=flag=0; i<IGUANA_MAXPEERS; i++) { if ( coin->peers->active[i].ipbits == (uint32_t)ipbits && coin->peers->active[i].usock >= 0 ) { printf("found existing peer.(%s) in slot[%d]\n",ipaddr,i); close(coin->peers->active[i].usock); coin->peers->active[i].dead = 0; coin->peers->active[i].usock = sock; coin->peers->active[i].A.port = cli_addr.sin_port; coin->peers->active[i].ready = (uint32_t)time(NULL); flag = 1; //instantdex_peerhas_clear(coin,&coin->peers->active[i]); //iguana_iAkill(coin,&coin->peers->active[i],0); //sleep(1); break; } } if ( flag != 0 ) continue; printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { }*/ if ( (addr= iguana_peerslot(coin,ipbits,1)) == 0 ) { ptr = mycalloc('a',1,sizeof(*ptr)); strcpy(ptr->ipaddr,ipaddr); ptr->ipbits = ipbits; ptr->sock = sock; ptr->port = cli_addr.sin_port; printf("queue PENDING ACCEPTS\n"); queue_enqueue("acceptQ",&coin->acceptQ,&ptr->DL,0); } else { printf("LAUNCH DEDICATED THREAD for %s:%u\n",ipaddr,cli_addr.sin_port); addr->usock = sock; addr->dead = 0; addr->A.port = cli_addr.sin_port; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); //iguana_dedicatedloop(coin,addr); } } }