|
|
@ -33,6 +33,7 @@ uint32_t prices777_NXTBLOCK,MAX_DEPTH = 100; |
|
|
|
char NXTAPIURL[256],IGUANA_NXTADDR[256],IGUANA_NXTACCTSECRET[256]; |
|
|
|
uint64_t IGUANA_MY64BITS; |
|
|
|
queue_t helperQ,jsonQ,finishedQ,bundlesQ; |
|
|
|
struct supernet_info MYINFO; |
|
|
|
static int32_t initflag; |
|
|
|
#ifdef __linux__ |
|
|
|
int32_t IGUANA_NUMHELPERS = 8; |
|
|
@ -159,13 +160,199 @@ char *iguana_JSON(char *jsonstr) |
|
|
|
return(retstr); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t SuperNET_confirmip(struct supernet_info *myinfo,uint32_t ipbits) |
|
|
|
{ |
|
|
|
int32_t i,j,total = 0; uint32_t x; |
|
|
|
for (i=0; i<IGUANA_MAXCOINS; i++) |
|
|
|
{ |
|
|
|
if ( Coins[i] != 0 ) |
|
|
|
{ |
|
|
|
for (j=0; j<IGUANA_MAXPEERS; j++) |
|
|
|
{ |
|
|
|
if ( (x= Coins[i]->peers.active[j].myipbits) != 0 ) |
|
|
|
{ |
|
|
|
if ( x == ipbits ) |
|
|
|
total++; |
|
|
|
else total--; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return(total); |
|
|
|
} |
|
|
|
|
|
|
|
void SuperNET_myipaddr(struct supernet_info *myinfo,struct iguana_peer *addr,char *myipaddr,char *remoteaddr) |
|
|
|
{ |
|
|
|
uint32_t myipbits = (uint32_t)calc_ipbits(myipaddr); |
|
|
|
if ( addr->myipbits == 0 ) |
|
|
|
addr->myipbits = myipbits; |
|
|
|
else if ( addr->myipbits != myipbits ) |
|
|
|
{ |
|
|
|
printf("%s: myipaddr conflict %x != %x?\n",addr->ipaddr,addr->myipbits,myipbits); |
|
|
|
addr->myipbits = 0; |
|
|
|
} |
|
|
|
if ( addr->myipbits != 0 && myinfo->myaddr.myipbits == 0 ) |
|
|
|
myinfo->myaddr.myipbits = addr->myipbits; |
|
|
|
if ( addr->myipbits == myinfo->myaddr.myipbits ) |
|
|
|
{ |
|
|
|
myinfo->myaddr.confirmed++; |
|
|
|
if ( myinfo->myaddr.selfipbits == 0 || myinfo->ipaddr[0] == 0 ) |
|
|
|
{ |
|
|
|
if ( (myinfo->myaddr.totalconfirmed= SuperNET_confirmip(myinfo,addr->myipbits)) > 3 ) |
|
|
|
myinfo->myaddr.selfipbits = addr->myipbits; |
|
|
|
} |
|
|
|
} |
|
|
|
else myinfo->myaddr.confirmed--; |
|
|
|
if ( myinfo->myaddr.selfipbits == myinfo->myaddr.myipbits ) |
|
|
|
{ |
|
|
|
expand_ipbits(myinfo->ipaddr,myinfo->myaddr.selfipbits); |
|
|
|
vcalc_sha256(0,myinfo->myaddr.iphash.bytes,(uint8_t *)&myinfo->myaddr.selfipbits,sizeof(myinfo->myaddr.selfipbits)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag) |
|
|
|
{ |
|
|
|
uint64_t ipbits; struct iguana_peer *addr; |
|
|
|
printf("got %s remotepeer.(%s) supernet.%d\n",symbol,ipaddr,supernetflag); |
|
|
|
if ( supernetflag != 0 ) |
|
|
|
{ |
|
|
|
ipbits = calc_ipbits(ipaddr); |
|
|
|
if ( (addr= iguana_peerslot(coin,ipbits)) != 0 ) |
|
|
|
{ |
|
|
|
printf("launch startconnection to supernet peer.(%s)\n",ipaddr); |
|
|
|
iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
iguana_possible_peer(coin,ipaddr); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,void *data,long datalen,int32_t delaymillis) |
|
|
|
{ |
|
|
|
uint64_t r; char *jsonstr = data; int32_t flag=0,qlen = -1; uint8_t serialized[8192],*buf; cJSON *json; |
|
|
|
if ( (json= cJSON_Parse((char *)data)) != 0 ) |
|
|
|
{ |
|
|
|
if ( j64bits(json,"tag") == 0 ) |
|
|
|
{ |
|
|
|
OS_randombytes((uint8_t *)&r,sizeof(r)); |
|
|
|
jadd64bits(json,"tag",r); |
|
|
|
} |
|
|
|
jdelete(json,"yourip"); |
|
|
|
jaddstr(json,"yourip",addr->ipaddr); |
|
|
|
jsonstr = jprint(json,1); |
|
|
|
datalen = strlen(jsonstr)+1; |
|
|
|
flag = 1; |
|
|
|
} |
|
|
|
buf = serialized; |
|
|
|
if ( datalen > sizeof(serialized)-sizeof(struct iguana_msghdr) ) |
|
|
|
buf = calloc(1,datalen+sizeof(struct iguana_msghdr)); |
|
|
|
memcpy(&buf[sizeof(struct iguana_msghdr)],jsonstr,datalen); |
|
|
|
printf("SUPERSEND.(%s) -> (%s) delaymillis.%d\n",jsonstr,addr->ipaddr,delaymillis); |
|
|
|
qlen = iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",(int32_t)datalen,0,1); |
|
|
|
if ( buf != serialized ) |
|
|
|
free(buf); |
|
|
|
if ( flag != 0 ) |
|
|
|
free(jsonstr); |
|
|
|
return(qlen); |
|
|
|
} |
|
|
|
|
|
|
|
uint64_t Packetcache[1024]; |
|
|
|
int32_t SuperNET_DHTsend(struct supernet_info *myinfo,bits256 routehash,uint8_t *data,int32_t datalen,int32_t maxdelay) |
|
|
|
{ |
|
|
|
static int lastpurge; |
|
|
|
bits256 packethash; int32_t i,j,firstz,iter,n = 0; struct iguana_peer *addr; |
|
|
|
vcalc_sha256(0,packethash.bytes,data,datalen); |
|
|
|
firstz = -1; |
|
|
|
for (i=0; i<sizeof(Packetcache)/sizeof(*Packetcache); i++) |
|
|
|
{ |
|
|
|
if ( Packetcache[i] == 0 ) |
|
|
|
{ |
|
|
|
Packetcache[i] = packethash.txid; |
|
|
|
printf("add.%llx packetcache(%s)\n",(long long)packethash.txid,(char *)data); |
|
|
|
break; |
|
|
|
} |
|
|
|
else if ( Packetcache[i] == packethash.txid ) |
|
|
|
{ |
|
|
|
printf("SuperNET_DHTsend reject repeated packet.%llx (%s)\n",(long long)packethash.txid,(char *)data); |
|
|
|
return(-1); |
|
|
|
} |
|
|
|
} |
|
|
|
if ( i == sizeof(Packetcache)/sizeof(*Packetcache) ) |
|
|
|
{ |
|
|
|
printf("purge slot[%d]\n",lastpurge); |
|
|
|
Packetcache[lastpurge++] = packethash.txid; |
|
|
|
if ( lastpurge >= sizeof(Packetcache)/sizeof(*Packetcache) ) |
|
|
|
lastpurge = 0; |
|
|
|
} |
|
|
|
for (iter=0; iter<2; iter++) |
|
|
|
{ |
|
|
|
for (i=0; i<IGUANA_MAXCOINS; i++) |
|
|
|
{ |
|
|
|
if ( Coins[i] != 0 ) |
|
|
|
{ |
|
|
|
for (j=0; j<IGUANA_MAXPEERS; j++) |
|
|
|
{ |
|
|
|
addr = &Coins[i]->peers.active[j]; |
|
|
|
if ( addr->usock >= 0 ) |
|
|
|
{ |
|
|
|
if ( iter == 0 && memcmp(addr->iphash.bytes,routehash.bytes,sizeof(addr->iphash)) == 0 ) |
|
|
|
{ |
|
|
|
iguana_send_supernet(Coins[i],addr,data,datalen,maxdelay==0?0:rand()%maxdelay); |
|
|
|
return(100); |
|
|
|
} |
|
|
|
else if ( iter == 1 ) |
|
|
|
{ |
|
|
|
if ( bits256_cmp(addr->iphash,myinfo->myaddr.iphash) < 0 ) |
|
|
|
{ |
|
|
|
iguana_send_supernet(Coins[i],addr,data,datalen,maxdelay==0?0:rand()%maxdelay); |
|
|
|
n++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return(n); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t SuperNET_mypacket(struct supernet_info *myinfo,uint32_t destipbits,bits256 destpub) |
|
|
|
{ |
|
|
|
if ( destipbits == myinfo->myaddr.selfipbits ) |
|
|
|
return(0); |
|
|
|
if ( memcmp(destpub.bytes,myinfo->myaddr.pubkey.bytes,sizeof(destpub)) == 0 ) |
|
|
|
return(0); |
|
|
|
// check for encrypted packets
|
|
|
|
return(-1); |
|
|
|
} |
|
|
|
|
|
|
|
char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen) |
|
|
|
{ |
|
|
|
cJSON *json,*retjson; char *agent,*method,*retstr = 0; |
|
|
|
cJSON *json,*retjson; bits256 destpub,routehash; uint32_t n,destipbits = 0; |
|
|
|
char *destip,*agent,*myipaddr,*method,retbuf[512],*retstr = 0; |
|
|
|
*delaymillisp = 0; |
|
|
|
if ( (json= cJSON_Parse((char *)data)) != 0 ) |
|
|
|
{ |
|
|
|
printf("GOT >>>>>>>> SUPERNET P2P.(%s) from.%s\n",(char *)data,coin->symbol); |
|
|
|
if ( (myipaddr= jstr(json,"yourip")) != 0 ) |
|
|
|
SuperNET_myipaddr(&MYINFO,addr,myipaddr,ipaddr); |
|
|
|
if ( (destip= jstr(json,"destip")) != 0 ) |
|
|
|
destipbits = (uint32_t)calc_ipbits(destip); |
|
|
|
destpub = jbits256(json,"destpub"); |
|
|
|
if ( SuperNET_mypacket(&MYINFO,destipbits,destpub) < 0 ) |
|
|
|
{ |
|
|
|
if ( destipbits != 0 ) |
|
|
|
vcalc_sha256(0,routehash.bytes,(uint8_t *)&destipbits,sizeof(destipbits)); |
|
|
|
else routehash = destpub; |
|
|
|
n = SuperNET_DHTsend(&MYINFO,routehash,data,datalen,juint(json,"delay")); |
|
|
|
free_json(json); |
|
|
|
if ( n > 0 ) |
|
|
|
{ |
|
|
|
if ( n == 100 ) |
|
|
|
sprintf(retbuf,"{\"result\":\"packet sent to destination\"}"); |
|
|
|
else sprintf(retbuf,"{\"result\":\"packet forwarded to superDHT\",\"branches\":%d}",n); |
|
|
|
} else return(clonestr("{\"error\":\"no nodes to forward packet to\"}")); |
|
|
|
} |
|
|
|
if ( (agent= jstr(json,"agent")) != 0 && (method= jstr(json,"method")) != 0 ) |
|
|
|
{ |
|
|
|
if ( strcmp(agent,"SuperNET") == 0 && strcmp(method,"stop") == 0 ) |
|
|
@ -196,31 +383,6 @@ char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *de |
|
|
|
return(retstr); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delaymillis) |
|
|
|
{ |
|
|
|
int32_t len,flag=0,qlen = -1; uint8_t serialized[8192],*buf; cJSON *json; |
|
|
|
if ( (json= cJSON_Parse(jsonstr)) != 0 ) |
|
|
|
{ |
|
|
|
jdelete(json,"yourip"); |
|
|
|
jaddstr(json,"yourip",addr->ipaddr); |
|
|
|
jsonstr = jprint(json,1); |
|
|
|
flag = 1; |
|
|
|
} |
|
|
|
buf = serialized; |
|
|
|
if ( (len= (int32_t)strlen(jsonstr)) > sizeof(serialized)-sizeof(struct iguana_msghdr) ) |
|
|
|
buf = calloc(1,len+sizeof(struct iguana_msghdr)); |
|
|
|
{ |
|
|
|
memcpy(&buf[sizeof(struct iguana_msghdr)],jsonstr,len+1); |
|
|
|
printf("SUPERSEND.(%s) -> (%s) delaymillis.%d\n",jsonstr,addr->ipaddr,delaymillis); |
|
|
|
qlen = iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",len+1,0,1); |
|
|
|
} |
|
|
|
if ( buf != serialized ) |
|
|
|
free(buf); |
|
|
|
if ( flag != 0 ) |
|
|
|
free(jsonstr); |
|
|
|
return(qlen); |
|
|
|
} |
|
|
|
|
|
|
|
void iguana_exit() |
|
|
|
{ |
|
|
|
int32_t i,j,k; char *stopstr = "{\"agent\":\"SuperNET\",\"method\":\"stop\"}"; |
|
|
@ -232,7 +394,7 @@ void iguana_exit() |
|
|
|
for (j=0; j<IGUANA_MAXPEERS; j++) |
|
|
|
{ |
|
|
|
if ( Coins[i]->peers.active[j].usock >= 0 && Coins[i]->peers.active[j].supernet != 0 ) |
|
|
|
iguana_send_supernet(Coins[i],&Coins[i]->peers.active[j],stopstr,0); |
|
|
|
iguana_send_supernet(Coins[i],&Coins[i]->peers.active[j],stopstr,strlen(stopstr)+1,0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -271,8 +433,22 @@ void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func |
|
|
|
|
|
|
|
void iguana_main(void *arg) |
|
|
|
{ |
|
|
|
struct supernet_info MYINFO; char helperstr[64],*helperargs,*coinargs=0,*secret,*jsonstr = arg; |
|
|
|
int32_t i,len,flag; cJSON *json; uint8_t secretbuf[512]; |
|
|
|
char helperstr[64],*helperargs,*ipaddr,*coinargs=0,*secret,*jsonstr = arg; |
|
|
|
int32_t i,len,flag,c; cJSON *json; uint8_t secretbuf[512]; int64_t allocsize; |
|
|
|
if ( (ipaddr= OS_filestr(&allocsize,"ipaddr")) != 0 ) |
|
|
|
{ |
|
|
|
printf("got ipaddr.(%s)\n",ipaddr); |
|
|
|
len = (int32_t)strlen(ipaddr) - 1; |
|
|
|
while ( len > 8 && ((c= ipaddr[len]) == '\r' || c == '\n' || c == ' ' || c == '\t') ) |
|
|
|
ipaddr[len] = 0, len--; |
|
|
|
printf("got ipaddr.(%s) %x\n",ipaddr,is_ipaddr(ipaddr)); |
|
|
|
if ( is_ipaddr(ipaddr) != 0 ) |
|
|
|
{ |
|
|
|
strcpy(MYINFO.ipaddr,ipaddr); |
|
|
|
MYINFO.myaddr.selfipbits = (uint32_t)calc_ipbits(ipaddr); |
|
|
|
} |
|
|
|
free(ipaddr); |
|
|
|
} |
|
|
|
signal(SIGINT,sigint_func); |
|
|
|
signal(SIGILL,sigillegal_func); |
|
|
|
signal(SIGHUP,sighangup_func); |
|
|
@ -288,6 +464,7 @@ void iguana_main(void *arg) |
|
|
|
OS_ensure_directory("DB"); |
|
|
|
OS_ensure_directory("tmp"); |
|
|
|
memset(&MYINFO,0,sizeof(MYINFO)); |
|
|
|
OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey)); |
|
|
|
if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) |
|
|
|
{ |
|
|
|
if ( jobj(json,"numhelpers") != 0 ) |
|
|
|