jl777
9 years ago
126 changed files with 5049 additions and 334 deletions
@ -0,0 +1,887 @@ |
|||||
|
/******************************************************************************
|
||||
|
* 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" |
||||
|
|
||||
|
// peer context, ie massively multithreaded -> bundlesQ
|
||||
|
|
||||
|
struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen) |
||||
|
{ |
||||
|
struct iguana_bundlereq *req; int32_t allocsize; |
||||
|
allocsize = (uint32_t)sizeof(*req) + datalen; |
||||
|
req = mycalloc(type,1,allocsize); |
||||
|
req->allocsize = allocsize; |
||||
|
req->datalen = datalen; |
||||
|
req->addr = addr; |
||||
|
req->coin = coin; |
||||
|
req->type = type; |
||||
|
return(req); |
||||
|
} |
||||
|
|
||||
|
/*struct iguana_block *iguana_blockrequest(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,uint32_t now,int32_t iamthreadsafe)
|
||||
|
{ |
||||
|
struct iguana_block *block = 0; |
||||
|
if( bp != 0 && bundlei >= 0 && bundlei < bp->n ) |
||||
|
block = bp->blocks[bundlei]; |
||||
|
if ( block == 0 && iamthreadsafe != 0 ) |
||||
|
block = iguana_blockfind(coin,hash2); |
||||
|
if ( block != 0 ) |
||||
|
{ |
||||
|
//block->issued = now;
|
||||
|
if ( block->numrequests < 100 ) |
||||
|
block->numrequests++; |
||||
|
} |
||||
|
return(block); |
||||
|
}*/ |
||||
|
|
||||
|
int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe) |
||||
|
{ |
||||
|
int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; |
||||
|
char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); |
||||
|
if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,hexstr)) > 0 ) |
||||
|
{ |
||||
|
iguana_send(coin,addr,serialized,len); |
||||
|
coin->numreqsent++; |
||||
|
addr->pendblocks++; |
||||
|
addr->pendtime = (uint32_t)time(NULL); |
||||
|
//iguana_blockrequest(coin,bp,bundlei,hash2,addr->pendtime,iamthreadsafe);
|
||||
|
//printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1);
|
||||
|
} else printf("MSG_BLOCK null datalen.%d\n",len); |
||||
|
return(len); |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_sendtxidreq(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2) |
||||
|
{ |
||||
|
uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; |
||||
|
int32_t len,i,r,j; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); |
||||
|
if ( (len= iguana_getdata(coin,serialized,MSG_TX,hexstr)) > 0 ) |
||||
|
{ |
||||
|
if ( addr == 0 ) |
||||
|
{ |
||||
|
r = rand(); |
||||
|
for (i=0; i<coin->MAXPEERS; i++) |
||||
|
{ |
||||
|
j = (i + r) % coin->MAXPEERS; |
||||
|
addr = &coin->peers.active[j]; |
||||
|
if ( coin->peers.active[j].usock >= 0 && coin->peers.active[j].dead == 0 ) |
||||
|
{ |
||||
|
iguana_send(coin,addr,serialized,len); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} else iguana_send(coin,addr,serialized,len); |
||||
|
} else printf("MSG_TX null datalen.%d\n",len); |
||||
|
printf("send MSG_TX.%d\n",len); |
||||
|
return(len); |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid) |
||||
|
{ |
||||
|
int32_t i; |
||||
|
while ( coin->numreqtxids >= sizeof(coin->reqtxids)/sizeof(*coin->reqtxids) ) |
||||
|
{ |
||||
|
printf("txidreq full, wait\n"); |
||||
|
sleep(1); |
||||
|
} |
||||
|
char str[65]; printf("txidreq.%s\n",bits256_str(str,txid)); |
||||
|
coin->reqtxids[coin->numreqtxids++] = txid; |
||||
|
for (i=0; i<coin->MAXPEERS; i++) |
||||
|
if ( coin->peers.active[i].usock >= 0 ) |
||||
|
iguana_sendtxidreq(coin,coin->peers.ranked[i],txid); |
||||
|
return(0); |
||||
|
} |
||||
|
|
||||
|
void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen) |
||||
|
{ |
||||
|
struct iguana_bundlereq *req; |
||||
|
char str[65]; printf("%s unconfirmed.%s\n",addr->ipaddr,bits256_str(str,tx->txid)); |
||||
|
req = iguana_bundlereq(coin,addr,'U',datalen); |
||||
|
req->datalen = datalen; |
||||
|
req->txid = tx->txid; |
||||
|
memcpy(req->serialized,data,datalen); |
||||
|
queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); |
||||
|
} |
||||
|
|
||||
|
void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) |
||||
|
{ |
||||
|
struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t i,j,copyflag; char fname[1024]; |
||||
|
if ( 0 ) |
||||
|
{ |
||||
|
for (i=0; i<txdata->space[0]; i++) |
||||
|
if ( txdata->space[i] != 0 ) |
||||
|
break; |
||||
|
if ( i != txdata->space[0] ) |
||||
|
{ |
||||
|
for (i=0; i<txdata->space[0]; i++) |
||||
|
printf("%02x ",txdata->space[i]); |
||||
|
printf("extra\n"); |
||||
|
} |
||||
|
} |
||||
|
if ( coin->numreqtxids > 0 ) |
||||
|
{ |
||||
|
for (i=0; i<origtxdata->block.RO.txn_count; i++) |
||||
|
{ |
||||
|
for (j=0; j<coin->numreqtxids; j++) |
||||
|
{ |
||||
|
if ( memcmp(coin->reqtxids[j].bytes,txarray[i].txid.bytes,sizeof(bits256)) == 0 ) |
||||
|
{ |
||||
|
char str[65]; printf("i.%d j.%d found txid.%s\n",i,j,bits256_str(str,coin->reqtxids[j])); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
copyflag = 1 * (strcmp(coin->symbol,"BTC") != 0); |
||||
|
req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); |
||||
|
req->recvlen = recvlen; |
||||
|
if ( copyflag != 0 && recvlen != 0 ) |
||||
|
{ |
||||
|
//printf("copy %p serialized[%d]\n",req->serialized,req->recvlen);
|
||||
|
req->H = *H; |
||||
|
memcpy(req->serialized,data,recvlen), req->copyflag = 1; |
||||
|
} |
||||
|
txdata = origtxdata; |
||||
|
if ( addr != 0 ) |
||||
|
{ |
||||
|
if ( addr->pendblocks > 0 ) |
||||
|
addr->pendblocks--; |
||||
|
addr->lastblockrecv = (uint32_t)time(NULL); |
||||
|
addr->recvblocks += 1.; |
||||
|
addr->recvtotal += recvlen; |
||||
|
if ( iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->block.RO.txn_count,data,recvlen) >= 0 ) |
||||
|
{ |
||||
|
txdata->block.fpipbits = addr->ipbits; |
||||
|
req->datalen = txdata->datalen; |
||||
|
req->ipbits = txdata->block.fpipbits; |
||||
|
if ( 0 ) |
||||
|
{ |
||||
|
struct iguana_txblock *checktxdata; struct OS_memspace checkmem; int32_t checkbundlei; |
||||
|
memset(&checkmem,0,sizeof(checkmem)); |
||||
|
iguana_meminit(&checkmem,"checkmem",0,txdata->datalen + 4096,0); |
||||
|
if ( (checktxdata= iguana_peertxdata(coin,&checkbundlei,fname,&checkmem,addr->ipbits,txdata->block.RO.hash2)) != 0 ) |
||||
|
{ |
||||
|
printf("check datalen.%d bundlei.%d T.%d U.%d S.%d P.%d X.%d\n",checktxdata->datalen,checkbundlei,checktxdata->numtxids,checktxdata->numunspents,checktxdata->numspends,checktxdata->numpkinds,checktxdata->numexternaltxids); |
||||
|
} |
||||
|
iguana_mempurge(&checkmem); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
//printf("recvlen.%d\n",req->recvlen);
|
||||
|
req->block = txdata->block; |
||||
|
req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; |
||||
|
coin->recvcount++; |
||||
|
coin->recvtime = (uint32_t)time(NULL); |
||||
|
req->addr = addr; |
||||
|
queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); |
||||
|
} |
||||
|
|
||||
|
void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n) |
||||
|
{ |
||||
|
struct iguana_bundlereq *req; |
||||
|
printf("got %d txids from %s\n",n,addr->ipaddr); |
||||
|
req = iguana_bundlereq(coin,addr,'T',0); |
||||
|
req->hashes = txids, req->n = n; |
||||
|
queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); |
||||
|
} |
||||
|
|
||||
|
void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) |
||||
|
{ |
||||
|
struct iguana_bundlereq *req; |
||||
|
if ( addr != 0 ) |
||||
|
{ |
||||
|
addr->recvhdrs++; |
||||
|
if ( addr->pendhdrs > 0 ) |
||||
|
addr->pendhdrs--; |
||||
|
//printf("%s blocks[%d] ht.%d gotheaders pend.%d %.0f\n",addr->ipaddr,n,blocks[0].height,addr->pendhdrs,milliseconds());
|
||||
|
} |
||||
|
req = iguana_bundlereq(coin,addr,'H',0); |
||||
|
req->blocks = blocks, req->n = n; |
||||
|
queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); |
||||
|
} |
||||
|
|
||||
|
void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n) |
||||
|
{ |
||||
|
struct iguana_bundlereq *req; |
||||
|
if ( addr != 0 ) |
||||
|
{ |
||||
|
addr->recvhdrs++; |
||||
|
if ( addr->pendhdrs > 0 ) |
||||
|
addr->pendhdrs--; |
||||
|
} |
||||
|
req = iguana_bundlereq(coin,addr,'S',0); |
||||
|
req->hashes = blockhashes, req->n = n; |
||||
|
//printf("bundlesQ blockhashes.%p[%d]\n",blockhashes,n);
|
||||
|
queue_enqueue("bundlesQ",&coin->bundlesQ,&req->DL,0); |
||||
|
} |
||||
|
|
||||
|
void iguana_patch(struct iguana_info *coin,struct iguana_block *block) |
||||
|
{ |
||||
|
int32_t i,j,origheight,height; struct iguana_block *prev,*next; struct iguana_bundle *bp; |
||||
|
prev = iguana_blockhashset(coin,-1,block->RO.prev_block,1); |
||||
|
block->hh.prev = prev; |
||||
|
if ( prev != 0 ) |
||||
|
{ |
||||
|
if ( prev->mainchain != 0 ) |
||||
|
{ |
||||
|
prev->hh.next = block; |
||||
|
if ( memcmp(block->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) |
||||
|
{ |
||||
|
_iguana_chainlink(coin,block); |
||||
|
//printf("link block %d\n",block->height);
|
||||
|
} |
||||
|
if ( (next= block->hh.next) != 0 && bits256_nonz(next->RO.hash2) > 0 ) |
||||
|
{ |
||||
|
next->height = block->height + 1; |
||||
|
//printf("autoreq %d\n",next->height);
|
||||
|
if ( 0 && strcmp(coin->symbol,"BTC") != 0 ) |
||||
|
iguana_blockQ(coin,coin->bundles[(block->height+1)/coin->chain->bundlesize],(block->height+1)%coin->chain->bundlesize,next->RO.hash2,0); |
||||
|
} |
||||
|
} |
||||
|
else if ( block->height < 0 ) |
||||
|
{ |
||||
|
for (i=0; i<1; i++) |
||||
|
{ |
||||
|
if ( (prev= prev->hh.prev) == 0 ) |
||||
|
break; |
||||
|
if ( prev->mainchain != 0 && prev->height >= 0 ) |
||||
|
{ |
||||
|
j = i; |
||||
|
origheight = (prev->height + i + 2); |
||||
|
prev = block->hh.prev; |
||||
|
height = (origheight - 1); |
||||
|
while ( i > 0 && prev != 0 ) |
||||
|
{ |
||||
|
if ( prev->mainchain != 0 && prev->height != height ) |
||||
|
{ |
||||
|
printf("mainchain height mismatch j.%d at i.%d %d != %d\n",j,i,prev->height,height); |
||||
|
break; |
||||
|
} |
||||
|
prev = prev->hh.prev; |
||||
|
height--; |
||||
|
} |
||||
|
if ( i == 0 ) |
||||
|
{ |
||||
|
//printf("SET HEIGHT.%d j.%d\n",origheight,j);
|
||||
|
if ( (bp= coin->bundles[origheight / coin->chain->bundlesize]) != 0 ) |
||||
|
{ |
||||
|
iguana_bundlehash2add(coin,0,bp,origheight % coin->chain->bundlesize,block->RO.hash2); |
||||
|
block->height = origheight; |
||||
|
block->mainchain = 1; |
||||
|
prev = block->hh.prev; |
||||
|
prev->hh.next = block; |
||||
|
} |
||||
|
} //else printf("break at i.%d for j.%d origheight.%d\n",i,j,origheight);
|
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_allhashcmp(struct iguana_info *coin,struct iguana_bundle *bp,bits256 *blockhashes,int32_t num) |
||||
|
{ |
||||
|
bits256 allhash; int32_t err,i,n; struct iguana_block *block; |
||||
|
if ( bits256_nonz(bp->allhash) > 0 && num >= coin->chain->bundlesize ) |
||||
|
{ |
||||
|
for (i=0; i<bp->n; i++) |
||||
|
if ( bits256_nonz(blockhashes[i]) == 0 ) |
||||
|
blockhashes[i] = bp->hashes[i]; |
||||
|
vcalc_sha256(0,allhash.bytes,blockhashes[0].bytes,coin->chain->bundlesize * sizeof(*blockhashes)); |
||||
|
if ( memcmp(allhash.bytes,bp->allhash.bytes,sizeof(allhash)) == 0 ) |
||||
|
{ |
||||
|
for (i=n=0; i<coin->chain->bundlesize&&i<bp->n; i++) |
||||
|
{ |
||||
|
if ( (err= iguana_bundlehash2add(coin,0,bp,i,blockhashes[i])) < 0 ) |
||||
|
return(err); |
||||
|
if ( bp->emitfinish == 0 && (block= bp->blocks[i]) != 0 && (block->queued == 0 && block->fpipbits == 0) && block->numrequests < 3 ) |
||||
|
iguana_blockQ(coin,bp,i,block->RO.hash2,0), n++; |
||||
|
} |
||||
|
//printf("ALLHASHES FOUND! %d requested.%d\n",bp->bundleheight,n);
|
||||
|
return(i); |
||||
|
} |
||||
|
} |
||||
|
return(-1); |
||||
|
} |
||||
|
|
||||
|
// main context, ie single threaded
|
||||
|
struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) |
||||
|
{ |
||||
|
struct iguana_block *block; bits256 zero; struct iguana_bundle *bp = 0; |
||||
|
int32_t bundlei = -2; |
||||
|
*bundleip = -2; *blockp = 0; |
||||
|
if ( origblock == 0 ) |
||||
|
return(0); |
||||
|
memset(zero.bytes,0,sizeof(zero)); |
||||
|
if ( (block= iguana_blockhashset(coin,-1,origblock->RO.hash2,1)) != 0 ) |
||||
|
{ |
||||
|
if ( block != origblock ) |
||||
|
iguana_blockcopy(coin,block,origblock); |
||||
|
*blockp = block; |
||||
|
//if ( bits256_nonz(block->RO.prev_block) > 0 )
|
||||
|
// iguana_patch(coin,block);
|
||||
|
if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,block->RO.hash2)) != 0 ) |
||||
|
{ |
||||
|
if ( bundlei < coin->chain->bundlesize ) |
||||
|
{ |
||||
|
block->bundlei = bundlei; |
||||
|
block->hdrsi = bp->hdrsi; |
||||
|
//iguana_hash2set(coin,"blockadd",bp,block->bundlei,block->hash2);
|
||||
|
iguana_bundlehash2add(coin,0,bp,bundlei,block->RO.hash2); |
||||
|
if ( bundlei > 0 ) |
||||
|
{ |
||||
|
//char str[65],str2[65]; printf("call hash2add %d:[%d -1] %s prev.%s\n",bp->hdrsi,bundlei,bits256_str(str2,block->RO.hash2),bits256_str(str,block->RO.prev_block));
|
||||
|
iguana_bundlehash2add(coin,0,bp,bundlei-1,block->RO.prev_block); |
||||
|
} |
||||
|
else if ( bp->hdrsi > 0 && (bp= coin->bundles[bp->hdrsi-1]) != 0 ) |
||||
|
iguana_bundlehash2add(coin,0,bp,coin->chain->bundlesize-1,block->RO.prev_block); |
||||
|
} |
||||
|
} |
||||
|
if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,block->RO.prev_block)) != 0 ) |
||||
|
{ |
||||
|
//printf("found prev.%d\n",bp->bundleheight+bundlei);
|
||||
|
if ( bundlei < coin->chain->bundlesize ) |
||||
|
{ |
||||
|
if ( bundlei == coin->chain->bundlesize-1 ) |
||||
|
{ |
||||
|
//if ( coin->bundlescount < bp->hdrsi+1 )
|
||||
|
{ |
||||
|
//char str[65]; printf("autoextend CREATE.%d new bundle.%s\n",bp->bundleheight + coin->chain->bundlesize,bits256_str(str,block->RO.hash2));
|
||||
|
iguana_bundlecreate(coin,&bundlei,bp->bundleheight + coin->chain->bundlesize,block->RO.hash2,zero,1); |
||||
|
} |
||||
|
} |
||||
|
else if ( bundlei < coin->chain->bundlesize-1 ) |
||||
|
iguana_bundlehash2add(coin,0,bp,bundlei+1,block->RO.hash2); |
||||
|
} |
||||
|
} |
||||
|
//char str[65]; printf("iguana_recvblock (%s) %d %d[%d] %p\n",bits256_str(str,block->hash2),block->havebundle,block->hdrsi,bundlei,bp);
|
||||
|
} else printf("iguana_bundleset: error adding blockhash\n"); |
||||
|
return(iguana_bundlefind(coin,&bp,bundleip,origblock->RO.hash2)); |
||||
|
} |
||||
|
|
||||
|
struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) |
||||
|
{ |
||||
|
int32_t i,bundlei; struct iguana_block *block; struct iguana_bundle *bp; |
||||
|
if ( blocks == 0 ) |
||||
|
{ |
||||
|
printf("iguana_recvblockhdrs null blocks?\n"); |
||||
|
return(req); |
||||
|
} |
||||
|
if ( blocks != 0 && n > 0 ) |
||||
|
{ |
||||
|
for (i=0; i<n; i++) |
||||
|
{ |
||||
|
//fprintf(stderr,"i.%d of %d bundleset\n",i,n);
|
||||
|
if ( (bp= iguana_bundleset(coin,&block,&bundlei,&blocks[i])) != 0 && bp->hdrsi < IGUANA_MAXACTIVEBUNDLES ) |
||||
|
{ |
||||
|
//if ( 0 && i < bp->n && bp->requests[i] == 0 )
|
||||
|
// iguana_blockQ(coin,bp,bundlei,blocks[i].RO.hash2,0);
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return(req); |
||||
|
} |
||||
|
|
||||
|
struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) |
||||
|
{ |
||||
|
int32_t bundlei,i,n = 0; struct iguana_block *block; struct iguana_bundle *bp;// char str[65];
|
||||
|
bp = 0, bundlei = -2, iguana_bundlefind(coin,&bp,&bundlei,blockhashes[1]); |
||||
|
if ( bp != 0 ) |
||||
|
{ |
||||
|
blockhashes[0] = bp->hashes[0]; |
||||
|
if ( num >= coin->chain->bundlesize ) |
||||
|
{ |
||||
|
bp->hdrtime = (uint32_t)time(NULL); |
||||
|
if ( iguana_allhashcmp(coin,bp,blockhashes,num) == 0 ) |
||||
|
return(req); |
||||
|
} |
||||
|
for (i=0; i<num; i++) |
||||
|
{ |
||||
|
if ( bits256_nonz(blockhashes[i]) > 0 && (block= iguana_blockhashset(coin,-1,blockhashes[i],1)) != 0 ) |
||||
|
{ |
||||
|
if ( block->hdrsi == bp->hdrsi && block->bundlei == i ) |
||||
|
n++; |
||||
|
} |
||||
|
} |
||||
|
//printf("got [%d] num.%d matched hashes\n",n,num);
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
//char str[65]; printf("blockhashes[%d] %s\n",num,bits256_str(str,blockhashes[1]));
|
||||
|
iguana_blockQ(coin,0,-1,blockhashes[1],1); |
||||
|
} |
||||
|
//iguana_blockQ(coin,0,-1,blockhashes[num-1],1);
|
||||
|
/*if ( (block= iguana_blockhashset(coin,-1,blockhashes[1],1)) != 0 && num > 2 )
|
||||
|
{ |
||||
|
if ( block->rawdata != 0 ) |
||||
|
{ |
||||
|
if ( block->copyflag != 0 ) |
||||
|
myfree(block->rawdata,block->RO.recvlen), block->copyflag = 0; |
||||
|
else myfree(block->rawdata,block->numhashes * sizeof(bits256)); |
||||
|
} |
||||
|
//char str[65]; printf("got %d unmatched hashes %d:%d %s\n",num,bp==0?-1:bp->bundleheight,bundlei,bits256_str(str,blockhashes[1]));
|
||||
|
block->rawdata = blockhashes, block->numhashes = num, block->havehashes = 1; |
||||
|
req->hashes = 0; |
||||
|
} |
||||
|
if ( 0 && num >= coin->chain->bundlesize+1 ) |
||||
|
{ |
||||
|
char str[65]; bits256_str(str,blockhashes[coin->chain->bundlesize]); |
||||
|
queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(str),1); |
||||
|
}*/ |
||||
|
return(req); |
||||
|
} |
||||
|
|
||||
|
struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundlereq *req,struct iguana_block *origblock,int32_t numtx,int32_t datalen,int32_t recvlen,int32_t *newhwmp) |
||||
|
{ |
||||
|
struct iguana_bundle *prevbp=0,*bp=0; int32_t prevbundlei=-2,bundlei = -2; struct iguana_block *prevblock,*block; |
||||
|
bp = iguana_bundleset(coin,&block,&bundlei,origblock); |
||||
|
//char str[65]; printf("RECV %s [%d:%d] block.%p\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block);
|
||||
|
iguana_bundlefind(coin,&prevbp,&prevbundlei,origblock->RO.prev_block); |
||||
|
if ( prevbp != 0 && prevbundlei >= 0 && prevbp->blocks[prevbundlei] == 0 && (prevblock= iguana_blockfind(coin,origblock->RO.prev_block)) != 0 ) |
||||
|
{ |
||||
|
prevbp->blocks[prevbundlei] = prevblock; |
||||
|
//printf("PREV %s prevbp.%p[%d]\n",bits256_str(str,origblock->RO.prev_block),prevbp,prevbundlei);
|
||||
|
} |
||||
|
if ( block != 0 ) |
||||
|
{ |
||||
|
if ( bp != 0 && bundlei >= 0 ) |
||||
|
bp->blocks[bundlei] = block; |
||||
|
block->RO.recvlen = recvlen; |
||||
|
if ( req->copyflag != 0 && block->queued == 0 )//block->rawdata == 0 )
|
||||
|
{ |
||||
|
//char str[65]; printf("%s copyflag.%d %d data %d %d\n",bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen);
|
||||
|
//block->rawdata = mycalloc('n',1,block->RO.recvlen);
|
||||
|
//memcpy(block->rawdata,req->serialized,block->RO.recvlen);
|
||||
|
//block->copyflag = 1;
|
||||
|
coin->numcached++; |
||||
|
block->queued = 1; |
||||
|
queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); |
||||
|
return(0); |
||||
|
} |
||||
|
//printf("datalen.%d ipbits.%x\n",datalen,req->ipbits);
|
||||
|
} else printf("cant create block.%llx block.%p bp.%p bundlei.%d\n",(long long)origblock->RO.hash2.txid,block,bp,bundlei); |
||||
|
return(req); |
||||
|
} |
||||
|
|
||||
|
struct iguana_bundlereq *iguana_recvtxids(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *txids,int32_t n) |
||||
|
{ |
||||
|
return(req); |
||||
|
} |
||||
|
|
||||
|
struct iguana_bundlereq *iguana_recvunconfirmed(struct iguana_info *coin,struct iguana_bundlereq *req,uint8_t *data,int32_t datalen) |
||||
|
{ |
||||
|
int32_t i; |
||||
|
for (i=0; i<coin->numreqtxids; i++) |
||||
|
{ |
||||
|
if ( memcmp(req->txid.bytes,coin->reqtxids[i].bytes,sizeof(req->txid)) == 0 ) |
||||
|
{ |
||||
|
char str[65]; printf("got reqtxid.%s datalen.%d | numreqs.%d\n",bits256_str(str,req->txid),req->datalen,coin->numreqtxids); |
||||
|
coin->reqtxids[i] = coin->reqtxids[--coin->numreqtxids]; |
||||
|
} |
||||
|
} |
||||
|
return(req); |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded
|
||||
|
{ |
||||
|
int32_t flag = 0; struct iguana_bundlereq *req; |
||||
|
*newhwmp = 0; |
||||
|
while ( flag < IGUANA_BUNDLELOOP && (req= queue_dequeue(&coin->bundlesQ,0)) != 0 ) |
||||
|
{ |
||||
|
//printf("%s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n);
|
||||
|
if ( req->type == 'B' ) // one block with all txdata
|
||||
|
req = iguana_recvblock(coin,req->addr,req,&req->block,req->numtx,req->datalen,req->recvlen,newhwmp); |
||||
|
else if ( req->type == 'H' ) // blockhdrs (doesnt have txn_count!)
|
||||
|
{ |
||||
|
if ( (req= iguana_recvblockhdrs(coin,req,req->blocks,req->n,newhwmp)) != 0 ) |
||||
|
{ |
||||
|
if ( req->blocks != 0 ) |
||||
|
myfree(req->blocks,sizeof(*req->blocks) * req->n), req->blocks = 0; |
||||
|
} |
||||
|
} |
||||
|
else if ( req->type == 'S' ) // blockhashes
|
||||
|
{ |
||||
|
if ( (req= iguana_recvblockhashes(coin,req,req->hashes,req->n)) != 0 && req->hashes != 0 ) |
||||
|
myfree(req->hashes,sizeof(*req->hashes) * req->n), req->hashes = 0; |
||||
|
} |
||||
|
else if ( req->type == 'U' ) // unconfirmed tx
|
||||
|
req = iguana_recvunconfirmed(coin,req,req->serialized,req->datalen); |
||||
|
else if ( req->type == 'T' ) // txids from inv
|
||||
|
{ |
||||
|
if ( (req= iguana_recvtxids(coin,req,req->hashes,req->n)) != 0 ) |
||||
|
myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; |
||||
|
} |
||||
|
else printf("iguana_updatebundles unknown type.%c\n",req->type); |
||||
|
flag++; |
||||
|
//printf("done %s bundlesQ.%p type.%c n.%d\n",req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n);
|
||||
|
if ( req != 0 ) |
||||
|
myfree(req,req->allocsize), req = 0; |
||||
|
} |
||||
|
return(flag); |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_needhdrs(struct iguana_info *coin) |
||||
|
{ |
||||
|
if ( coin->longestchain == 0 || coin->blocks.hashblocks < coin->longestchain-coin->chain->bundlesize ) |
||||
|
return(1); |
||||
|
else return(0); |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_reqhdrs(struct iguana_info *coin) |
||||
|
{ |
||||
|
int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65]; |
||||
|
if ( iguana_needhdrs(coin) > 0 && queue_size(&coin->hdrsQ) == 0 ) |
||||
|
{ |
||||
|
if ( coin->zcount++ > 1 ) |
||||
|
{ |
||||
|
for (i=0; i<coin->bundlescount; i++) |
||||
|
{ |
||||
|
if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish < coin->startutc ) |
||||
|
{ |
||||
|
if ( i == coin->bundlescount-1 ) |
||||
|
lag = 5; |
||||
|
else lag = 30 + (rand() % 30); |
||||
|
if ( i < coin->bundlescount-1 && (bp->numhashes >= (rand() % bp->n) || time(NULL) < bp->hdrtime+lag) ) |
||||
|
continue; |
||||
|
if ( bp->numhashes < bp->n && bp->bundleheight+bp->numhashes < coin->longestchain && time(NULL) > bp->issuetime+lag ) |
||||
|
{ |
||||
|
//printf("LAG.%ld hdrsi.%d numhashes.%d:%d needhdrs.%d qsize.%d zcount.%d\n",time(NULL)-bp->hdrtime,i,bp->numhashes,bp->n,iguana_needhdrs(coin),queue_size(&coin->hdrsQ),coin->zcount);
|
||||
|
if ( bp->issuetime == 0 ) |
||||
|
coin->numpendings++; |
||||
|
char str[65]; |
||||
|
bits256_str(str,bp->hashes[0]); |
||||
|
//printf("(%s %d).%d ",str,bp->bundleheight,i);
|
||||
|
//printf("%d ",bp->bundleheight);
|
||||
|
init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); |
||||
|
queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); |
||||
|
/*if ( strcmp(coin->symbol,"BTC") != 0 && bits256_nonz(bp->hashes[1]) > 0 )
|
||||
|
{ |
||||
|
if ( (block= iguana_blockfind(coin,bp->hashes[1])) != 0 ) |
||||
|
{ |
||||
|
if ( block->havehashes != 0 && block->rawdata != 0 ) |
||||
|
iguana_allhashcmp(coin,bp,block->rawdata,block->numhashes); |
||||
|
//iguana_blockQ(coin,bp,1,bp->hashes[1],1);
|
||||
|
} |
||||
|
}*/ |
||||
|
n++; |
||||
|
bp->hdrtime = bp->issuetime = (uint32_t)time(NULL); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if ( n > 0 ) |
||||
|
printf("REQ HDRS pending.%d\n",n); |
||||
|
coin->zcount = 0; |
||||
|
} |
||||
|
} else coin->zcount = 0; |
||||
|
return(n); |
||||
|
} |
||||
|
|
||||
|
struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; }; |
||||
|
|
||||
|
int32_t iguana_blockQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority) |
||||
|
{ |
||||
|
queue_t *Q; char *str; struct iguana_blockreq *req; struct iguana_block *block = 0; |
||||
|
if ( bits256_nonz(hash2) == 0 ) |
||||
|
{ |
||||
|
printf("cant queue zerohash bundlei.%d\n",bundlei); |
||||
|
return(-1); |
||||
|
} |
||||
|
if ( (bp != 0 && (block= iguana_blockfind(coin,bp->hashes[bundlei])) == 0) || priority != 0 || bp == 0 ) |
||||
|
{ |
||||
|
if ( block != 0 ) |
||||
|
{ |
||||
|
if ( block->fpipbits != 0 || block->queued != 0 ) |
||||
|
return(0); |
||||
|
/*if ( block->rawdata != 0 && block->RO.recvlen != 0 )
|
||||
|
{ |
||||
|
printf("free cached copy recvlen.%d need to process it here\n",block->RO.recvlen); |
||||
|
myfree(block->rawdata,block->RO.recvlen); |
||||
|
block->rawdata = 0; |
||||
|
block->RO.recvlen = 0; |
||||
|
}*/ |
||||
|
} |
||||
|
if ( priority != 0 ) |
||||
|
str = "priorityQ", Q = &coin->priorityQ; |
||||
|
else str = "blocksQ", Q = &coin->blocksQ; |
||||
|
if ( Q != 0 ) |
||||
|
{ |
||||
|
req = mycalloc('r',1,sizeof(*req)); |
||||
|
req->hash2 = hash2; |
||||
|
req->bp = bp; |
||||
|
req->bundlei = bundlei; |
||||
|
if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) |
||||
|
{ |
||||
|
//bp->issued[bundlei] = (uint32_t)time(NULL);
|
||||
|
if ( bp->bundleheight >= 0 ) |
||||
|
req->height = (bp->bundleheight + bundlei); |
||||
|
} |
||||
|
char str[65]; |
||||
|
bits256_str(str,hash2); |
||||
|
if ( 0 && (bundlei % 250) == 0 ) |
||||
|
printf("%s %d %s recv.%d numranked.%d qsize.%d\n",str,req->height,str,coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); |
||||
|
queue_enqueue(str,Q,&req->DL,0); |
||||
|
return(1); |
||||
|
} else printf("null Q\n"); |
||||
|
} //else printf("queueblock skip priority.%d bundlei.%d\n",bundlei,priority);
|
||||
|
return(0); |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) |
||||
|
{ |
||||
|
uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; |
||||
|
char *hashstr=0; bits256 hash2; uint32_t now; struct iguana_block *block; struct iguana_blockreq *req=0; |
||||
|
int32_t i,r,diff,j,k,n,m; double metric,bestmetric = -1.; struct iguana_bundle *bp,*bestbp = 0; |
||||
|
int32_t limit,refbundlei,height=-1,incr,datalen,flag = 0; double val; |
||||
|
now = (uint32_t)time(NULL); |
||||
|
if ( iguana_needhdrs(coin) != 0 && addr->pendhdrs < IGUANA_MAXPENDHDRS ) |
||||
|
{ |
||||
|
//printf("%s check hdrsQ\n",addr->ipaddr);
|
||||
|
if ( (hashstr= queue_dequeue(&coin->hdrsQ,1)) != 0 ) |
||||
|
{ |
||||
|
if ( (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,hashstr)) > 0 ) |
||||
|
{ |
||||
|
decode_hex(hash2.bytes,sizeof(hash2),hashstr); |
||||
|
if ( bits256_nonz(hash2) > 0 ) |
||||
|
{ |
||||
|
//printf("%s request hdr.(%s)\n",addr!=0?addr->ipaddr:"local",hashstr);
|
||||
|
iguana_send(coin,addr,serialized,datalen); |
||||
|
addr->pendhdrs++; |
||||
|
flag++; |
||||
|
} |
||||
|
free_queueitem(hashstr); |
||||
|
return(flag); |
||||
|
} else printf("datalen.%d from gethdrs\n",datalen); |
||||
|
free_queueitem(hashstr); |
||||
|
hashstr = 0; |
||||
|
} |
||||
|
} |
||||
|
if ( (limit= addr->recvblocks) > coin->MAXPENDING ) |
||||
|
limit = coin->MAXPENDING; |
||||
|
if ( limit < 1 ) |
||||
|
limit = 1; |
||||
|
//if ( addr->pendblocks >= limit )
|
||||
|
// printf("%s %d overlimit.%d\n",addr->ipaddr,addr->pendblocks,limit);
|
||||
|
if ( coin->bundlescount > 0 && (req= queue_dequeue(&coin->priorityQ,0)) == 0 && addr->pendblocks < limit )//&& now > addr->lastpoll )
|
||||
|
{ |
||||
|
if ( 1 )//strcmp("BTC",coin->symbol) != 0 )
|
||||
|
{ |
||||
|
int32_t bundlei; |
||||
|
incr = coin->peers.numranked == 0 ? coin->MAXPEERS : coin->peers.numranked; |
||||
|
if ( (rand() % 100) < 50 ) |
||||
|
height = addr->rank * _IGUANA_MAXPENDING; |
||||
|
else if ( (rand() % 100) < 50 ) |
||||
|
height = addr->addrind + (addr->rank * (coin->longestchain - coin->blocks.hwmchain.height) / (coin->peers.numranked+1)); |
||||
|
else if ( (rand() % 100) < 50 ) |
||||
|
{ |
||||
|
height = (addr->lastheight + 1); |
||||
|
if ( height >= coin->longestchain-coin->chain->bundlesize ) |
||||
|
height = addr->rank*incr*_IGUANA_MAXPENDING; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
height = coin->longestchain - (rand() % incr) * 1000; |
||||
|
if ( height < 0 ) |
||||
|
height = coin->blocks.hwmchain.height; |
||||
|
} |
||||
|
for (; height<coin->bundlescount*coin->chain->bundlesize; height+=incr) |
||||
|
{ |
||||
|
if ( height > coin->longestchain ) |
||||
|
height = addr->rank*incr*_IGUANA_MAXPENDING; |
||||
|
if ( height > addr->lastheight ) |
||||
|
addr->lastheight = height; |
||||
|
if ( (bp= coin->bundles[height/coin->chain->bundlesize]) != 0 && bp->emitfinish == 0 ) |
||||
|
{ |
||||
|
bundlei = (height % coin->chain->bundlesize); |
||||
|
if ( bundlei < bp->n && bits256_nonz(bp->hashes[bundlei]) > 0 && (block= bp->blocks[bundlei]) != 0 && block->numrequests <= bp->minrequests && block->fpipbits == 0 )//&& block->queued == 0 )//(bp->issued[bundlei] == 0 || now > bp->issued[bundlei]+10) )
|
||||
|
{ |
||||
|
if ( block->numrequests < 100 ) |
||||
|
block->numrequests++; |
||||
|
//block->issued = (uint32_t)time(NULL);;
|
||||
|
if ( 0 && (rand() % 100) == 0 ) |
||||
|
printf("%s Send auto blockreq.%d [%d] minreq.%d\n",addr->ipaddr,bp->bundleheight+bundlei,block->numrequests,bp->minrequests); |
||||
|
iguana_sendblockreq(coin,addr,bp,bundlei,bp->hashes[bundlei],0); |
||||
|
return(1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
//printf("%s lastpoll.%u %u\n",addr->ipaddr,addr->lastpoll,now);
|
||||
|
addr->lastpoll = now; |
||||
|
for (i=n=0; i<coin->bundlescount; i++) |
||||
|
if ( coin->bundles[i] != 0 && coin->bundles[i]->emitfinish == 0 ) |
||||
|
n++; |
||||
|
if ( n >= coin->bundlescount-(coin->bundlescount>>3) || (addr->ipbits % 10) < 5 ) |
||||
|
refbundlei = (addr->ipbits % coin->bundlescount); |
||||
|
else |
||||
|
{ |
||||
|
if ( n*2 < coin->bundlescount ) |
||||
|
{ |
||||
|
for (i=refbundlei=0; i<IGUANA_MAXPEERS; i++) |
||||
|
{ |
||||
|
if ( addr->usock == coin->peers.active[i].usock ) |
||||
|
break; |
||||
|
if ( coin->peers.active[i].usock >= 0 ) |
||||
|
refbundlei++; |
||||
|
} |
||||
|
//printf("half done\n");
|
||||
|
} else refbundlei = ((addr->addrind*100) % coin->bundlescount); |
||||
|
} |
||||
|
for (i=0; i<coin->bundlescount; i++) |
||||
|
{ |
||||
|
if ( (diff= (i - refbundlei)) < 0 ) |
||||
|
diff = -diff; |
||||
|
if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 ) |
||||
|
{ |
||||
|
metric = (1 + diff * ((addr->addrind&1) == 0 ? 1 : 1) * (1. + bp->metric));// / (i*((addr->addrind&1) != 0 ? 1 : i) + 1);
|
||||
|
//printf("%f ",bp->metric);
|
||||
|
if ( bestmetric < 0. || metric < bestmetric ) |
||||
|
bestmetric = metric, bestbp = bp; |
||||
|
} |
||||
|
} |
||||
|
if ( bestbp != 0 && bp->emitfinish == 0 ) |
||||
|
{ |
||||
|
for (k=0; k<coin->bundlescount; k++) |
||||
|
{ |
||||
|
i = (bestbp->hdrsi + k) % coin->bundlescount; |
||||
|
if ( (bp= coin->bundles[i]) == 0 || bp->emitfinish != 0 ) |
||||
|
continue; |
||||
|
printf("%.15f ref.%d addrind.%d bestbp.%d\n",bestmetric,refbundlei,addr->addrind,bp->hdrsi); |
||||
|
m = coin->chain->bundlesize; |
||||
|
if ( bp->n < m ) |
||||
|
m = bp->n; |
||||
|
j = (addr->addrind*3 + 0) % m; |
||||
|
val = (bp->threshold / 1000.); |
||||
|
for (r=0; r<m; r++,j++) |
||||
|
{ |
||||
|
if ( j >= m ) |
||||
|
j = 0; |
||||
|
if ( (block= bp->blocks[j]) != 0 && block->fpipbits == 0 && block->queued == 0 && block->numrequests <= bp->minrequests ) |
||||
|
{ |
||||
|
if ( block->numrequests < 100 ) |
||||
|
block->numrequests++; |
||||
|
//block->issued = (uint32_t)time(NULL);;
|
||||
|
printf("%s Send auto blockreq.%d\n",addr->ipaddr,bp->bundleheight+j); |
||||
|
iguana_sendblockreq(coin,addr,bp,j,hash2,0); |
||||
|
return(1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
int32_t priority; |
||||
|
if ( addr->rank != 1 && req == 0 ) |
||||
|
{ |
||||
|
priority = 0; |
||||
|
req = queue_dequeue(&coin->blocksQ,0); |
||||
|
} else priority = 1; |
||||
|
if ( req != 0 ) |
||||
|
{ |
||||
|
hash2 = req->hash2; |
||||
|
height = req->height; |
||||
|
block = 0; |
||||
|
if ( priority == 0 && (bp= req->bp) != 0 && req->bundlei >= 0 && req->bundlei < bp->n && req->bundlei < coin->chain->bundlesize && (block= bp->blocks[req->bundlei]) != 0 && (block->fpipbits != 0 || block->queued != 0) ) |
||||
|
{ |
||||
|
//if ( 0 && priority != 0 )
|
||||
|
printf("SKIP %p[%d] %d\n",bp,bp!=0?bp->bundleheight:-1,req->bundlei); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
char str[65]; |
||||
|
if ( 0 && priority != 0 ) |
||||
|
printf(" issue.%s\n",bits256_str(str,hash2)); |
||||
|
if ( block != 0 && block->numrequests < 100 ) |
||||
|
block->numrequests++; |
||||
|
iguana_sendblockreq(coin,addr,req->bp,req->bundlei,hash2,0); |
||||
|
} |
||||
|
flag++; |
||||
|
myfree(req,sizeof(*req)); |
||||
|
} |
||||
|
return(flag); |
||||
|
} |
||||
|
|
||||
|
int32_t iguana_processrecv(struct iguana_info *coin) // single threaded
|
||||
|
{ |
||||
|
int32_t newhwm = 0,h,lflag,bundlei,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; |
||||
|
//printf("process bundlesQ\n");
|
||||
|
flag += iguana_processbundlesQ(coin,&newhwm); |
||||
|
flag += iguana_reqhdrs(coin); |
||||
|
lflag = 1; |
||||
|
while ( lflag != 0 ) |
||||
|
{ |
||||
|
lflag = 0; |
||||
|
h = coin->blocks.hwmchain.height / coin->chain->bundlesize; |
||||
|
if ( (next= iguana_blockfind(coin,iguana_blockhash(coin,coin->blocks.hwmchain.height+1))) == 0 ) |
||||
|
{ |
||||
|
if ( (block= iguana_blockfind(coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) |
||||
|
next = block->hh.next, block->mainchain = 1; |
||||
|
} |
||||
|
if ( next != 0 ) |
||||
|
{ |
||||
|
//printf("have next\n");
|
||||
|
if ( memcmp(next->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) |
||||
|
{ |
||||
|
if ( _iguana_chainlink(coin,next) != 0 ) |
||||
|
lflag++; |
||||
|
//else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1);
|
||||
|
} |
||||
|
else if ( 1 ) |
||||
|
{ |
||||
|
double threshold,lag = OS_milliseconds() - coin->backstopmillis; |
||||
|
threshold = (10 + coin->longestchain - coin->blocksrecv); |
||||
|
if ( threshold < 1 ) |
||||
|
threshold = 1.; |
||||
|
if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) != 0 ) |
||||
|
threshold = (bp->avetime + coin->avetime) * .5; |
||||
|
else threshold = coin->avetime; |
||||
|
threshold *= 100. * sqrt(threshold) * .000777; |
||||
|
if ( strcmp(coin->symbol,"BTC") != 0 ) |
||||
|
threshold = 400; |
||||
|
else threshold = 1000; |
||||
|
if ( coin->blocks.hwmchain.height+1 < coin->longestchain && (coin->backstop != coin->blocks.hwmchain.height+1 || lag > threshold) ) |
||||
|
{ |
||||
|
coin->backstop = coin->blocks.hwmchain.height+1; |
||||
|
hash2 = iguana_blockhash(coin,coin->backstop); |
||||
|
if ( bits256_nonz(hash2) > 0 ) |
||||
|
{ |
||||
|
bp = coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]; |
||||
|
bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; |
||||
|
if ( bp != 0 ) |
||||
|
{ |
||||
|
coin->backstopmillis = OS_milliseconds(); |
||||
|
iguana_blockQ(coin,bp,bundlei,iguana_blockhash(coin,coin->backstop),1); |
||||
|
//iguana_blockrequest(coin,bp,bundlei,hash2,(uint32_t)time(NULL),1);
|
||||
|
/*if ( (bp= coin->bundles[(coin->blocks.hwmchain.height+1)/coin->chain->bundlesize]) == 0 || bp->fpos[bundlei] >= 0 )
|
||||
|
{ |
||||
|
if ( bp != 0 && coin->backstop == coin->blocks.hwmchain.height+1 ) |
||||
|
{ |
||||
|
iguana_bundleiclear(coin,bp,bundlei); |
||||
|
} |
||||
|
iguana_blockQ(coin,bp,bundlei,next->RO.hash2,1); |
||||
|
}*/ |
||||
|
if ( (rand() % 100) == 0 ) |
||||
|
printf("MAINCHAIN.%d threshold %.3f %.3f lag %.3f\n",coin->blocks.hwmchain.height+1,threshold,coin->backstopmillis,lag); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
else if ( 0 && bits256_nonz(next->RO.prev_block) > 0 ) |
||||
|
printf("next prev cmp error nonz.%d\n",bits256_nonz(next->RO.prev_block)); |
||||
|
} |
||||
|
} |
||||
|
if ( h != coin->blocks.hwmchain.height / coin->chain->bundlesize ) |
||||
|
iguana_savehdrs(coin); |
||||
|
} |
||||
|
return(flag); |
||||
|
} |
@ -1 +1,2 @@ |
|||||
echo do equivalent of: gcc -o ../agents/iguana -O2 *.c ../agents/libcrypto777.a -lssl -lcrypto -lpthread -lm |
make -f mingw32 |
||||
|
|
||||
|
@ -0,0 +1,14 @@ |
|||||
|
SOURCES := iguana_pubkeys.c iguana_recv.c iguana_bundles.c iguana_msg.c iguana_rpc.c iguana777.c iguana_chains.c iguana_peers.c iguana_accept.c iguana_html.c iguana_bitmap.c iguana_init.c iguana_ramchain.c iguana_blocks.c iguana_json.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/libgfshare.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c \ |
||||
|
../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c \ |
||||
|
../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c \ |
||||
|
../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c \ |
||||
|
../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c \ |
||||
|
../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c \ |
||||
|
../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c \ |
||||
|
../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/jmemmgr.c ../crypto777/jpeg/jmemnobs.c main.c |
||||
|
|
||||
|
|
||||
|
all: |
||||
|
$(TOOL_DIR)/$(MINGW)-gcc -o ../agents/iguana.exe -D __MINGW $(SOURCES) $(LIBS) |
||||
|
$(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/iguana.exe |
||||
|
|
@ -0,0 +1,9 @@ |
|||||
|
TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin |
||||
|
MINGW := i586-mingw32 |
||||
|
LIBS := ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2.a -lws2_32 -lgdi32 |
||||
|
|
||||
|
include mingw |
||||
|
|
||||
|
all: |
||||
|
$(TOOL_DIR)/$(MINGW)-gcc -o ../agents/iguana.exe -D __MINGW $(SOURCES) $(LIBS) |
||||
|
$(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/iguana.exe |
@ -0,0 +1,9 @@ |
|||||
|
TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw64/win64-gcc/bin |
||||
|
MINGW := i686-mingw64 |
||||
|
LIBS := ../win/libcrypto.a ../win/libs/libssl.a ../win/libpthreadGC2_64.a -lws2_64 -lgdi64 |
||||
|
|
||||
|
include mingw |
||||
|
|
||||
|
all: |
||||
|
$(TOOL_DIR)/$(MINGW)-gcc -o ../agents/iguana.exe -D __MINGW $(SOURCES) $(LIBS) |
||||
|
$(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/iguana.exe |
@ -0,0 +1,741 @@ |
|||||
|
/* e_os.h */ |
||||
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
|
* All rights reserved. |
||||
|
* |
||||
|
* This package is an SSL implementation written |
||||
|
* by Eric Young (eay@cryptsoft.com). |
||||
|
* The implementation was written so as to conform with Netscapes SSL. |
||||
|
* |
||||
|
* This library is free for commercial and non-commercial use as long as |
||||
|
* the following conditions are aheared to. The following conditions |
||||
|
* apply to all code found in this distribution, be it the RC4, RSA, |
||||
|
* lhash, DES, etc., code; not just the SSL code. The SSL documentation |
||||
|
* included with this distribution is covered by the same copyright terms |
||||
|
* except that the holder is Tim Hudson (tjh@cryptsoft.com). |
||||
|
* |
||||
|
* Copyright remains Eric Young's, and as such any Copyright notices in |
||||
|
* the code are not to be removed. |
||||
|
* If this package is used in a product, Eric Young should be given attribution |
||||
|
* as the author of the parts of the library used. |
||||
|
* This can be in the form of a textual message at program startup or |
||||
|
* in documentation (online or textual) provided with the package. |
||||
|
* |
||||
|
* Redistribution and use in source and binary forms, with or without |
||||
|
* modification, are permitted provided that the following conditions |
||||
|
* are met: |
||||
|
* 1. Redistributions of source code must retain the copyright |
||||
|
* notice, this list of conditions and the following disclaimer. |
||||
|
* 2. Redistributions in binary form must reproduce the above copyright |
||||
|
* notice, this list of conditions and the following disclaimer in the |
||||
|
* documentation and/or other materials provided with the distribution. |
||||
|
* 3. All advertising materials mentioning features or use of this software |
||||
|
* must display the following acknowledgement: |
||||
|
* "This product includes cryptographic software written by |
||||
|
* Eric Young (eay@cryptsoft.com)" |
||||
|
* The word 'cryptographic' can be left out if the rouines from the library |
||||
|
* being used are not cryptographic related :-). |
||||
|
* 4. If you include any Windows specific code (or a derivative thereof) from |
||||
|
* the apps directory (application code) you must include an acknowledgement: |
||||
|
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
||||
|
* |
||||
|
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
||||
|
* SUCH DAMAGE. |
||||
|
* |
||||
|
* The licence and distribution terms for any publically available version or |
||||
|
* derivative of this code cannot be changed. i.e. this code cannot simply be |
||||
|
* copied and put under another distribution licence |
||||
|
* [including the GNU Public Licence.] |
||||
|
*/ |
||||
|
|
||||
|
#ifndef HEADER_E_OS_H |
||||
|
#define HEADER_E_OS_H |
||||
|
|
||||
|
#include <openssl/opensslconf.h> |
||||
|
|
||||
|
#include <openssl/e_os2.h> |
||||
|
/* <openssl/e_os2.h> contains what we can justify to make visible
|
||||
|
* to the outside; this file e_os.h is not part of the exported |
||||
|
* interface. */ |
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
extern "C" { |
||||
|
#endif |
||||
|
|
||||
|
/* Used to checking reference counts, most while doing perl5 stuff :-) */ |
||||
|
#ifdef REF_PRINT |
||||
|
#undef REF_PRINT |
||||
|
#define REF_PRINT(a,b) fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a) |
||||
|
#endif |
||||
|
|
||||
|
#ifndef DEVRANDOM |
||||
|
/* set this to a comma-separated list of 'random' device files to try out.
|
||||
|
* My default, we will try to read at least one of these files */ |
||||
|
#define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom" |
||||
|
#endif |
||||
|
#ifndef DEVRANDOM_EGD |
||||
|
/* set this to a comma-seperated list of 'egd' sockets to try out. These
|
||||
|
* sockets will be tried in the order listed in case accessing the device files |
||||
|
* listed in DEVRANDOM did not return enough entropy. */ |
||||
|
#define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy" |
||||
|
#endif |
||||
|
|
||||
|
#if defined(OPENSSL_SYS_VXWORKS) |
||||
|
# define NO_SYS_PARAM_H |
||||
|
# define NO_CHMOD |
||||
|
# define NO_SYSLOG |
||||
|
#endif |
||||
|
|
||||
|
#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) |
||||
|
# if macintosh==1 |
||||
|
# ifndef MAC_OS_GUSI_SOURCE |
||||
|
# define MAC_OS_pre_X |
||||
|
# define NO_SYS_TYPES_H |
||||
|
# endif |
||||
|
# define NO_SYS_PARAM_H |
||||
|
# define NO_CHMOD |
||||
|
# define NO_SYSLOG |
||||
|
# undef DEVRANDOM |
||||
|
# define GETPID_IS_MEANINGLESS |
||||
|
# endif |
||||
|
#endif |
||||
|
|
||||
|
/********************************************************************
|
||||
|
The Microsoft section |
||||
|
********************************************************************/ |
||||
|
/* The following is used because of the small stack in some
|
||||
|
* Microsoft operating systems */ |
||||
|
#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32) |
||||
|
# define MS_STATIC static |
||||
|
#else |
||||
|
# define MS_STATIC |
||||
|
#endif |
||||
|
|
||||
|
#if defined(OPENSSL_SYS_WIN32) && !defined(WIN32) |
||||
|
# define WIN32 |
||||
|
#endif |
||||
|
#if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS) |
||||
|
# define WINDOWS |
||||
|
#endif |
||||
|
#if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS) |
||||
|
# define MSDOS |
||||
|
#endif |
||||
|
|
||||
|
#if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS) |
||||
|
# define GETPID_IS_MEANINGLESS |
||||
|
#endif |
||||
|
|
||||
|
#ifdef WIN32 |
||||
|
#define get_last_sys_error() GetLastError() |
||||
|
#define clear_sys_error() SetLastError(0) |
||||
|
#if !defined(WINNT) |
||||
|
#define WIN_CONSOLE_BUG |
||||
|
#endif |
||||
|
#else |
||||
|
#define get_last_sys_error() errno |
||||
|
#define clear_sys_error() errno=0 |
||||
|
#endif |
||||
|
|
||||
|
#if defined(WINDOWS) |
||||
|
#define get_last_socket_error() WSAGetLastError() |
||||
|
#define clear_socket_error() WSASetLastError(0) |
||||
|
#define readsocket(s,b,n) recv((s),(b),(n),0) |
||||
|
#define writesocket(s,b,n) send((s),(b),(n),0) |
||||
|
#elif defined(__DJGPP__) |
||||
|
#define WATT32 |
||||
|
#define get_last_socket_error() errno |
||||
|
#define clear_socket_error() errno=0 |
||||
|
#define closesocket(s) close_s(s) |
||||
|
#define readsocket(s,b,n) read_s(s,b,n) |
||||
|
#define writesocket(s,b,n) send(s,b,n,0) |
||||
|
#elif defined(MAC_OS_pre_X) |
||||
|
#define get_last_socket_error() errno |
||||
|
#define clear_socket_error() errno=0 |
||||
|
#define closesocket(s) MacSocket_close(s) |
||||
|
#define readsocket(s,b,n) MacSocket_recv((s),(b),(n),true) |
||||
|
#define writesocket(s,b,n) MacSocket_send((s),(b),(n)) |
||||
|
#elif defined(OPENSSL_SYS_VMS) |
||||
|
#define get_last_socket_error() errno |
||||
|
#define clear_socket_error() errno=0 |
||||
|
#define ioctlsocket(a,b,c) ioctl(a,b,c) |
||||
|
#define closesocket(s) close(s) |
||||
|
#define readsocket(s,b,n) recv((s),(b),(n),0) |
||||
|
#define writesocket(s,b,n) send((s),(b),(n),0) |
||||
|
#elif defined(OPENSSL_SYS_VXWORKS) |
||||
|
#define get_last_socket_error() errno |
||||
|
#define clear_socket_error() errno=0 |
||||
|
#define ioctlsocket(a,b,c) ioctl((a),(b),(int)(c)) |
||||
|
#define closesocket(s) close(s) |
||||
|
#define readsocket(s,b,n) read((s),(b),(n)) |
||||
|
#define writesocket(s,b,n) write((s),(char *)(b),(n)) |
||||
|
#elif defined(OPENSSL_SYS_BEOS_R5) |
||||
|
#define get_last_socket_error() errno |
||||
|
#define clear_socket_error() errno=0 |
||||
|
#define FIONBIO SO_NONBLOCK |
||||
|
#define ioctlsocket(a,b,c) setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c))) |
||||
|
#define readsocket(s,b,n) recv((s),(b),(n),0) |
||||
|
#define writesocket(s,b,n) send((s),(b),(n),0) |
||||
|
#elif defined(OPENSSL_SYS_NETWARE) |
||||
|
#if defined(NETWARE_BSDSOCK) |
||||
|
#define get_last_socket_error() errno |
||||
|
#define clear_socket_error() errno=0 |
||||
|
#define closesocket(s) close(s) |
||||
|
#define ioctlsocket(a,b,c) ioctl(a,b,c) |
||||
|
#if defined(NETWARE_LIBC) |
||||
|
#define readsocket(s,b,n) recv((s),(b),(n),0) |
||||
|
#define writesocket(s,b,n) send((s),(b),(n),0) |
||||
|
#else |
||||
|
#define readsocket(s,b,n) recv((s),(char*)(b),(n),0) |
||||
|
#define writesocket(s,b,n) send((s),(char*)(b),(n),0) |
||||
|
#endif |
||||
|
#else |
||||
|
#define get_last_socket_error() WSAGetLastError() |
||||
|
#define clear_socket_error() WSASetLastError(0) |
||||
|
#define readsocket(s,b,n) recv((s),(b),(n),0) |
||||
|
#define writesocket(s,b,n) send((s),(b),(n),0) |
||||
|
#endif |
||||
|
#else |
||||
|
#define get_last_socket_error() errno |
||||
|
#define clear_socket_error() errno=0 |
||||
|
#define ioctlsocket(a,b,c) ioctl(a,b,c) |
||||
|
#define closesocket(s) close(s) |
||||
|
#define readsocket(s,b,n) read((s),(b),(n)) |
||||
|
#define writesocket(s,b,n) write((s),(b),(n)) |
||||
|
#endif |
||||
|
|
||||
|
#ifdef WIN16 /* never the case */ |
||||
|
# define MS_CALLBACK _far _loadds |
||||
|
# define MS_FAR _far |
||||
|
#else |
||||
|
# define MS_CALLBACK |
||||
|
# define MS_FAR |
||||
|
#endif |
||||
|
|
||||
|
#ifdef OPENSSL_NO_STDIO |
||||
|
# undef OPENSSL_NO_FP_API |
||||
|
# define OPENSSL_NO_FP_API |
||||
|
#endif |
||||
|
|
||||
|
#if (defined(WINDOWS) || defined(MSDOS)) |
||||
|
|
||||
|
# ifdef __DJGPP__ |
||||
|
# include <unistd.h> |
||||
|
# include <sys/stat.h> |
||||
|
# include <sys/socket.h> |
||||
|
# include <tcp.h> |
||||
|
# include <netdb.h> |
||||
|
# define _setmode setmode |
||||
|
# define _O_TEXT O_TEXT |
||||
|
# define _O_BINARY O_BINARY |
||||
|
# undef DEVRANDOM |
||||
|
# define DEVRANDOM "/dev/urandom\x24" |
||||
|
# endif /* __DJGPP__ */ |
||||
|
|
||||
|
# ifndef S_IFDIR |
||||
|
# define S_IFDIR _S_IFDIR |
||||
|
# endif |
||||
|
|
||||
|
# ifndef S_IFMT |
||||
|
# define S_IFMT _S_IFMT |
||||
|
# endif |
||||
|
|
||||
|
# if !defined(WINNT) && !defined(__DJGPP__) |
||||
|
# define NO_SYSLOG |
||||
|
# endif |
||||
|
# define NO_DIRENT |
||||
|
|
||||
|
# ifdef WINDOWS |
||||
|
# if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT) |
||||
|
/*
|
||||
|
* Defining _WIN32_WINNT here in e_os.h implies certain "discipline." |
||||
|
* Most notably we ought to check for availability of each specific |
||||
|
* routine with GetProcAddress() and/or guard NT-specific calls with |
||||
|
* GetVersion() < 0x80000000. One can argue that in latter "or" case |
||||
|
* we ought to /DELAYLOAD some .DLLs in order to protect ourselves |
||||
|
* against run-time link errors. This doesn't seem to be necessary, |
||||
|
* because it turned out that already Windows 95, first non-NT Win32 |
||||
|
* implementation, is equipped with at least NT 3.51 stubs, dummy |
||||
|
* routines with same name, but which do nothing. Meaning that it's |
||||
|
* apparently sufficient to guard "vanilla" NT calls with GetVersion |
||||
|
* alone, while NT 4.0 and above interfaces ought to be linked with |
||||
|
* GetProcAddress at run-time. |
||||
|
*/ |
||||
|
# define _WIN32_WINNT 0x0400 |
||||
|
# endif |
||||
|
# if !defined(OPENSSL_NO_SOCK) && defined(_WIN32_WINNT) |
||||
|
/*
|
||||
|
* Just like defining _WIN32_WINNT including winsock2.h implies |
||||
|
* certain "discipline" for maintaining [broad] binary compatibility. |
||||
|
* As long as structures are invariant among Winsock versions, |
||||
|
* it's sufficient to check for specific Winsock2 API availability |
||||
|
* at run-time [DSO_global_lookup is recommended]... |
||||
|
*/ |
||||
|
# include <winsock2.h> |
||||
|
# include <ws2tcpip.h> |
||||
|
/* yes, they have to be #included prior to <windows.h> */ |
||||
|
# endif |
||||
|
# include <windows.h> |
||||
|
# include <stdio.h> |
||||
|
# include <stddef.h> |
||||
|
# include <errno.h> |
||||
|
# include <string.h> |
||||
|
# ifdef _WIN64 |
||||
|
# define strlen(s) _strlen31(s) |
||||
|
/* cut strings to 2GB */ |
||||
|
static unsigned int _strlen31(const char *str) |
||||
|
{ |
||||
|
unsigned int len=0; |
||||
|
while (*str && len<0x80000000U) str++, len++; |
||||
|
return len&0x7FFFFFFF; |
||||
|
} |
||||
|
# endif |
||||
|
# include <malloc.h> |
||||
|
# if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace) |
||||
|
/* compensate for bug in VC6 ctype.h */ |
||||
|
# undef isspace |
||||
|
# undef isdigit |
||||
|
# undef isalnum |
||||
|
# undef isupper |
||||
|
# undef isxdigit |
||||
|
# endif |
||||
|
# if defined(_MSC_VER) && !defined(_DLL) && defined(stdin) |
||||
|
# if _MSC_VER>=1300 |
||||
|
# undef stdin |
||||
|
# undef stdout |
||||
|
# undef stderr |
||||
|
FILE *__iob_func(); |
||||
|
# define stdin (&__iob_func()[0]) |
||||
|
# define stdout (&__iob_func()[1]) |
||||
|
# define stderr (&__iob_func()[2]) |
||||
|
# elif defined(I_CAN_LIVE_WITH_LNK4049) |
||||
|
# undef stdin |
||||
|
# undef stdout |
||||
|
# undef stderr |
||||
|
/* pre-1300 has __p__iob(), but it's available only in msvcrt.lib,
|
||||
|
* or in other words with /MD. Declaring implicit import, i.e. |
||||
|
* with _imp_ prefix, works correctly with all compiler options, |
||||
|
* but without /MD results in LINK warning LNK4049: |
||||
|
* 'locally defined symbol "__iob" imported'. |
||||
|
*/ |
||||
|
extern FILE *_imp___iob; |
||||
|
# define stdin (&_imp___iob[0]) |
||||
|
# define stdout (&_imp___iob[1]) |
||||
|
# define stderr (&_imp___iob[2]) |
||||
|
# endif |
||||
|
# endif |
||||
|
# endif |
||||
|
# include <io.h> |
||||
|
# include <fcntl.h> |
||||
|
|
||||
|
# ifdef OPENSSL_SYS_WINCE |
||||
|
# define OPENSSL_NO_POSIX_IO |
||||
|
# endif |
||||
|
|
||||
|
# if defined (__BORLANDC__) |
||||
|
# define _setmode setmode |
||||
|
# define _O_TEXT O_TEXT |
||||
|
# define _O_BINARY O_BINARY |
||||
|
# define _int64 __int64 |
||||
|
# define _kbhit kbhit |
||||
|
# endif |
||||
|
|
||||
|
# define EXIT(n) exit(n) |
||||
|
# define LIST_SEPARATOR_CHAR ';' |
||||
|
# ifndef X_OK |
||||
|
# define X_OK 0 |
||||
|
# endif |
||||
|
# ifndef W_OK |
||||
|
# define W_OK 2 |
||||
|
# endif |
||||
|
# ifndef R_OK |
||||
|
# define R_OK 4 |
||||
|
# endif |
||||
|
# define OPENSSL_CONF "openssl.cnf" |
||||
|
# define SSLEAY_CONF OPENSSL_CONF |
||||
|
# define NUL_DEV "nul" |
||||
|
# define RFILE ".rnd" |
||||
|
# ifdef OPENSSL_SYS_WINCE |
||||
|
# define DEFAULT_HOME "" |
||||
|
# else |
||||
|
# define DEFAULT_HOME "C:" |
||||
|
# endif |
||||
|
|
||||
|
/* Avoid Windows 8 SDK GetVersion deprecated problems */ |
||||
|
#if defined(_MSC_VER) && _MSC_VER>=1800 |
||||
|
# define check_winnt() (1) |
||||
|
#else |
||||
|
# define check_winnt() (GetVersion() < 0x80000000) |
||||
|
#endif |
||||
|
|
||||
|
#else /* The non-microsoft world */ |
||||
|
|
||||
|
# ifdef OPENSSL_SYS_VMS |
||||
|
# define VMS 1 |
||||
|
/* some programs don't include stdlib, so exit() and others give implicit
|
||||
|
function warnings */ |
||||
|
# include <stdlib.h> |
||||
|
# if defined(__DECC) |
||||
|
# include <unistd.h> |
||||
|
# else |
||||
|
# include <unixlib.h> |
||||
|
# endif |
||||
|
# define OPENSSL_CONF "openssl.cnf" |
||||
|
# define SSLEAY_CONF OPENSSL_CONF |
||||
|
# define RFILE ".rnd" |
||||
|
# define LIST_SEPARATOR_CHAR ',' |
||||
|
# define NUL_DEV "NLA0:" |
||||
|
/* We don't have any well-defined random devices on VMS, yet... */ |
||||
|
# undef DEVRANDOM |
||||
|
/* We need to do this since VMS has the following coding on status codes:
|
||||
|
|
||||
|
Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ... |
||||
|
The important thing to know is that odd numbers are considered |
||||
|
good, while even ones are considered errors. |
||||
|
Bits 3-15: actual status number |
||||
|
Bits 16-27: facility number. 0 is considered "unknown" |
||||
|
Bits 28-31: control bits. If bit 28 is set, the shell won't try to |
||||
|
output the message (which, for random codes, just looks ugly) |
||||
|
|
||||
|
So, what we do here is to change 0 to 1 to get the default success status, |
||||
|
and everything else is shifted up to fit into the status number field, and |
||||
|
the status is tagged as an error, which I believe is what is wanted here. |
||||
|
-- Richard Levitte |
||||
|
*/ |
||||
|
# define EXIT(n) do { int __VMS_EXIT = n; \ |
||||
|
if (__VMS_EXIT == 0) \ |
||||
|
__VMS_EXIT = 1; \ |
||||
|
else \ |
||||
|
__VMS_EXIT = (n << 3) | 2; \ |
||||
|
__VMS_EXIT |= 0x10000000; \ |
||||
|
exit(__VMS_EXIT); } while(0) |
||||
|
# define NO_SYS_PARAM_H |
||||
|
|
||||
|
# elif defined(OPENSSL_SYS_NETWARE) |
||||
|
# include <fcntl.h> |
||||
|
# include <unistd.h> |
||||
|
# define NO_SYS_TYPES_H |
||||
|
# undef DEVRANDOM |
||||
|
# ifdef NETWARE_CLIB |
||||
|
# define getpid GetThreadID |
||||
|
extern int GetThreadID(void); |
||||
|
/* # include <conio.h> */ |
||||
|
extern int kbhit(void); |
||||
|
# else |
||||
|
# include <screen.h> |
||||
|
# endif |
||||
|
# define NO_SYSLOG |
||||
|
# define _setmode setmode |
||||
|
# define _kbhit kbhit |
||||
|
# define _O_TEXT O_TEXT |
||||
|
# define _O_BINARY O_BINARY |
||||
|
# define OPENSSL_CONF "openssl.cnf" |
||||
|
# define SSLEAY_CONF OPENSSL_CONF |
||||
|
# define RFILE ".rnd" |
||||
|
# define LIST_SEPARATOR_CHAR ';' |
||||
|
# define EXIT(n) { if (n) printf("ERROR: %d\n", (int)n); exit(n); } |
||||
|
|
||||
|
# else |
||||
|
/* !defined VMS */ |
||||
|
# ifdef OPENSSL_SYS_MPE |
||||
|
# define NO_SYS_PARAM_H |
||||
|
# endif |
||||
|
# ifdef OPENSSL_UNISTD |
||||
|
# include OPENSSL_UNISTD |
||||
|
# else |
||||
|
# include <unistd.h> |
||||
|
# endif |
||||
|
# ifndef NO_SYS_TYPES_H |
||||
|
# include <sys/types.h> |
||||
|
# endif |
||||
|
# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) |
||||
|
# define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP |
||||
|
* (unless when compiling with -D_POSIX_SOURCE, |
||||
|
* which doesn't work for us) */ |
||||
|
# endif |
||||
|
# ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */ |
||||
|
# define setvbuf(a, b, c, d) setbuffer((a), (b), (d)) |
||||
|
typedef unsigned long clock_t; |
||||
|
# endif |
||||
|
# ifdef OPENSSL_SYS_WIN32_CYGWIN |
||||
|
# include <io.h> |
||||
|
# include <fcntl.h> |
||||
|
# endif |
||||
|
|
||||
|
# define OPENSSL_CONF "openssl.cnf" |
||||
|
# define SSLEAY_CONF OPENSSL_CONF |
||||
|
# define RFILE ".rnd" |
||||
|
# define LIST_SEPARATOR_CHAR ':' |
||||
|
# define NUL_DEV "/dev/null" |
||||
|
# define EXIT(n) exit(n) |
||||
|
# endif |
||||
|
|
||||
|
# define SSLeay_getpid() getpid() |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
/*************/ |
||||
|
|
||||
|
#ifdef USE_SOCKETS |
||||
|
# if defined(WINDOWS) || defined(MSDOS) |
||||
|
/* windows world */ |
||||
|
|
||||
|
# ifdef OPENSSL_NO_SOCK |
||||
|
# define SSLeay_Write(a,b,c) (-1) |
||||
|
# define SSLeay_Read(a,b,c) (-1) |
||||
|
# define SHUTDOWN(fd) close(fd) |
||||
|
# define SHUTDOWN2(fd) close(fd) |
||||
|
# elif !defined(__DJGPP__) |
||||
|
# if defined(_WIN32_WCE) && _WIN32_WCE<410 |
||||
|
# define getservbyname _masked_declaration_getservbyname |
||||
|
# endif |
||||
|
# if !defined(IPPROTO_IP) |
||||
|
/* winsock[2].h was included already? */ |
||||
|
# include <winsock.h> |
||||
|
# endif |
||||
|
# ifdef getservbyname |
||||
|
# undef getservbyname |
||||
|
/* this is used to be wcecompat/include/winsock_extras.h */ |
||||
|
struct servent* PASCAL getservbyname(const char*,const char*); |
||||
|
# endif |
||||
|
|
||||
|
# ifdef _WIN64 |
||||
|
/*
|
||||
|
* Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because |
||||
|
* the value constitutes an index in per-process table of limited size |
||||
|
* and not a real pointer. |
||||
|
*/ |
||||
|
# define socket(d,t,p) ((int)socket(d,t,p)) |
||||
|
# define accept(s,f,l) ((int)accept(s,f,l)) |
||||
|
# endif |
||||
|
# define SSLeay_Write(a,b,c) send((a),(b),(c),0) |
||||
|
# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) |
||||
|
# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } |
||||
|
# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } |
||||
|
# else |
||||
|
# define SSLeay_Write(a,b,c) write_s(a,b,c,0) |
||||
|
# define SSLeay_Read(a,b,c) read_s(a,b,c) |
||||
|
# define SHUTDOWN(fd) close_s(fd) |
||||
|
# define SHUTDOWN2(fd) close_s(fd) |
||||
|
# endif |
||||
|
|
||||
|
# elif defined(MAC_OS_pre_X) |
||||
|
|
||||
|
# include "MacSocket.h" |
||||
|
# define SSLeay_Write(a,b,c) MacSocket_send((a),(b),(c)) |
||||
|
# define SSLeay_Read(a,b,c) MacSocket_recv((a),(b),(c),true) |
||||
|
# define SHUTDOWN(fd) MacSocket_close(fd) |
||||
|
# define SHUTDOWN2(fd) MacSocket_close(fd) |
||||
|
|
||||
|
# elif defined(OPENSSL_SYS_NETWARE) |
||||
|
/* NetWare uses the WinSock2 interfaces by default, but can be configured for BSD
|
||||
|
*/ |
||||
|
# if defined(NETWARE_BSDSOCK) |
||||
|
# include <sys/socket.h> |
||||
|
# include <netinet/in.h> |
||||
|
# include <sys/time.h> |
||||
|
# if defined(NETWARE_CLIB) |
||||
|
# include <sys/bsdskt.h> |
||||
|
# else |
||||
|
# include <sys/select.h> |
||||
|
# endif |
||||
|
# define INVALID_SOCKET (int)(~0) |
||||
|
# else |
||||
|
# include <novsock2.h> |
||||
|
# endif |
||||
|
# define SSLeay_Write(a,b,c) send((a),(b),(c),0) |
||||
|
# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) |
||||
|
# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } |
||||
|
# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } |
||||
|
|
||||
|
# else |
||||
|
|
||||
|
# ifndef NO_SYS_PARAM_H |
||||
|
# include <sys/param.h> |
||||
|
# endif |
||||
|
# ifdef OPENSSL_SYS_VXWORKS |
||||
|
# include <time.h> |
||||
|
# elif !defined(OPENSSL_SYS_MPE) |
||||
|
# include <sys/time.h> /* Needed under linux for FD_XXX */ |
||||
|
# endif |
||||
|
|
||||
|
# include <netdb.h> |
||||
|
# if defined(OPENSSL_SYS_VMS_NODECC) |
||||
|
# include <socket.h> |
||||
|
# include <in.h> |
||||
|
# include <inet.h> |
||||
|
# else |
||||
|
# include <sys/socket.h> |
||||
|
# ifdef FILIO_H |
||||
|
# include <sys/filio.h> /* Added for FIONBIO under unixware */ |
||||
|
# endif |
||||
|
# include <netinet/in.h> |
||||
|
# if !defined(OPENSSL_SYS_BEOS_R5) |
||||
|
# include <arpa/inet.h> |
||||
|
# endif |
||||
|
# endif |
||||
|
|
||||
|
# if defined(NeXT) || defined(_NEXT_SOURCE) |
||||
|
# include <sys/fcntl.h> |
||||
|
# include <sys/types.h> |
||||
|
# endif |
||||
|
|
||||
|
# ifdef OPENSSL_SYS_AIX |
||||
|
# include <sys/select.h> |
||||
|
# endif |
||||
|
|
||||
|
# ifdef __QNX__ |
||||
|
# include <sys/select.h> |
||||
|
# endif |
||||
|
|
||||
|
# if defined(sun) |
||||
|
# include <sys/filio.h> |
||||
|
# else |
||||
|
# ifndef VMS |
||||
|
# include <sys/ioctl.h> |
||||
|
# else |
||||
|
/* ioctl is only in VMS > 7.0 and when socketshr is not used */ |
||||
|
# if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000) |
||||
|
# include <sys/ioctl.h> |
||||
|
# endif |
||||
|
# endif |
||||
|
# endif |
||||
|
|
||||
|
# ifdef VMS |
||||
|
# include <unixio.h> |
||||
|
# if defined(TCPIP_TYPE_SOCKETSHR) |
||||
|
# include <socketshr.h> |
||||
|
# endif |
||||
|
# endif |
||||
|
|
||||
|
# define SSLeay_Read(a,b,c) read((a),(b),(c)) |
||||
|
# define SSLeay_Write(a,b,c) write((a),(b),(c)) |
||||
|
# define SHUTDOWN(fd) { shutdown((fd),0); closesocket((fd)); } |
||||
|
# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket((fd)); } |
||||
|
# ifndef INVALID_SOCKET |
||||
|
# define INVALID_SOCKET (-1) |
||||
|
# endif /* INVALID_SOCKET */ |
||||
|
# endif |
||||
|
|
||||
|
/* Some IPv6 implementations are broken, disable them in known bad
|
||||
|
* versions. |
||||
|
*/ |
||||
|
# if !defined(OPENSSL_USE_IPV6) |
||||
|
# if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB) |
||||
|
# define OPENSSL_USE_IPV6 1 |
||||
|
# else |
||||
|
# define OPENSSL_USE_IPV6 0 |
||||
|
# endif |
||||
|
# endif |
||||
|
|
||||
|
#endif |
||||
|
|
||||
|
#if defined(sun) && !defined(__svr4__) && !defined(__SVR4) |
||||
|
/* include headers first, so our defines don't break it */ |
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
/* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */ |
||||
|
# define memmove(s1,s2,n) bcopy((s2),(s1),(n)) |
||||
|
# define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b))) |
||||
|
extern char *sys_errlist[]; extern int sys_nerr; |
||||
|
# define strerror(errnum) \ |
||||
|
(((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum]) |
||||
|
/* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */ |
||||
|
#include "crypto/o_str.h" |
||||
|
# define memcmp OPENSSL_memcmp |
||||
|
#endif |
||||
|
|
||||
|
#ifndef OPENSSL_EXIT |
||||
|
# if defined(MONOLITH) && !defined(OPENSSL_C) |
||||
|
# define OPENSSL_EXIT(n) return(n) |
||||
|
# else |
||||
|
# define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0) |
||||
|
# endif |
||||
|
#endif |
||||
|
|
||||
|
/***********************************************/ |
||||
|
|
||||
|
#define DG_GCC_BUG /* gcc < 2.6.3 on DGUX */ |
||||
|
|
||||
|
#ifdef sgi |
||||
|
#define IRIX_CC_BUG /* all version of IRIX I've tested (4.* 5.*) */ |
||||
|
#endif |
||||
|
#ifdef OPENSSL_SYS_SNI |
||||
|
#define IRIX_CC_BUG /* CDS++ up to V2.0Bsomething suffered from the same bug.*/ |
||||
|
#endif |
||||
|
|
||||
|
#if defined(OPENSSL_SYS_WINDOWS) |
||||
|
# define strcasecmp _stricmp |
||||
|
# define strncasecmp _strnicmp |
||||
|
#elif defined(OPENSSL_SYS_VMS) |
||||
|
/* VMS below version 7.0 doesn't have strcasecmp() */ |
||||
|
# include "o_str.h" |
||||
|
# define strcasecmp OPENSSL_strcasecmp |
||||
|
# define strncasecmp OPENSSL_strncasecmp |
||||
|
# define OPENSSL_IMPLEMENTS_strncasecmp |
||||
|
#elif defined(OPENSSL_SYS_OS2) && defined(__EMX__) |
||||
|
# define strcasecmp stricmp |
||||
|
# define strncasecmp strnicmp |
||||
|
#elif defined(OPENSSL_SYS_NETWARE) |
||||
|
# include <string.h> |
||||
|
# if defined(NETWARE_CLIB) |
||||
|
# define strcasecmp stricmp |
||||
|
# define strncasecmp strnicmp |
||||
|
# endif /* NETWARE_CLIB */ |
||||
|
#endif |
||||
|
|
||||
|
#if defined(OPENSSL_SYS_OS2) && defined(__EMX__) |
||||
|
# include <io.h> |
||||
|
# include <fcntl.h> |
||||
|
# define NO_SYSLOG |
||||
|
#endif |
||||
|
|
||||
|
/* vxworks */ |
||||
|
#if defined(OPENSSL_SYS_VXWORKS) |
||||
|
#include <ioLib.h> |
||||
|
#include <tickLib.h> |
||||
|
#include <sysLib.h> |
||||
|
|
||||
|
#define TTY_STRUCT int |
||||
|
|
||||
|
#define sleep(a) taskDelay((a) * sysClkRateGet()) |
||||
|
|
||||
|
#include <vxWorks.h> |
||||
|
#include <sockLib.h> |
||||
|
#include <taskLib.h> |
||||
|
|
||||
|
#define getpid taskIdSelf |
||||
|
|
||||
|
/* NOTE: these are implemented by helpers in database app!
|
||||
|
* if the database is not linked, we need to implement them |
||||
|
* elswhere */ |
||||
|
struct hostent *gethostbyname(const char *name); |
||||
|
struct hostent *gethostbyaddr(const char *addr, int length, int type); |
||||
|
struct servent *getservbyname(const char *name, const char *proto); |
||||
|
|
||||
|
#endif |
||||
|
/* end vxworks */ |
||||
|
|
||||
|
/* beos */ |
||||
|
#if defined(OPENSSL_SYS_BEOS_R5) |
||||
|
#define SO_ERROR 0 |
||||
|
#define NO_SYS_UN |
||||
|
#define IPPROTO_IP 0 |
||||
|
#include <OS.h> |
||||
|
#endif |
||||
|
|
||||
|
|
||||
|
#ifdef __cplusplus |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
#endif |
||||
|
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue