From b501f9fb01f7d86bc6b94b9321b3578d6503db84 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 9 Sep 2017 18:50:57 +0200 Subject: [PATCH] LP_socket != test --- iguana/exchanges/LP_nativeDEX.c | 3 +- iguana/exchanges/LP_rpc.c | 11 +- iguana/exchanges/LP_socket.c | 284 ++++++++++++++++++++++++++++++++ iguana/exchanges/LP_utxos.c | 8 +- iguana/exchanges/mm.c | 2 + 5 files changed, 299 insertions(+), 9 deletions(-) create mode 100644 iguana/exchanges/LP_socket.c diff --git a/iguana/exchanges/LP_nativeDEX.c b/iguana/exchanges/LP_nativeDEX.c index dcc65a31c..d788262be 100644 --- a/iguana/exchanges/LP_nativeDEX.c +++ b/iguana/exchanges/LP_nativeDEX.c @@ -80,6 +80,7 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_ return(0); } +#include "LP_socket.c" #include "LP_secp.c" #include "LP_bitcoin.c" #include "LP_coins.c" @@ -419,7 +420,7 @@ int32_t LP_mainloop_iter(void *ctx,char *myipaddr,struct LP_peerinfo *mypeer,int } HASH_ITER(hh,LP_coins,coin,ctmp) // firstrefht,firstscanht,lastscanht { - cJSON *obj; int32_t height; bits256 zero; + int32_t height; bits256 zero; //printf("%s ref.%d scan.%d to %d, longest.%d\n",coin->symbol,coin->firstrefht,coin->firstscanht,coin->lastscanht,coin->longestchain); if ( coin->inactive != 0 ) continue; diff --git a/iguana/exchanges/LP_rpc.c b/iguana/exchanges/LP_rpc.c index cb36dd3aa..bc4027538 100644 --- a/iguana/exchanges/LP_rpc.c +++ b/iguana/exchanges/LP_rpc.c @@ -105,18 +105,21 @@ char *issue_LP_getprices(char *destip,uint16_t destport) cJSON *bitcoin_json(struct iguana_info *coin,char *method,char *params) { - //static uint32_t stratumid; - cJSON *retjson = 0; char *retstr;//,stratumreq[8192]; + static uint32_t stratumid; + cJSON *retjson = 0; char *retstr,stratumreq[8192]; // "getinfo", "getrawmempool", "paxprice", "gettxout", "getrawtransaction", "getblock", "listunspent", "listtransactions", "validateaddress", "importprivkey" // bitcoind_passthru callers: "importaddress", "estimatefee", "getblockhash", "sendrawtransaction", "signrawtransaction" //"server.version", "server.banner", "server.donation_address", "server.peers.subscribe", "--blockchain.numblocks.subscribe", "blockchain.headers.subscribe", "blockchain.address.subscribe", "blockchain.address.get_history", "blockchain.address.get_mempool", "blockchain.address.get_balance", "--blockchain.address.get_proof", "blockchain.address.listunspent", "--blockchain.utxo.get_address", "blockchain.block.get_header", "blockchain.block.get_chunk", "blockchain.transaction.broadcast", "blockchain.transaction.get_merkle", "blockchain.transaction.get", "blockchain.estimatefee" // 1.1: "blockchain.scripthash.get_balance", "blockchain.scripthash.get_history", "blockchain.scripthash.get_mempool", "blockchain.scripthash.listunspent", "blockchain.scripthash.subscribe", "server.features", "server.add_peer" - /*method = "server.version"; + method = "server.version"; params = "[]"; sprintf(stratumreq,"{ \"jsonrpc\":\"2.0\", \"id\": %u, \"method\":\"%s\", \"params\": %s }\n",stratumid++,method,params); - if ( (retstr= issue_curlt("46.4.125.2:50001",LP_HTTP_TIMEOUT*5)) != 0 ) + LP_sendstr = stratumreq; + while ( LP_sendstr != 0 ) + usleep(10000); + /*if ( (retstr= issue_curlt("46.4.125.2:50001",LP_HTTP_TIMEOUT*5)) != 0 ) { printf("%s -> %s\n",stratumreq,retstr); free(retstr); diff --git a/iguana/exchanges/LP_socket.c b/iguana/exchanges/LP_socket.c new file mode 100644 index 000000000..3428f8cb8 --- /dev/null +++ b/iguana/exchanges/LP_socket.c @@ -0,0 +1,284 @@ +/****************************************************************************** + * 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. * + * * + ******************************************************************************/ + +/** + * - we need to include WinSock2.h header to correctly use windows structure + * as the application is still using 32bit structure from mingw so, we need to + * add the include based on checking + * @author - fadedreamz@gmail.com + * @remarks - #if (defined(_M_X64) || defined(__amd64__)) && defined(WIN32) + * is equivalent to #if defined(_M_X64) as _M_X64 is defined for MSVC only + */ +#if defined(_M_X64) +#define WIN32_LEAN_AND_MEAN +#include +#endif + +int32_t LP_socket(int32_t bindflag,char *hostname,uint16_t port) +{ + int32_t opt,sock,result; char ipaddr[64],checkipaddr[64]; struct timeval timeout; + struct sockaddr_in saddr; socklen_t addrlen,slen; + addrlen = sizeof(saddr); + struct hostent *hostent; + + /** + * gethostbyname() is deprecated and cause crash on x64 windows + * the solution is to implement similar functionality by using getaddrinfo() + * it is standard posix function and is correctly supported in win32/win64/linux + * @author - fadedreamz@gmail.com + */ +#if defined(_M_X64) + struct addrinfo *addrresult = NULL; + struct addrinfo *returnptr = NULL; + struct addrinfo hints; + struct sockaddr_in * sockaddr_ipv4; + int retVal; + int found = 0; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; +#endif + + if ( parse_ipaddr(ipaddr,hostname) != 0 ) + port = parse_ipaddr(ipaddr,hostname); + +#if defined(_M_X64) + retVal = getaddrinfo(ipaddr, NULL, &hints, &addrresult); + for (returnptr = addrresult; returnptr != NULL && found == 0; returnptr = returnptr->ai_next) { + switch (returnptr->ai_family) { + case AF_INET: + sockaddr_ipv4 = (struct sockaddr_in *) returnptr->ai_addr; + // we want to break from the loop after founding the first ipv4 address + found = 1; + break; + } + } + + // if we iterate through the loop and didn't find anything, + // that means we failed in the dns lookup + if (found == 0) { + printf("getaddrinfo(%s) returned error\n", hostname); + freeaddrinfo(addrresult); + return(-1); + } +#else + hostent = gethostbyname(ipaddr); + if ( hostent == NULL ) + { + printf("gethostbyname(%s) returned error: %d port.%d ipaddr.(%s)\n",hostname,errno,port,ipaddr); + return(-1); + } +#endif + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + //#ifdef WIN32 + // saddr.sin_addr.s_addr = (uint32_t)calc_ipbits("127.0.0.1"); + //#else + +#if defined(_M_X64) + saddr.sin_addr.s_addr = sockaddr_ipv4->sin_addr.s_addr; + // graceful cleanup + sockaddr_ipv4 = NULL; + freeaddrinfo(addrresult); +#else + memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); +#endif + expand_ipbits(checkipaddr,saddr.sin_addr.s_addr); + if ( strcmp(ipaddr,checkipaddr) != 0 ) + printf("bindflag.%d iguana_socket mismatch (%s) -> (%s)?\n",bindflag,checkipaddr,ipaddr); + //#endif + if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) + { + if ( errno != ETIMEDOUT ) + printf("socket() failed: %s errno.%d", strerror(errno),errno); + return(-1); + } + opt = 1; + slen = sizeof(opt); + //printf("set keepalive.%d\n",setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,slen)); +#ifndef WIN32 + if ( 1 )//&& bindflag != 0 ) + { + opt = 0; + getsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,(void *)&opt,&slen); + opt = 1; + //printf("keepalive.%d\n",opt); + } + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)); +#ifdef __APPLE__ + setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); +#endif +#endif + if ( bindflag == 0 ) + { + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + result = connect(sock,(struct sockaddr *)&saddr,addrlen); + if ( result != 0 ) + { + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + //printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + } + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + timeout.tv_sec = 10000000; + timeout.tv_usec = 0; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + } + else + { + while ( (result= bind(sock,(struct sockaddr*)&saddr,addrlen)) != 0 ) + { + if ( errno == EADDRINUSE ) + { + sleep(1); + printf("ERROR BINDING PORT.%d. this is normal tcp timeout, unless another process is using port\n",port); + fflush(stdout); + sleep(3); + printf("%s(%s) port.%d try again: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + if ( bindflag == 1 ) + { + closesocket(sock); + return(-1); + } + sleep(13); + //continue; + } + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + { + printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); + closesocket(sock); + return(-1); + } + } + if ( listen(sock,64) != 0 ) + { + printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); + if ( sock >= 0 ) + closesocket(sock); + return(-1); + } + } +#ifdef __APPLE__ + //timeout.tv_sec = 0; + //timeout.tv_usec = 30000; + //setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(void *)&timeout,sizeof(timeout)); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(void *)&timeout,sizeof(timeout)); +#endif + return(sock); +} + +int32_t LP_socketsend(int32_t sock,uint8_t *serialized,int32_t len) +{ + int32_t numsent,remains,flags = 0; +#ifndef _WIN32 + flags = MSG_NOSIGNAL; +#endif + remains = len; + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,serialized,remains,flags)) < 0 ) + { + if ( errno == EAGAIN || errno == EWOULDBLOCK ) + { + sleep(1); + continue; + } + printf("(%s): numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",serialized,numsent,remains,len,errno,strerror(errno),sock); + return(-errno); + } + else if ( remains > 0 ) + { + remains -= numsent; + serialized += numsent; + if ( remains > 0 ) + printf("%d LP_socket sent.%d remains.%d of len.%d\n",sock,numsent,remains,len); + } + } + return(len); +} + +int32_t LP_socketrecv(int32_t sock,uint8_t *recvbuf,int32_t maxlen) +{ + int32_t recvlen = -1; + while ( 1 ) + { + if ( (recvlen= (int32_t)recv(sock,recvbuf,maxlen,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + //printf("%s recv errno.%d %s len.%d remains.%d\n",ipaddr,errno,strerror(errno),len,remains); + //printf("EAGAIN for len %d, remains.%d\n",len,remains); + sleep(1); + } else return(-errno); + } else break; + } + return(recvlen); +} + +int32_t LP_recvfunc(char *ipaddr,char *str,int32_t len) +{ + printf("RECV.(%s) from %s\n",str,ipaddr); + return(0); +} + +void LP_dedicatedloop(int32_t (*recvfunc)(char *ipaddr,char *str,int32_t len),char **sendstrp,char *ipaddr,uint16_t port) +{ + struct pollfd fds; uint8_t *buf; char *str; int32_t len,sock,bufsize,flag,timeout = 10; + bufsize = IGUANA_MAXPACKETSIZE * 2; + buf = malloc(bufsize); + sock = LP_socket(0,ipaddr,port); + while ( sock >= 0 ) + { + flag = 0; + memset(&fds,0,sizeof(fds)); + fds.fd = sock; + fds.events |= (POLLOUT | POLLIN); + if ( poll(&fds,1,timeout) > 0 && (fds.revents & POLLOUT) != 0 && (str= *sendstrp) != 0 ) + { + *sendstrp = 0; + if ( LP_socketsend(sock,(uint8_t *)str,(int32_t)strlen(str+1)) <= 0 ) + { + printf("%s:%u is dead\n",ipaddr,port); + closesocket(sock); + sock = -1; + break; + } + flag++; + } + if ( flag == 0 ) + { + if ( (fds.revents & POLLIN) != 0 ) + { + if ( (len= LP_socketrecv(sock,buf,bufsize)) > 0 ) + { + (*recvfunc)(ipaddr,(char *)buf,len); + flag++; + } + } + if ( flag == 0 ) + usleep(100000); + } + } + free(buf); +} + diff --git a/iguana/exchanges/LP_utxos.c b/iguana/exchanges/LP_utxos.c index 9f003e3fb..a3d191dcd 100644 --- a/iguana/exchanges/LP_utxos.c +++ b/iguana/exchanges/LP_utxos.c @@ -952,13 +952,13 @@ char *LP_secretaddresses(void *ctx,char *passphrase,int32_t n,uint8_t taddr,uint bits256 LP_privkeycalc(void *ctx,uint8_t *pubkey33,bits256 *pubkeyp,struct iguana_info *coin,char *passphrase,char *wifstr) { static uint32_t counter; - bits256 privkey,userpub,userpass,checkkey; char tmpstr[128],pstr[65]; cJSON *retjson; uint8_t tmptype,rmd160[20]; + bits256 privkey,userpub,userpass,checkkey; char tmpstr[128]; cJSON *retjson; uint8_t tmptype,rmd160[20]; if ( passphrase != 0 && passphrase[0] != 0 ) { conv_NXTpassword(privkey.bytes,pubkeyp->bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - printf("SHA256.(%s) ",bits256_str(pstr,checkkey)); - printf("privkey.(%s)\n",bits256_str(pstr,privkey)); + //vcalc_sha256(0,checkkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + //printf("SHA256.(%s) ",bits256_str(pstr,checkkey)); + //printf("privkey.(%s)\n",bits256_str(pstr,privkey)); } else { diff --git a/iguana/exchanges/mm.c b/iguana/exchanges/mm.c index ffde8b2f3..fb00d6595 100644 --- a/iguana/exchanges/mm.c +++ b/iguana/exchanges/mm.c @@ -26,6 +26,7 @@ #define MAX(a,b) ((a) > (b) ? (a) : (b)) char *stats_JSON(void *ctx,char *myipaddr,int32_t pubsock,cJSON *argjson,char *remoteaddr,uint16_t port); #include "stats.c" +char *LP_sendstr; void LP_priceupdate(char *base,char *rel,double price,double avebid,double aveask,double highbid,double lowask,double PAXPRICES[32]); //defined(__APPLE__) || @@ -816,6 +817,7 @@ int main(int argc, const char * argv[]) exit(-1); } else printf("(%s) launched.(%s)\n",argv[1],passphrase); incr = 100.; + LP_dedicatedloop(LP_recvfunc,&LP_sendstr,"46.4.125.2",50001); while ( 1 ) sleep(1); profitmargin = jdouble(retjson,"profitmargin");