From abea900b3512d632aeb1c41868980eb29ae2c624 Mon Sep 17 00:00:00 2001 From: fadedreamz Date: Thu, 1 Dec 2016 00:35:43 -0500 Subject: [PATCH] working 32bit solution, 64bit compiles, but crashes on runtime Signed-off-by: fadedreamz --- .gitignore | 2 +- OSlibs/win/mingw.h | 12 +++++++ crypto777/OS_nonportable.c | 19 ++++++++++- iguana.sln | 28 +++++++++++++++++ iguana.vcxproj | 2 +- iguana/iguana_accept.c | 34 ++++++++++++++++++++ iguana/iguana_init.c | 6 ++++ iguana/iguana_peers.c | 64 ++++++++++++++++++++++++++++++++++++-- includes/iguana_defines.h | 1 + 9 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 iguana.sln diff --git a/.gitignore b/.gitignore index 92b11bd00..d7f6bfab7 100755 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - +x64 *.o agents/iguana.exe Debug/* diff --git a/OSlibs/win/mingw.h b/OSlibs/win/mingw.h index a59a2305a..0ec007c21 100755 --- a/OSlibs/win/mingw.h +++ b/OSlibs/win/mingw.h @@ -34,11 +34,23 @@ #define POLLERR 0x0008 /* Error condition */ #define POLLHUP 0x0010 /* Hung up */ #define POLLNVAL 0x0020 /* Invalid request: fd not open */ + + /** + * we want to use mingw provided pollfd if and only if we are compiling this + * in windows 32bit but exclude it when we are compiling it in win 64 + * + * @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) struct pollfd { SOCKET fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ }; +#endif + #define poll(x, y, z) win32_poll(x, y, z) /* These wrappers do nothing special except set the global errno variable if diff --git a/crypto777/OS_nonportable.c b/crypto777/OS_nonportable.c index 56a7a8258..52832bba9 100755 --- a/crypto777/OS_nonportable.c +++ b/crypto777/OS_nonportable.c @@ -13,7 +13,24 @@ * * ******************************************************************************/ - + /** + * - 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 + * + * @remarks - we need this because in win64 we are using windows provided pollfd structure + * not from the mingw header, so we need to include the windows header + * if we are compiling in windows 64bit + */ +#if defined(_M_X64) +#define WIN32_LEAN_AND_MEAN +#include +#endif + #include "OS_portable.h" diff --git a/iguana.sln b/iguana.sln new file mode 100644 index 000000000..621e199f3 --- /dev/null +++ b/iguana.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iguana", "iguana.vcxproj", "{80F58B93-D1FC-4FC4-A880-1F40A1FC851B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x64.ActiveCfg = Debug|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x64.Build.0 = Debug|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x86.ActiveCfg = Debug|Win32 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Debug|x86.Build.0 = Debug|Win32 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x64.ActiveCfg = Release|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x64.Build.0 = Release|x64 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x86.ActiveCfg = Release|Win32 + {80F58B93-D1FC-4FC4-A880-1F40A1FC851B}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/iguana.vcxproj b/iguana.vcxproj index 53f641904..4abd04777 100644 --- a/iguana.vcxproj +++ b/iguana.vcxproj @@ -113,7 +113,7 @@ Console true - C:\Users\faded_000\Desktop\New folder\SuperNET\OSlibs\win\x64;%(AdditionalLibraryDirectories) + .\OSlibs\win\x64;%(AdditionalLibraryDirectories) pthread_lib.lib;Ws2_32.lib;%(AdditionalDependencies) diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 835e68828..63d69787e 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -13,6 +13,19 @@ * * ******************************************************************************/ + /** + * - 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 + #include "iguana777.h" #include "exchanges777.h" @@ -20,10 +33,27 @@ struct iguana_accept { struct queueitem DL; char ipaddr[64]; uint32_t ipbits; in int32_t iguana_acceptspoll(uint8_t *buf,int32_t bufsize,struct iguana_accept *accepts,int32_t num,int32_t timeout) { + /** + * This solution is for win64 + * 2^11*sizeof(struct fd) for win64 bit gives a very big number + * for that reason it cannot allocate memory from stack + * so the solution is to allocate memory from heap, instead of stack + */ +#if defined(_M_X64) + struct pollfd * fds; + int32_t i, j, n, r, nonz, flag; struct iguana_accept *ptr; + if (num == 0) + return(0);; + fds = (struct pollfd *) malloc(sizeof(struct pollfd) * IGUANA_MAXPEERS); + if (NULL == fds) + return -1; + memset(fds, 0, sizeof(struct pollfd) * IGUANA_MAXPEERS); +#else struct pollfd fds[IGUANA_MAXPEERS]; int32_t i,j,n,r,nonz,flag; struct iguana_accept *ptr; if ( num == 0 ) return(0);; memset(fds,0,sizeof(fds)); +#endif flag = 0; r = (rand() % num); for (j=n=nonz=0; jsymbol, j == 0 ? "" : "old", (iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); +#else sprintf(fname,"%s/%s_%s%s.txt",GLOBAL_CONFSDIR,coin->symbol,j==0?"":"old",(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); +#endif //sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); //sprintf(fname,"tmp/%s/%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); OS_compatible_path(fname); diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index f90ec2bf4..65049f9df 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -13,6 +13,19 @@ * * ******************************************************************************/ + /** + * - 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 + #include "iguana777.h" #define _iguana_hashfind(coin,ipbits) _iguana_hashset(coin,ipbits,-1) @@ -351,29 +364,76 @@ void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t mar // iguana_possible_peer(coin,ipaddr); } - int32_t iguana_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; - // fadedreamz - change + + /** + * 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); diff --git a/includes/iguana_defines.h b/includes/iguana_defines.h index 451944593..7fbf0a817 100755 --- a/includes/iguana_defines.h +++ b/includes/iguana_defines.h @@ -58,6 +58,7 @@ #define IGUANA_MAXBUNDLES (50000000 / 500) #define IGUANA_MINPEERS 64 + #define IGUANA_LOG2MAXPEERS 11 // cant exceed 13 bits as ramchain unspents has bitfield #define IGUANA_MAXPEERS (1 << IGUANA_LOG2MAXPEERS)