/****************************************************************************** * Copyright © 2014-2016 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) { 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 ) { 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); for (i=0; ipeers.active[i].ipbits == (uint32_t)ipbits && coin->peers.active[i].usock >= 0 ) { printf("found existing peer.(%s) in slot[%d]\n",ipaddr,i); close(sock); sock = -1; //iguana_iAkill(coin,&coin->peers.active[i],0); //sleep(1); break; } } if ( sock < 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,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; addr->dead = 0; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); //iguana_dedicatedloop(coin,addr); } } } 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_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); }*/ int32_t iguana_peerhdrrequest(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2) { struct iguana_txid *tx,T; int32_t len=0,i,height,retval=-1; struct iguana_block *block; struct iguana_msgblock msgB; uint8_t *serialized; bits256 checkhash2; if ( (tx= iguana_txidfind(coin,&height,&T,hash2,coin->bundlescount-1)) != 0 ) { serialized = calloc(coin->chain->bundlesize,sizeof(msgB)); for (i=0; ichain->bundlesize; i++) { if ( (block= iguana_blockptr("peerhdr",coin,height + i)) != 0 ) { iguana_blockunconv(&msgB,block,1); len += iguana_rwblock(1,&checkhash2,&serialized[sizeof(struct iguana_msghdr) + len],&msgB); if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) { char str[65],str2[65]; printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",height+i,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2)); free(serialized); return(-1); } } else printf("cant find block at ht.%d\n",height+i); } retval = iguana_queue_send(coin,addr,0,serialized,"headers",len,0,0); printf("hdrs request retval.%d len.%d\n",retval,len); free(serialized); } else printf("couldnt find header\n"); return(retval); } int32_t iguana_peerinvrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t max) { int32_t i,type,len = 0; uint64_t x; struct iguana_bundle *bp; x = coin->bundlescount; len += iguana_rwvarint(1,&space[sizeof(struct iguana_msghdr) + len],&x); for (i=0; ibundles[i]) != 0 ) { type = MSG_BLOCK; len += iguana_rwnum(1,&space[sizeof(struct iguana_msghdr) + len],sizeof(uint32_t),&type); len += iguana_rwbignum(1,&space[sizeof(struct iguana_msghdr) + len],sizeof(bits256),bp->hashes[0].bytes); } } return(len); } 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_msghdr H; struct iguana_msgaddress A; struct iguana_peer *tmpaddr; sendlen = 0; max = (IGUANA_MINPEERS + IGUANA_MAXPEERS) / 2; if ( max > coin->peers.numranked ) max = coin->peers.numranked; x = 0; sendlen = iguana_rwvarint(1,&space[sizeof(H)],&x); for (iter=0; iter<2; iter++) { for (i=n=0; ipeers.ranked[i]) != 0 && ((iter == 0 && tmpaddr->supernet != 0) || (iter == 1 && tmpaddr->supernet == 0)) ) { sendlen += iguana_rwaddr(1,&space[sizeof(H) + sendlen],&tmpaddr->A,(int32_t)tmpaddr->protover); x++; } } } sendlen = iguana_rwvarint(1,&space[sizeof(H)],&x); printf("addrrequest: sendlen.%d x.%d\n",sendlen,(int32_t)x); return(sendlen); }