diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 973404376..2105eed46 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -348,7 +348,7 @@ void iguana_coinloop(void *arg) coin = coins[0]; iguana_rwiAddrind(coin,0,0,0); iguana_possible_peer(coin,"127.0.0.1"); - while ( 1 ) sleep(1); + //while ( 1 ) sleep(1); memset(zero.bytes,0,sizeof(zero)); if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 0f92a47b4..da816b7ba 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -373,7 +373,7 @@ struct iguana_peers { bits256 lastrequest; struct iguana_peer active[IGUANA_MAXPEERS],*ranked[IGUANA_MAXPEERS],*localaddr; - struct iguana_thread *peersloop,*recvloop,*acceptloop; + struct iguana_thread *peersloop,*recvloop; pthread_t *acceptloop; double topmetrics[IGUANA_MAXPEERS],avemetric; uint32_t numranked,mostreceived,shuttingdown,lastpeer,lastmetrics,numconnected; int32_t numfiles; @@ -427,7 +427,7 @@ struct iguana_info struct iguana_bitmap screen; //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; struct OS_memspace TXMEM; - queue_t bundlesQ,hdrsQ,blocksQ,priorityQ,possibleQ,jsonQ,finishedQ,TerminateQ,cacheQ; + queue_t acceptQ,bundlesQ,hdrsQ,blocksQ,priorityQ,possibleQ,jsonQ,finishedQ,TerminateQ,cacheQ; double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; portable_mutex_t peers_mutex,blocks_mutex; struct iguana_bundle *bundles[IGUANA_MAXBUNDLES]; @@ -648,8 +648,8 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st int32_t iguana_scriptgen(struct iguana_info *coin,uint8_t *script,char *asmstr,struct iguana_bundle *bp,struct iguana_pkhash *p,uint8_t type); int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); struct iguana_info *iguana_coinselect(); -//void init_InstantDEX(); -//char *InstantDEX(char *jsonstr,char *remoteaddr,int32_t localaccess); +void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); +struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint32_t ipbits); char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *destNXTaddr); void peggy(); diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c new file mode 100755 index 000000000..d65efa705 --- /dev/null +++ b/iguana/iguana_accept.c @@ -0,0 +1,108 @@ +/****************************************************************************** + * Copyright © 2014-2015 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "iguana777.h" + +struct iguana_accept { struct queueitem DL; char ipaddr[64]; uint32_t ipbits; int32_t sock; uint16_t port; }; + +int32_t iguana_acceptspoll(uint8_t *buf,int32_t bufsize,struct iguana_accept *accepts,int32_t num,int32_t timeout) +{ + struct pollfd fds[IGUANA_MAXPEERS]; int32_t i,j,n,r,nonz,flag; struct iguana_accept *ptr; + if ( num == 0 ) + return(0);; + memset(fds,0,sizeof(fds)); + flag = 0; + r = (rand() % num); + for (j=n=nonz=0; jsock >= 0 ) + { + fds[i].fd = ptr->sock; + fds[i].events = (POLLIN | POLLOUT); + nonz++; + } + } + if ( nonz != 0 && poll(fds,num,timeout) > 0 ) + { + for (j=0; jsock < 0 ) + continue; + if ( (fds[i].revents & POLLIN) != 0 ) + { + //return(iguana_recvmsg(ptr->ipaddr,ptr->sock,buf,bufsize)); + } + if ( (fds[i].revents & POLLOUT) != 0 ) + { + //if ( iguana_pollsendQ(coin,addr) == 0 ) + // flag += iguana_poll(coin,addr); + //else flag++; + } + } + } + return(0); +} + +void iguana_acceptloop(void *args) +{ + int32_t bindsock,sock; struct iguana_accept *ptr; struct iguana_peer *addr; struct iguana_info *coin = args; + socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t ipbits; + bindsock = iguana_socket(1,"127.0.0.1",coin->chain->portp2p); + printf("iguana_bindloop 127.0.0.1:%d bind sock.%d\n",coin->chain->portp2p,bindsock); + while ( bindsock >= 0 ) + { + clilen = sizeof(cli_addr); + printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",coin->chain->portp2p,bindsock); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + printf("ERROR on accept bindsock.%d errno.%d (%s)\n",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); + if ( (addr= iguana_peerslot(coin,ipbits)) == 0 ) + { + ptr = mycalloc('a',1,sizeof(*ptr)); + strcpy(ptr->ipaddr,ipaddr); + ptr->ipbits = ipbits; + ptr->sock = sock; + ptr->port = coin->chain->portp2p; + printf("NEED TO DEAL WITH PENDING ACCEPTS\n"); + queue_enqueue("acceptQ",&coin->acceptQ,&ptr->DL,0); + } + else + { + printf("LAUNCH DEDICATED THREAD for %s\n",ipaddr); + iguana_dedicatedloop(coin,addr); + } + } +} + +/*int32_t iguana_acceptport(struct iguana_info *coin,uint16_t port) +{ + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)iguana_acceptloop,(void *)coin) != 0 ) + { + printf("error launching accept thread for port.%u\n",port); + return(-1); + } + return(0); +}*/ diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index 47baa5f6d..1a56c97de 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -26,6 +26,7 @@ void iguana_initQ(queue_t *Q,char *name) void iguana_initQs(struct iguana_info *coin) { int32_t i; + iguana_initQ(&coin->acceptQ,"acceptQ"); iguana_initQ(&coin->bundlesQ,"bundlesQ"); iguana_initQ(&coin->hdrsQ,"hdrsQ"); iguana_initQ(&coin->blocksQ,"blocksQ"); @@ -333,7 +334,13 @@ struct iguana_info *iguana_startcoin(struct iguana_info *coin,int32_t initialhei if ( (coin->myservices & NODE_NETWORK) != 0 ) { printf("MYSERVICES.%llx\n",(long long)coin->myservices); - coin->peers.acceptloop = iguana_launch(coin,"acceptloop",iguana_acceptloop,coin,IGUANA_PERMTHREAD); + coin->peers.acceptloop = malloc(sizeof(pthread_t)); + if ( OS_thread_create(coin->peers.acceptloop,NULL,(void *)iguana_acceptloop,(void *)coin) != 0 ) + { + free(coin->peers.acceptloop); + coin->peers.acceptloop = 0; + printf("error launching accept thread for port.%u\n",coin->chain->portp2p); + } } coin->firstblock = coin->blocks.parsedblocks + 1; iguana_genesis(coin,coin->chain); @@ -354,7 +361,6 @@ struct iguana_info *iguana_startcoin(struct iguana_info *coin,int32_t initialhei #endif if ( 0 && (coin->MAXBUNDLES= coin->bundlescount / 4) < _IGUANA_MAXBUNDLES ) coin->MAXBUNDLES = _IGUANA_MAXBUNDLES; - //coin->peers.recvloop = iguana_launch("recvloop",iguana_recvloop,coin,IGUANA_PERMTHREAD); printf("started.%s\n",coin->symbol); return(coin); } diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 1f746e017..94ae0137a 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -352,7 +352,7 @@ char *iguana_txbytes(struct iguana_info *coin,bits256 *txidp,struct iguana_txid return(txbytes); } -int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txdata,int32_t *lenp,uint8_t *data,int32_t datalen) +int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txdata,int32_t *lenp,uint8_t *data,int32_t recvlen) { struct iguana_msgtx *tx; bits256 hash2; struct iguana_msgblock msg; int32_t i,n,len,numvouts,numvins; memset(&msg,0,sizeof(msg)); @@ -361,18 +361,18 @@ int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struc tx = iguana_memalloc(mem,msg.txn_count*sizeof(*tx),1); for (i=numvins=numvouts=0; iblock.height,coin->chain->hastimestamp)) < 0 ) + if ( (n= iguana_rwtx(0,mem,&data[len],&tx[i],recvlen - len,&tx[i].txid,txdata->block.height,coin->chain->hastimestamp)) < 0 ) break; numvouts += tx[i].tx_out; numvins += tx[i].tx_in; len += n; } - if ( coin->chain->hastimestamp != 0 && len != datalen && data[len] == (datalen - len - 1) ) + if ( coin->chain->hastimestamp != 0 && len != recvlen && data[len] == (recvlen - len - 1) ) { - //printf("\n>>>>>>>>>>> len.%d vs datalen.%d [%d]\n",len,datalen,data[len]); - memcpy(txdata->space,&data[len],datalen-len); - len += (datalen-len); - txdata->extralen = (datalen - len); + //printf("\n>>>>>>>>>>> len.%d vs recvlen.%d [%d]\n",len,recvlen,data[len]); + memcpy(txdata->space,&data[len],recvlen-len); + len += (recvlen-len); + txdata->extralen = (recvlen - len); } else txdata->extralen = 0; txdata->recvlen = len; txdata->numtxids = msg.txn_count; @@ -397,7 +397,7 @@ int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_ return(retval); } -int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen) +int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) { uint8_t serialized[512]; int32_t i,retval,srvmsg,bloom,intvectors,len= -100; uint64_t nonce,x; uint32_t type; bits256 hash2; @@ -415,9 +415,9 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O if ( addr != 0 ) { len = iguana_rwversion(0,data,&recvmv,addr->ipaddr); - if ( len == datalen ) + if ( len == recvlen ) iguana_gotversion(coin,addr,&recvmv); - //printf("deser.(%s) len.%d datalen.%d\n",recvmv.H.command,len,datalen); + //printf("deser.(%s) len.%d recvlen.%d\n",recvmv.H.command,len,recvlen); addr->msgcounts.version++; } } @@ -432,7 +432,7 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O } else if ( strcmp(H->command,"ping") == 0 ) { - if ( datalen == sizeof(uint64_t) && addr != 0 ) + if ( recvlen == sizeof(uint64_t) && addr != 0 ) { len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce); if ( addr != 0 ) @@ -447,12 +447,12 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O else if ( strcmp(H->command,"pong") == 0 ) { len = 0; - if ( datalen == sizeof(uint64_t) ) + if ( recvlen == sizeof(uint64_t) ) { len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce); iguana_gotpong(coin,addr,nonce); - } else printf("unexpected pong datalen.%d\n",datalen); - if ( len == datalen && addr != 0 ) + } else printf("unexpected pong recvlen.%d\n",recvlen); + if ( len == recvlen && addr != 0 ) addr->msgcounts.pong++; iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); } @@ -467,12 +467,12 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O len += iguana_rwaddr(0,&data[len],&A,(int32_t)addr->protover); iguana_gotaddr(coin,addr,&A); } - if ( len == datalen && addr != 0 ) + if ( len == recvlen && addr != 0 ) { addr->lastgotaddr = (uint32_t)time(NULL); addr->msgcounts.addr++; } - //printf("%s -> addr datalen.%d num.%d\n",addr->ipaddr,datalen,(int32_t)x); + //printf("%s -> addr recvlen.%d num.%d\n",addr->ipaddr,recvlen,(int32_t)x); } else if ( strcmp(H->command,"headers") == 0 ) { @@ -489,7 +489,7 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O //printf("GOT HEADERS n.%d len.%d\n",n,len); iguana_gotheadersM(coin,addr,blocks,n); //myfree(blocks,sizeof(*blocks) * n); - if ( len == datalen && addr != 0 ) + if ( len == recvlen && addr != 0 ) addr->msgcounts.headers++; } else printf("got unexpected n.%d for headers\n",n); } @@ -498,9 +498,9 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O struct iguana_msgtx *tx; iguana_memreset(rawmem); tx = iguana_memalloc(rawmem,sizeof(*tx),1);//mycalloc('u',1,sizeof(*tx)); - len = iguana_rwtx(0,rawmem,data,tx,datalen,&tx->txid,-1,coin->chain->hastimestamp); - iguana_gotunconfirmedM(coin,addr,tx,data,datalen); - printf("tx datalen.%d vs len.%d\n",datalen,len); + len = iguana_rwtx(0,rawmem,data,tx,recvlen,&tx->txid,-1,coin->chain->hastimestamp); + iguana_gotunconfirmedM(coin,addr,tx,data,recvlen); + printf("tx recvlen.%d vs len.%d\n",recvlen,len); addr->msgcounts.tx++; } else if ( strcmp(H->command,"block") == 0 ) @@ -510,30 +510,31 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O addr->msgcounts.block++; iguana_memreset(rawmem), iguana_memreset(txmem);//, iguana_memreset(hashmem); memset(&txdata,0,sizeof(txdata)); - if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,datalen)) == datalen ) - iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,datalen); - else printf("parse error block txn_count.%d, len.%d vs datalen.%d\n",txdata.block.RO.txn_count,len,datalen); + if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen ) + iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen); + else printf("parse error block txn_count.%d, len.%d vs recvlen.%d\n",txdata.block.RO.txn_count,len,recvlen); } else if ( strcmp(H->command,"reject") == 0 ) { - for (i=0; imsgcounts.reject++; } else if ( strcmp(H->command,"alert") == 0 ) { - for (i=0; imsgcounts.alert++; } else if ( addr != 0 ) { + printf("GOT.(%s) len.%d from %s\n",H->command,recvlen,addr->ipaddr); if ( strcmp(H->command,"inv") == 0 ) intvectors = 'I', addr->msgcounts.inv++; else if ( strcmp(H->command,"notfound") == 0 ) // for servers @@ -558,7 +559,7 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O bloom = 'M', addr->msgcounts.merkleblock++; } if ( bloom >= 0 || srvmsg >= 0 ) - len = datalen; // just mark as valid + len = recvlen; // just mark as valid if ( intvectors >= 0 ) { bits256 *txids=0,*blockhashes=0,hash; int32_t n,m; @@ -613,19 +614,19 @@ int32_t iguana_parser(struct iguana_info *coin,struct iguana_peer *addr,struct O myfree(txids,sizeof(*txids) * (x+1)); if ( blockhashes != 0 ) myfree(blockhashes,sizeof(*blockhashes) * (x+1)); - //printf("intvectors.%c datalen.%d\n",intvectors,datalen); + //printf("intvectors.%c recvlen.%d\n",intvectors,recvlen); } - if ( len != datalen && len != datalen-1 ) + if ( len != recvlen && len != recvlen-1 ) { - //printf("error.(%s) (%s): len.%d != datalen.%d\n",H->command,addr->ipaddr,len,datalen); + //printf("error.(%s) (%s): len.%d != recvlen.%d\n",H->command,addr->ipaddr,len,recvlen); //for (i=0; icommand,"addr") != 0 ) - printf("%s.%s len mismatch %d != %d\n",addr!=0?addr->ipaddr:"local",H->command,len,datalen); + printf("%s.%s len mismatch %d != %d\n",addr!=0?addr->ipaddr:"local",H->command,len,recvlen); } - else if ( len == datalen-1 ) + else if ( len == recvlen-1 ) { - printf("extra byte.[%02x] command.%s len.%d datalen.%d\n",data[datalen-1],H->command,len,datalen); + printf("extra byte.[%02x] command.%s len.%d recvlen.%d\n",data[recvlen-1],H->command,len,recvlen); //retval = -1; } return(retval); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index a83e7ea9c..bc3d021df 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -14,7 +14,6 @@ ******************************************************************************/ #include "iguana777.h" -void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); #define _iguana_hashfind(coin,ipbits) _iguana_hashset(coin,ipbits,-1) struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint32_t ipbits,int32_t createflag); @@ -593,10 +592,7 @@ void iguana_startconnection(void *arg) coin->peers.numconnected++; printf("PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) - { coin->peers.localaddr = addr; - iguana_send_ping(coin,addr); - } #ifdef IGUANA_DEDICATED_THREADS //iguana_launch("recv",iguana_dedicatedrecv,addr,IGUANA_RECVTHREAD); iguana_dedicatedloop(coin,addr); @@ -765,64 +761,6 @@ int32_t iguana_pollrecv(struct iguana_info *coin,struct iguana_peer *addr,uint8_ return(1); } -void iguana_acceptloop(void *args) -{ - socklen_t clilen; struct sockaddr_in cli_addr; uint32_t ipbits; uint16_t port; int32_t bindsock; - struct iguana_peer *addr; struct iguana_info *coin = args; - port = coin->chain->portp2p; - bindsock = iguana_socket(1,"127.0.0.1",port); - printf("iguana_bindloop 127.0.0.1:%d bind sock.%d\n",port,bindsock); - while ( bindsock >= 0 ) - { - ipbits = rand(); - while ( (addr= iguana_peerslot(coin,ipbits)) == 0 ) - { - ipbits = rand(); - sleep(1); - } - clilen = sizeof(cli_addr); - printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",port,bindsock); - addr->usock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); - if ( addr->usock < 0 ) - { - printf("ERROR on accept bindsock.%d errno.%d (%s)\n",bindsock,errno,strerror(errno)); - continue; - } - memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - addr->ipbits = ipbits; - expand_ipbits(addr->ipaddr,addr->ipbits); - printf("NEWSOCK.%d for %x (%s)\n",addr->usock,addr->ipbits,addr->ipaddr); - iguana_dedicatedloop(coin,addr); - } -} - -/*void iguana_recvloop(void *arg) -{ - int32_t i; uint8_t buf[32768]; struct iguana_info *coin = arg; - while ( 1 ) - { - if ( coin->numsocks == 0 ) - { - sleep(1); - continue; - } - for (i=0; inumsocks; i++) - coin->fds[i].revents = POLLIN, coin->fds[i].events = 0; - if ( poll(coin->fds,coin->numsocks,10000) > 0 ) - { - for (i=0; inumsocks; i++) - { - if ( (coin->fds[i].events & POLLIN) != 0 ) - { - printf("process message from [%d]\n",i); - _iguana_processmsg(coin,coin->fds[i].fd,&coin->bindaddr,buf,sizeof(buf)); - printf("iguana_bindloop processed.(%s)\n",buf+4); - } - } - } else printf("numsocks.%d nothing to receive\n",coin->numsocks); - } -}*/ - #ifdef IGUANA_PEERALLOC void *iguana_peeralloc(struct iguana_info *coin,struct iguana_peer *addr,int32_t datalen) { @@ -980,10 +918,6 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) flag += iguana_pollsendQ(coin,addr); if ( flag == 0 ) { - //memset(&fds,0,sizeof(fds)); - //fds.fd = addr->usock; - //fds.events |= POLLIN; - //if ( poll(&fds,1,timeout) > 0 ) if ( (fds.revents & POLLIN) != 0 ) flag += iguana_pollrecv(coin,addr,buf,bufsize); if ( flag == 0 ) @@ -996,10 +930,6 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) addr->pendhdrs--; addr->pendtime = 0; } - //memset(&fds,0,sizeof(fds)); - //fds.fd = addr->usock; - //fds.events |= POLLOUT; - //if ( poll(&fds,1,timeout) > 0 ) if ( coin->active != 0 && (fds.revents & POLLOUT) != 0 ) flag += iguana_pollQsPT(coin,addr); }