diff --git a/libretroshare/src/dht/p3bitdht_peers.cc b/libretroshare/src/dht/p3bitdht_peers.cc index f488af671..1b5425209 100644 --- a/libretroshare/src/dht/p3bitdht_peers.cc +++ b/libretroshare/src/dht/p3bitdht_peers.cc @@ -219,22 +219,31 @@ int p3BitDht::addBadPeer(const struct sockaddr_storage &addr, uint32_t /*reason* int p3BitDht::addKnownPeer(const std::string &pid, const struct sockaddr_storage &addr, uint32_t flags) { struct sockaddr_in addrv4; + if (addr.ss_family != AF_INET) { - std::cerr << "p3BitDht::addKnownPeer() cannot handle IPV6 Yet, aborting"; + std::cerr << "p3BitDht::addKnownPeer() Warning! Non IPv4 Address - Cannot handle IPV6 Yet."; std::cerr << std::endl; - abort(); + sockaddr_clear(&addrv4); + + if (flags & NETASSIST_KNOWN_PEER_ONLINE) + { + std::cerr << "p3BitDht::addKnownPeer() Non IPv4 Address & ONLINE. Abort()ing."; + std::cerr << std::endl; + abort(); + } } - struct sockaddr_in *ap = (struct sockaddr_in *) &addr; - - // convert. - addrv4.sin_family = ap->sin_family; - addrv4.sin_addr = ap->sin_addr; - addrv4.sin_port = ap->sin_port; - - - + else + { + + // convert. + struct sockaddr_in *ap = (struct sockaddr_in *) &addr; + addrv4.sin_family = ap->sin_family; + addrv4.sin_addr = ap->sin_addr; + addrv4.sin_port = ap->sin_port; + } + int p3type = 0; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 643f0964f..013fa0531 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -541,6 +541,7 @@ SOURCES += util/folderiterator.cc \ util/rsdir.cc \ util/rsdiscspace.cc \ util/rsnet.cc \ + util/rsnet_ss.cc \ util/extaddrfinder.cc \ util/dnsresolver.cc \ util/rsprint.cc \ diff --git a/libretroshare/src/pqi/p3netmgr.cc b/libretroshare/src/pqi/p3netmgr.cc index 382c0f417..8eed3d093 100644 --- a/libretroshare/src/pqi/p3netmgr.cc +++ b/libretroshare/src/pqi/p3netmgr.cc @@ -135,6 +135,12 @@ p3NetMgrIMPL::p3NetMgrIMPL() mOldNatHole = RSNET_NATHOLE_UNKNOWN; sockaddr_storage_clear(mLocalAddr); sockaddr_storage_clear(mExtAddr); + + // force to IPv4 for the moment. + mLocalAddr.ss_family = AF_INET; + mExtAddr.ss_family = AF_INET; + + mVisState = 0 ; } diff --git a/libretroshare/src/pqi/pqiassist.h b/libretroshare/src/pqi/pqiassist.h index 2823571b7..5a2eaabb2 100644 --- a/libretroshare/src/pqi/pqiassist.h +++ b/libretroshare/src/pqi/pqiassist.h @@ -74,8 +74,8 @@ class PortForwardParams uint32_t fwdId; uint32_t status; uint32_t typeFlags; - struct sockaddr_in intAddr; - struct sockaddr_in extaddr; + struct sockaddr_storage intAddr; + struct sockaddr_storage extaddr; }; class pqiNetAssistFirewall: public pqiNetAssist diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index 4e3567e45..bc359edb6 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -946,9 +946,34 @@ int unix_fcntl_nonblock(int fd) } -int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t addrlen) +int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t socklen) { - int ret = connect(fd, serv_addr, addrlen); + std::cerr << "unix_connect()"; + std::cerr << std::endl; + + const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) serv_addr; + socklen_t len = socklen; + + switch (ss_addr->ss_family) + { + case AF_INET: + len = sizeof(struct sockaddr_in); + break; + case AF_INET6: + len = sizeof(struct sockaddr_in6); + break; + } + + if (len > socklen) + { + std::cerr << "unix_connect() ERROR len > socklen"; + std::cerr << std::endl; + + len = socklen; + //return EINVAL; + } + + int ret = connect(fd, serv_addr, len); /******************* WINDOWS SPECIFIC PART ******************/ #ifdef WINDOWS_SYS // WINDOWS diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 10f35d946..6f68a543a 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -753,8 +753,9 @@ int pqissl::Initiate_Connection() waiting = WAITING_FAIL_INTERFACE; rslog(RSL_WARNING, pqisslzone, out); + // extra output for the moment. - //std::cerr << out.str(); + std::cerr << out; return -1; } diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 49db80942..a9bbc9492 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -182,15 +182,19 @@ int pqissllistenbase::setuplisten() #ifdef OPEN_UNIVERSAL_PORT struct sockaddr_storage tmpaddr = laddr; sockaddr_storage_zeroip(tmpaddr); - if (0 != (err = bind(lsock, (struct sockaddr *) &tmpaddr, sizeof(tmpaddr)))) + if (0 != (err = universal_bind(lsock, (struct sockaddr *) &tmpaddr, sizeof(tmpaddr)))) #else - if (0 != (err = bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr)))) + if (0 != (err = universal_bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr)))) #endif { std::string out = "pqissllistenbase::setuplisten() Cannot Bind to Local Address!\n"; showSocketError(out); pqioutput(PQL_ALERT, pqissllistenzone, out); std::cerr << out << std::endl; + std::cerr << "laddr: " << sockaddr_storage_tostring(laddr) << std::endl; +#ifdef OPEN_UNIVERSAL_PORT + std::cerr << "Zeroed tmpaddr: " << sockaddr_storage_tostring(tmpaddr) << std::endl; +#endif exit(1); return -1; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 8854c3f25..9614708dd 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -999,12 +999,14 @@ bool p3Peers::loadDetailsFromStringCert(const std::string &certstr, RsPeerDetai pd.isOnlyGPGdetail = pd.id.empty(); pd.service_perm_flags = RS_SERVICE_PERM_ALL ; - if (pd.isHiddenNode) + if (!cert.hidden_node_string().empty()) { + pd.isHiddenNode = true; pd.hiddenNodeAddress = cert.hidden_node_string(); } else { + pd.isHiddenNode = false; pd.localAddr = cert.loc_ip_string(); pd.localPort = cert.loc_port_us(); pd.extAddr = cert.ext_ip_string(); diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index ec772ec2f..07f15f774 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2110,22 +2110,16 @@ int RsServer::StartupRetroShare() // NOW WE BUILD THE SECOND STACK. // Create the Second UdpStack... Port should be random (but openable!). - - //#define MIN_RANDOM_PORT 30000 - //#define MAX_RANDOM_PORT 50000 + // We do this by binding to xx.xx.xx.xx:0 which which gives us a random port. struct sockaddr_in sndladdr; sockaddr_clear(&sndladdr); - // #ifdef LOCALNET_TESTING +#ifdef LOCALNET_TESTING + // // HACK Proxy Port near Dht Port - For Relay Testing. // uint16_t rndport = RsInitConfig::port + 3; // sndladdr.sin_port = htons(rndport); - // #else - // uint16_t rndport = MIN_RANDOM_PORT + RSRandom::random_u32() % (MAX_RANDOM_PORT - MIN_RANDOM_PORT); - // #endif - -#ifdef LOCALNET_TESTING rsFixedUdpStack *mProxyStack = new rsFixedUdpStack(UDP_TEST_RESTRICTED_LAYER, sndladdr); diff --git a/libretroshare/src/upnp/upnphandler_linux.cc b/libretroshare/src/upnp/upnphandler_linux.cc index 5d54b5581..f252d03f9 100644 --- a/libretroshare/src/upnp/upnphandler_linux.cc +++ b/libretroshare/src/upnp/upnphandler_linux.cc @@ -386,18 +386,22 @@ void upnphandler::setExternalPort(unsigned short eport_in) } /* as determined by uPnP */ -bool upnphandler::getInternalAddress(struct sockaddr_in &addr) +bool upnphandler::getInternalAddress(struct sockaddr_storage &addr) { dataMtx.lock(); /*** LOCK MUTEX ***/ - addr = upnp_iaddr; + bool valid = (upnpState >= RS_UPNP_S_ACTIVE); + // copy to universal addr. + sockaddr_storage_clear(addr); + sockaddr_storage_setipv4(addr, &upnp_iaddr); + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ return valid; } -bool upnphandler::getExternalAddress(struct sockaddr_in &addr) +bool upnphandler::getExternalAddress(struct sockaddr_storage &addr) { std::string externalAdress = cUPnPControlPoint->getExternalAddress(); @@ -416,9 +420,13 @@ bool upnphandler::getExternalAddress(struct sockaddr_in &addr) inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr)); upnp_eaddr.sin_family = AF_INET; upnp_eaddr.sin_port = htons(eport_curr); + + // copy to universal addr. + sockaddr_storage_clear(addr); + sockaddr_storage_setipv4(addr, &upnp_eaddr); + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - addr = upnp_eaddr; return true; } else diff --git a/libretroshare/src/upnp/upnphandler_linux.h b/libretroshare/src/upnp/upnphandler_linux.h index e0b8588a2..b0300dfc9 100644 --- a/libretroshare/src/upnp/upnphandler_linux.h +++ b/libretroshare/src/upnp/upnphandler_linux.h @@ -36,8 +36,8 @@ class upnphandler: public pqiNetAssistFirewall virtual void setInternalPort(unsigned short iport_in); virtual void setExternalPort(unsigned short eport_in); - virtual bool getInternalAddress(struct sockaddr_in &addr); - virtual bool getExternalAddress(struct sockaddr_in &addr); + virtual bool getInternalAddress(struct sockaddr_storage &addr); + virtual bool getExternalAddress(struct sockaddr_storage &addr); /* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */ virtual bool requestPortForward(const PortForwardParams ¶ms) { return false; } diff --git a/libretroshare/src/upnp/upnphandler_miniupnp.cc b/libretroshare/src/upnp/upnphandler_miniupnp.cc index b4cb3c199..3c2442527 100644 --- a/libretroshare/src/upnp/upnphandler_miniupnp.cc +++ b/libretroshare/src/upnp/upnphandler_miniupnp.cc @@ -535,7 +535,7 @@ void upnphandler::setExternalPort(unsigned short eport_in) } /* as determined by uPnP */ -bool upnphandler::getInternalAddress(struct sockaddr_in &addr) +bool upnphandler::getInternalAddress(struct sockaddr_storage &addr) { // std::cerr << "UPnPHandler::getInternalAddress() pre Lock!" << std::endl; dataMtx.lock(); /*** LOCK MUTEX ***/ @@ -543,7 +543,10 @@ bool upnphandler::getInternalAddress(struct sockaddr_in &addr) std::cerr << "UPnPHandler::getInternalAddress()" << std::endl; - addr = upnp_iaddr; + // copy to universal addr. + sockaddr_storage_clear(addr); + sockaddr_storage_setipv4(addr, &upnp_iaddr); + bool valid = (upnpState >= RS_UPNP_S_ACTIVE); dataMtx.unlock(); /*** UNLOCK MUTEX ***/ @@ -551,14 +554,18 @@ bool upnphandler::getInternalAddress(struct sockaddr_in &addr) return valid; } -bool upnphandler::getExternalAddress(struct sockaddr_in &addr) +bool upnphandler::getExternalAddress(struct sockaddr_storage &addr) { // std::cerr << "UPnPHandler::getExternalAddress() pre Lock!" << std::endl; dataMtx.lock(); /*** LOCK MUTEX ***/ // std::cerr << "UPnPHandler::getExternalAddress() postLock!" << std::endl; std::cerr << "UPnPHandler::getExternalAddress()" << std::endl; - addr = upnp_eaddr; + + // copy to universal addr. + sockaddr_storage_clear(addr); + sockaddr_storage_setipv4(addr, &upnp_eaddr); + bool valid = (upnpState == RS_UPNP_S_ACTIVE); dataMtx.unlock(); /*** UNLOCK MUTEX ***/ diff --git a/libretroshare/src/upnp/upnphandler_miniupnp.h b/libretroshare/src/upnp/upnphandler_miniupnp.h index c30b3e39a..6b4660e32 100644 --- a/libretroshare/src/upnp/upnphandler_miniupnp.h +++ b/libretroshare/src/upnp/upnphandler_miniupnp.h @@ -62,8 +62,8 @@ virtual bool getActive(); virtual void setInternalPort(unsigned short iport_in); virtual void setExternalPort(unsigned short eport_in); -virtual bool getInternalAddress(struct sockaddr_in &addr); -virtual bool getExternalAddress(struct sockaddr_in &addr); +virtual bool getInternalAddress(struct sockaddr_storage &addr); +virtual bool getExternalAddress(struct sockaddr_storage &addr); /* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */ virtual bool requestPortForward(const PortForwardParams &/*params*/) { return false; } diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index 7b854c00c..01f73a313 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -78,6 +78,10 @@ std::string rs_inet_ntoa(struct in_addr in); /***************************/ // sockaddr_storage 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); + void sockaddr_storage_clear(struct sockaddr_storage &addr); // mods. @@ -86,9 +90,13 @@ bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr); bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port); +bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *addr_ipv4); +bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6); + bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name); bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, const uint16_t port); + // comparisons. bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b); diff --git a/libretroshare/src/util/rsnet_ss.cc b/libretroshare/src/util/rsnet_ss.cc new file mode 100644 index 000000000..ed4f188eb --- /dev/null +++ b/libretroshare/src/util/rsnet_ss.cc @@ -0,0 +1,971 @@ +/* + * libretroshare/src/util: rsnet_ss.cc + * + * sockaddr_storage functions for RetroShare. + * + * Copyright 2013-2013 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.1 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". + * + */ + +#include "util/rsnet.h" +#include "util/rsstring.h" + +/***************************** Internal Helper Fns ******************************/ + +/******************************** Casting **************************************/ +struct sockaddr_in *to_ipv4_ptr(struct sockaddr_storage &addr); +struct sockaddr_in6 *to_ipv6_ptr(struct sockaddr_storage &addr); + +const struct sockaddr_in *to_const_ipv4_ptr(const struct sockaddr_storage &addr); +const struct sockaddr_in6 *to_const_ipv6_ptr(const struct sockaddr_storage &addr); + + +/******************************** Set / Clear ***********************************/ + +bool sockaddr_storage_ipv4_zeroip(struct sockaddr_storage &addr); +bool sockaddr_storage_ipv4_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src); + +uint16_t sockaddr_storage_ipv4_port(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, uint16_t port); + +bool sockaddr_storage_ipv6_zeroip(struct sockaddr_storage &addr); +bool sockaddr_storage_ipv6_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src); + +uint16_t sockaddr_storage_ipv6_port(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv6_setport(struct sockaddr_storage &addr, uint16_t port); + +/******************************** Comparisions **********************************/ + +bool sockaddr_storage_ipv4_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv4_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv4_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv4_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv4_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); + +bool sockaddr_storage_ipv6_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv6_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv6_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv6_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); +bool sockaddr_storage_ipv6_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2); + + +/********************************* Output ***********************************/ +std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr); +std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage &addr); + +/********************************* Net Checks ***********************************/ +bool sockaddr_storage_ipv4_isnull(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv4_isValidNet(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv4_isLoopbackNet(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv4_isPrivateNet(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv4_isExternalNet(const struct sockaddr_storage &addr); + +bool sockaddr_storage_ipv6_isnull(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage &addr); +bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &addr); +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) +{ + std::cerr << "universal_bind()"; + std::cerr << std::endl; + + const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) addr; + socklen_t len = socklen; + + switch (ss_addr->ss_family) + { + case AF_INET: + len = sizeof(struct sockaddr_in); + break; + case AF_INET6: + len = sizeof(struct sockaddr_in6); + break; + } + + if (len > socklen) + { + std::cerr << "universal_bind() ERROR len > socklen"; + std::cerr << std::endl; + + len = socklen; + //return EINVAL; + } + + return bind(fd, addr, len); +} + + + + +/******************************** Set / Clear ***********************************/ + +void sockaddr_storage_clear(struct sockaddr_storage &addr) +{ + memset(&addr, 0, sizeof(addr)); +} + +// mods. +bool sockaddr_storage_zeroip(struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_zeroip()"; + std::cerr << std::endl; + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_zeroip(addr); + break; + case AF_INET6: + return sockaddr_storage_ipv6_zeroip(addr); + break; + default: + std::cerr << "sockaddr_storage_zeroip() invalid addr.ss_family clearing whole address"; + std::cerr << std::endl; + sockaddr_storage_clear(addr); + break; + } + return false; +} + +bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) +{ + std::cerr << "sockaddr_storage_copyip()"; + std::cerr << std::endl; + switch(src.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_copyip(dst, src); + break; + case AF_INET6: + return sockaddr_storage_ipv6_copyip(dst, src); + break; + default: + std::cerr << "sockaddr_storage_copyip() invalid addr.ss_family"; + std::cerr << std::endl; + break; + } + return false; +} + + +uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_port()"; + std::cerr << std::endl; + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_port(addr); + break; + case AF_INET6: + return sockaddr_storage_ipv6_port(addr); + break; + default: + std::cerr << "sockaddr_storage_port() invalid addr.ss_family"; + std::cerr << std::endl; + break; + } + return 0; +} + +bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port) +{ + std::cerr << "sockaddr_storage_setport()"; + std::cerr << std::endl; + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_setport(addr, port); + break; + case AF_INET6: + return sockaddr_storage_ipv6_setport(addr, port); + break; + default: + std::cerr << "sockaddr_storage_setport() invalid addr.ss_family"; + std::cerr << std::endl; + break; + } + return false; +} + + +bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *addr_ipv4) +{ + std::cerr << "sockaddr_storage_setipv4()"; + std::cerr << std::endl; + + sockaddr_storage_clear(addr); + struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); + + ipv4_ptr->sin_family = AF_INET; + ipv4_ptr->sin_addr = addr_ipv4->sin_addr; + ipv4_ptr->sin_port = addr_ipv4->sin_port; + + return true; +} + +bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6) +{ + std::cerr << "sockaddr_storage_setipv6()"; + std::cerr << std::endl; + + sockaddr_storage_clear(addr); + struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr); + + ipv6_ptr->sin6_family = AF_INET6; + ipv6_ptr->sin6_addr = addr_ipv6->sin6_addr; + ipv6_ptr->sin6_port = addr_ipv6->sin6_port; + + return true; +} + + +bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name) +{ + std::cerr << "sockaddr_storage_ipv4_aton()"; + std::cerr << std::endl; + + struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); + ipv4_ptr->sin_family = AF_INET; + return (1 == inet_aton(name, &(ipv4_ptr->sin_addr))); +} + + +/******************************** Comparisions **********************************/ + +bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b) +{ + if (!sockaddr_storage_samefamily(a, b)) + { + return (a.ss_family < b.ss_family); + } + + switch(a.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_lessthan(a, b); + break; + case AF_INET6: + return sockaddr_storage_ipv6_lessthan(a, b); + break; + default: + std::cerr << "sockaddr_storage_operator<() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + + +bool sockaddr_storage_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_same()"; + std::cerr << std::endl; + + if (!sockaddr_storage_samefamily(addr, addr2)) + return false; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_same(addr, addr2); + break; + case AF_INET6: + return sockaddr_storage_ipv6_same(addr, addr2); + break; + default: + std::cerr << "sockaddr_storage_same() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + + +bool sockaddr_storage_samefamily(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_samefamily()"; + std::cerr << std::endl; + + return (addr.ss_family == addr2.ss_family); +} + +bool sockaddr_storage_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_sameip()"; + std::cerr << std::endl; + + if (!sockaddr_storage_samefamily(addr, addr2)) + return false; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_sameip(addr, addr2); + break; + case AF_INET6: + return sockaddr_storage_ipv6_sameip(addr, addr2); + break; + default: + std::cerr << "sockaddr_storage_sameip() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + + +bool sockaddr_storage_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_samenet()"; + std::cerr << std::endl; + + if (!sockaddr_storage_samefamily(addr, addr2)) + return false; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_samenet(addr, addr2); + break; + case AF_INET6: + return sockaddr_storage_ipv6_samenet(addr, addr2); + break; + default: + std::cerr << "sockaddr_storage_samenet() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + +bool sockaddr_storage_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_samesubnet()"; + std::cerr << std::endl; + + if (!sockaddr_storage_samefamily(addr, addr2)) + return false; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_samesubnet(addr, addr2); + break; + case AF_INET6: + return sockaddr_storage_ipv6_samesubnet(addr, addr2); + break; + default: + std::cerr << "sockaddr_storage_samesubnet() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + + +/********************************* Output ***********************************/ + +std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr) +{ + std::string output; + output += sockaddr_storage_familytostring(addr); + + switch(addr.ss_family) + { + case AF_INET: + case AF_INET6: + output += "="; + output += sockaddr_storage_iptostring(addr); + output += ":"; + output += sockaddr_storage_porttostring(addr); + break; + default: + break; + } + return output; +} + + + + +std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr) +{ + std::string output; + switch(addr.ss_family) + { + case AF_INET: + output = "IPv4"; + break; + case AF_INET6: + output = "IPv6"; + break; + default: + output = "AF_INVALID"; + break; + } + return output; +} + +std::string sockaddr_storage_iptostring(const struct sockaddr_storage &addr) +{ + std::string output; + switch(addr.ss_family) + { + case AF_INET: + output = sockaddr_storage_ipv4_iptostring(addr); + break; + case AF_INET6: + output = sockaddr_storage_ipv6_iptostring(addr); + break; + default: + output = "INVALID_IP"; + break; + } + return output; +} + +std::string sockaddr_storage_porttostring(const struct sockaddr_storage &addr) +{ + std::string output; + uint16_t port = sockaddr_storage_port(addr); + rs_sprintf(output, "%u", port); + return output; +} + + +/********************************* Net Checks ***********************************/ +bool sockaddr_storage_isnull(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_isnull()"; + std::cerr << std::endl; + + if (addr.ss_family == 0) + return true; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_isnull(addr); + break; + case AF_INET6: + return sockaddr_storage_ipv6_isnull(addr); + break; + default: + return true; + break; + } + return true; +} + +bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_isValidNet()"; + std::cerr << std::endl; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_isValidNet(addr); + break; + case AF_INET6: + return sockaddr_storage_ipv6_isValidNet(addr); + break; + default: + std::cerr << "sockaddr_storage_isValidNet() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + +bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_isLoopbackNet()"; + std::cerr << std::endl; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_isLoopbackNet(addr); + break; + case AF_INET6: + return sockaddr_storage_ipv6_isLoopbackNet(addr); + break; + default: + std::cerr << "sockaddr_storage_isLoopbackNet() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + + +bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_isPrivateNet()"; + std::cerr << std::endl; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_isPrivateNet(addr); + break; + case AF_INET6: + return sockaddr_storage_ipv6_isPrivateNet(addr); + break; + default: + std::cerr << "sockaddr_storage_isPrivateNet() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + + +bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_isExternalNet()"; + std::cerr << std::endl; + + switch(addr.ss_family) + { + case AF_INET: + return sockaddr_storage_ipv4_isExternalNet(addr); + break; + case AF_INET6: + return sockaddr_storage_ipv6_isExternalNet(addr); + break; + default: + std::cerr << "sockaddr_storage_isExternalNet() INVALID Family - error"; + std::cerr << std::endl; + break; + } + return false; +} + + + + + +/***************************** Internal Helper Fns ******************************/ + + +/******************************** Casting **************************************/ + +struct sockaddr_in *to_ipv4_ptr(struct sockaddr_storage &addr) +{ + struct sockaddr_in *ipv4_ptr = (struct sockaddr_in *) &addr; + return ipv4_ptr; +} + +struct sockaddr_in6 *to_ipv6_ptr(struct sockaddr_storage &addr) +{ + struct sockaddr_in6 *ipv6_ptr = (struct sockaddr_in6 *) &addr; + return ipv6_ptr; +} + +const struct sockaddr_in *to_const_ipv4_ptr(const struct sockaddr_storage &addr) +{ + const struct sockaddr_in *ipv4_ptr = (const struct sockaddr_in *) &addr; + return ipv4_ptr; +} + +const struct sockaddr_in6 *to_const_ipv6_ptr(const struct sockaddr_storage &addr) +{ + const struct sockaddr_in6 *ipv6_ptr = (const struct sockaddr_in6 *) &addr; + return ipv6_ptr; +} + + +/******************************** Set / Clear ***********************************/ + +bool sockaddr_storage_ipv4_zeroip(struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_zeroip()"; + std::cerr << std::endl; + + struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); + memset(&(ipv4_ptr->sin_addr), 0, sizeof(ipv4_ptr->sin_addr)); + return true; +} + + +bool sockaddr_storage_ipv4_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) +{ + std::cerr << "sockaddr_storage_ipv4_copyip()"; + std::cerr << std::endl; + + struct sockaddr_in *dst_ptr = to_ipv4_ptr(dst); + const struct sockaddr_in *src_ptr = to_const_ipv4_ptr(src); + + dst_ptr->sin_family = AF_INET; + memcpy(&(dst_ptr->sin_addr), &(src_ptr->sin_addr), sizeof(src_ptr->sin_addr)); + return true; +} + +uint16_t sockaddr_storage_ipv4_port(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_port()"; + std::cerr << std::endl; + + const struct sockaddr_in *ipv4_ptr = to_const_ipv4_ptr(addr); + uint16_t port = ntohs(ipv4_ptr->sin_port); + return port; +} + +bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, uint16_t port) +{ + std::cerr << "sockaddr_storage_ipv4_setport()"; + std::cerr << std::endl; + + struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); + ipv4_ptr->sin_port = htons(port); + return true; +} + +bool sockaddr_storage_ipv6_zeroip(struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv6_zeroip()"; + std::cerr << std::endl; + + struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr); + memset(&(ipv6_ptr->sin6_addr), 0, sizeof(ipv6_ptr->sin6_addr)); + return true; +} + +bool sockaddr_storage_ipv6_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) +{ + std::cerr << "sockaddr_storage_ipv6_copyip()"; + std::cerr << std::endl; + + struct sockaddr_in6 *dst_ptr = to_ipv6_ptr(dst); + const struct sockaddr_in6 *src_ptr = to_const_ipv6_ptr(src); + + dst_ptr->sin6_family = AF_INET6; + memcpy(&(dst_ptr->sin6_addr), &(src_ptr->sin6_addr), sizeof(src_ptr->sin6_addr)); + return true; +} + +uint16_t sockaddr_storage_ipv6_port(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv6_port()"; + std::cerr << std::endl; + + const struct sockaddr_in6 *ipv6_ptr = to_const_ipv6_ptr(addr); + uint16_t port = ntohs(ipv6_ptr->sin6_port); + return port; +} + +bool sockaddr_storage_ipv6_setport(struct sockaddr_storage &addr, uint16_t port) +{ + std::cerr << "sockaddr_storage_ipv6_setport()"; + std::cerr << std::endl; + + struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr); + ipv6_ptr->sin6_port = htons(port); + return true; +} + + +/******************************** Comparisions **********************************/ + +bool sockaddr_storage_ipv4_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_ipv4_lessthan()"; + std::cerr << std::endl; + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + const struct sockaddr_in *ptr2 = to_const_ipv4_ptr(addr2); + + if (ptr1->sin_addr.s_addr == ptr2->sin_addr.s_addr) + { + return ptr1->sin_port < ptr2->sin_port; + } + return (ptr1->sin_addr.s_addr < ptr2->sin_addr.s_addr); +} + +bool sockaddr_storage_ipv4_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_ipv4_same()"; + std::cerr << std::endl; + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + const struct sockaddr_in *ptr2 = to_const_ipv4_ptr(addr2); + + return (ptr1->sin_addr.s_addr == ptr2->sin_addr.s_addr) && + (ptr1->sin_port == ptr2->sin_port); +} + +bool sockaddr_storage_ipv4_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_ipv4_sameip()"; + std::cerr << std::endl; + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + const struct sockaddr_in *ptr2 = to_const_ipv4_ptr(addr2); + + return (ptr1->sin_addr.s_addr == ptr2->sin_addr.s_addr); +} + + +bool sockaddr_storage_ipv4_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + (void) addr; + (void) addr2; + + std::cerr << "sockaddr_storage_ipv4_samenet()"; + std::cerr << std::endl; + + return false; +} + +bool sockaddr_storage_ipv4_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + (void) addr; + (void) addr2; + + std::cerr << "sockaddr_storage_ipv4_samesubnet()"; + std::cerr << std::endl; + + return false; +} + +// IPV6 +bool sockaddr_storage_ipv6_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_ipv6_lessthan()"; + std::cerr << std::endl; + + const struct sockaddr_in6 *ptr1 = to_const_ipv6_ptr(addr); + const struct sockaddr_in6 *ptr2 = to_const_ipv6_ptr(addr2); + + uint32_t *ip6addr1 = (uint32_t *) ptr1->sin6_addr.s6_addr; + uint32_t *ip6addr2 = (uint32_t *) ptr2->sin6_addr.s6_addr; + for(int i = 0; i < 4; i++) + { + if (ip6addr1[i] == ip6addr2[i]) + { + continue; + } + + return (ip6addr1[i] < ip6addr2[i]); + } + + return (ptr1->sin6_port < ptr2->sin6_port); +} + +bool sockaddr_storage_ipv6_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_ipv6_same()"; + std::cerr << std::endl; + const struct sockaddr_in6 *ptr1 = to_const_ipv6_ptr(addr); + const struct sockaddr_in6 *ptr2 = to_const_ipv6_ptr(addr2); + + return sockaddr_storage_ipv6_sameip(addr, addr2) && (ptr1->sin6_port == ptr2->sin6_port); +} + +bool sockaddr_storage_ipv6_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + std::cerr << "sockaddr_storage_ipv6_sameip()"; + std::cerr << std::endl; + + const struct sockaddr_in6 *ptr1 = to_const_ipv6_ptr(addr); + const struct sockaddr_in6 *ptr2 = to_const_ipv6_ptr(addr2); + + uint32_t *ip6addr1 = (uint32_t *) ptr1->sin6_addr.s6_addr; + uint32_t *ip6addr2 = (uint32_t *) ptr2->sin6_addr.s6_addr; + + for(int i = 0; i < 4; i++) + { + if (ip6addr1[i] != ip6addr2[i]) + { + return false; + } + } + return true; +} + + +bool sockaddr_storage_ipv6_samenet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + (void) addr; + (void) addr2; + + std::cerr << "sockaddr_storage_ipv6_samenet() TODO"; + std::cerr << std::endl; + + return false; +} + +bool sockaddr_storage_ipv6_samesubnet(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) +{ + (void) addr; + (void) addr2; + + std::cerr << "sockaddr_storage_ipv6_samesubnet() TODO"; + std::cerr << std::endl; + + return false; +} + + +/********************************* Output ***********************************/ +std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr) +{ + const struct sockaddr_in *ptr = to_const_ipv4_ptr(addr); + std::string output; + output = rs_inet_ntoa(ptr->sin_addr); + return output; +} + +std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & /* addr */) +{ + std::string output; + output += "IPv6-ADDRESS-TODO"; + return output; +} + + + + + +/********************************* Net Checks ***********************************/ +bool sockaddr_storage_ipv4_isnull(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_isnull()"; + std::cerr << std::endl; + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + if (ptr1->sin_family != AF_INET) + { + return true; + } + if ((ptr1->sin_addr.s_addr == 0) || (ptr1->sin_addr.s_addr == 1)) + { + return true; + } + return false; +} + +bool sockaddr_storage_ipv4_isValidNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_isValidNet()"; + std::cerr << std::endl; + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + if (ptr1->sin_family != AF_INET) + { + return false; + } + return isValidNet(&(ptr1->sin_addr)); +} + + +bool sockaddr_storage_ipv4_isLoopbackNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_isLoopbackNet()"; + std::cerr << std::endl; + + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + if (ptr1->sin_family != AF_INET) + { + return false; + } + return isLoopbackNet(&(ptr1->sin_addr)); +} + +bool sockaddr_storage_ipv4_isPrivateNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_isPrivateNet()"; + std::cerr << std::endl; + + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + if (ptr1->sin_family != AF_INET) + { + return false; + } + return isPrivateNet(&(ptr1->sin_addr)); +} + +bool sockaddr_storage_ipv4_isExternalNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv4_isExternalNet()"; + std::cerr << std::endl; + + const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); + if (ptr1->sin_family != AF_INET) + { + return false; + } + return isExternalNet(&(ptr1->sin_addr)); +} + + +bool sockaddr_storage_ipv6_isnull(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv6_isnull() TODO"; + std::cerr << std::endl; + + return false; +} + +bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv6_isValidNet() TODO"; + std::cerr << std::endl; + + return false; +} + +bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv6_isLoopbackNet() TODO"; + std::cerr << std::endl; + + return false; +} + +bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv6_isPrivateNet() TODO"; + std::cerr << std::endl; + + return false; +} + +bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &addr) +{ + std::cerr << "sockaddr_storage_ipv6_isExternalNet() TODO"; + std::cerr << std::endl; + + return false; +} + + +