void iguana_shutdownpeers(struct iguana_info *coin,int32_t forceflag) { #ifndef IGUANA_DEDICATED_THREADS int32_t i,skip,iter; struct iguana_peer *addr; if ( forceflag != 0 ) coin->peers.shuttingdown = (uint32_t)time(NULL); for (iter=0; iter<60; iter++) { skip = 0; for (i=0; i<coin->MAXPEERS; i++) { addr = &coin->peers.active[i]; if ( addr->ipbits == 0 || addr->usock < 0 || (forceflag == 0 && addr->dead == 0) ) continue; if ( addr->startsend != 0 || addr->startrecv != 0 ) { skip++; continue; } iguana_iAkill(coin,addr,0); } if ( skip == 0 ) break; sleep(1); printf("iguana_shutdownpeers force.%d skipped.%d\n",forceflag,skip); } if ( forceflag != 0 ) coin->peers.shuttingdown = 0; #endif }
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 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); }
void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { struct pollfd fds; uint8_t *buf,serialized[64]; int32_t bufsize,flag,timeout = coin->MAXPEERS/64+1; printf("start dedicatedloop.%s\n",addr->ipaddr); bufsize = IGUANA_MAXPACKETSIZE; buf = mycalloc('r',1,bufsize); //printf("send version myservices.%llu\n",(long long)coin->myservices); iguana_send_version(coin,addr,coin->myservices); iguana_queue_send(coin,addr,serialized,"getaddr",0,0,0); //printf("after send version\n"); while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 ) { flag = 0; memset(&fds,0,sizeof(fds)); fds.fd = addr->usock; fds.events |= POLLOUT; if ( poll(&fds,1,timeout) > 0 ) 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 ) flag += iguana_pollrecv(coin,addr,buf,bufsize); if ( flag == 0 ) { if ( time(NULL) > addr->pendtime+30 ) { if ( addr->pendblocks > 0 ) addr->pendblocks--; if ( addr->pendhdrs > 0 ) addr->pendhdrs--; addr->pendtime = 0; } if ( addr->pendblocks < IGUANA_MAXPENDING ) { //if ( ((int64_t)coin->R.RSPACE.openfiles * coin->R.RSPACE.size) < coin->MAXRECVCACHE ) { memset(&fds,0,sizeof(fds)); fds.fd = addr->usock; fds.events |= POLLOUT; if ( poll(&fds,1,timeout) > 0 ) flag += iguana_pollQs(coin,addr); } //else printf("%s > %llu coin->IGUANA_MAXRECVCACHE\n",mbstr((int64_t)coin->R.RSPACE.openfiles * coin->R.RSPACE.size),(long long)coin->MAXRECVCACHE); } } if ( flag == 0 )//&& iguana_processjsonQ(coin) == 0 ) usleep(20000);//+ 100000*(coin->blocks.hwmheight > (long)coin->longestchain-coin->minconfirms*2)); } } iguana_iAkill(coin,addr,addr->dead != 0); printf("finish dedicatedloop.%s\n",addr->ipaddr); myfree(buf,bufsize); coin->peers.numconnected--; }