You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

311 lines
14 KiB

/******************************************************************************
* Copyright © 2014-2017 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. *
* *
******************************************************************************/
//
// LP_network.c
// marketmaker
//
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp)
{
/* char keystr[64],databuf[1024],pubkeystr[128],*retstr,*retstr2,*datastr,*pushaddr=0,*subaddr=0; cJSON *retjson,*addrjson; uint8_t data[512]; int32_t datalen,timeout,pushsock = -1,subsock = -1;
if ( swap->connected == 1 )
return;
if ( swap->pushsock < 0 && swap->subsock < 0 && (pushsock= nn_socket(AF_SP,NN_PUSH)) >= 0 && (subsock= nn_socket(AF_SP,NN_SUB)) >= 0 )
{
timeout = 1000;
nn_setsockopt(pushsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout));
timeout = 1;
nn_setsockopt(subsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout));
nn_setsockopt(subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0);
swap->pushsock = pushsock;
swap->subsock = subsock;
}
if ( (subsock= swap->subsock) < 0 || (pushsock= swap->pushsock) < 0 )
{
printf("error getting nn_sockets\n");
return;
}
sprintf(keystr,"%08x-%08x",swap->I.req.requestid,swap->I.req.quoteid);
if ( swap->connected == 0 && (retstr= _dex_kvsearch("KV",keystr)) != 0 )
{
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
if ( (datastr= jstr(retjson,"value")) != 0 )
{
datalen = (int32_t)strlen(datastr) >> 1;
decode_hex((uint8_t *)databuf,datalen,datastr);
if ( (addrjson= cJSON_Parse(databuf)) != 0 )
{
pushaddr = jstr(addrjson,"push");
subaddr = jstr(addrjson,"sub");
if ( pushaddr != 0 && subaddr != 0 )
{
printf("KV decoded (%s and %s) %d %d\n",pushaddr,subaddr,swap->pushsock,swap->subsock);
if ( nn_connect(swap->pushsock,pushaddr) >= 0 && nn_connect(swap->subsock,subaddr) >= 0 )
swap->connected = 1;
}
free_json(addrjson);
}
}
free_json(retjson);
}
printf("KVsearch.(%s) -> (%s) connected.%d socks.(%d %d) amlp.%d\n",keystr,retstr,swap->connected,swap->pushsock,swap->subsock,amlp);
free(retstr);
}
printf("connected.%d amlp.%d subsock.%d pushsock.%d\n",swap->connected,amlp,subsock,pushsock);
if ( swap->connected <= 0 && amlp != 0 && subsock >= 0 && pushsock >= 0 )
{
if ( (retstr= _dex_psock("{}")) != 0 )
{
printf("psock returns.(%s)\n",retstr);
// {"result":"success","pushaddr":"tcp://5.9.102.210:30002","subaddr":"tcp://5.9.102.210:30003","randipbits":3606291758,"coin":"KMD","tag":"6952562460568228137"}
if ( (retjson= cJSON_Parse(retstr)) != 0 )
{
pushaddr = jstr(retjson,"pushaddr");
subaddr = jstr(retjson,"subaddr");
if ( pushaddr != 0 && subaddr != 0 )
{
if ( nn_connect(pushsock,pushaddr) >= 0 )
{
printf("connected to %d pushaddr.(%s)\n",pushsock,pushaddr);
if ( nn_connect(subsock,subaddr) >= 0 )
{
swap->connected = 1;
init_hexbytes_noT(pubkeystr,myinfo->persistent_pubkey33,33);
sprintf((char *)data,"{\"push\":\"%s\",\"sub\":\"%s\",\"trade\":[\"%s\", %.8f, \"%s\", %.8f],\"pub\":\"%s\"}",pushaddr,subaddr,swap->I.req.src,dstr(swap->I.req.srcamount),swap->I.req.dest,dstr(swap->I.req.destamount),pubkeystr);
datalen = (int32_t)strlen((char *)data) + 1;
printf("datalen.%d (%s)\n",datalen,(char *)data);
init_hexbytes_noT(databuf,data,datalen);
printf("%s -> %s\n",keystr,databuf);
if ( (retstr2= _dex_kvupdate("KV",keystr,databuf,1)) != 0 )
{
printf("KVupdate.(%s)\n",retstr2);
free(retstr2);
}
} else printf("nn_connect error to %d subaddr.(%s)\n",subsock,subaddr);
} else printf("nn_connect error to %d pushaddr.(%s)\n",pushsock,pushaddr);
}
else printf("missing addr (%p) (%p) (%s)\n",pushaddr,subaddr,jprint(retjson,0));
free_json(retjson);
} else printf("Error parsing psock.(%s)\n",retstr);
free(retstr);
} else printf("error issuing _dex_psock\n");
}*/
}
char *nanomsg_tcpname(char *str,char *ipaddr,uint16_t port)
{
sprintf(str,"tcp://%s:%u",ipaddr,port);
return(str);
}
int32_t LP_send(int32_t sock,char *msg,int32_t freeflag)
{
int32_t sentbytes,len,i; struct nn_pollfd pfd;
if ( sock < 0 )
{
printf("LP_send to illegal socket\n");
if ( freeflag != 0 )
free(msg);
return(-1);
}
for (i=0; i<100; i++)
{
pfd.fd = sock;
pfd.events = NN_POLLOUT;
if ( nn_poll(&pfd,1,100) > 0 )
{
len = (int32_t)strlen(msg) + 1;
if ( (sentbytes= nn_send(sock,msg,len,0)) != len )
printf("LP_send sent %d instead of %d\n",sentbytes,len);
else printf("SENT.(%s)\n",msg);
if ( freeflag != 0 )
free(msg);
return(sentbytes);
}
usleep(1000);
}
printf("error LP_send\n");
if ( freeflag != 0 )
free(msg);
return(-1);
}
uint32_t LP_swapsend(int32_t pairsock,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits,uint32_t crcs[2])
{
uint8_t *buf; int32_t sentbytes,offset=0,i;
buf = malloc(datalen + sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2);
for (i=0; i<32; i++)
buf[offset++] = swap->I.myhash.bytes[i];
for (i=0; i<32; i++)
buf[offset++] = swap->I.otherhash.bytes[i];
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid);
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits);
if ( datalen > 0 )
memcpy(&buf[offset],data,datalen), offset += datalen;
if ( (sentbytes= nn_send(pairsock,buf,offset,0)) != offset )
{
printf("sentbytes.%d vs offset.%d\n",sentbytes,offset);
if ( sentbytes < 0 )
{
}
}
printf("sent %d bytes\n",sentbytes);
//else printf("send.[%d] %x offset.%d datalen.%d [%llx]\n",sentbytes,msgbits,offset,datalen,*(long long *)data);
free(buf);
return(nextbits);
}
void basilisk_swap_sendabort(struct basilisk_swap *swap)
{
uint32_t msgbits = 0; uint8_t buf[sizeof(msgbits) + sizeof(swap->I.req.quoteid) + sizeof(bits256)*2]; int32_t sentbytes,offset=0;
memset(buf,0,sizeof(buf));
offset += iguana_rwnum(1,&buf[offset],sizeof(swap->I.req.quoteid),&swap->I.req.quoteid);
offset += iguana_rwnum(1,&buf[offset],sizeof(msgbits),&msgbits);
if ( (sentbytes= nn_send(swap->pushsock,buf,offset,0)) != offset )
{
if ( sentbytes < 0 )
{
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
}
} else printf("basilisk_swap_sendabort\n");
}
void basilisk_psockinit(struct basilisk_swap *swap,int32_t amlp);
void basilisk_swapgotdata(struct basilisk_swap *swap,uint32_t crc32,bits256 srchash,bits256 desthash,uint32_t quoteid,uint32_t msgbits,uint8_t *data,int32_t datalen,int32_t reinit)
{
int32_t i; struct basilisk_swapmessage *mp;
for (i=0; i<swap->nummessages; i++)
if ( crc32 == swap->messages[i].crc32 && msgbits == swap->messages[i].msgbits && bits256_cmp(srchash,swap->messages[i].srchash) == 0 && bits256_cmp(desthash,swap->messages[i].desthash) == 0 )
return;
//printf(" new message.[%d] datalen.%d Q.%x msg.%x [%llx]\n",swap->nummessages,datalen,quoteid,msgbits,*(long long *)data);
swap->messages = realloc(swap->messages,sizeof(*swap->messages) * (swap->nummessages + 1));
mp = &swap->messages[swap->nummessages++];
mp->crc32 = crc32;
mp->srchash = srchash;
mp->desthash = desthash;
mp->msgbits = msgbits;
mp->quoteid = quoteid;
mp->data = malloc(datalen);
mp->datalen = datalen;
memcpy(mp->data,data,datalen);
if ( reinit == 0 && swap->fp != 0 )
{
fwrite(mp,1,sizeof(*mp),swap->fp);
fwrite(data,1,datalen,swap->fp);
fflush(swap->fp);
}
}
int32_t basilisk_swapget(struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(void *ptr,uint8_t *data,int32_t datalen))
{
uint8_t *ptr; bits256 srchash,desthash; uint32_t crc32,_msgbits,quoteid; int32_t i,size,offset,retval = -1; struct basilisk_swapmessage *mp = 0;
while ( (size= nn_recv(swap->subsock,&ptr,NN_MSG,0)) >= 0 )
{
swap->lasttime = (uint32_t)time(NULL);
memset(srchash.bytes,0,sizeof(srchash));
memset(desthash.bytes,0,sizeof(desthash));
//printf("gotmsg.[%d] crc.%x\n",size,crc32);
offset = 0;
for (i=0; i<32; i++)
srchash.bytes[i] = ptr[offset++];
for (i=0; i<32; i++)
desthash.bytes[i] = ptr[offset++];
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&quoteid);
offset += iguana_rwnum(0,&ptr[offset],sizeof(uint32_t),&_msgbits);
if ( size > offset )
{
crc32 = calc_crc32(0,&ptr[offset],size-offset);
if ( size > offset )
{
//printf("size.%d offset.%d datalen.%d\n",size,offset,size-offset);
basilisk_swapgotdata(swap,crc32,srchash,desthash,quoteid,_msgbits,&ptr[offset],size-offset,0);
}
}
else if ( bits256_nonz(srchash) == 0 && bits256_nonz(desthash) == 0 )
{
if ( swap->aborted == 0 )
{
swap->aborted = (uint32_t)time(NULL);
printf("got abort signal from other side\n");
}
} else printf("basilisk_swapget: got strange packet\n");
if ( ptr != 0 )
nn_freemsg(ptr), ptr = 0;
}
//char str[65],str2[65];
for (i=0; i<swap->nummessages; i++)
{
//printf("%d: %s vs %s\n",i,bits256_str(str,swap->messages[i].srchash),bits256_str(str2,swap->messages[i].desthash));
if ( bits256_cmp(swap->messages[i].desthash,swap->I.myhash) == 0 )
{
if ( swap->messages[i].msgbits == msgbits )
{
if ( swap->I.iambob == 0 && swap->lasttime != 0 && time(NULL) > swap->lasttime+360 )
{
printf("nothing received for a while from Bob, try new sockets\n");
if ( swap->pushsock >= 0 ) //
nn_close(swap->pushsock), swap->pushsock = -1;
if ( swap->subsock >= 0 ) //
nn_close(swap->subsock), swap->subsock = -1;
swap->connected = 0;
basilisk_psockinit(swap,swap->I.iambob != 0);
}
mp = &swap->messages[i];
if ( msgbits != 0x80000000 )
break;
}
}
}
if ( mp != 0 )
retval = (*basilisk_verify_func)(swap,mp->data,mp->datalen);
//printf("mine/other %s vs %s\n",bits256_str(str,swap->I.myhash),bits256_str(str2,swap->I.otherhash));
return(retval);
}
int32_t basilisk_messagekeyread(uint8_t *key,uint32_t *channelp,uint32_t *msgidp,bits256 *srchashp,bits256 *desthashp)
{
int32_t keylen = 0;
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),channelp);
keylen += iguana_rwnum(0,&key[keylen],sizeof(uint32_t),msgidp);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*srchashp),srchashp->bytes);
keylen += iguana_rwbignum(0,&key[keylen],sizeof(*desthashp),desthashp->bytes);
return(keylen);
}
int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash)
{
int32_t keylen = 0;
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel);
keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes);
keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes);
return(keylen);
}
void LP_channelsend(bits256 srchash,bits256 desthash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen)
{
int32_t keylen; uint8_t key[BASILISK_KEYSIZE]; //char *retstr;
keylen = basilisk_messagekey(key,channel,msgid,srchash,desthash);
//if ( (retstr= _dex_reqsend(myinfo,"DEX",key,keylen,data,datalen)) != 0 )
// free(retstr);
}