From d9f05f26e1cadd7def7102636148d2ef8cd8b89e Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 17 Jan 2016 21:41:11 -0300 Subject: [PATCH] encrypted/compressed packets --- crypto777/ramcoder.c | 7 ++- iguana/SuperNET.c | 103 ++++++++++++++++++++++++++++++------------ iguana/SuperNET.h | 2 + iguana/iguana777.h | 4 +- iguana/iguana_msg.c | 6 +-- iguana/iguana_peers.c | 5 +- iguana/main.c | 37 ++++++++++++++- 7 files changed, 120 insertions(+), 44 deletions(-) diff --git a/crypto777/ramcoder.c b/crypto777/ramcoder.c index 63d049076..7a3f3e3c6 100755 --- a/crypto777/ramcoder.c +++ b/crypto777/ramcoder.c @@ -49,7 +49,7 @@ int32_t init_ramcoder(struct ramcoder *coder,HUFF *hp,bits256 *seed); int32_t ramcoder_emit(HUFF *hp,struct ramcoder *coder,int32_t updateprobs,uint8_t *buf,int32_t len); int32_t ramcoder_decompress(uint8_t *data,int32_t maxlen,uint8_t *bits,uint32_t numbits,bits256 seed); -int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen); +int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed); uint64_t hconv_bitlen(uint64_t bitlen); void _init_HUFF(HUFF *hp,int32_t allocsize,void *buf); @@ -439,10 +439,9 @@ int32_t ramcoder_decoder(struct ramcoder *coder,int32_t updateprobs,uint8_t *buf return(n); } -int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen) +int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed) { - int32_t numbits; bits256 seed; HUFF H,*hp = &H; - memset(seed.bytes,0,sizeof(seed)); + int32_t numbits; HUFF H,*hp = &H; _init_HUFF(hp,maxlen,bits); if ( ramcoder_encoder(0,1,data,datalen,hp,0,&seed) < 0 ) return(-1); diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c index ea9a8ecf5..dba503b43 100644 --- a/iguana/SuperNET.c +++ b/iguana/SuperNET.c @@ -92,9 +92,10 @@ void SuperNET_myipaddr(struct supernet_info *myinfo,struct iguana_peer *addr,cha } } -int32_t SuperNET_json2bits(struct supernet_info *myinfo,uint8_t *serialized,int32_t maxsize,char *destip,bits256 destpub,cJSON *json) +int32_t SuperNET_json2bits(struct supernet_info *myinfo,uint8_t *serialized,int32_t *complenp,uint8_t *compressed,int32_t maxsize,char *destip,bits256 destpub,cJSON *json) { - uint32_t ipbits; uint64_t tag; char *hexmsg; int32_t n,len = 0; + uint16_t apinum; uint32_t ipbits; uint64_t tag; bits256 seed,seed2; char *hexmsg; int32_t n,numbits,len = 0; + *complenp = -1; if ( (tag= j64bits(json,"tag")) == 0 ) OS_randombytes((uint8_t *)&tag,sizeof(tag)); ipbits = (uint32_t)calc_ipbits(destip); @@ -103,6 +104,9 @@ int32_t SuperNET_json2bits(struct supernet_info *myinfo,uint8_t *serialized,int3 len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&ipbits); len += iguana_rwbignum(1,&serialized[len],sizeof(myinfo->myaddr.pubkey),myinfo->myaddr.pubkey.bytes); len += iguana_rwnum(1,&serialized[len],sizeof(tag),&tag); + if ( (apinum= SuperNET_API2num(jstr(json,"agent"),jstr(json,"method"))) == 0xffff ) + return(-1); + len += iguana_rwnum(1,&serialized[len],sizeof(apinum),&apinum); if ( (hexmsg= jstr(json,"message")) != 0 ) { n = (int32_t)strlen(hexmsg); @@ -110,48 +114,83 @@ int32_t SuperNET_json2bits(struct supernet_info *myinfo,uint8_t *serialized,int3 { n >>= 1; decode_hex(&serialized[len],n,hexmsg); + len += n; } else return(-1); } + compressed[0] = (len & 0xff); + compressed[1] = ((len>>8) & 0xff); + compressed[2] = ((len>>16) & 0xff); + memset(seed.bytes,0,sizeof(seed)); + numbits = ramcoder_compress(&compressed[3],maxsize-3,serialized,len,seed); + *complenp = (int32_t)hconv_bitlen(numbits); + seed = curve25519_shared(myinfo->privkey,destpub); + vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(seed)); + int32_t seedlen; seedlen = ramcoder_compress(&compressed[3],maxsize-3,serialized,len,seed2); + printf("strlen.%d len.%d -> complen.%d seedlen.%d\n",(int32_t)strlen(jprint(json,0)),len,*complenp,seedlen); return(len); } -cJSON *SuperNET_bits2json(struct supernet_info *myinfo,bits256 prevpub,uint8_t *serialized,int32_t datalen) +cJSON *SuperNET_bits2json(struct supernet_info *myinfo,bits256 prevpub,uint8_t *serialized,uint8_t *space,int32_t datalen,int32_t iscompressed) { - char destip[64],myipaddr[64],str[65],*hexmsg; uint64_t tag; int32_t len = 0; - uint32_t destipbits,myipbits; bits256 senderpub; cJSON *json = cJSON_CreateObject(); - int32_t i; for (i=0; iprivkey,prevpub); + vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(seed)); + datalen = ramcoder_decompress(space,datalen,serialized,datalen<<3,seed2); + serialized = space; + } len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&destipbits); len += iguana_rwnum(0,&serialized[len],sizeof(uint32_t),&myipbits); len += iguana_rwbignum(0,&serialized[len],sizeof(bits256),senderpub.bytes); len += iguana_rwnum(0,&serialized[len],sizeof(tag),&tag); - printf("-> dest.%x myip.%x senderpub.%llx tag.%llu\n",destipbits,myipbits,(long long)senderpub.txid,(long long)tag); - expand_ipbits(destip,destipbits), jaddstr(json,"yourip",destip); - expand_ipbits(myipaddr,myipbits), jaddstr(json,"myip",myipaddr); - jaddstr(json,"mypub",bits256_str(str,senderpub)); - jadd64bits(json,"tag",tag); - if ( len < datalen ) + len += iguana_rwnum(0,&serialized[len],sizeof(apinum),&apinum); + //printf("-> dest.%x myip.%x senderpub.%llx tag.%llu\n",destipbits,myipbits,(long long)senderpub.txid,(long long)tag); + if ( SuperNET_num2API(agent,method,apinum) >= 0 ) { - printf("len %d vs %d datalen\n",len,datalen); - hexmsg = malloc(((datalen - len)<<1) + 1); - init_hexbytes_noT(hexmsg,&serialized[len],datalen - len); - printf("hex.(%s)\n",hexmsg); - jaddstr(json,"message",hexmsg); - free(hexmsg); + jaddstr(json,"agent",agent); + jaddstr(json,"method",method); + expand_ipbits(destip,destipbits), jaddstr(json,"yourip",destip); + expand_ipbits(myipaddr,myipbits), jaddstr(json,"myip",myipaddr); + jaddstr(json,"mypub",bits256_str(str,senderpub)); + jadd64bits(json,"tag",tag); + if ( len < datalen ) + { + printf("len %d vs %d datalen\n",len,datalen); + hexmsg = malloc(((datalen - len)<<1) + 1); + init_hexbytes_noT(hexmsg,&serialized[len],datalen - len); + printf("hex.(%s)\n",hexmsg); + jaddstr(json,"message",hexmsg); + free(hexmsg); + } + return(json); } - return(json); + return(0); } int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delaymillis) { - int32_t datalen,qlen = -1; uint8_t *serialized; cJSON *json; + int32_t datalen,complen,qlen = -1; uint8_t *serialized,*compressed; cJSON *json; if ( (json= cJSON_Parse(jsonstr)) != 0 ) { + compressed = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE); serialized = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE); - datalen = SuperNET_json2bits(SuperNET_MYINFO(0),&serialized[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,addr->ipaddr,addr->pubkey,json); - printf("SUPERSEND.(%s) -> (%s) delaymillis.%d\n",jsonstr,addr->ipaddr,delaymillis); - qlen = iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",datalen,0,1); + datalen = SuperNET_json2bits(SuperNET_MYINFO(0),&serialized[sizeof(struct iguana_msghdr)],&complen,&compressed[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,addr->ipaddr,addr->pubkey,json); + printf("SUPERSEND.(%s) -> (%s) delaymillis.%d datalen.%d\n",jsonstr,addr->ipaddr,delaymillis,datalen); + if ( datalen >= 0 ) + { + if ( complen >= 0 && complen < (((datalen-3) * 7) >> 3) ) + qlen = iguana_queue_send(coin,addr,delaymillis,compressed,"SuperNETb",complen,0,0); + else qlen = iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",datalen,0,0); + } + free(compressed); free(serialized); } return(qlen); @@ -316,12 +355,14 @@ char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr) return(retstr); } -char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen) +char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed) { - cJSON *json; bits256 senderpub; char *myipaddr,*method,*retstr = 0; int32_t maxdelay; struct supernet_info *myinfo; + cJSON *json; bits256 senderpub; char *myipaddr,*method,*retstr = 0; int32_t maxdelay; struct supernet_info *myinfo; uint8_t *space = 0; myinfo = SuperNET_MYINFO(0); *delaymillisp = 0; - if ( (json= SuperNET_bits2json(myinfo,addr->pubkey,data,datalen)) != 0 ) + if ( compressed != 0 ) + space = malloc(datalen); + if ( (json= SuperNET_bits2json(myinfo,addr->pubkey,data,space,datalen,compressed)) != 0 ) { maxdelay = juint(json,"maxdelay"); printf("GOT >>>>>>>> SUPERNET P2P.(%s) from.%s\n",jprint(json,0),coin->symbol); @@ -336,13 +377,15 @@ char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *de { addr->dead = (uint32_t)time(NULL); free_json(json); + if ( space != 0 ) + free(space); return(clonestr("{\"result\":\"peer marked as dead\"}")); } retstr = SuperNET_JSON(myinfo,json,ipaddr); - printf("call delaymillis\n"); *delaymillisp = SuperNET_delaymillis(myinfo,maxdelay); free_json(json); } else retstr = clonestr("{\"error\":\"p2p cant parse json\"}"); - printf("P2PRET.(%s)\n",retstr); + if ( space != 0 ) + free(space); return(retstr); } diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h index 501036bc7..91bfa92ce 100644 --- a/iguana/SuperNET.h +++ b/iguana/SuperNET.h @@ -111,6 +111,8 @@ char *SuperNET_DHTencode(struct supernet_info *myinfo,char *destip,bits256 destp char *SuperNET_parser(struct supernet_info *myinfo,char *agent,char *method,cJSON *json,char *remoteaddr); char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr); char *SuperNET_DHTsend(struct supernet_info *myinfo,bits256 routehash,char *hexmessage,int32_t maxdelay); +uint16_t SuperNET_API2num(char *agent,char *method); +int32_t SuperNET_num2API(char *agent,char *method,uint16_t num); #endif diff --git a/iguana/iguana777.h b/iguana/iguana777.h index e77ed93b5..47b66e22b 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -529,7 +529,7 @@ int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max // recvbits int32_t iguana_recvinit(struct iguana_info *coin,int32_t initialheight); int32_t ramcoder_decompress(uint8_t *data,int32_t maxlen,uint8_t *bits,uint32_t numbits,bits256 seed); -int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen); +int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed); uint64_t hconv_bitlen(uint64_t bitlen); struct iguana_block *iguana_blockptr(struct iguana_info *coin,int32_t height); int32_t iguana_processrecv(struct iguana_info *coin); // single threaded @@ -562,7 +562,7 @@ double dxblend(double *destp,double val,double decay); // json int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime char *iguana_JSON(char *jsonstr); -char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen); +char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed); char *mbstr(char *str,double); int init_hexbytes_noT(char *hexbytes,unsigned char *message,long len); diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index 99a702fff..aed4d80a3 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -430,17 +430,17 @@ int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struc } retval = 0; //printf("iguana_msgparser %s parse.(%s)\n",addr->ipaddr,H->command); - if ( strcmp(H->command,"SuperNET") == 0 ) + if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 ) { addr->supernet = 1; addr->msgcounts.verack++; len = recvlen; - if ( (retstr= SuperNET_p2p(coin,addr,&delay,addr->ipaddr,data,recvlen)) != 0 ) + if ( (retstr= SuperNET_p2p(coin,addr,&delay,addr->ipaddr,data,recvlen,H->command[strlen("SuperNET")]=='b')) != 0 ) { iguana_send_supernet(coin,addr,retstr,delay); free(retstr); } - printf("GOT.(%s) [%s] len.%d from %s -> (%s)\n",H->command,data,recvlen,addr->ipaddr,retstr==0?"null":retstr); + //printf("GOT.(%s) [%s] len.%d from %s -> (%s)\n",H->command,data,recvlen,addr->ipaddr,retstr==0?"null":retstr); } else if ( strcmp(H->command,"version") == 0 ) { diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 22de3de06..ffaeb63b4 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -434,9 +434,6 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig iguana_sethdr(&checkH,coin->chain->netmagic,H->command,buf,len); if ( memcmp(&checkH,H,sizeof(checkH)) == 0 ) { - //if ( strcmp(addr->ipaddr,"127.0.0.1") == 0 ) - //printf("%s parse.(%s) len.%d\n",addr->ipaddr,H->command,len); - //printf("addr->dead.%u\n",addr->dead); if ( strcmp(H->command,"block") == 0 || strcmp(H->command,"tx") == 0 ) { if ( addr->RAWMEM.ptr == 0 ) @@ -977,7 +974,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } if ( flag != 0 ) run = 0; - else if ( addr->supernet != 0 && time(NULL) > lastping+600 ) + else if ( addr->supernet != 0 && time(NULL) > lastping+60 ) { iguana_send_supernet(coin,addr,"{\"agent\":\"SuperNET\",\"method\":\"getpeers\"}",0); lastping = (uint32_t)time(NULL); diff --git a/iguana/main.c b/iguana/main.c index c1e34aa47..f8c58cf67 100644 --- a/iguana/main.c +++ b/iguana/main.c @@ -33,6 +33,7 @@ uint64_t IGUANA_MY64BITS; queue_t helperQ,jsonQ,finishedQ,bundlesQ; struct supernet_info MYINFO; static int32_t initflag; +cJSON *API_json; #ifdef __linux__ int32_t IGUANA_NUMHELPERS = 8; #else @@ -40,6 +41,33 @@ int32_t IGUANA_NUMHELPERS = 1; #endif struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char **retjsonstrp; char remoteaddr[64]; char jsonstr[]; }; +uint16_t SuperNET_API2num(char *agent,char *method) +{ + int32_t i,n = 0; cJSON *item; + if ( agent != 0 && method != 0 && API_json != 0 && (n= cJSON_GetArraySize(API_json)) > 0 ) + { + for (i=0; i 0 && num < n ) + { + item = jitem(API_json,num); + strcpy(agent,jstr(item,"agent")); + strcpy(method,jstr(item,"method")); + return(num); + } + return(-1); +} struct supernet_info *SuperNET_MYINFO(char *passphrase) { @@ -215,7 +243,7 @@ void sigcontinue_func() { printf("\nSIGCONT\n"); signal(SIGCONT,sigcontinue_func void iguana_main(void *arg) { - char helperstr[64],*helperargs,*ipaddr,*coinargs=0,*secret,*jsonstr = arg; + char helperstr[64],*tmpstr,*helperargs,*ipaddr,*coinargs=0,*secret,*jsonstr = arg; int32_t i,len,flag,c; cJSON *json; uint8_t secretbuf[512]; int64_t allocsize; if ( (ipaddr= OS_filestr(&allocsize,"ipaddr")) != 0 ) { @@ -245,6 +273,12 @@ void iguana_main(void *arg) OS_ensure_directory("confs"); OS_ensure_directory("DB"); OS_ensure_directory("tmp"); + if ( (tmpstr= SuperNET_JSON(&MYINFO,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"help\"}"),0)) != 0 ) + { + if ( (API_json= cJSON_Parse(tmpstr)) != 0 ) + API_json = jobj(API_json,"result"); + free(tmpstr); + } memset(&MYINFO,0,sizeof(MYINFO)); OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey)); if ( jsonstr != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) @@ -264,6 +298,7 @@ void iguana_main(void *arg) if ( jobj(json,"coins") != 0 ) coinargs = jsonstr; } + MYINFO.myaddr.pubkey = curve25519(MYINFO.privkey,curve25519_basepoint9()); if ( IGUANA_NUMHELPERS == 0 ) IGUANA_NUMHELPERS = 1; for (i=0; i