mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-08-05 21:04:14 -04:00
improved IPv6 handling (Patch 19a39b42c4bb6256363b1624520c200835a9b93e from G10H4ck)
git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.6-IPv6@8198 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
09d601aac0
commit
d40a9002fa
7 changed files with 124 additions and 87 deletions
|
@ -219,29 +219,23 @@ int p3BitDht::addBadPeer(const struct sockaddr_storage &addr, uint32_t /*reason*
|
|||
int p3BitDht::addKnownPeer(const RsPeerId &pid, const struct sockaddr_storage &addr, uint32_t flags)
|
||||
{
|
||||
struct sockaddr_in addrv4;
|
||||
sockaddr_storage tmpAddr = addr;
|
||||
|
||||
if (addr.ss_family != AF_INET)
|
||||
if (!sockaddr_storage_ipv6_to_ipv4(tmpAddr))
|
||||
{
|
||||
std::cerr << "p3BitDht::addKnownPeer() Warning! Non IPv4 Address - Cannot handle IPV6 Yet. addr.ss_family=" << addr.ss_family;
|
||||
std::cerr << std::endl;
|
||||
sockaddr_clear(&addrv4);
|
||||
|
||||
|
||||
if (flags & NETASSIST_KNOWN_PEER_ONLINE)
|
||||
{
|
||||
std::cerr << "p3BitDht::addKnownPeer() Non IPv4 Address & ONLINE. Abort()ing.";
|
||||
std::cerr << std::endl;
|
||||
return 0; // TODO:IPV6
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_BITDHT
|
||||
std::cerr << "p3BitDht::addKnownPeer() Warning! Cannot add non IPv4 Address" << std::endl;
|
||||
sockaddr_storage_dump(addr);
|
||||
#endif
|
||||
return 0; // TODO:IPV6
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// convert.
|
||||
struct sockaddr_in *ap = (struct sockaddr_in *) &addr;
|
||||
|
||||
struct sockaddr_in *ap = (struct sockaddr_in *) &tmpAddr;
|
||||
|
||||
sockaddr_clear(&addrv4);
|
||||
addrv4.sin_family = ap->sin_family;
|
||||
addrv4.sin_addr = ap->sin_addr;
|
||||
addrv4.sin_port = ap->sin_port;
|
||||
|
|
|
@ -975,31 +975,34 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr, c
|
|||
std::cerr << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
std::list<struct sockaddr_storage> lAddrs;
|
||||
getLocalAddresses(lAddrs); // Better to have this outside mutex
|
||||
|
||||
{
|
||||
/****** STACK LOCK MUTEX *******/
|
||||
RsStackMutex stack(mPeerMtx); (void)stack;
|
||||
|
||||
mOwnState.localaddr = localAddr;
|
||||
RS_STACK_MUTEX(mPeerMtx);
|
||||
|
||||
// update ip address list
|
||||
uint16_t port = 0;
|
||||
if(!sockaddr_storage_isnull(localAddr))
|
||||
{
|
||||
lAddrs.push_front(localAddr);
|
||||
port = sockaddr_storage_port(localAddr);
|
||||
}
|
||||
|
||||
if (!lAddrs.empty())
|
||||
mOwnState.localaddr = lAddrs.front();
|
||||
|
||||
std::list<struct sockaddr_storage>::iterator it;
|
||||
std::list<struct sockaddr_storage> lAddrs;
|
||||
getLocalAddresses(lAddrs);
|
||||
lAddrs.push_front(localAddr);
|
||||
for ( it = lAddrs.begin(); it != lAddrs.end(); ++it)
|
||||
{
|
||||
pqiIpAddress ipAddressTimed;
|
||||
ipAddressTimed.mAddr = *it;
|
||||
sockaddr_storage_setport(ipAddressTimed.mAddr, sockaddr_storage_port(localAddr));
|
||||
sockaddr_storage_setport(ipAddressTimed.mAddr, port);
|
||||
ipAddressTimed.mSeenTime = time(NULL);
|
||||
ipAddressTimed.mSrc = 0 ;
|
||||
ipAddressTimed.mSrc = 0;
|
||||
mOwnState.ipAddrs.updateLocalAddrs(ipAddressTimed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
//update ip address list
|
||||
pqiIpAddress ipAddressTimed;
|
||||
|
@ -1015,7 +1018,7 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr, c
|
|||
* This should keep people happy, and allow for misconfiguration!
|
||||
*/
|
||||
|
||||
if (mOwnState.netMode & RS_NET_MODE_TRY_EXT)
|
||||
if (mOwnState.netMode & RS_NET_MODE_TRY_EXT)
|
||||
{
|
||||
/**** THIS CASE SHOULD NOT BE TRIGGERED ****/
|
||||
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress() Disabling Update of Server Port ";
|
||||
|
@ -1025,10 +1028,10 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr, c
|
|||
std::cerr << sockaddr_storage_tostring(mOwnState.serveraddr);
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else if (mOwnState.netMode & RS_NET_MODE_EXT)
|
||||
else if (mOwnState.netMode & RS_NET_MODE_EXT)
|
||||
{
|
||||
sockaddr_storage_copyip(mOwnState.serveraddr,extAddr);
|
||||
|
||||
sockaddr_storage_copyip(mOwnState.serveraddr, extAddr);
|
||||
|
||||
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress() Disabling Update of Server Port ";
|
||||
std::cerr << " as MANUAL FORWARD Mode";
|
||||
std::cerr << std::endl;
|
||||
|
@ -1037,10 +1040,9 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr, c
|
|||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
mOwnState.serveraddr = extAddr;
|
||||
}
|
||||
}
|
||||
|
||||
} // end RS_STACK_MUTEX(mPeerMtx);
|
||||
|
||||
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
|
||||
mLinkMgr->setLocalAddress(localAddr);
|
||||
|
|
|
@ -371,21 +371,25 @@ in_addr_t inet_network(const char *inet_name)
|
|||
bool getLocalAddresses(std::list<struct sockaddr_storage> & addrs)
|
||||
{
|
||||
struct ifaddrs *ifsaddrs, *ifa;
|
||||
if(getifaddrs(&ifsaddrs) != 0) exit(1);
|
||||
if(getifaddrs(&ifsaddrs) != 0)
|
||||
{
|
||||
freeifaddrs(ifsaddrs);
|
||||
return false;
|
||||
}
|
||||
|
||||
addrs.clear();
|
||||
for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next )
|
||||
if ( (ifa->ifa_flags & IFF_UP) && !(ifa->ifa_flags & IFF_LOOPBACK) )
|
||||
{
|
||||
sockaddr_storage * tmp = new sockaddr_storage;
|
||||
if (sockaddr_storage_copyip(* tmp, * (const struct sockaddr_storage *) ifa->ifa_addr))
|
||||
addrs.push_back(*tmp);
|
||||
else delete tmp;
|
||||
const sockaddr_storage & ifaaddr = * (const struct sockaddr_storage *) ifa->ifa_addr;
|
||||
if (sockaddr_storage_isLinkLocal(ifaaddr)) continue;
|
||||
sockaddr_storage tmp;
|
||||
if (sockaddr_storage_copyip(tmp, ifaaddr)) addrs.push_back(tmp);
|
||||
}
|
||||
|
||||
freeifaddrs(ifsaddrs);
|
||||
|
||||
return (!addrs.empty());
|
||||
freeifaddrs(ifsaddrs);
|
||||
return !addrs.empty();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -604,12 +604,12 @@ int pqissl::Delay_Connection()
|
|||
}
|
||||
|
||||
rslog(RSL_WARNING, pqisslzone,
|
||||
"pqissl::Initiate_Connection() Already Attempt in Progress!");
|
||||
"pqissl::Delay_Connection() Already Attempt in Progress!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int pqissl::Initiate_Connection()
|
||||
int pqissl::Initiate_Connection()
|
||||
{
|
||||
int err;
|
||||
struct sockaddr_storage addr = remote_addr;
|
||||
|
@ -750,6 +750,7 @@ int pqissl::Initiate_Connection()
|
|||
{
|
||||
std::string out;
|
||||
rs_sprintf(out, "pqissl::Initiate_Connection() connect returns:%d -> errno: %d error: %s\n", err, errno, socket_errorType(errno).c_str());
|
||||
sockaddr_storage_dump(addr, &out);
|
||||
|
||||
if (errno == EINPROGRESS)
|
||||
{
|
||||
|
|
|
@ -894,7 +894,9 @@ bool p3Peers::setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht)
|
|||
|
||||
bool p3Peers::getProxyServer(std::string &addr, uint16_t &port, uint32_t &status)
|
||||
{
|
||||
std::cerr << "p3Peers::getProxyServer()" << std::endl;
|
||||
#ifdef P3PEERS_DEBUG
|
||||
std::cerr << "p3Peers::getProxyServer()" << std::endl;
|
||||
#endif
|
||||
|
||||
struct sockaddr_storage proxy_addr;
|
||||
mPeerMgr->getProxyServerAddress(proxy_addr);
|
||||
|
|
|
@ -110,7 +110,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);
|
||||
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);
|
||||
|
@ -118,6 +118,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr);
|
|||
|
||||
// net checks.
|
||||
bool sockaddr_storage_isnull(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isLinkLocal(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isIPv4Mapped(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "util/rsnet.h"
|
||||
#include "util/rsstring.h"
|
||||
#include "util/stacktrace.h"
|
||||
#include "pqi/pqinetwork.h"
|
||||
|
||||
/***************************** Internal Helper Fns ******************************/
|
||||
|
@ -180,8 +181,7 @@ bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr
|
|||
uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_port()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_port()" << std::endl;
|
||||
#endif
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
|
@ -192,8 +192,9 @@ uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr)
|
|||
return sockaddr_storage_ipv6_port(addr);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "sockaddr_storage_port() invalid addr.ss_family" << std::endl;
|
||||
std::cerr << "sockaddr_storage_port() invalid addr.ss_family ";
|
||||
sockaddr_storage_dump(addr);
|
||||
//print_stacktrace();
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -310,27 +311,20 @@ bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr)
|
|||
|
||||
if ( addr.ss_family == AF_INET ) return true;
|
||||
|
||||
if ( addr.ss_family == AF_INET6 )
|
||||
if(sockaddr_storage_isIPv4Mapped(addr))
|
||||
{
|
||||
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
|
||||
bool ipv4m = addr_ipv6.sin6_addr.s6_addr16[5] == (u_int16_t) 0xffff;
|
||||
for ( int i = 0; ipv4m && i < 5 ; ++i )
|
||||
ipv4m &= addr_ipv6.sin6_addr.s6_addr16[i] == (u_int16_t) 0x0000;
|
||||
u_int32_t ip = addr_ipv6.sin6_addr.s6_addr32[3];
|
||||
u_int16_t port = addr_ipv6.sin6_port;
|
||||
|
||||
if(ipv4m)
|
||||
{
|
||||
u_int32_t ip = addr_ipv6.sin6_addr.s6_addr32[3];
|
||||
u_int16_t port = addr_ipv6.sin6_port;
|
||||
sockaddr_in & addr_ipv4 = (sockaddr_in &) addr;
|
||||
|
||||
sockaddr_in & addr_ipv4 = (sockaddr_in &) addr;
|
||||
sockaddr_storage_clear(addr);
|
||||
addr_ipv4.sin_family = AF_INET;
|
||||
addr_ipv4.sin_port = port;
|
||||
addr_ipv4.sin_addr.s_addr = ip;
|
||||
|
||||
sockaddr_storage_clear(addr);
|
||||
addr_ipv4.sin_family = AF_INET;
|
||||
addr_ipv4.sin_port = port;
|
||||
addr_ipv4.sin_addr.s_addr = ip;
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -478,26 +472,54 @@ std::string sockaddr_storage_porttostring(const struct sockaddr_storage &addr)
|
|||
bool sockaddr_storage_isnull(const struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_isnull()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_isnull()" << std::endl;
|
||||
#endif
|
||||
|
||||
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_isLinkLocal(const struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_isLinkLocal()" << std::endl;
|
||||
#endif
|
||||
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
return false; // TODO:IPv4
|
||||
case AF_INET6:
|
||||
{
|
||||
const sockaddr_in6 * addr6 = (const sockaddr_in6 *) &addr;
|
||||
u_int16_t mask = 0xc0ff; // Mask end prefix inverted because of IPv6 is big endian
|
||||
return ((addr6->sin6_addr.s6_addr16[0] & mask ) == 0x80fe);
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool sockaddr_storage_isIPv4Mapped(const struct sockaddr_storage &addr)
|
||||
{
|
||||
if (addr.ss_family == AF_INET6)
|
||||
{
|
||||
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
|
||||
bool ipv4m = addr_ipv6.sin6_addr.s6_addr16[5] == (u_int16_t) 0xffff;
|
||||
for ( int i = 0; ipv4m && i < 5 ; ++i )
|
||||
ipv4m &= addr_ipv6.sin6_addr.s6_addr16[i] == (u_int16_t) 0x0000;
|
||||
return ipv4m;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr)
|
||||
|
@ -587,8 +609,7 @@ bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr)
|
|||
return sockaddr_storage_ipv6_isExternalNet(addr);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "sockaddr_storage_isExternalNet() INVALID Family - error";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_isExternalNet() INVALID Family - error" << std::endl;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
@ -703,14 +724,14 @@ bool sockaddr_storage_ipv6_copyip(struct sockaddr_storage &dst, const struct soc
|
|||
|
||||
dst_ptr->sin6_family = AF_INET6;
|
||||
memcpy(&(dst_ptr->sin6_addr), &(src_ptr->sin6_addr), sizeof(src_ptr->sin6_addr));
|
||||
dst_ptr->sin6_scope_id = src_ptr->sin6_scope_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t sockaddr_storage_ipv6_port(const struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_port()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "sockaddr_storage_ipv6_port()" << std::endl;
|
||||
#endif
|
||||
const struct sockaddr_in6 *ipv6_ptr = to_const_ipv6_ptr(addr);
|
||||
uint16_t port = ntohs(ipv6_ptr->sin6_port);
|
||||
|
@ -719,8 +740,9 @@ uint16_t sockaddr_storage_ipv6_port(const struct sockaddr_storage &addr)
|
|||
|
||||
bool sockaddr_storage_ipv6_setport(struct sockaddr_storage &addr, uint16_t port)
|
||||
{
|
||||
std::cerr << "sockaddr_storage_ipv6_setport()";
|
||||
std::cerr << std::endl;
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_setport()" << std::endl;
|
||||
#endif
|
||||
|
||||
struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr);
|
||||
ipv6_ptr->sin6_port = htons(port);
|
||||
|
@ -866,7 +888,7 @@ std::string sockaddr_storage_iptostring(const struct sockaddr_storage & addr)
|
|||
return output;
|
||||
}
|
||||
|
||||
void sockaddr_storage_dump(const sockaddr_storage & addr)
|
||||
void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputString)
|
||||
{
|
||||
// This function must not rely on others sockaddr_storage_*
|
||||
|
||||
|
@ -892,6 +914,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr)
|
|||
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;
|
||||
|
@ -906,7 +930,15 @@ void sockaddr_storage_dump(const sockaddr_storage & addr)
|
|||
output << addr.__ss_padding;
|
||||
}}
|
||||
|
||||
std::cerr << output.str() << std::endl;
|
||||
if(outputString)
|
||||
{
|
||||
outputString->append(output.str() + "\n");
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << output.str() << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
std::cerr << output.str() << std::endl;
|
||||
}
|
||||
|
||||
/********************************* Net Checks ***********************************/
|
||||
|
@ -1013,9 +1045,9 @@ bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage & )
|
|||
bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage & addr )
|
||||
{
|
||||
sockaddr_in6 & addr6 = (sockaddr_in6 &) addr;
|
||||
bool isLp = (addr6.sin6_addr.s6_addr32[3] == 0x1);
|
||||
bool isLp = (addr6.sin6_addr.s6_addr32[3] == 0x10000000); // IPv6 is big endian
|
||||
for (int i=0; isLp && i<3; ++i)
|
||||
isLp &= (addr6.sin6_addr.s6_addr32[i] == 0x0);
|
||||
isLp &= (addr6.sin6_addr.s6_addr32[i] == 0x00000000);
|
||||
|
||||
#ifdef SS_DEBUG
|
||||
sockaddr_storage_dump(addr);
|
||||
|
@ -1034,13 +1066,13 @@ bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &)
|
||||
bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage & addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_isExternalNet() TODO" << std::endl;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return !sockaddr_storage_isLinkLocal(addr);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue