TWO_STRINGS(iguana,addnode,activecoin,ipaddr) { struct iguana_peer *addr; int32_t i,n; if ( coin == 0 ) coin = iguana_coinfind(activecoin); if ( coin != 0 && strcmp(coin->symbol,"RELAY") == 0 ) basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(ipaddr),GENESIS_PUBKEY); printf("coin.%p.[%s] addnode.%s -> %s\n",coin,coin!=0?coin->symbol:"",activecoin,ipaddr); if ( coin != 0 && coin->peers != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 ) { //iguana_possible_peer(coin,ipaddr); if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),1)) != 0 ) { addr->supernet = 1; if ( addr->usock >= 0 ) { if ( (n= coin->peers->numranked) != 0 ) { for (i=0; i<n; i++) { if ( addr == coin->peers->ranked[i] ) break; } if ( i == n ) { if ( i == IGUANA_MAXPEERS ) i--; else coin->peers->numranked = n+1; coin->peers->ranked[i] = addr; addr->recvblocks = coin->peers->ranked[0]->recvblocks + 100; addr->recvtotal = coin->peers->ranked[0]->recvtotal*1.1 + 100; printf("set (%s) -> slot.%d numranked.%d\n",ipaddr,i,coin->peers->numranked); } else printf("(%s) is already peer.%d\n",ipaddr,i); } return(clonestr("{\"result\":\"peer was already connected\"}")); } if ( addr->pending == 0 ) { addr->pending = (uint32_t)time(NULL); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); return(clonestr("{\"result\":\"addnode submitted\"}")); } else return(clonestr("{\"result\":\"addnode connection was already pending\"}")); } else return(clonestr("{\"result\":\"addnode cant find peer slot\"}")); } else if ( coin == 0 ) return(clonestr("{\"error\":\"addnode needs active coin, do an addcoin first\"}")); else return(clonestr("{\"error\":\"addnode needs ipaddr\"}")); }
int32_t ismyaddress(char *server) { char ipaddr[64]; uint32_t ipbits; if ( strncmp(server,"tcp://",6) == 0 ) server += 6; else if ( strncmp(server,"ws://",5) == 0 ) server += 5; if ( (ipbits= is_ipaddr(server)) != 0 ) { if ( strcmp(server,SUPERNET.myipaddr) == 0 || calc_ipbits(SUPERNET.myipaddr) == ipbits ) { printf("(%s) MATCHES me (%s)\n",server,SUPERNET.myipaddr); return(1); } } else { if ( SUPERNET.hostname[0] != 0 && strcmp(SUPERNET.hostname,server) == 0 ) return(1); if ( conv_domainname(ipaddr,server) == 0 && (strcmp(SUPERNET.myipaddr,ipaddr) == 0 || strcmp(SUPERNET.hostname,ipaddr) == 0) ) return(1); } //printf("(%s) is not me (%s)\n",server,SUPERNET.myipaddr); return(0); }
void iguana_acceptloop(void *args) { socklen_t clilen; struct sockaddr_in cli_addr; struct iguana_peer *addr; struct iguana_info *coin = args; addr = &coin->bindaddr; memset(addr,0,sizeof(*addr)); iguana_initpeer(coin,addr,(uint32_t)calc_ipbits("127.0.0.1")); addr->usock = pp_bind("127.0.0.1",coin->chain->portp2p); printf("iguana_bindloop 127.0.0.1 bind sock.%d\n",addr->usock); memset(coin->fds,0,sizeof(coin->fds)); while ( 1 ) { printf("LISTEN on sock.%d\n",addr->usock); listen(addr->usock,64); clilen = sizeof(cli_addr); printf("ACCEPT on sock.%d\n",addr->usock); coin->fds[coin->numsocks].fd = accept(addr->usock,(struct sockaddr *)&cli_addr,&clilen); printf("NEWSOCK.%d\n",coin->fds[coin->numsocks].fd); if ( coin->fds[coin->numsocks].fd < 0 ) { printf("ERROR on accept\n"); continue; } coin->numsocks++; } }
struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson) { uint32_t requestid,quoteid; memset(rp,0,sizeof(*rp)); rp->hash = jbits256(reqjson,"hash"); rp->desthash = jbits256(reqjson,"desthash"); rp->srcamount = j64bits(reqjson,"srcamount"); rp->minamount = j64bits(reqjson,"minamount"); rp->destamount = j64bits(reqjson,"destamount"); requestid = juint(reqjson,"requestid"); quoteid = juint(reqjson,"quoteid"); if ( jstr(reqjson,"relay") != 0 ) rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay")); rp->timestamp = juint(reqjson,"timestamp"); rp->quotetime = juint(reqjson,"quotetime"); safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest)); if ( quoteid != 0 ) { rp->quoteid = basilisk_quoteid(rp); if ( quoteid != rp->quoteid ) printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid); } rp->requestid = basilisk_requestid(rp); if ( requestid != rp->requestid ) printf("basilisk_parsejson requestid.%u != %u error\n",requestid,rp->requestid); return(rp); }
void iguana_startconnection(void *arg) { void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); int32_t status,i,n; char ipaddr[64]; struct iguana_peer *addr = arg; struct iguana_info *coin = 0; if ( addr == 0 || (coin= iguana_coin(addr->symbol)) == 0 ) { printf("iguana_startconnection nullptrs addr.%p coin.%p\n",addr,coin); return; } printf("startconnection.(%s)\n",addr->ipaddr); if ( strcmp(coin->name,addr->coinstr) != 0 ) { printf("iguana_startconnection.%s mismatched coin.%p (%s) vs (%s)\n",addr->ipaddr,coin,coin->symbol,addr->coinstr); return; } addr->usock = pp_connect(addr->ipaddr,coin->chain->portp2p); //addr->usock = iguana_connect(coin,addrs,sizeof(addrs)/sizeof(*addrs),addr->ipaddr,coin->chain->portp2p,2); if ( addr->usock < 0 || coin->peers.shuttingdown != 0 ) { status = IGUANA_PEER_KILLED; strcpy(ipaddr,addr->ipaddr); printf("refused PEER STATUS.%d for %s usock.%d\n",status,addr->ipaddr,addr->usock); iguana_iAkill(coin,addr,1); if ( iguana_rwipbits_status(coin,1,addr->ipbits,&status) == 0 ) printf("error updating status.%d for %s\n",status,ipaddr); addr->pending = 0; addr->ipbits = 0; addr->dead = 1; } else { addr->ready = (uint32_t)time(NULL); addr->ipbits = (uint32_t)calc_ipbits(addr->ipaddr); addr->dead = 0; addr->pending = 0; addr->height = iguana_set_iAddrheight(coin,addr->ipbits,0); strcpy(addr->symbol,coin->symbol); strcpy(addr->coinstr,coin->name); coin->peers.lastpeer = (uint32_t)time(NULL); status = IGUANA_PEER_READY; for (i=n=0; i<coin->MAXPEERS; i++) if ( coin->peers.active[i].usock > 0 ) n++; printf("CONNECTED.%d of max.%d! PEER STATUS.%d for %s usock.%d\n",n,coin->MAXPEERS,status,addr->ipaddr,addr->usock); iguana_iAconnected(coin,addr); coin->peers.numconnected++; if ( iguana_rwipbits_status(coin,1,addr->ipbits,&status) == 0 ) printf("error updating status.%d for %s\n",status,addr->ipaddr); if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) coin->peers.localaddr = addr; #ifdef IGUANA_DEDICATED_THREADS //iguana_launch("recv",iguana_dedicatedrecv,addr,IGUANA_RECVTHREAD); iguana_dedicatedloop(coin,addr); #endif } //printf("%s ready.%u dead.%d numthreads.%d\n",addr->ipaddr,addr->ready,addr->dead,coin->numthreads); //queue_enqueue("retryQ",&coin->peers.retryQ,&addr->DL); }
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)); }
int32_t nn_add_lbservers(uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t priority,int32_t sock,char servers[][MAX_SERVERNAME],int32_t num) { int32_t i; char endpoint[512],pubendpoint[512]; struct endpoint epbits; uint32_t ipbits; if ( num > 0 && servers != 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)) >= 0 ) { for (i=0; i<num; i++) { if ( (ipbits= (uint32_t)calc_ipbits(servers[i])) == 0 ) { printf("null ipbits.(%s)\n",servers[i]); continue; } //printf("epbits.%llx ipbits.%x %s\n",*(long long *)&epbits,(uint32_t)ipbits,endpoint); if ( ismyaddress(servers[i]) == 0 ) { epbits = calc_epbits("tcp",ipbits,port,NN_REP); expand_epbits(endpoint,epbits); if ( nn_connect(sock,endpoint) >= 0 ) { printf("+R%s ",endpoint); add_relay(&RELAYS.active,epbits); } if ( RELAYS.subclient >= 0 ) { if ( SUPERNET.iamrelay != 0 ) { epbits = calc_epbits("tcp",ipbits,relaysport,NN_PUB); expand_epbits(pubendpoint,epbits); if ( nn_connect(RELAYS.subclient,pubendpoint) >= 0 ) printf("+P%s ",pubendpoint); } epbits = calc_epbits("tcp",ipbits,globalport,NN_PUB); expand_epbits(pubendpoint,epbits); if ( nn_connect(RELAYS.subclient,pubendpoint) >= 0 ) printf("+P%s ",pubendpoint); } } } priority++; } else printf("error setting priority.%d (%s)\n",priority,nn_errstr()); return(priority); }
uint64_t call_SuperNET_broadcast(struct pserver_info *pserver,char *msg,int32_t len,int32_t duration) { int32_t SuperNET_broadcast(char *msg,int32_t duration); int32_t SuperNET_narrowcast(char *destip,unsigned char *msg,int32_t len); char ip_port[64],*ptr; uint64_t txid = 0; int32_t port; if ( 1 || SUPERNET_PORT != _SUPERNET_PORT ) return(0); if ( Debuglevel > 1 ) printf("call_SuperNET_broadcast.%p %p len.%d\n",pserver,msg,len); txid = calc_txid((uint8_t *)msg,(int32_t)strlen(msg)); if ( pserver != 0 ) { port = (pserver->p2pport == 0) ? BTCD_PORT : pserver->p2pport; //fprintf(stderr,"port.%d\n",port); sprintf(ip_port,"%s:%d",pserver->ipaddr,port); txid ^= calc_ipbits(pserver->ipaddr); if ( Debuglevel > 1 ) { char debugstr[4096]; init_hexbytes_noT(debugstr,(uint8_t *)msg,len); debugstr[32] = 0; fprintf(stderr,"%s NARROWCAST.(%s) txid.%llu (%s)\n",pserver->ipaddr,debugstr,(long long)txid,ip_port); } ptr = calloc(1,64 + sizeof(len) + len + 1); memcpy(ptr,&len,sizeof(len)); memcpy(&ptr[sizeof(len)],ip_port,strlen(ip_port)); memcpy(&ptr[sizeof(len) + 64],msg,len); queue_enqueue(&NarrowQ,ptr); return(txid); } else { char *cmdstr,NXTaddr[64]; cJSON *array; int32_t valid; array = cJSON_Parse(msg); if ( array != 0 ) { cmdstr = verify_tokenized_json(0,NXTaddr,&valid,array); if ( cmdstr != 0 ) free(cmdstr); free_json(array); if ( Debuglevel > 1 ) { char debugstr[4096]; init_hexbytes_noT(debugstr,(uint8_t *)msg,len); debugstr[32] = 0; printf("BROADCAST parms.(%s) valid.%d duration.%d txid.%llu len.%d\n",debugstr,valid,duration,(long long)txid,len); } ptr = calloc(1,sizeof(len) + sizeof(duration) + len); memcpy(ptr,&len,sizeof(len)); memcpy(&ptr[sizeof(len)],&duration,sizeof(duration)); memcpy(&ptr[sizeof(len) + sizeof(duration)],msg,len); ptr[sizeof(len) + sizeof(duration) + len] = 0; queue_enqueue(&BroadcastQ,ptr); return(txid); } else printf("cant broadcast non-JSON.(%s)\n",msg); } return(txid); }
TWO_STRINGS(iguana,dpow,symbol,pubkey) { char *retstr,srcaddr[64],destaddr[64]; struct iguana_info *src,*dest; cJSON *ismine; int32_t i,srcvalid,destvalid; struct dpow_info *dp = &myinfo->DPOWS[myinfo->numdpows]; destvalid = srcvalid = 0; if ( myinfo->NOTARY.RELAYID < 0 ) { if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(myinfo->ipaddr),myinfo->myaddr.persistent)) != 0 ) { printf("addrelay.(%s)\n",retstr); free(retstr); } if ( myinfo->NOTARY.RELAYID < 0 ) return(clonestr("{\"error\":\"must be running as notary node\"}")); } if ( dp->symbol[0] != 0 ) return(clonestr("{\"error\":\"cant dPoW more than one coin at a time\"}")); if ( pubkey == 0 || pubkey[0] == 0 || is_hexstr(pubkey,0) != 66 ) return(clonestr("{\"error\":\"need 33 byte pubkey\"}")); if ( symbol == 0 || symbol[0] == 0 ) symbol = "KMD"; //if ( myinfo->numdpows == 1 ) // komodo_assetcoins(-1); if ( iguana_coinfind(symbol) == 0 ) return(clonestr("{\"error\":\"cant dPoW an inactive coin\"}")); if ( strcmp(symbol,"KMD") == 0 && iguana_coinfind("BTC") == 0 ) return(clonestr("{\"error\":\"cant dPoW KMD without BTC\"}")); else if ( myinfo->numdpows == 0 && strcmp(symbol,"KMD") != 0 && iguana_coinfind("KMD") == 0 ) return(clonestr("{\"error\":\"cant dPoW without KMD\"}")); if ( myinfo->numdpows > 1 ) { if ( strcmp(symbol,"KMD") == 0 || iguana_coinfind("BTC") == 0 ) { dp->symbol[0] = 0; return(clonestr("{\"error\":\"cant dPoW KMD or BTC again\"}")); } for (i=1; i<myinfo->numdpows; i++) if ( strcmp(symbol,myinfo->DPOWS[i].symbol) == 0 ) { dp->symbol[0] = 0; return(clonestr("{\"error\":\"cant dPoW same coin again\"}")); } } strcpy(dp->symbol,symbol); if ( strcmp(dp->symbol,"KMD") == 0 ) { strcpy(dp->dest,"BTC"); dp->srcconfirms = DPOW_KOMODOCONFIRMS; } else { strcpy(dp->dest,"KMD"); dp->srcconfirms = DPOW_THIRDPARTY_CONFIRMS; } if ( dp->srcconfirms > DPOW_FIFOSIZE ) dp->srcconfirms = DPOW_FIFOSIZE; src = iguana_coinfind(dp->symbol); dest = iguana_coinfind(dp->dest); if ( src == 0 || dest == 0 ) { dp->symbol[0] = 0; return(clonestr("{\"error\":\"source coin or dest coin not there\"}")); } char tmp[67]; safecopy(tmp,pubkey,sizeof(tmp)); decode_hex(dp->minerkey33,33,tmp); bitcoin_address(srcaddr,src->chain->pubtype,dp->minerkey33,33); if ( (retstr= dpow_validateaddress(myinfo,src,srcaddr)) != 0 ) { json = cJSON_Parse(retstr); if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) srcvalid = 1; else srcvalid = 0; free(retstr); retstr = 0; } bitcoin_address(destaddr,dest->chain->pubtype,dp->minerkey33,33); if ( (retstr= dpow_validateaddress(myinfo,dest,destaddr)) != 0 ) { json = cJSON_Parse(retstr); if ( (ismine= jobj(json,"ismine")) != 0 && is_cJSON_True(ismine) != 0 ) destvalid = 1; else destvalid = 0; free(retstr); retstr = 0; } for (i=0; i<33; i++) printf("%02x",dp->minerkey33[i]); printf(" DPOW with pubkey.(%s) %s.valid%d %s -> %s %s.valid%d\n",tmp,srcaddr,srcvalid,dp->symbol,dp->dest,destaddr,destvalid); if ( srcvalid <= 0 || destvalid <= 0 ) { dp->symbol[0] = 0; return(clonestr("{\"error\":\"source address or dest address has no privkey, importprivkey\"}")); } if ( bitcoin_pubkeylen(dp->minerkey33) <= 0 ) { dp->symbol[0] = 0; return(clonestr("{\"error\":\"illegal pubkey\"}")); } if ( dp->blocks == 0 ) { dp->maxblocks = 1000000; dp->blocks = calloc(dp->maxblocks,sizeof(*dp->blocks)); } portable_mutex_init(&dp->paxmutex); portable_mutex_init(&dp->dexmutex); PAX_init(); //printf(">>>>>>>>>>>>>>> call paxpending\n"); //uint8_t buf[32768]; //dpow_paxpending(buf); myinfo->numdpows++; return(clonestr("{\"result\":\"success\"}")); }