diff --git a/libretroshare/src/pqi/p3netmgr.cc b/libretroshare/src/pqi/p3netmgr.cc index 8776ad182..e6b6b4cff 100644 --- a/libretroshare/src/pqi/p3netmgr.cc +++ b/libretroshare/src/pqi/p3netmgr.cc @@ -997,7 +997,7 @@ void p3NetMgrIMPL::netExtCheck() ************************************** Interfaces ***************************************** **********************************************************************************************/ -bool p3NetMgrIMPL::checkNetAddress() +bool p3NetMgrIMPL::checkNetAddress() { bool addrChanged = false; bool validAddr = false; @@ -1016,7 +1016,17 @@ bool p3NetMgrIMPL::checkNetAddress() } else { - validAddr = getPreferredInterface(mLocalAddr, prefAddr); + // TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local address is a flawed assumption, this should be redesigned soon. + std::list addrs; + std::list::iterator it; + if (getLocalAddresses(addrs)) + for(it = addrs.begin(); (it != addrs.end() && !validAddr); ++it) + if(sockaddr_storage_isValidNet(*it) && !sockaddr_storage_isLoopbackNet(*it)) + { + prefAddr = *it; + validAddr = true; + std::cout << "p3NetMgrIMPL::checkNetAddress() prefAddr: " << sockaddr_storage_iptostring(prefAddr) << std::endl; + } } diff --git a/libretroshare/src/pqi/p3netmgr.h b/libretroshare/src/pqi/p3netmgr.h index eb1802328..afc1bda1a 100644 --- a/libretroshare/src/pqi/p3netmgr.h +++ b/libretroshare/src/pqi/p3netmgr.h @@ -326,6 +326,7 @@ private: void netStatusReset_locked(); + // TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just two possible address is a flawed assumption, this should be redesigned soon. struct sockaddr_storage mLocalAddr; struct sockaddr_storage mExtAddr; diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index 5d5c35e8d..6b589cf44 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -38,7 +38,8 @@ #include "util/rsdebug.h" #include "util/rsstring.h" -#include +#include "util/rsnet.h" + static const int pqinetzone = 96184; /***** @@ -149,78 +150,6 @@ std::string socket_errorType(int err) return std::string("UNKNOWN ERROR CODE - ASK RS-DEVS TO ADD IT!"); } -#include -#include - -bool getLocalInterfaces_ipv4(struct in_addr &/*routeAddr*/, std::list &addrs) -{ - int sock = 0; - struct ifreq ifreq; - - struct if_nameindex *iflist = if_nameindex(); - struct if_nameindex *ifptr = iflist; - - //need a socket for ioctl() - if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - pqioutput(PQL_ALERT, pqinetzone, - "Cannot Determine Local Addresses!"); - return false; - } - - if (!ifptr) - { - pqioutput(PQL_ALERT, pqinetzone, - "getLocalInterfaces(): ERROR if_nameindex == NULL"); - return false; - } - - // loop through the interfaces. - for(; ifptr->if_index != 0; ++ifptr) - { - //copy in the interface name to look up address of - strncpy(ifreq.ifr_name, ifptr->if_name, IF_NAMESIZE-1);// the -1 is here to ensure that there's enough room left to place a \0 termination byte - - if(ioctl(sock, SIOCGIFADDR, &ifreq) != 0) - { - std::string out; - rs_sprintf(out, "Cannot Determine Address for Iface: %s", ifptr -> if_name); - pqioutput(PQL_DEBUG_BASIC, pqinetzone, out); - } - else - { - struct sockaddr_in *aptr = - (struct sockaddr_in *) &ifreq.ifr_addr; - std::string astr =rs_inet_ntoa(aptr -> sin_addr); - - std::string out; - rs_sprintf(out, "Iface: %s\n Address: %s", ifptr -> if_name, astr.c_str()); - pqioutput(PQL_DEBUG_BASIC, pqinetzone, out); - - // Now check wether the interface is up and running. If not, we don't use it!! - // - if(ioctl(sock,SIOCGIFFLAGS,&ifreq) != 0) - { - std::cerr << "Could not get flags from interface " << ifptr -> if_name << std::endl ; - continue ; - } -#ifdef NET_DEBUG - std::cout << out.str() ; - std::cout << "flags = " << ifreq.ifr_flags << std::endl ; -#endif - if((ifreq.ifr_flags & IFF_UP) == 0) continue ; - if((ifreq.ifr_flags & IFF_RUNNING) == 0) continue ; - - addrs.push_back(aptr->sin_addr); - } - } - // free socket -> or else run out of fds. - close(sock); - - if_freenameindex(iflist); - return (addrs.size() > 0); -} - /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ #else @@ -327,80 +256,6 @@ std::string socket_errorType(int err) return std::string("----WINDOWS OPERATING SYSTEM FAILURE----"); } -#include -//#include - -// A function to determine the interfaces on your computer.... -// No idea of how to do this in windows.... -// see if it compiles. -bool getLocalInterfaces_ipv4(struct in_addr &routeAddr, std::list &addrs) -{ - // Get the best interface for transport to routeAddr - // This interface should be first in list! - DWORD bestInterface; - if (GetBestInterface((IPAddr) routeAddr.s_addr, &bestInterface) != NO_ERROR) - { - bestInterface = 0; - } - - /* USE MIB IPADDR Interface */ - PMIB_IPADDRTABLE iptable = NULL; - DWORD dwSize = 0; - - if (GetIpAddrTable(iptable, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER) - { - pqioutput(PQL_ALERT, pqinetzone, "Cannot Find Windoze Interfaces!"); - exit(0); - } - - iptable = (MIB_IPADDRTABLE *) malloc(dwSize); - GetIpAddrTable(iptable, &dwSize, 0); - - struct in_addr addr; - - for (unsigned int i = 0; i < iptable -> dwNumEntries; i++) - { - MIB_IPADDRROW &ipaddr = iptable->table[i]; - - std::string out; - - addr.s_addr = ipaddr.dwAddr; - rs_sprintf(out, "Iface(%ld) => %s\n", ipaddr.dwIndex, rs_inet_ntoa(addr).c_str()); - -#if __MINGW_MAJOR_VERSION <= 3 && !defined(__MINGW64_VERSION_MAJOR) - unsigned short wType = ipaddr.unused2; // should be wType -#else - unsigned short wType = ipaddr.wType; -#endif - if (wType & MIB_IPADDR_DISCONNECTED) - { - pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface disconnected, " + out); - continue; - } - - if (wType & MIB_IPADDR_DELETED) - { - pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Interface deleted, " + out); - continue; - } - - if (ipaddr.dwIndex == bestInterface) - { - pqioutput(PQL_DEBUG_BASIC, pqinetzone, "Best address, " + out); - addrs.push_front(addr); - } - else - { - pqioutput(PQL_DEBUG_BASIC, pqinetzone, out); - addrs.push_back(addr); - } - } - - free (iptable); - - return (addrs.size() > 0); -} - // implement the improved unix inet address fn. // using old one. int inet_aton(const char *name, struct in_addr *addr) @@ -408,432 +263,84 @@ int inet_aton(const char *name, struct in_addr *addr) return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE); } - -// This returns in Net Byte Order. -// NB: Linux man page claims it is in Host Byte order, but -// this is blatantly wrong!..... (for Debian anyway) -// Making this consistent with the Actual behavior (rather than documented). -in_addr_t inet_netof(struct in_addr addr) -{ - return pqi_inet_netof(addr); -} - -// This returns in Host Byte Order. (as the man page says) -// Again, to be consistent with Linux. -in_addr_t inet_network(const char *inet_name) -{ - struct in_addr addr; - if (inet_aton(inet_name, &addr)) - { -#ifdef NET_DEBUG -// std::cerr << "inet_network(" << inet_name << ") : "; -// std::cerr << rs_inet_ntoa(addr) << std::endl; -#endif - return ntohl(inet_netof(addr)); - } - return 0xffffffff; - //return -1; -} - - #endif /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#include +#include +#ifdef WINDOWS_SYS +#include +#include +#pragma comment(lib, "IPHLPAPI.lib") +#else // WINDOWS_SYS +#include +#include +#endif // WINDOWS_SYS -// This returns in Net Byte Order. -// NB: Linux man page claims it is in Host Byte order, but -// this is blatantly wrong!..... (for Debian anyway) -// Making this consistent with the Actual behavior (rather than documented). -in_addr_t pqi_inet_netof(struct in_addr addr) +void getLocalAddressesFailed() { - // decide if A class address. - unsigned long haddr = ntohl(addr.s_addr); - unsigned long abit = haddr & 0xff000000UL; - unsigned long bbit = haddr & 0xffff0000UL; - unsigned long cbit = haddr & 0xffffff00UL; - -#ifdef NET_DEBUG - std::cerr << "inet_netof(" << rs_inet_ntoa(addr) << ") "; -#endif - - if (!((haddr >> 31) | 0x0UL)) // MSB = 0 - { -#ifdef NET_DEBUG - std::cerr << " Type A " << std::endl; - std::cerr << "\tShifted(31): " << (haddr >> 31); - std::cerr << " Xord(0x0UL): " << - !((haddr >> 31) | 0x0UL) << std::endl; -#endif - - return htonl(abit); - } - else if (!((haddr >> 30) ^ 0x2UL)) // 2MSBs = 10 - { -#ifdef NET_DEBUG - std::cerr << " Type B " << std::endl; - std::cerr << "\tShifted(30): " << (haddr >> 30); - std::cerr << " Xord(0x2UL): " << - !((haddr >> 30) | 0x2UL) << std::endl; -#endif - - return htonl(bbit); - } - else if (!((haddr >> 29) ^ 0x6UL)) // 3MSBs = 110 - { -#ifdef NET_DEBUG - std::cerr << " Type C " << std::endl; - std::cerr << "\tShifted(29): " << (haddr >> 29); - std::cerr << " Xord(0x6UL): " << - !((haddr >> 29) | 0x6UL) << std::endl; -#endif - - return htonl(cbit); - } - else if (!((haddr >> 28) ^ 0xeUL)) // 4MSBs = 1110 - { -#ifdef NET_DEBUG - std::cerr << " Type Multicast " << std::endl; - std::cerr << "\tShifted(28): " << (haddr >> 28); - std::cerr << " Xord(0xeUL): " << - !((haddr >> 29) | 0xeUL) << std::endl; -#endif - - return addr.s_addr; // return full address. - } - else if (!((haddr >> 27) ^ 0x1eUL)) // 5MSBs = 11110 - { -#ifdef NET_DEBUG - std::cerr << " Type Reserved " << std::endl; - std::cerr << "\tShifted(27): " << (haddr >> 27); - std::cerr << " Xord(0x1eUL): " << - !((haddr >> 27) | 0x1eUL) << std::endl; -#endif - - return addr.s_addr; // return full address. - } - return htonl(abit); + std::cerr << "FATAL ERROR: getLocalAddresses failed!" << std::endl; + exit(1); } -int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 ) +bool getLocalAddresses(std::list & addrs) { - if (addr1.sin_family != addr2.sin_family) - return addr1.sin_family - addr2.sin_family; - if (addr1.sin_addr.s_addr != addr2.sin_addr.s_addr) - return (addr1.sin_addr.s_addr - addr2.sin_addr.s_addr); - if (addr1.sin_port != addr2.sin_port) - return (addr1.sin_port - addr2.sin_port); - return 0; -} + addrs.clear(); -int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 ) -{ -#ifdef NET_DEBUG - std::string out; - rs_sprintf(out, "inaddr_cmp(%s-%lu,%s-%lu)", rs_inet_ntoa(addr1.sin_addr).c_str(), addr1.sin_addr.s_addr, rs_inet_ntoa(addr2.sin_addr).c_str(), addr2.sin_addr.s_addr); - pqioutput(PQL_DEBUG_BASIC, pqinetzone, out); -#endif +#ifdef WINDOWS_SYS + // Seems strange to me but M$ documentation suggests to allocate this way... + DWORD bf_size = 16000; + IP_ADAPTER_ADDRESSES* adapter_addresses = (IP_ADAPTER_ADDRESSES*) malloc(bf_size); + DWORD error = GetAdaptersAddresses(AF_UNSPEC, + GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | + GAA_FLAG_SKIP_FRIENDLY_NAME, + NULL, + adapter_addresses, + &bf_size); + if (error != ERROR_SUCCESS) getLocalAddressesFailed(); - - if (addr1.sin_addr.s_addr == addr2.sin_addr.s_addr) + IP_ADAPTER_ADDRESSES* adapter(NULL); + for(adapter = adapter_addresses; NULL != adapter; adapter = adapter->Next) { - return 0; + IP_ADAPTER_UNICAST_ADDRESS* address; + for ( address = adapter->FirstUnicastAddress; address; address = address->Next) + { + sockaddr_storage * tmp = new sockaddr_storage; + sockaddr_storage_clear(*tmp); + if (sockaddr_storage_copyip(* tmp, * reinterpret_cast(address->Address.lpSockaddr))) + addrs.push_back(*tmp); + else delete tmp; + } } - if (addr1.sin_addr.s_addr < addr2.sin_addr.s_addr) - return -1; - return 1; -} - -int inaddr_cmp(struct sockaddr_in addr1, unsigned long addr2) -{ -#ifdef NET_DEBUG - struct in_addr inaddr_tmp; - inaddr_tmp.s_addr = addr2; - - std::string out; - rs_sprintf(out, "inaddr_cmp2(%s vs %s /or/ %10x vs %10x)", rs_inet_ntoa(addr1.sin_addr).c_str(), rs_inet_ntoa(inaddr_tmp).c_str(), addr1.sin_addr.s_addr, addr2); - pqioutput(PQL_DEBUG_BASIC, pqinetzone, out); -#endif - - if (addr1.sin_addr.s_addr == addr2) - { - return 0; - } - if (addr1.sin_addr.s_addr < addr2) - return -1; - return 1; -} - -bool getPreferredInterface_ipv4(in_addr &routeAddr, struct in_addr &prefAddr) // returns best addr. -{ - std::list addrs; - std::list::iterator it; - struct in_addr addr_zero, addr_loop, addr_priv, addr_ext; + free(adapter_addresses); +#else // WINDOWS_SYS + struct ifaddrs *ifsaddrs, *ifa; + if(getifaddrs(&ifsaddrs) != 0) getLocalAddressesFailed(); + for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next ) + if ( ifa->ifa_addr && (ifa->ifa_flags & IFF_UP) ) + { + sockaddr_storage * tmp = new sockaddr_storage; + sockaddr_storage_clear(*tmp); + if (sockaddr_storage_copyip(* tmp, * reinterpret_cast(ifa->ifa_addr))) + addrs.push_back(*tmp); + else delete tmp; + } + freeifaddrs(ifsaddrs); +#endif // WINDOWS_SYS #ifdef NET_DEBUG - struct in_addr addr; -#endif - - bool found_zero = false; - bool found_loopback = false; - bool found_priv = false; - bool found_ext = false; - - if (!getLocalInterfaces_ipv4(routeAddr, addrs)) - { - return false; - } - - memset(&addr_zero, 0, sizeof(addr_zero)); - memset(&addr_loop, 0, sizeof(addr_loop)); - memset(&addr_priv, 0, sizeof(addr_priv)); - memset(&addr_ext, 0, sizeof(addr_ext)); - -#ifdef NET_DEBUG - memset(&addr, 0, sizeof(addr)); -#endif - - // find the first of each of these. - // if ext - take first. - // if no ext -> first priv - // if no priv -> first loopback. - -#ifdef NET_DEBUG - std::cerr << "getPreferredInterface() " << addrs.size() << " interfaces." << std::endl; -#endif - + std::list::iterator it; + std::cout << "getLocalAddresses(...) returning: <" ; for(it = addrs.begin(); it != addrs.end(); ++it) - { - struct in_addr addr = *it; - -#ifdef NET_DEBUG - std::cerr << "Examining addr: " << rs_inet_ntoa(addr); - std::cerr << " => " << (uint32_t) addr.s_addr << std::endl ; + std::cout << sockaddr_storage_iptostring(*it) << ", "; + std::cout << ">" << std::endl; #endif - // for windows silliness (returning 0.0.0.0 as valid addr!). - if (addr.s_addr == 0) - { - if (!found_zero) - { -#ifdef NET_DEBUG - std::cerr << "\tFound Zero Address" << std::endl ; -#endif - - found_zero = true; - addr_zero = addr; - } - } - else if (isLoopbackNet(&addr)) - { - if (!found_loopback) - { -#ifdef NET_DEBUG - std::cerr << "\tFound Loopback Address" << std::endl ; -#endif - - found_loopback = true; - addr_loop = addr; - } - } - else if (isPrivateNet(&addr)) - { - if (!found_priv) - { -#ifdef NET_DEBUG - std::cerr << "\tFound Private Address" << std::endl ; -#endif - - found_priv = true; - addr_priv = addr; - } - } - else - { - if (!found_ext) - { -#ifdef NET_DEBUG - std::cerr << "\tFound Other Address (Ext?) " << std::endl ; -#endif - found_ext = true; - addr_ext = addr; - } - } - } - - if(found_ext) // external address is best. - { - prefAddr = addr_ext; - return true; - } - - if (found_priv) - { - prefAddr = addr_priv; - return true; - } - - // next bit can happen under windows, - // a general address is still - // preferable to a loopback device. - if (found_zero) - { - prefAddr = addr_zero; - return true; - } - - if (found_loopback) - { - prefAddr = addr_loop; - return true; - } - - // shound be 255.255.255.255 (error). - prefAddr.s_addr = 0xffffffff; - return false; + return !addrs.empty(); } - -bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr) -{ - struct in_addr existing_addr; - struct in_addr pref_addr; - - { - struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr; - if (eaddr->sin_family != AF_INET) - { - std::cerr << "getPreferredInterface() ERROR only valid for IPv4 for now"; - abort(); - return false; - } - existing_addr = eaddr->sin_addr; - } - - if (getPreferredInterface_ipv4(existing_addr, pref_addr)) - { - /* store into prefAddr */ - sockaddr_storage_clear(prefAddr); - struct sockaddr_in *addr = (sockaddr_in *) &prefAddr; - addr->sin_family = AF_INET; - addr->sin_addr = pref_addr; - addr->sin_port = htons(0); - - return true; - } - return false; -} - - -bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list &addrs) -{ - struct in_addr existing_addr; - std::list local_addrs; - - { - struct sockaddr_in *eaddr = (sockaddr_in *) &existAddr; - if (eaddr->sin_family != AF_INET) - { - std::cerr << "getLocalInterfaces() ERROR only valid for IPv4 for now"; - abort(); - return false; - } - existing_addr = eaddr->sin_addr; - } - - if (getLocalInterfaces_ipv4(existing_addr, local_addrs)) - { - std::list::iterator it; - for(it = local_addrs.begin(); it != local_addrs.end(); ++it) - { - /* store into prefAddr */ - - sockaddr_storage localAddr; - sockaddr_storage_clear(localAddr); - struct sockaddr_in *addr = (sockaddr_in *) &localAddr; - addr->sin_family = AF_INET; - addr->sin_addr = *it; - addr->sin_port = htons(0); - addrs.push_back(localAddr); - } - return true; - } - return false; -} - -/* This just might be portable!!! will see!!! - * Unfortunately this is usable on winXP+, determined by: (_WIN32_WINNT >= 0x0501) - * but not older platforms.... which must use gethostbyname. - * - * include it for now..... - */ - -bool LookupDNSAddr(std::string name, struct sockaddr_in &addr) -{ - -#if 1 - char service[100]; - struct addrinfo hints_st; - struct addrinfo *hints = &hints_st; - struct addrinfo *res; - - hints -> ai_flags = 0; // (cygwin don;t like these) AI_ADDRCONFIG | AI_NUMERICSERV; - hints -> ai_family = AF_INET; - hints -> ai_socktype = 0; - hints -> ai_protocol = 0; - hints -> ai_addrlen = 0; - hints -> ai_addr = NULL; - hints -> ai_canonname = NULL; - hints -> ai_next = NULL; - - /* get the port number */ - sprintf(service, "%d", ntohs(addr.sin_port)); - - /* set it to IPV4 */ -#ifdef NET_DEBUG - std::cerr << "LookupDNSAddr() name: " << name << " service: " << service << std::endl; -#endif - - int err = 0; - if (0 != (err = getaddrinfo(name.c_str(), service, hints, &res))) - { -#ifdef NET_DEBUG - std::cerr << "LookupDNSAddr() getaddrinfo failed!" << std::endl; - std::cerr << "Error: " << gai_strerror(err) << std::endl; -#endif - return false; - } - - if (res) - { - if (res->ai_family == AF_INET) - { - addr = *((struct sockaddr_in *) res->ai_addr); - freeaddrinfo(res); - -#ifdef NET_DEBUG - std::cerr << "LookupDNSAddr() getaddrinfo found address" << std::endl; - std::cerr << "addr: " << rs_inet_ntoa(addr.sin_addr) << std::endl; - std::cerr << "port: " << ntohs(addr.sin_port) << std::endl; -#endif - return true; - } - freeaddrinfo(res); - } - -#ifdef NET_DEBUG - std::cerr << "getaddrinfo failed - no address" << std::endl; -#endif - -#endif -#ifdef NET_DEBUG - //std::cerr << "getaddrinfo disabled" << std::endl; -#endif - return false; -} - /************************************************************* * Socket Library Wrapper Functions * to get over the crapness of the windows. diff --git a/libretroshare/src/pqi/pqinetwork.h b/libretroshare/src/pqi/pqinetwork.h index 32719f90f..7cb7f93cf 100644 --- a/libretroshare/src/pqi/pqinetwork.h +++ b/libretroshare/src/pqi/pqinetwork.h @@ -49,9 +49,6 @@ #include "util/rsnet.h" /* more generic networking header */ // Some Network functions that are missing from windows. - -in_addr_t inet_netof(struct in_addr addr); -in_addr_t inet_network(const char *inet_name); int inet_aton(const char *name, struct in_addr *addr); extern int errno; /* Define extern errno, to duplicate unix behaviour */ @@ -94,20 +91,11 @@ extern int errno; /* Define extern errno, to duplicate unix behaviour */ #include // Same def - different functions... - void showSocketError(std::string &out); std::string socket_errorType(int err); -int sockaddr_cmp(struct sockaddr_in &addr1, struct sockaddr_in &addr2 ); -int inaddr_cmp(struct sockaddr_in addr1, struct sockaddr_in addr2 ); -int inaddr_cmp(struct sockaddr_in addr1, unsigned long); -bool getPreferredInterface(struct sockaddr_storage &existAddr, struct sockaddr_storage &prefAddr); // returns best addr. -bool getLocalInterfaces(struct sockaddr_storage &existAddr, std::list &addrs); // returns all possible addrs. - -in_addr_t pqi_inet_netof(struct in_addr addr); // our implementation. - -bool LookupDNSAddr(std::string name, struct sockaddr_in &addr); +bool getLocalAddresses(std::list & addrs); /* universal socket interface */ diff --git a/libretroshare/src/tests/pqi/TestNotes.txt b/libretroshare/src/tests/pqi/TestNotes.txt index 655c9d7bc..6d6089e9b 100644 --- a/libretroshare/src/tests/pqi/TestNotes.txt +++ b/libretroshare/src/tests/pqi/TestNotes.txt @@ -59,7 +59,6 @@ net_test Tested Code: pqinetwork.cc, rsnet.cc Description: (1) Tests ntohll / htonll -(2) Demonstrates inet_netof / inet_network strange behaviour. (3) Tests socket binding. ------------------------------------------------------------ @@ -71,17 +70,6 @@ Description: (2) isPrivateNet() (3) isLoopbackNet() (5) isValidNet() -(7) pqi_inet_netof() - ------------------------------------------------------------- -netiface_test ------------------------------------------------------------- -Tested Code: pqinetwork.cc -Description : -(1) getPreferredInterface() -(2) getLocalInterfaces() - -This is currently a manual test - needs to be converted. ------------------------------------------------------------ pqiarchive_test diff --git a/libretroshare/src/tests/pqi/net_test.cc b/libretroshare/src/tests/pqi/net_test.cc index 8df64d440..ff7744141 100644 --- a/libretroshare/src/tests/pqi/net_test.cc +++ b/libretroshare/src/tests/pqi/net_test.cc @@ -39,7 +39,6 @@ bool test_byte_manipulation(); bool test_local_address_manipulation(); -bool test_address_listen(); INITTEST(); @@ -49,8 +48,6 @@ int main(int argc, char **argv) std::cerr << "libretroshare:pqi " << argv[0] << std::endl; test_byte_manipulation(); - test_local_address_manipulation(); - test_address_listen(); FINALREPORT("libretroshare Net Basics Tests"); return TESTRESULT(); @@ -89,160 +86,8 @@ const char * localnet2_addrstr = "10.0.0.1"; const char * localnet3_addrstr = "10.5.63.78"; const char * localnet4_addrstr = "192.168.74.91"; - /* test 2: address manipulation */ -bool test_local_address_manipulation() -{ - struct sockaddr_in loopback_addr; - struct sockaddr_in localnet1_addr; - struct sockaddr_in localnet2_addr; - struct sockaddr_in localnet3_addr; - struct sockaddr_in localnet4_addr; - - std::cerr << "test_local_address_manipulation() NB: This function demonstrates "; - std::cerr << "the strange behaviour of inet_netof() and inet_network()"; - std::cerr << std::endl; - std::cerr << "FAILures are not counted in the test!"; - std::cerr << std::endl; - - /* setup some addresses */ - inet_aton(loopback_addrstr, &(loopback_addr.sin_addr)); - inet_aton(localnet1_addrstr, &(localnet1_addr.sin_addr)); - inet_aton(localnet2_addrstr, &(localnet2_addr.sin_addr)); - inet_aton(localnet3_addrstr, &(localnet3_addr.sin_addr)); - inet_aton(localnet4_addrstr, &(localnet4_addr.sin_addr)); - - - std::cerr << "Loopback Addr " << rs_inet_ntoa(loopback_addr.sin_addr); - std::cerr << std::endl; - - std::cerr << "Localnet1 Addr " << rs_inet_ntoa(localnet1_addr.sin_addr); - std::cerr << std::endl; - std::cerr << "Localnet2 Addr " << rs_inet_ntoa(localnet2_addr.sin_addr); - std::cerr << std::endl; - std::cerr << "Localnet3 Addr " << rs_inet_ntoa(localnet3_addr.sin_addr); - std::cerr << std::endl; - std::cerr << "Localnet4 Addr " << rs_inet_ntoa(localnet4_addr.sin_addr); - std::cerr << std::endl; - std::cerr << std::endl; - - std::cerr << "Test 1a - networks"; - std::cerr << std::endl; - - struct sockaddr_in addr_ans, addr1, addr2; - std::string addr_ans_str; - - addr_ans_str = "127.0.0.0"; - inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr)); - addr1.sin_addr.s_addr = htonl(inet_netof(loopback_addr.sin_addr)); - addr2.sin_addr.s_addr = htonl(inet_network(loopback_addrstr)); - - std::cerr << "Loopback Net(expected): " << addr_ans_str; - std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr); - std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr); - std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr); - std::cerr << std::endl; - - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr))); - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr))); - - - addr_ans_str = "192.168.0.0"; - inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr)); - addr1.sin_addr.s_addr = htonl(inet_netof(localnet1_addr.sin_addr)); - addr2.sin_addr.s_addr = htonl(inet_network(localnet1_addrstr)); - - std::cerr << "Localnet1 Net(expected): " << addr_ans_str; - std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr); - std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr); - std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr); - std::cerr << std::endl; - - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr))); - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr))); - - addr_ans_str = "10.0.0.0"; - inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr)); - addr1.sin_addr.s_addr = htonl(inet_netof(localnet2_addr.sin_addr)); - addr2.sin_addr.s_addr = htonl(inet_network(localnet2_addrstr)); - - std::cerr << "Localnet2 Net(expected): " << addr_ans_str; - std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr); - std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr); - std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr); - std::cerr << std::endl; - - - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr))); - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr))); - - - addr_ans_str = "10.0.0.0"; - inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr)); - addr1.sin_addr.s_addr = htonl(inet_netof(localnet3_addr.sin_addr)); - addr2.sin_addr.s_addr = htonl(inet_network(localnet3_addrstr)); - - std::cerr << "Localnet3 Net(expected): " << addr_ans_str; - std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr); - std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr); - std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr); - std::cerr << std::endl; - - - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr))); - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr))); - - - addr_ans_str = "192.168.0.0"; - inet_aton(addr_ans_str.c_str(), &(addr_ans.sin_addr)); - addr1.sin_addr.s_addr = htonl(inet_netof(localnet4_addr.sin_addr)); - addr2.sin_addr.s_addr = htonl(inet_network(localnet4_addrstr)); - - std::cerr << "Localnet4 Net(expected): " << addr_ans_str; - std::cerr << " -> " << rs_inet_ntoa(addr_ans.sin_addr); - std::cerr << " Net(1):" << rs_inet_ntoa(addr1.sin_addr); - std::cerr << " Net(2):" << rs_inet_ntoa(addr2.sin_addr); - std::cerr << std::endl; - - - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr1.sin_addr))); - //CHECK( 0 == strcmp(addr_ans_str.c_str(), rs_inet_ntoa(addr2.sin_addr))); - - REPORT("Test Local Address Manipulation"); - return true; -} - bool test_bind_addr(struct sockaddr_in addr); -bool test_address_listen() -{ - struct sockaddr_in addr1, addr2, addr3; - - sockaddr_clear(&addr1); - addr1.sin_family = AF_INET; - inet_aton(loopback_addrstr, &(addr1.sin_addr)); - addr1.sin_port = htons(12345); - - sockaddr_clear(&addr2); - addr2.sin_family = AF_INET; - getPreferredInterface(addr2.sin_addr); // returns best addr. - addr2.sin_port = htons(13245); - - sockaddr_clear(&addr3); - addr3.sin_family = AF_INET; - getPreferredInterface(addr3.sin_addr); // returns best addr. - addr3.sin_port = htons(23451); - - /* test bind to loopback, and preferred interfaces */ - test_bind_addr(addr1); - test_bind_addr(addr2); - test_bind_addr(addr3); - - - - REPORT("Test Address Listen"); - return true; -} - bool test_bind_addr(struct sockaddr_in addr) { diff --git a/libretroshare/src/tests/pqi/net_test1.cc b/libretroshare/src/tests/pqi/net_test1.cc index 13c7c51ba..fe0f7e353 100644 --- a/libretroshare/src/tests/pqi/net_test1.cc +++ b/libretroshare/src/tests/pqi/net_test1.cc @@ -54,7 +54,6 @@ int test_isExternalNet(); int test_isPrivateNet(); int test_isLoopbackNet(); int test_isValidNet(); -int test_pqi_inet_netof(); INITTEST(); @@ -66,7 +65,6 @@ int main(int argc, char **argv) test_isPrivateNet(); test_isLoopbackNet(); test_isValidNet(); - test_pqi_inet_netof(); FINALREPORT("net_test1"); @@ -170,40 +168,3 @@ int test_isValidNet() return 1; } - -int test_pqi_inet_netof() -{ - struct in_addr localnet1_addr; - struct in_addr localnet2_addr; - struct in_addr localnet3_addr; - struct in_addr localnet4_addr; - struct in_addr localnet5_addr; - struct in_addr localnet6_addr; - struct in_addr localnet7_addr; - struct in_addr localnet8_addr; - struct in_addr external_addr; - - inet_aton(localnet1_addrstr, &localnet1_addr); - inet_aton(localnet2_addrstr, &localnet2_addr); - inet_aton(localnet3_addrstr, &localnet3_addr); - inet_aton(localnet4_addrstr, &localnet4_addr); - inet_aton(localnet5_addrstr, &localnet5_addr); - inet_aton(localnet6_addrstr, &localnet6_addr); - inet_aton(localnet7_addrstr, &localnet7_addr); - inet_aton(localnet8_addrstr, &localnet8_addr); - inet_aton(external_addrstr, &external_addr); - - CHECK(pqi_inet_netof(localnet1_addr)==htonl(10<<24)); - CHECK(pqi_inet_netof(localnet2_addr)==htonl(169<<24 | 254<<16)); - CHECK(pqi_inet_netof(localnet3_addr)==htonl(172<<24 | 16<<16)); - CHECK(pqi_inet_netof(localnet4_addr)==htonl(192<<24 | 168<<16 | 1<<8)); - CHECK(pqi_inet_netof(localnet5_addr)==htonl(10<<24)); - CHECK(pqi_inet_netof(localnet6_addr)==htonl(169<<24 | 254<<16)); - CHECK(pqi_inet_netof(localnet7_addr)==htonl(172<<24 | 20<<16)); - CHECK(pqi_inet_netof(localnet8_addr)==htonl(192<<24 | 168<<16 | 1<<8)); - CHECK(pqi_inet_netof(external_addr)==htonl(74<<24)); - - REPORT("pqi_inet_netof()"); - - return 1; -} diff --git a/libretroshare/src/tests/pqi/netiface_test.cc b/libretroshare/src/tests/pqi/netiface_test.cc deleted file mode 100644 index a031ff178..000000000 --- a/libretroshare/src/tests/pqi/netiface_test.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * libretroshare/src/pqi net_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * NETWORKING Test to check Big/Little Endian behaviour - * as well as socket behaviour - * - */ - -#include "pqi/pqinetwork.h" -#include "util/rsnet.h" -#include -#include - - -bool test_iface(); -bool test_iface_loop(); - -int main(int argc, char **argv) -{ - bool repeat = false; - if (argc > 1) - { - repeat = true; - } - - test_iface(); - - if (repeat) - { - test_iface_loop(); - } - - return 1; -} - - /* test 1: single check if interfaces */ -bool test_iface() -{ - struct in_addr pref_iface; - std::list ifaces; - std::list::iterator it; - - getPreferredInterface(pref_iface); - getLocalInterfaces(ifaces); - - std::cerr << "test_iface()" << std::endl; - for(it = ifaces.begin(); it != ifaces.end(); it++) - { - std::cerr << "available iface: " << rs_inet_ntoa(*it) << std::endl; - } - std::cerr << "preferred " << rs_inet_ntoa(pref_iface) << std::endl; - - return true; -} - - /* test 2: catch changing interfaces */ -bool test_iface_loop() -{ - std::cerr << "test_iface_loop()" << std::endl; - struct in_addr curr_pref_iface; - getPreferredInterface(curr_pref_iface); - time_t start = time(NULL); - while(1) - { - struct in_addr pref_iface; - std::list ifaces; - std::list::iterator it; - - getPreferredInterface(pref_iface); - getLocalInterfaces(ifaces); - - - std::cerr << "T(" << time(NULL) - start << ") "; - - for(it = ifaces.begin(); it != ifaces.end(); it++) - { - std::cerr << " I: " << rs_inet_ntoa(*it); - } - std::cerr << " P: " << rs_inet_ntoa(pref_iface) << std::endl; - - if (curr_pref_iface.s_addr != - pref_iface.s_addr) - { - std::cerr << "+++++++++++++ Address CHANGED ++++++++++"; - std::cerr << std::endl; - std::cerr << "+++++++++++++ Address CHANGED ++++++++++"; - std::cerr << std::endl; - std::cerr << "+++++++++++++ Address CHANGED ++++++++++"; - std::cerr << std::endl; - - curr_pref_iface = pref_iface; - } - - sleep(1); - } - return true; -} - - diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index 002337fbe..0dd3b6741 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -88,7 +88,7 @@ std::string rs_inet_ntoa(struct in_addr in); // Standard bind, on OSX anyway will not accept a longer socklen for IPv4. // so hidding details behind function. -int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen); +int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen); void sockaddr_storage_clear(struct sockaddr_storage &addr); @@ -117,6 +117,7 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr); std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr); std::string sockaddr_storage_iptostring(const struct sockaddr_storage &addr); std::string sockaddr_storage_porttostring(const struct sockaddr_storage &addr); +void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputString = NULL); // output //void sockaddr_storage_output(const struct sockaddr_storage &addr, std::ostream &out); @@ -129,6 +130,6 @@ bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr); bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr); bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr); - +bool rs_inet_ntop(const sockaddr_storage &addr, std::string &dst); #endif /* RS_UNIVERSAL_NETWORK_HEADER */ diff --git a/libretroshare/src/util/rsnet_ss.cc b/libretroshare/src/util/rsnet_ss.cc index c7b94c89b..891c2b56e 100644 --- a/libretroshare/src/util/rsnet_ss.cc +++ b/libretroshare/src/util/rsnet_ss.cc @@ -23,6 +23,9 @@ * */ +#include +#include + #include "util/rsnet.h" #include "util/rsstring.h" #include "pqi/pqinetwork.h" @@ -85,7 +88,7 @@ bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &addr); /******************************** Socket Fns ***********************************/ // Standard bind, on OSX anyway will not accept a longer socklen for IPv4. // so hidding details behind function. -int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen) +int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen) { #ifdef SS_DEBUG std::cerr << "universal_bind()"; @@ -107,11 +110,8 @@ int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen) if (len > socklen) { - std::cerr << "universal_bind() ERROR len > socklen"; - std::cerr << std::endl; - + std::cerr << "universal_bind() ERROR len > socklen" << std::endl; len = socklen; - //return EINVAL; } return bind(fd, addr, len); @@ -155,8 +155,7 @@ bool sockaddr_storage_zeroip(struct sockaddr_storage &addr) bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) { #ifdef SS_DEBUG - std::cerr << "sockaddr_storage_copyip()"; - std::cerr << std::endl; + std::cerr << "sockaddr_storage_copyip()" << std::endl; #endif switch(src.ss_family) @@ -169,8 +168,7 @@ bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr break; default: #ifdef SS_DEBUG - std::cerr << "sockaddr_storage_copyip() invalid addr.ss_family"; - std::cerr << std::endl; + std::cerr << "sockaddr_storage_copyip() Unknown ss_family: " << src.ss_family << std::endl; #endif break; } @@ -192,11 +190,9 @@ uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr) case AF_INET6: return sockaddr_storage_ipv6_port(addr); break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_port() invalid addr.ss_family: " << addr.ss_family; - std::cerr << std::endl; -#endif + default: + std::cerr << "sockaddr_storage_port() invalid addr.ss_family" << std::endl; + sockaddr_storage_dump(addr); break; } return 0; @@ -205,8 +201,7 @@ uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr) bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port) { #ifdef SS_DEBUG - std::cerr << "sockaddr_storage_setport()"; - std::cerr << std::endl; + std::cerr << "sockaddr_storage_setport()" << std::endl; #endif switch(addr.ss_family) @@ -218,10 +213,7 @@ bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port) return sockaddr_storage_ipv6_setport(addr, port); break; default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_setport() invalid addr.ss_family"; - std::cerr << std::endl; -#endif + std::cerr << "sockaddr_storage_setport() invalid addr.ss_family" << std::endl; break; } return false; @@ -247,8 +239,7 @@ bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in * bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6) { - std::cerr << "sockaddr_storage_setipv6()"; - std::cerr << std::endl; + std::cerr << "sockaddr_storage_setipv6()" << std::endl; sockaddr_storage_clear(addr); struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr); @@ -391,8 +382,56 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr) return output; } +void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputString) +{ + // This function must not rely on others sockaddr_storage_* + std::stringstream output; + output << "sockaddr_storage_dump(addr) "; + switch (addr.ss_family){ + case AF_INET: + { + const sockaddr_in * in = (const sockaddr_in *) & addr; + output << "addr.ss_family = AF_INET"; + output << " in->sin_addr = "; + output << inet_ntoa(in->sin_addr); + output << " in->sin_port = "; + output << in->sin_port; + break; + } + case AF_INET6: + { + const sockaddr_in6 * in6 = (const sockaddr_in6 *) & addr; + std::string addrStr = "INVALID_IPV6"; + rs_inet_ntop(addr, addrStr); + output << "addr.ss_family = AF_INET6"; + output << " in6->sin6_addr = "; + output << addrStr; + output << " in6->sin6_scope_id = "; + output << in6->sin6_scope_id; + output << " in6->sin6_port = "; + output << in6->sin6_port; + break; + } + default: + { + output << "unknown addr.ss_family "; + const uint8_t * buf = reinterpret_cast(&addr); + for( uint32_t i = 0; i < sizeof(addr); ++i ) + output << std::setw(2) << std::setfill('0') << std::hex << +buf[i]; + }} + + if(outputString) + { + outputString->append(output.str() + "\n"); +#ifdef SS_DEBUG + std::cerr << output.str() << std::endl; +#endif + } + else + std::cerr << output.str() << std::endl; +} std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr) { @@ -670,8 +709,7 @@ bool sockaddr_storage_ipv6_zeroip(struct sockaddr_storage &addr) bool sockaddr_storage_ipv6_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) { #ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_copyip()"; - std::cerr << std::endl; + std::cerr << "sockaddr_storage_ipv6_copyip()" << std::endl; #endif struct sockaddr_in6 *dst_ptr = to_ipv6_ptr(dst); @@ -823,17 +861,14 @@ std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr return output; } -std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & /* addr */) +std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & addr) { - std::string output; - output += "IPv6-ADDRESS-TODO"; - return output; + std::string addrStr; + rs_inet_ntop(addr, addrStr); + return addrStr; } - - - /********************************* Net Checks ***********************************/ bool sockaddr_storage_ipv4_isnull(const struct sockaddr_storage &addr) { @@ -968,5 +1003,43 @@ bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &addr) return false; } +#ifdef WINDOWS_SYS +#include +#include +#endif +bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst) +{ + bool success = false; + char ipStr[255]; +#ifdef WINDOWS_SYS + // Use WSAAddressToString instead of InetNtop because the latter is missing + // on XP and is present only on Vista and newers + wchar_t wIpStr[255]; + long unsigned int len = 255; + sockaddr_storage tmp; + sockaddr_storage_clear(tmp); + sockaddr_storage_copyip(tmp, addr); + sockaddr * sptr = (sockaddr *) &tmp; + success = (0 == WSAAddressToString( sptr, sizeof(sockaddr_storage), NULL, wIpStr, &len )); + wcstombs(ipStr, wIpStr, len); +#else // WINDOWS_SYS + switch(addr.ss_family) + { + case AF_INET: + { + const struct sockaddr_in * addrv4p = (const struct sockaddr_in *) &addr; + success = inet_ntop( addr.ss_family, (const void *) &(addrv4p->sin_addr), ipStr, INET_ADDRSTRLEN ); + } + case AF_INET6: + { + const struct sockaddr_in6 * addrv6p = (const struct sockaddr_in6 *) &addr; + success = inet_ntop( addr.ss_family, (const void *) &(addrv6p->sin6_addr), ipStr, INET6_ADDRSTRLEN ); + } + } +#endif // WINDOWS_SYS + + dst = ipStr; + return success; +}