Merge pull request #1191 from G10h4ck/IPv6-v3

IPv6 support
This commit is contained in:
csoler 2018-03-27 20:54:31 +02:00 committed by GitHub
commit 73c6deebf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 838 additions and 689 deletions

View File

@ -4,6 +4,7 @@
* BitDht interface for RetroShare.
*
* Copyright 2009-2010 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -184,18 +185,24 @@ bool p3BitDht::dropPeer(const RsPeerId& pid)
********************************* Basic Peer Details *************************************
******************************************************************************************/
int p3BitDht::addBadPeer(const struct sockaddr_storage &addr, uint32_t /*reason*/, uint32_t /*flags*/, uint32_t /*age*/)
int p3BitDht::addBadPeer( const sockaddr_storage &addr, uint32_t /*reason*/,
uint32_t /*flags*/, uint32_t /*age*/ )
{
//mUdpBitDht->updateKnownPeer(&id, 0, bdflags);
struct sockaddr_in addrv4;
if (addr.ss_family != AF_INET)
sockaddr_in addrv4;
sockaddr_storage tmpaddr;
sockaddr_storage_copy(addr, tmpaddr);
if(!sockaddr_storage_ipv6_to_ipv4(tmpaddr))
{
std::cerr << "p3BitDht::addBadPeer() cannot handle IPV6 Yet, aborting";
std::cerr << std::endl;
abort();
std::cerr << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!"
<< std::endl;
sockaddr_storage_dump(addr);
print_stacktrace();
return -EINVAL;
}
struct sockaddr_in *ap = (struct sockaddr_in *) &addr;
struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr;
// convert.
addrv4.sin_family = ap->sin_family;
@ -216,39 +223,30 @@ 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)
int p3BitDht::addKnownPeer( const RsPeerId &pid,
const sockaddr_storage &addr, uint32_t flags )
{
struct sockaddr_in addrv4;
sockaddr_clear(&addrv4);
sockaddr_in addrv4;
sockaddr_clear(&addrv4);
if (addr.ss_family != AF_INET)
{
if(addr.ss_family != AF_UNSPEC)
{
std::cerr << "p3BitDht::addKnownPeer() Warning! Non IPv4 Address - Cannot handle IPV6 Yet. addr.ss_family=" << addr.ss_family;
std::cerr << std::endl;
}
if (flags & NETASSIST_KNOWN_PEER_ONLINE)
{
std::cerr << "p3BitDht::addKnownPeer() Non IPv4 Address & ONLINE. Abort()ing.";
std::cerr << std::endl;
abort();
}
}
else
sockaddr_storage tmpaddr;
sockaddr_storage_copy(addr, tmpaddr);
if( !sockaddr_storage_isnull(addr) &&
!sockaddr_storage_ipv6_to_ipv4(tmpaddr) )
{
// 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;
std::cerr << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!"
<< std::endl;
sockaddr_storage_dump(addr);
print_stacktrace();
return -EINVAL;
}
// convert.
struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr;
addrv4.sin_family = ap->sin_family;
addrv4.sin_addr = ap->sin_addr;
addrv4.sin_port = ap->sin_port;
int p3type = 0;
int bdflags = 0;
bdId id;
@ -295,7 +293,7 @@ int p3BitDht::addKnownPeer(const RsPeerId &pid, const struct sockaddr_storage &a
if (!isOwnId)
{
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
RS_STACK_MUTEX(dhtMtx);
DhtPeerDetails *dpd = addInternalPeer_locked(pid, p3type);

View File

@ -174,24 +174,24 @@ RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *b
try
{
scan_ip(Detail.localAddr,Detail.localPort,ipv4_internal_ip_and_port) ;
scan_ip(Detail.localAddr,Detail.localPort,ipv4_internal_ip_and_port);
}
catch(...)
{
std::cerr << "RsCertificate::Invalid LocalAddress";
std::cerr << std::endl;
memset(ipv4_internal_ip_and_port,0,6) ;
std::cerr << "RsCertificate::Invalid LocalAddress: "
<< Detail.localAddr << std::endl;
memset(ipv4_internal_ip_and_port,0,6);
}
try
{
scan_ip(Detail.extAddr,Detail.extPort,ipv4_external_ip_and_port) ;
scan_ip(Detail.extAddr,Detail.extPort,ipv4_external_ip_and_port);
}
catch(...)
{
std::cerr << "RsCertificate::Invalid ExternalAddress";
std::cerr << std::endl;
std::cerr << "RsCertificate::Invalid ExternalAddress: "
<< Detail.extAddr << std::endl;
memset(ipv4_external_ip_and_port,0,6) ;
}

View File

@ -3,7 +3,8 @@
*
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-2011 by Robert Fernie.
* Copyright (C) 2007-2011 Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -1344,8 +1345,10 @@ void p3LinkMgrIMPL::peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs,
}
/* This has become very unwieldy - as extra arguments are required for UDP connections */
void p3LinkMgrIMPL::peerConnectRequest(const RsPeerId& id, const struct sockaddr_storage &raddr, const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr,
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth)
void p3LinkMgrIMPL::peerConnectRequest(
const RsPeerId& id, const sockaddr_storage &raddr,
const sockaddr_storage &proxyaddr, const sockaddr_storage &srcaddr,
uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth )
{
#ifdef LINKMGR_DEBUG
std::cerr << "p3LinkMgrIMPL::peerConnectRequest() id: " << id;

View File

@ -692,11 +692,11 @@ void p3NetMgrIMPL::netExtCheck()
bool netSetupDone = false;
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mNetMtx);
bool isStable = false;
struct sockaddr_storage tmpip ;
sockaddr_storage tmpip;
std::map<sockaddr_storage,ZeroInt> address_votes ;
std::map<sockaddr_storage,ZeroInt> address_votes;
/* check for External Address */
/* in order of importance */
@ -705,38 +705,30 @@ void p3NetMgrIMPL::netExtCheck()
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Not Ok" << std::endl;
#endif
/* net Assist */
if (netAssistExtAddress(tmpip))
if ( netAssistExtAddress(tmpip) &&
sockaddr_storage_isValidNet(tmpip) &&
sockaddr_storage_ipv6_to_ipv4(tmpip) )
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied from netAssistExternalAddress()" << std::endl;
#endif
if(sockaddr_storage_isValidNet(tmpip))
if( !rsBanList ||
rsBanList->isAddressAccepted(
tmpip, RSBANLIST_CHECKING_FLAGS_BLACKLIST ) )
{
if( (rsBanList==NULL) || rsBanList->isAddressAccepted(tmpip,RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
// must be stable???
isStable = true;
//mNetFlags.mExtAddr = tmpip;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isStable;
address_votes[tmpip].n++ ;
std::cerr << "NetAssistAddress reported external address " << sockaddr_storage_iptostring(tmpip) << std::endl;
}
else
std::cerr << "(SS) netAssisExternalAddress returned banned own IP " << sockaddr_storage_iptostring(tmpip) << " (banned). Rejecting." << std::endl;
// must be stable???
isStable = true;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isStable;
address_votes[tmpip].n++ ;
std::cerr << __PRETTY_FUNCTION__ << " NetAssistAddress "
<< " reported external address "
<< sockaddr_storage_iptostring(tmpip)
<< std::endl;
}
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
else
{
std::cerr << "p3NetMgrIMPL::netExtCheck() Bad Address supplied from netAssistExternalAddress()" << std::endl;
}
#endif
std::cerr << "(SS) netAssisExternalAddress returned banned "
<< "own IP " << sockaddr_storage_iptostring(tmpip)
<< " (banned). Rejecting." << std::endl;
}
}
#ifdef ALLOW_DHT_STUNNER
@ -780,7 +772,7 @@ void p3NetMgrIMPL::netExtCheck()
}
#endif
/* otherwise ask ExtAddrFinder */
/* ask ExtAddrFinder */
{
/* ExtAddrFinder */
if (mUseExtAddrFinder)
@ -789,7 +781,7 @@ void p3NetMgrIMPL::netExtCheck()
std::cerr << "p3NetMgrIMPL::netExtCheck() checking ExtAddrFinder" << std::endl;
#endif
bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip);
if (extFinderOk)
if (extFinderOk && sockaddr_storage_ipv6_to_ipv4(tmpip))
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl;
@ -803,38 +795,41 @@ void p3NetMgrIMPL::netExtCheck()
std::cerr << std::endl;
#endif
//mNetFlags.mExtAddr = tmpip;
mNetFlags.mExtAddrOk = true;
address_votes[tmpip].n++ ;
/* XXX HACK TO FIX */
#warning drbob: ALLOWING ExtAddrFinder -> ExtAddrStableOk = true (which it is not normally)
/* XXX HACK TO FIX drbob: ALLOWING
* ExtAddrFinder -> ExtAddrStableOk = true
* (which it is not normally) */
mNetFlags.mExtAddrStableOk = true;
std::cerr << "ExtAddrFinder reported external address " << sockaddr_storage_iptostring(tmpip) << std::endl;
std::cerr << __PRETTY_FUNCTION__ << " ExtAddrFinder "
<< " reported external address "
<< sockaddr_storage_iptostring(tmpip)
<< std::endl;
}
}
}
/* also ask peer mgr. */
/* also ask peer mgr. */
if (mPeerMgr)
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() checking mPeerMgr" << std::endl;
#endif
uint8_t isstable ; // unused
sockaddr_storage tmpaddr ;
uint8_t isstable; // unused
sockaddr_storage tmpaddr;
if (mPeerMgr->getExtAddressReportedByFriends(tmpaddr, isstable))
if ( mPeerMgr->getExtAddressReportedByFriends(tmpaddr, isstable) &&
sockaddr_storage_ipv6_to_ipv4(tmpaddr) )
{
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl;
#endif
/* best guess at port */
sockaddr_storage_setport(tmpaddr, sockaddr_storage_port(mLocalAddr));
sockaddr_storage_setport( tmpaddr,
sockaddr_storage_port(mLocalAddr) );
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
std::cerr << "p3NetMgrIMPL::netExtCheck() ";
@ -842,20 +837,21 @@ void p3NetMgrIMPL::netExtCheck()
std::cerr << std::endl;
#endif
//mNetFlags.mExtAddr = tmpaddr;
mNetFlags.mExtAddrOk = true;
mNetFlags.mExtAddrStableOk = isstable;
address_votes[tmpaddr].n++ ;
std::cerr << "PeerMgr reported external address " << sockaddr_storage_iptostring(tmpaddr) << std::endl;
address_votes[tmpaddr].n++;
std::cerr << __PRETTY_FUNCTION__ << " PeerMgr reported external"
<< " address "
<< sockaddr_storage_iptostring(tmpaddr) << std::endl;
}
#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET)
else
std::cerr << " No reliable address returned." << std::endl;
else
std::cerr << " No reliable address returned." << std::endl;
#endif
}
/* any other sources ??? */
/* finalise address */
@ -950,14 +946,6 @@ void p3NetMgrIMPL::netExtCheck()
#endif
netAssistSetAddress(mNetFlags.mLocalAddr, mNetFlags.mExtAddr, mNetMode);
}
#if 0
else
{
std::cerr << "p3NetMgrIMPL::netExtCheck() setting ERR netAssistSetAddress(0)" << std::endl;
/* mode = 0 for error */
netAssistSetAddress(mNetFlags.mLocalAddr, mNetFlags.mExtAddr, mNetMode);
}
#endif
/* flag unreachables! */
if ((mNetFlags.mExtAddrOk) && (!mNetFlags.mExtAddrStableOk))
@ -966,9 +954,6 @@ void p3NetMgrIMPL::netExtCheck()
std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Unstable - Unreachable Check" << std::endl;
#endif
}
}
if (netSetupDone)
@ -988,9 +973,9 @@ void p3NetMgrIMPL::netExtCheck()
RsPeerId fakeId;
netAssistKnownPeer(fakeId, mExtAddr, NETASSIST_KNOWN_PEER_SELF | NETASSIST_KNOWN_PEER_ONLINE);
rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr::netExtCheck() Network Setup Complete");
std::cerr << __PRETTY_FUNCTION__ << " Network Setup Complete"
<< std::endl;
}
}
/**********************************************************************************************
@ -1021,6 +1006,9 @@ bool p3NetMgrIMPL::checkNetAddress()
* possible. It will require complete reenginering of the network layer
* code. */
/* For retro-compatibility strictly accept only IPv4 addresses here,
* IPv6 addresses are handled in a retro-compatible manner in
* p3PeerMgrIMPL::UpdateOwnAddress */
std::vector<sockaddr_storage> addrs;
if (getLocalAddresses(addrs))
{
@ -1029,7 +1017,8 @@ bool p3NetMgrIMPL::checkNetAddress()
sockaddr_storage& addr(*it);
if( sockaddr_storage_isValidNet(addr) &&
!sockaddr_storage_isLoopbackNet(addr) &&
!sockaddr_storage_isLinkLocalNet(addr))
!sockaddr_storage_isLinkLocalNet(addr) &&
sockaddr_storage_ipv6_to_ipv4(addr) )
{
prefAddr = addr;
validAddr = true;
@ -1043,7 +1032,8 @@ bool p3NetMgrIMPL::checkNetAddress()
{
sockaddr_storage& addr(*it);
if( sockaddr_storage_isValidNet(addr) &&
!sockaddr_storage_isLoopbackNet(addr) )
!sockaddr_storage_isLoopbackNet(addr) &&
sockaddr_storage_ipv6_to_ipv4(addr) )
{
prefAddr = addr;
validAddr = true;
@ -1069,7 +1059,7 @@ bool p3NetMgrIMPL::checkNetAddress()
/* check addresses */
{
RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mNetMtx);
oldAddr = mLocalAddr;
addrChanged = !sockaddr_storage_sameip(prefAddr, mLocalAddr);
@ -1171,8 +1161,10 @@ bool p3NetMgrIMPL::checkNetAddress()
{
mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr);
}
rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr::checkNetAddress() local address changed, resetting network");
std::cerr << __PRETTY_FUNCTION__
<< " local address changed, resetting network" << std::endl;
netReset();
}

View File

@ -4,6 +4,7 @@
* 3P/PQI network interface for RetroShare.
*
* Copyright 2007-2011 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -23,6 +24,9 @@
*
*/
#include <vector> // for std::vector
#include <algorithm> // for std::random_shuffle
#include "rsserver/p3face.h"
#include "util/rsnet.h"
#include "pqi/authgpg.h"
@ -32,6 +36,7 @@
#include "pqi/p3linkmgr.h"
#include "pqi/p3netmgr.h"
#include "pqi/p3historymgr.h"
#include "pqi/pqinetwork.h" // for getLocalAddresses
//#include "pqi/p3dhtmgr.h" // Only need it for constants.
//#include "tcponudp/tou.h"
@ -326,8 +331,8 @@ const RsPeerId& p3PeerMgrIMPL::getOwnId()
bool p3PeerMgrIMPL::getOwnNetStatus(peerState &state)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
state = mOwnState;
RS_STACK_MUTEX(mPeerMtx);
state = mOwnState;
return true;
}
@ -812,15 +817,12 @@ int p3PeerMgrIMPL::getFriendCount(bool ssl, bool online)
bool p3PeerMgrIMPL::getFriendNetStatus(const RsPeerId &id, peerState &state)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mPeerMtx);
/* check for existing */
std::map<RsPeerId, peerState>::iterator it;
it = mFriendList.find(id);
if (it == mFriendList.end())
{
return false;
}
if (it == mFriendList.end()) return false;
state = it->second;
return true;
@ -829,27 +831,24 @@ bool p3PeerMgrIMPL::getFriendNetStatus(const RsPeerId &id, peerState &state)
bool p3PeerMgrIMPL::getOthersNetStatus(const RsPeerId &id, peerState &state)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mPeerMtx);
/* check for existing */
std::map<RsPeerId, peerState>::iterator it;
it = mOthersList.find(id);
if (it == mOthersList.end())
{
return false;
}
if (it == mOthersList.end()) return false;
state = it->second;
return true;
}
int p3PeerMgrIMPL::getConnectAddresses(const RsPeerId &id,
struct sockaddr_storage &lAddr, struct sockaddr_storage &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns)
int p3PeerMgrIMPL::getConnectAddresses(
const RsPeerId &id, sockaddr_storage &lAddr, sockaddr_storage &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns )
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
RS_STACK_MUTEX(mPeerMtx);
/* check for existing */
std::map<RsPeerId, peerState>::iterator it;
it = mFriendList.find(id);
@ -860,7 +859,7 @@ int p3PeerMgrIMPL::getConnectAddresses(const RsPeerId &id,
std::cerr << std::endl;
return 0;
}
lAddr = it->second.localaddr;
eAddr = it->second.serveraddr;
histAddrs = it->second.ipAddrs;
@ -1227,45 +1226,101 @@ void p3PeerMgrIMPL::printPeerLists(std::ostream &out)
* as it doesn't call back to there.
*/
bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr, const struct sockaddr_storage &extAddr)
bool p3PeerMgrIMPL::UpdateOwnAddress( const sockaddr_storage& pLocalAddr,
const sockaddr_storage& pExtAddr )
{
sockaddr_storage localAddr;
sockaddr_storage_copy(pLocalAddr, localAddr);
sockaddr_storage_ipv6_to_ipv4(localAddr);
sockaddr_storage extAddr;
sockaddr_storage_copy(pExtAddr, extAddr);
sockaddr_storage_ipv6_to_ipv4(extAddr);
#ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress(";
std::cerr << sockaddr_storage_tostring(localAddr);
std::cerr << ", ";
std::cerr << sockaddr_storage_tostring(extAddr);
std::cerr << ")" << std::endl;
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress("
<< sockaddr_storage_tostring(localAddr) << ", "
<< sockaddr_storage_tostring(extAddr) << ")" << std::endl;
#endif
if((rsBanList != NULL) && !rsBanList->isAddressAccepted(localAddr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{
std::cerr << "(SS) Trying to set own IP to a banned IP " << sockaddr_storage_iptostring(localAddr) << ". This probably means that a friend in under traffic re-routing attack." << std::endl;
return false ;
}
if( rsBanList &&
!rsBanList->isAddressAccepted(localAddr,
RSBANLIST_CHECKING_FLAGS_BLACKLIST) )
{
std::cerr << "(SS) Trying to set own IP to a banned IP "
<< sockaddr_storage_iptostring(localAddr) << ". This probably"
<< "means that a friend in under traffic re-routing attack."
<< std::endl;
return false;
}
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
{
RS_STACK_MUTEX(mPeerMtx);
//update ip address list
pqiIpAddress ipAddressTimed;
ipAddressTimed.mAddr = localAddr;
ipAddressTimed.mSeenTime = time(NULL);
ipAddressTimed.mSrc = 0 ;
mOwnState.ipAddrs.updateLocalAddrs(ipAddressTimed);
//update ip address list
pqiIpAddress ipAddressTimed;
sockaddr_storage_copy(localAddr, ipAddressTimed.mAddr);
ipAddressTimed.mSeenTime = time(NULL);
ipAddressTimed.mSrc = 0;
mOwnState.ipAddrs.updateLocalAddrs(ipAddressTimed);
mOwnState.localaddr = localAddr;
}
if(!mOwnState.hiddenNode)
{
/* Workaround to spread multiple local ip addresses when presents.
* This is needed because RS wrongly assumes that there is just one
* active local ip address at time. */
std::vector<sockaddr_storage> addrs;
if(getLocalAddresses(addrs))
{
/* To work around MAX_ADDRESS_LIST_SIZE addresses limitation,
* let's shuffle the list of local addresses in the hope that
* with enough time every local address is advertised to
* trusted nodes so they may try to connect to all of them
* including the most convenient if a local connection exists.
*/
std::random_shuffle(addrs.begin(), addrs.end());
for (auto it = addrs.begin(); it!=addrs.end(); ++it)
{
sockaddr_storage& addr(*it);
if( sockaddr_storage_isValidNet(addr) &&
!sockaddr_storage_isLoopbackNet(addr) &&
/* Avoid IPv6 link local addresses as we don't have
* implemented the logic needed to handle sin6_scope_id.
* To properly handle sin6_scope_id it would probably
* require deep reenginering of the RetroShare
* networking stack */
!sockaddr_storage_ipv6_isLinkLocalNet(addr) )
{
sockaddr_storage_ipv6_to_ipv4(addr);
pqiIpAddress pqiIp;
sockaddr_storage_clear(pqiIp.mAddr);
pqiIp.mAddr.ss_family = addr.ss_family;
sockaddr_storage_copyip(pqiIp.mAddr, addr);
sockaddr_storage_setport(
pqiIp.mAddr,
sockaddr_storage_port(localAddr) );
pqiIp.mSeenTime = time(nullptr);
pqiIp.mSrc = 0;
mOwnState.ipAddrs.updateLocalAddrs(pqiIp);
}
}
}
}
sockaddr_storage_copy(localAddr, mOwnState.localaddr);
}
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
{
RS_STACK_MUTEX(mPeerMtx);
//update ip address list
pqiIpAddress ipAddressTimed;
ipAddressTimed.mAddr = extAddr;
ipAddressTimed.mSeenTime = time(NULL);
ipAddressTimed.mSrc = 0 ;
mOwnState.ipAddrs.updateExtAddrs(ipAddressTimed);
//update ip address list
pqiIpAddress ipAddressTimed;
sockaddr_storage_copy(extAddr, ipAddressTimed.mAddr);
ipAddressTimed.mSeenTime = time(NULL);
ipAddressTimed.mSrc = 0;
mOwnState.ipAddrs.updateExtAddrs(ipAddressTimed);
/* Attempted Fix to MANUAL FORWARD Mode....
* don't update the server address - if we are in this mode
@ -1285,8 +1340,8 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr,
std::cerr << std::endl;
}
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";
@ -1296,8 +1351,8 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr,
std::cerr << std::endl;
}
else
{
mOwnState.serveraddr = extAddr;
{
sockaddr_storage_copy(extAddr, mOwnState.serveraddr);
}
}

View File

@ -119,17 +119,20 @@ class p3NetMgrIMPL;
class p3PeerMgr
{
public:
public:
p3PeerMgr() { return; }
virtual ~p3PeerMgr() { return; }
p3PeerMgr() {}
virtual ~p3PeerMgr() {}
virtual bool addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id, uint32_t netMode = RS_NET_MODE_UDP,
uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL,
time_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT)) = 0;
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0;
virtual bool addFriend( const RsPeerId &ssl_id, const RsPgpId &gpg_id,
uint32_t netMode = RS_NET_MODE_UDP,
uint16_t vsDisc = RS_VS_DISC_FULL,
uint16_t vsDht = RS_VS_DHT_FULL,
time_t lastContact = 0,
ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT) ) = 0;
virtual bool isFriend(const RsPeerId& ssl_id) = 0;
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0;
virtual bool isFriend(const RsPeerId& ssl_id) = 0;
virtual bool getAssociatedPeers(const RsPgpId &gpg_id, std::list<RsPeerId> &ids) = 0;
virtual bool removeAllFriendLocations(const RsPgpId &gpgid) = 0;
@ -146,7 +149,7 @@ virtual bool getGroupInfoByName(const std::string& groupName, RsGroupInfo &gr
virtual bool getGroupInfoList(std::list<RsGroupInfo> &groupInfoList) = 0;
virtual bool assignPeersToGroup(const RsNodeGroupId &groupId, const std::list<RsPgpId> &peerIds, bool assign) = 0;
virtual bool resetOwnExternalAddressList() = 0 ;
virtual bool resetOwnExternalAddressList() = 0 ;
virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) =0;
virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) =0;
@ -354,9 +357,9 @@ public:
bool setOwnNetworkMode(uint32_t netMode);
bool setOwnVisState(uint16_t vs_disc, uint16_t vs_dht);
int getConnectAddresses(const RsPeerId &id,
struct sockaddr_storage &lAddr, struct sockaddr_storage &eAddr,
pqiIpAddrSet &histAddrs, std::string &dyndns);
int getConnectAddresses( const RsPeerId &id, sockaddr_storage &lAddr,
sockaddr_storage &eAddr, pqiIpAddrSet &histAddrs,
std::string &dyndns );
protected:

View File

@ -41,6 +41,7 @@
#include "util/rsdebug.h"
#include "util/rsstring.h"
#include "util/rsnet.h"
#include "util/stacktrace.h"
static struct RsLog::logInfo pqinetzoneInfo = {RsLog::Default, "pqinet"};
#define pqinetzone &pqinetzoneInfo
@ -335,15 +336,17 @@ bool getLocalAddresses(std::vector<sockaddr_storage>& addrs)
struct ifaddrs *ifsaddrs, *ifa;
if(getifaddrs(&ifsaddrs) != 0)
{
std::cerr << "FATAL ERROR: getLocalAddresses failed!" << std::endl;
return false ;
std::cerr << __PRETTY_FUNCTION__ << " FATAL ERROR: " << errno << " "
<< strerror(errno) << std::endl;
print_stacktrace();
return false;
}
for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next )
if ( ifa->ifa_addr && (ifa->ifa_flags & IFF_UP) )
{
sockaddr_storage tmp;
sockaddr_storage_clear(tmp);
if (sockaddr_storage_copyip(tmp, * reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr)))
if (sockaddr_storage_copyip(tmp, *reinterpret_cast<sockaddr_storage*>(ifa->ifa_addr)))
addrs.push_back(tmp);
}
freeifaddrs(ifsaddrs);
@ -438,43 +441,17 @@ int unix_fcntl_nonblock(int fd)
}
int unix_connect(int fd, const struct sockaddr *serv_addr, socklen_t socklen)
int unix_connect(int fd, const sockaddr_storage &serv_addr)
{
#ifdef NET_DEBUG
std::cerr << "unix_connect()";
std::cerr << std::endl;
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
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);
int ret = connect( fd, (const struct sockaddr *) &serv_addr,
sizeof(struct sockaddr_in6) );
/******************* WINDOWS SPECIFIC PART ******************/
#ifdef WINDOWS_SYS // WINDOWS
#ifdef NET_DEBUG
std::cerr << "unix_connect()" << std::endl;
#endif
if (ret != 0)
{
errno = WinToUnixError(WSAGetLastError());

View File

@ -103,7 +103,7 @@ bool getLocalAddresses(std::vector<sockaddr_storage> & addrs);
int unix_close(int sockfd);
int unix_socket(int domain, int type, int protocol);
int unix_fcntl_nonblock(int sockfd);
int unix_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
int unix_connect(int sockfd, const sockaddr_storage& serv_addr);
int unix_getsockopt_error(int sockfd, int *err);
#ifdef WINDOWS_SYS // WINDOWS

View File

@ -4,6 +4,7 @@
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -59,14 +60,15 @@ static struct RsLog::logInfo pqisslzoneInfo = {RsLog::Default, "pqisslzone"};
#define PQISSL_PASSIVE 0x00
#define PQISSL_ACTIVE 0x01
#define PQISSL_DEBUG 1
#define PQISSL_LOG_DEBUG 1
const int PQISSL_LOCAL_FLAG = 0x01;
const int PQISSL_REMOTE_FLAG = 0x02;
const int PQISSL_UDP_FLAG = 0x02;
***********/
//#define PQISSL_DEBUG 1
//#define PQISSL_LOG_DEBUG 1
static const int PQISSL_MAX_READ_ZERO_COUNT = 20;
static const time_t PQISSL_MAX_READ_ZERO_TIME = 15; // 15 seconds of no data => reset. (atm HeartBeat pkt sent 5 secs)
@ -96,44 +98,14 @@ static const int PQISSL_SSL_CONNECT_TIMEOUT = 30;
*
*/
pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
:NetBinInterface(parent, parent->PeerId()),
mLinkMgr(lm), pqil(l),
mSslMtx("pqissl"),
active(false), certvalid(false), waiting(WAITING_NOT),
sslmode(PQISSL_ACTIVE), ssl_connection(NULL), sockfd(-1),
readpkt(NULL), pktlen(0), total_len(0),
attempt_ts(0),
n_read_zero(0), mReadZeroTS(0), ssl_connect_timeout(0),
mConnectDelay(0), mConnectTS(0),
mConnectTimeout(0), mTimeoutTS(0)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
/* set address to zero */
sockaddr_storage_clear(remote_addr);
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissl for PeerId: " + PeerId());
#endif
#if 0
if (!(AuthSSL::getAuthSSL()->isAuthenticated(PeerId())))
{
rslog(RSL_ALERT, pqisslzone,
"pqissl::Warning Certificate Not Approved!");
rslog(RSL_ALERT, pqisslzone,
"\t pqissl will not initialise....");
}
#else
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Warning SSL Certificate Approval Not CHECKED??");
#endif
return;
}
pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) :
NetBinInterface(parent, parent->PeerId()),
mLinkMgr(lm), pqil(l), mSslMtx("pqissl"), active(false), certvalid(false),
waiting(WAITING_NOT), sslmode(PQISSL_ACTIVE), ssl_connection(NULL),
sockfd(-1), readpkt(NULL), pktlen(0), total_len(0), attempt_ts(0),
n_read_zero(0), mReadZeroTS(0), ssl_connect_timeout(0), mConnectDelay(0),
mConnectTS(0), mConnectTimeout(0), mTimeoutTS(0)
{ sockaddr_storage_clear(remote_addr); }
pqissl::~pqissl()
{
@ -151,11 +123,9 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm)
int pqissl::connect(const struct sockaddr_storage &raddr)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
RS_STACK_MUTEX(mSslMtx);
// reset failures
remote_addr = raddr;
return ConnectAttempt();
}
@ -203,12 +173,11 @@ int pqissl::close()
// put back on the listening queue.
int pqissl::reset()
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
RS_STACK_MUTEX(mSslMtx);
return reset_locked();
}
int pqissl::reset_locked()
int pqissl::reset_locked()
{
std::string outLog;
bool neededReset = false;
@ -387,7 +356,7 @@ int pqissl::status()
out += " active: \n";
// print out connection.
out += "Connected TO : " + PeerId() + "\n";
out += "Connected TO : " + PeerId().toStdString() + "\n";
// print out cipher.
rs_sprintf_append(out, "\t\tSSL Cipher:%s", SSL_get_cipher(ssl_connection));
rs_sprintf_append(out, " (%d:%d)", SSL_get_cipher_bits(ssl_connection, &alg), alg);
@ -583,7 +552,7 @@ int pqissl::Delay_Connection()
#ifdef PQISSL_LOG_DEBUG
{
std::string out;
rs_sprintf(out, "pqissl::Delay_Connection() Delaying Connection to %s for %lu seconds", PeerId().c_str(), mConnectDelay);
rs_sprintf(out, "pqissl::Delay_Connection() Delaying Connection to %s for %lu seconds", PeerId().toStdString(), mConnectDelay);
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
}
#endif
@ -596,7 +565,7 @@ int pqissl::Delay_Connection()
#ifdef PQISSL_LOG_DEBUG
{
std::string out;
rs_sprintf(out, "pqissl::Delay_Connection() Connection to %s starting in %ld seconds", PeerId().c_str(), mConnectTS - time(NULL));
rs_sprintf(out, "pqissl::Delay_Connection() Connection to %s starting in %ld seconds", PeerId().toStdString(), mConnectTS - time(NULL));
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
}
#endif
@ -608,35 +577,30 @@ 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;
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Initiate_Connection() Attempting Outgoing Connection....");
#ifdef PQISSL_DEBUG
std::cout << __PRETTY_FUNCTION__ << std::endl;
#endif
if (waiting != WAITING_DELAY)
int err;
sockaddr_storage addr = remote_addr;
if(waiting != WAITING_DELAY)
{
rslog(RSL_WARNING, pqisslzone,
"pqissl::Initiate_Connection() Already Attempt in Progress!");
std::cerr << __PRETTY_FUNCTION__ << " Already Attempt in Progress!"
<< std::endl;
return -1;
}
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Initiate_Connection() Opening Socket");
#endif
// open socket connection to addr.
int osock = unix_socket(PF_INET, SOCK_STREAM, 0);
int osock = unix_socket(PF_INET6, SOCK_STREAM, 0);
#ifdef PQISSL_LOG_DEBUG
{
@ -662,7 +626,7 @@ int pqissl::Initiate_Connection()
"pqissl::Initiate_Connection() Making Non-Blocking");
#endif
err = unix_fcntl_nonblock(osock);
err = unix_fcntl_nonblock(osock);
if (err < 0)
{
std::string out;
@ -736,66 +700,47 @@ int pqissl::Initiate_Connection()
#endif
#endif // WINDOWS_SYS
/* Systems that supports dual stack sockets defines IPV6_V6ONLY and some set
* it to 1 by default. This enable dual stack socket on such systems.
* Systems which don't support dual stack (only Windows older then XP SP3)
* will support IPv6 only and not IPv4 */
#ifdef IPV6_V6ONLY
int no = 0;
err = rs_setsockopt( osock, IPPROTO_IPV6, IPV6_V6ONLY,
reinterpret_cast<uint8_t*>(&no), sizeof(no) );
#ifdef PQISSL_DEBUG
if (err) std::cerr << __PRETTY_FUNCTION__
<< " Error setting IPv6 socket dual stack: "
<< errno << " " << strerror(errno) << std::endl;
else std::cerr << __PRETTY_FUNCTION__
<< " Setting IPv6 socket dual stack" << std::endl;
#endif // PQISSL_DEBUG
#endif // IPV6_V6ONLY
mTimeoutTS = time(NULL) + mConnectTimeout;
//std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl;
if (0 != (err = unix_connect(osock, (struct sockaddr *) &addr, sizeof(addr))))
sockaddr_storage_ipv4_to_ipv6(addr);
if (0 != (err = unix_connect(osock, addr)))
{
std::string out;
rs_sprintf(out, "pqissl::Initiate_Connection() connect returns:%d -> errno: %d error: %s\n", err, errno, socket_errorType(errno).c_str());
if (errno == EINPROGRESS)
switch (errno)
{
// set state to waiting.....
case EINPROGRESS:
waiting = WAITING_SOCK_CONNECT;
sockfd = osock;
#ifdef PQISSL_LOG_DEBUG
out += " EINPROGRESS Waiting for Socket Connection";
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
#endif
return 0;
}
else if ((errno == ENETUNREACH) || (errno == ETIMEDOUT))
{
out += "ENETUNREACHABLE: cert: " + PeerId().toStdString();
rslog(RSL_WARNING, pqisslzone, out);
default:
std::cerr << __PRETTY_FUNCTION__ << " Failure connect "
<< sockaddr_storage_tostring(addr)
<< " returns: "
<< err << " -> errno: " << errno << " "
<< socket_errorType(errno) << std::endl;
// Then send unreachable message.
net_internal_close(osock);
osock=-1;
//reset();
osock = -1;
waiting = WAITING_FAIL_INTERFACE;
return -1;
}
/* IF we get here ---- we Failed for some other reason.
* Should abandon this interface
* Known reasons to get here: EINVAL (bad address)
*/
rs_sprintf_append(out, "Error: Connection Failed: %d - %s", errno, socket_errorType(errno).c_str());
net_internal_close(osock);
osock=-1;
waiting = WAITING_FAIL_INTERFACE;
rslog(RSL_WARNING, pqisslzone, out);
// extra output for the moment.
std::cerr << out;
return -1;
}
else
{
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Init_Connection() connect returned 0");
#endif
}
waiting = WAITING_SOCK_CONNECT;
@ -1105,7 +1050,7 @@ int pqissl::Initiate_SSL_Connection()
return 1;
}
int pqissl::SSL_Connection_Complete()
int pqissl::SSL_Connection_Complete()
{
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
@ -1247,27 +1192,21 @@ int pqissl::Extract_Failed_SSL_Certificate()
int pqissl::Authorise_SSL_Connection()
int pqissl::Authorise_SSL_Connection()
{
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::Authorise_SSL_Connection()");
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
if (time(NULL) > ssl_connect_timeout)
{
rslog(RSL_WARNING, pqisslzone,
"pqissl::Authorise_SSL_Connection() Connection Timed Out!");
/* as sockfd is valid, this should close it all up */
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
reset_locked();
if (time(NULL) > ssl_connect_timeout)
{
std::cerr << __PRETTY_FUNCTION__ << " Connection timed out reset!"
<< std::endl;
reset_locked();
}
int err;
if (0 >= (err = SSL_Connection_Complete()))
{
return err;
}
if (0 >= (err = SSL_Connection_Complete())) return err;
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
@ -1352,36 +1291,54 @@ int pqissl::Authorise_SSL_Connection()
/* This function is public, and callable from pqilistener - so must be mutex protected */
int pqissl::accept(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr) // initiate incoming connection.
int pqissl::accept( SSL *ssl, int fd,
const sockaddr_storage &foreign_addr)
{
#ifdef PQISSL_DEBUG
std::cerr << "pqissl::accept()";
std::cerr << std::endl;
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
RS_STACK_MUTEX(mSslMtx);
return accept_locked(ssl, fd, foreign_addr);
}
int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr) // initiate incoming connection.
int pqissl::accept_locked( SSL *ssl, int fd,
const sockaddr_storage &foreign_addr )
{
uint32_t check_result;
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(foreign_addr,checking_flags,&check_result))
{
std::cerr << "(SS) refusing incoming SSL connection from blacklisted foreign address " << sockaddr_storage_iptostring(foreign_addr)
<< ". Reason: " << check_result << "." << std::endl;
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_BLACKLISTED, PeerId().toStdString(), sockaddr_storage_iptostring(foreign_addr), "", "", check_result);
uint32_t check_result;
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
if( rsBanList && !rsBanList->isAddressAccepted( foreign_addr,
checking_flags,
&check_result ) )
{
std::cerr << __PRETTY_FUNCTION__
<< " (SS) refusing incoming SSL connection from blacklisted "
<< "foreign address "
<< sockaddr_storage_iptostring(foreign_addr)
<< ". Reason: " << check_result << "." << std::endl;
RsServer::notify()->AddFeedItem(
RS_FEED_ITEM_SEC_IP_BLACKLISTED,
PeerId().toStdString(),
sockaddr_storage_iptostring(foreign_addr), "", "",
check_result);
reset_locked();
return -1;
}
return -1;
}
if (waiting != WAITING_NOT)
{
rslog(RSL_WARNING, pqisslzone, "pqissl::accept() Peer: " + PeerId().toStdString() + " - Two connections in progress - Shut 1 down!");
std::cerr << __PRETTY_FUNCTION__ << " Peer: " << PeerId().toStdString()
<< " - Two connections in progress - Shut 1 down!"
<< std::endl;
// outgoing connection in progress.
// shut this baby down.
@ -1392,70 +1349,51 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei
switch(waiting)
{
case WAITING_SOCK_CONNECT:
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::accept() STATE = Waiting Sock Connect - close the socket");
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting Sock Connect "
<< "- close the socket" << std::endl;
#endif
break;
case WAITING_SSL_CONNECTION:
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::accept() STATE = Waiting SSL Connection - close sockfd + ssl_conn");
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting SSL "
<< "Connection - close sockfd + ssl_conn" << std::endl;
#endif
break;
case WAITING_SSL_AUTHORISE:
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::accept() STATE = Waiting SSL Authorise - close sockfd + ssl_conn");
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting SSL Authorise"
<< " - close sockfd + ssl_conn" << std::endl;
#endif
break;
case WAITING_FAIL_INTERFACE:
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone,
"pqissl::accept() STATE = Failed, ignore?");
#ifdef PQISSL_DEBUG
std::cerr << __PRETTY_FUNCTION__ << " STATE = Failed, ignore?"
<< std::endl;
#endif
break;
default:
rslog(RSL_ALERT, pqisslzone,
"pqissl::accept() STATE = Unknown - ignore?");
rslog(RSL_ALERT, pqisslzone, "pqissl::accept() -> calling reset()");
std::cerr << __PRETTY_FUNCTION__ << " STATE = Unknown - resetting!"
<< std::endl;
reset_locked();
break;
}
//waiting = WAITING_FAIL_INTERFACE;
//return -1;
}
/* shutdown existing - in all cases use the new one */
if ((ssl_connection) && (ssl_connection != ssl))
{
rslog(RSL_ALERT, pqisslzone,
"pqissl::accept() closing Previous/Existing ssl_connection");
std::cerr << __PRETTY_FUNCTION__
<< " closing Previous/Existing ssl_connection" << std::endl;
SSL_shutdown(ssl_connection);
SSL_free (ssl_connection);
}
if ((sockfd > -1) && (sockfd != fd))
{
rslog(RSL_ALERT, pqisslzone,
"pqissl::accept() closing Previous/Existing sockfd");
std::cerr << __PRETTY_FUNCTION__ << " closing Previous/Existing sockfd"
<< std::endl;
net_internal_close(sockfd);
}
@ -1468,54 +1406,39 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei
/* if we connected - then just writing the same over,
* but if from ssllistener then we need to save the address.
*/
remote_addr = foreign_addr;
sockaddr_storage_copy(foreign_addr, remote_addr);
/* check whether it is on the same LAN */
struct sockaddr_storage localaddr;
mLinkMgr->getLocalAddress(localaddr);
std::cerr << __PRETTY_FUNCTION__ << " SUCCESSFUL connection to: "
<< PeerId().toStdString() << " remoteaddr: "
<< sockaddr_storage_iptostring(remote_addr) << std::endl;
#ifdef PQISSL_DEBUG
{
std::string out = "pqissl::accept() SUCCESSFUL connection to: " + PeerId().toStdString();
out += " localaddr: " + sockaddr_storage_iptostring(localaddr);
out += " remoteaddr: " + sockaddr_storage_iptostring(remote_addr);
rslog(RSL_WARNING, pqisslzone, out);
}
// establish the ssl details.
// cipher name.
int err;
#ifdef PQISSL_LOG_DEBUG
{
int alg;
std::string out;
rs_sprintf(out, "SSL Cipher:%s\n", SSL_get_cipher(ssl));
rs_sprintf_append(out, "SSL Cipher Bits:%d - %d\n", SSL_get_cipher_bits(ssl, &alg), alg);
rs_sprintf_append(out, "SSL Cipher Version:%s\n", SSL_get_cipher_version(ssl));
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
int alg;
std::cerr << __PRETTY_FUNCTION__ << "SSL Cipher: "
<< SSL_get_cipher(ssl) << std::endl << "SSL Cipher Bits: "
<< SSL_get_cipher_bits(ssl, &alg) << " - " << alg
<< std::endl;
}
#endif
// make non-blocking / or check.....
if ((err = net_internal_fcntl_nonblock(sockfd)) < 0)
int err;
if ((err = net_internal_fcntl_nonblock(sockfd)) < 0)
{
rslog(RSL_ALERT, pqisslzone, "Error: Cannot make socket NON-Blocking: ");
std::cerr << __PRETTY_FUNCTION__ << "Cannot make socket NON-Blocking "
<< "reset!" << std::endl;
active = false;
waiting = WAITING_FAIL_INTERFACE;
// failed completely.
rslog(RSL_ALERT, pqisslzone, "pqissl::accept() -> calling reset()");
waiting = WAITING_FAIL_INTERFACE; // failed completely.
reset_locked();
return -1;
}
else
{
#ifdef PQISSL_LOG_DEBUG
rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissl::accept() Socket Made Non-Blocking!");
#ifdef PQISSL_DEBUG
else std::cerr << __PRETTY_FUNCTION__ << " Socket made non-nlocking!"
<< std::endl;
#endif
}
// we want to continue listening - incase this socket is crap, and they try again.
//stoplistening();
@ -1524,15 +1447,16 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei
waiting = WAITING_NOT;
#ifdef PQISSL_DEBUG
std::cerr << "pqissl::accept_locked() connection complete - notifying parent";
std::cerr << std::endl;
std::cerr << __PRETTY_FUNCTION__ << "connection complete - notifying parent"
<< std::endl;
#endif
// Notify the pqiperson.... (Both Connect/Receive)
if (parent())
{
struct sockaddr_storage addr = remote_addr;
parent() -> notifyEvent(this, NET_CONNECT_SUCCESS, addr);
// Is the copy necessary?
sockaddr_storage addr; sockaddr_storage_copy(remote_addr, addr);
parent()->notifyEvent(this, NET_CONNECT_SUCCESS, addr);
}
return 1;
}
@ -1626,31 +1550,35 @@ int pqissl::senddata(void *data, int len)
return tmppktlen;
}
int pqissl::readdata(void *data, int len)
int pqissl::readdata(void *data, int len)
{
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
RS_STACK_MUTEX(mSslMtx);
#ifdef PQISSL_DEBUG
std::cout << "Reading data thread=" << pthread_self() << ", ssl=" << (void*)this << std::endl ;
std::cout << "Reading data thread=" << pthread_self() << ", ssl="
<< (void*)this << std::endl;
#endif
// Safety check. Apparently this avoids some SIGSEGV.
//
if (ssl_connection == NULL)
return -1 ;
if (ssl_connection == NULL) return -1;
// There is a do, because packets can be splitted into multiple ssl buffers
// when they are larger than 16384 bytes. Such packets have to be read in
// multiple slices.
do
{
int tmppktlen ;
int tmppktlen;
#ifdef PQISSL_DEBUG
std::cerr << "calling SSL_read. len=" << len << ", total_len=" << total_len << std::endl ;
std::cerr << "calling SSL_read. len=" << len << ", total_len="
<< total_len << std::endl;
#endif
ERR_clear_error() ;
tmppktlen = SSL_read(ssl_connection, (void*)( &(((uint8_t*)data)[total_len])), len-total_len) ;
ERR_clear_error();
tmppktlen = SSL_read(ssl_connection,
(void*)( &(((uint8_t*)data)[total_len])),
len-total_len);
#ifdef PQISSL_DEBUG
std::cerr << "have read " << tmppktlen << " bytes" << std::endl ;
std::cerr << "data[0] = "
@ -1665,7 +1593,6 @@ int pqissl::readdata(void *data, int len)
#endif
// Need to catch errors.....
//
if (tmppktlen <= 0) // probably needs a reset.
{
std::string out;

View File

@ -4,6 +4,7 @@
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -114,16 +115,13 @@ virtual bool cansend(uint32_t usec);
virtual int close(); /* BinInterface version of reset() */
virtual RsFileHash gethash(); /* not used here */
virtual bool bandwidthLimited() { return true ; } // replace by !sameLAN to avoid bandwidth limiting on LAN
virtual bool bandwidthLimited() { return true ; }
public:
/* Completion of the SSL connection,
* this is public, so it can be called by
* the listener (should make friends??)
*/
/// initiate incoming connection.
int accept(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr);
int accept(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr);
void getCryptoParams(RsPeerCryptoParams& params) ;
bool actAsServer();
@ -139,7 +137,10 @@ protected:
RsMutex mSslMtx; /**** MUTEX protects data and fn below ****/
virtual int reset_locked();
int accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr);
/// initiate incoming connection.
int accept_locked( SSL *ssl, int fd,
const sockaddr_storage& foreign_addr );
// A little bit of information to describe
// the SSL state, this is needed

View File

@ -4,6 +4,7 @@
* 3P/PQI network interface for RetroShare.
*
* Copyright 2004-2006 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -103,17 +104,27 @@ int pqissllistenbase::status()
return 1;
}
int pqissllistenbase::setuplisten()
int pqissllistenbase::setuplisten()
{
int err;
if (active)
return -1;
int err;
if (active) return -1;
lsock = socket(PF_INET6, SOCK_STREAM, 0);
#ifdef IPV6_V6ONLY
int no = 0;
err = rs_setsockopt(lsock, IPPROTO_IPV6, IPV6_V6ONLY,
reinterpret_cast<uint8_t*>(&no), sizeof(no));
if (err) std::cerr << __PRETTY_FUNCTION__
<< ": Error setting IPv6 socket dual stack" << std::endl;
else std::cerr << __PRETTY_FUNCTION__
<< ": Success setting IPv6 socket dual stack" << std::endl;
#endif // IPV6_V6ONLY
lsock = socket(PF_INET, SOCK_STREAM, 0);
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS // ie UNIX
if (lsock < 0)
{
if (lsock < 0)
{
pqioutput(PQL_ALERT, pqissllistenzone,
"pqissllistenbase::setuplisten() Cannot Open Socket!");
@ -199,10 +210,14 @@ int pqissllistenbase::setuplisten()
#ifdef OPEN_UNIVERSAL_PORT
struct sockaddr_storage tmpaddr = laddr;
if (!mPeerMgr->isHidden()) sockaddr_storage_zeroip(tmpaddr);
if (0 != (err = universal_bind(lsock, (struct sockaddr *) &tmpaddr, sizeof(tmpaddr))))
if (!mPeerMgr->isHidden())
{
tmpaddr.ss_family = PF_INET6;
sockaddr_storage_zeroip(tmpaddr);
}
if (0 != (err = rs_bind(lsock, tmpaddr)))
#else
if (0 != (err = universal_bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr))))
if (0 != (err = universal_bind(lsock, laddr)))
#endif
{
std::string out = "pqissllistenbase::setuplisten() Cannot Bind to Local Address!\n";

View File

@ -250,22 +250,38 @@ int pqissludp::Initiate_Connection()
{
std::cerr << "CONVERTING ALL ADDRESSES TO IPV4: TODO make IPV6";
std::cerr << std::endl;
struct sockaddr_in srcaddr;
struct sockaddr_in proxyaddr;
struct sockaddr_in remoteaddr;
if ((mConnectSrcAddr.ss_family != AF_INET) ||
(mConnectProxyAddr.ss_family != AF_INET) ||
(remote_addr.ss_family != AF_INET))
bool nonIpV4 = false;
if(!sockaddr_storage_ipv6_to_ipv4(remote_addr))
{
std::cerr << "Error One Address is not IPv4. aborting";
std::cerr << std::endl;
abort();
nonIpV4 = true;
std::cerr << __PRETTY_FUNCTION__ << "Error: remote_addr is not "
<< "valid IPv4!" << std::endl;
sockaddr_storage_dump(remote_addr);
}
if(!sockaddr_storage_ipv6_to_ipv4(mConnectSrcAddr))
{
nonIpV4 = true;
std::cerr << __PRETTY_FUNCTION__ << "Error: mConnectSrcAddr is "
<< "not valid IPv4!" << std::endl;
sockaddr_storage_dump(mConnectSrcAddr);
}
if(!sockaddr_storage_ipv6_to_ipv4(mConnectProxyAddr))
{
nonIpV4 = true;
std::cerr << __PRETTY_FUNCTION__ << "Error: mConnectProxyAddr "
<< "is not valid IPv4!" << std::endl;
sockaddr_storage_dump(mConnectProxyAddr);
}
if(!nonIpV4)
{
print_stacktrace();
return -EINVAL;
}
struct sockaddr_in *rap = (struct sockaddr_in *) &remote_addr;
struct sockaddr_in *pap = (struct sockaddr_in *) &mConnectProxyAddr;
struct sockaddr_in *sap = (struct sockaddr_in *) &mConnectSrcAddr;

View File

@ -4,6 +4,7 @@
* RetroShare C++ Interface.
*
* Copyright 2004-2008 by Robert Fernie.
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@ -332,27 +333,29 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.hiddenNodePort = 0;
d.hiddenType = RS_HIDDEN_TYPE_NONE;
if (sockaddr_storage_isnull(ps.localaddr))
if(!sockaddr_storage_isnull(ps.localaddr))
{
sockaddr_storage_ipv6_to_ipv4(ps.localaddr);
d.localAddr = sockaddr_storage_iptostring(ps.localaddr);
d.localPort = sockaddr_storage_port(ps.localaddr);
}
else
{
d.localAddr = "INVALID_IP";
d.localPort = 0;
}
else
{
d.localAddr = sockaddr_storage_iptostring(ps.localaddr);
d.localPort = sockaddr_storage_port(ps.localaddr);
}
if (sockaddr_storage_isnull(ps.serveraddr))
if(!sockaddr_storage_isnull(ps.serveraddr))
{
sockaddr_storage_ipv6_to_ipv4(ps.serveraddr);
d.extAddr = sockaddr_storage_iptostring(ps.serveraddr);
d.extPort = sockaddr_storage_port(ps.serveraddr);
}
else
{
d.extAddr = "INVALID_IP";
d.extPort = 0;
}
else
{
d.extAddr = sockaddr_storage_iptostring(ps.serveraddr);
d.extPort = sockaddr_storage_port(ps.serveraddr);
}
d.dyndns = ps.dyndns;
@ -360,16 +363,16 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
for(it = ps.ipAddrs.mLocal.mAddrs.begin();
it != ps.ipAddrs.mLocal.mAddrs.end(); ++it)
{
sockaddr_storage_ipv6_to_ipv4(it->mAddr);
std::string toto;
toto += "L:";
toto += sockaddr_storage_tostring(it->mAddr);
rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime);
d.ipAddressList.push_back(toto);
}
for(it = ps.ipAddrs.mExt.mAddrs.begin(); it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
{
sockaddr_storage_ipv6_to_ipv4(it->mAddr);
std::string toto;
toto += "E:";
toto += sockaddr_storage_tostring(it->mAddr);
rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime);
d.ipAddressList.push_back(toto);
@ -416,6 +419,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
if (pcs.state & RS_PEER_S_CONNECTED)
{
sockaddr_storage_ipv6_to_ipv4(pcs.connectaddr);
d.connectAddr = sockaddr_storage_iptostring(pcs.connectaddr);
d.connectPort = sockaddr_storage_port(pcs.connectaddr);
}
@ -900,68 +904,33 @@ bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uin
return true;
}
bool p3Peers::setLocalAddress(const RsPeerId &id, const std::string &addr_str, uint16_t port)
bool p3Peers::setLocalAddress(const RsPeerId &id,
const std::string &addr_str, uint16_t port)
{
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::setLocalAddress() " << id << std::endl;
std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " "
<< port << std::endl;
#endif
if(port < 1024)
{
std::cerr << "(EE) attempt to use a port that is reserved to the system: " << port << std::endl;
return false ;
}
struct sockaddr_storage addr;
struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr;
addrv4p->sin_family = AF_INET;
addrv4p->sin_port = htons(port);
int ret = 1;
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
#ifndef WINDOWS_SYS
if (ret && (0 != inet_aton(addr_str.c_str(), &(addrv4p->sin_addr))))
#else
addrv4p->sin_addr.s_addr = inet_addr(addr_str.c_str());
if (ret)
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
{
return mPeerMgr->setLocalAddress(id, addr);
}
sockaddr_storage addr;
if (sockaddr_storage_inet_pton(addr, addr_str))
if (sockaddr_storage_setport(addr, port))
return mPeerMgr->setLocalAddress(id, addr);
return false;
}
bool p3Peers::setExtAddress(const RsPeerId &id, const std::string &addr_str, uint16_t port)
bool p3Peers::setExtAddress(const RsPeerId &id,
const std::string &addr_str, uint16_t port)
{
#ifdef P3PEERS_DEBUG
std::cerr << "p3Peers::setExtAddress() " << id << std::endl;
std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " "
<< port << std::endl;
#endif
if(port < 1024)
{
std::cerr << "(EE) attempt to use a port that is reserved to the system: " << port << std::endl;
return false ;
}
// NOTE THIS IS IPV4 FOR NOW.
struct sockaddr_storage addr;
struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr;
addrv4p->sin_family = AF_INET;
addrv4p->sin_port = htons(port);
int ret = 1;
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
#ifndef WINDOWS_SYS
if (ret && (0 != inet_aton(addr_str.c_str(), &(addrv4p->sin_addr))))
#else
addrv4p->sin_addr.s_addr = inet_addr(addr_str.c_str());
if (ret)
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
{
return mPeerMgr->setExtAddress(id, addr);
}
sockaddr_storage addr;
if (sockaddr_storage_inet_pton(addr, addr_str))
if (sockaddr_storage_setport(addr, port))
return mPeerMgr->setExtAddress(id, addr);
return false;
}
@ -1085,22 +1054,22 @@ std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures)
unsigned char *mem_block = NULL;
size_t mem_block_size = 0;
if(!AuthGPG::getAuthGPG()->exportPublicKey(RsPgpId(pgp_id),mem_block,mem_block_size,false,include_signatures))
if( !AuthGPG::getAuthGPG()->exportPublicKey(
RsPgpId(pgp_id), mem_block, mem_block_size,
false, include_signatures ) )
{
std::cerr << "Cannot output certificate for id \"" << pgp_id << "\". Sorry." << std::endl;
std::cerr << "Cannot output certificate for id \"" << pgp_id
<< "\". Sorry." << std::endl;
return "" ;
}
RsPeerDetails Detail ;
RsPeerDetails Detail;
if(!getGPGDetails(pgp_id,Detail)) return "";
if(!getGPGDetails(pgp_id,Detail) )
return "" ;
RsCertificate cert( Detail,mem_block,mem_block_size );
delete[] mem_block ;
RsCertificate cert( Detail,mem_block,mem_block_size ) ;
delete[] mem_block ;
return cert.armouredPGPKey() ;
return cert.armouredPGPKey();
}

View File

@ -890,7 +890,7 @@ bool p3I2pBob::connectI2P()
}
// create socket
mSocket = unix_socket(AF_INET, SOCK_STREAM, 0);
mSocket = unix_socket(PF_INET, SOCK_STREAM, 0);
if (mSocket < 0)
{
rslog(RsLog::Warning, &i2pBobLogInfo, "connectI2P_locked Failed to open socket! Socket Error: " + socket_errorType(errno));
@ -898,7 +898,7 @@ bool p3I2pBob::connectI2P()
}
// connect
int err = unix_connect(mSocket, (struct sockaddr *)&mI2PProxyAddr, sizeof(mI2PProxyAddr));
int err = unix_connect(mSocket, mI2PProxyAddr);
if (err != 0) {
rslog(RsLog::Warning, &i2pBobLogInfo, "connectI2P_locked Failed to connect to BOB! Socket Error: " + socket_errorType(errno));
return false;

View File

@ -26,15 +26,11 @@
#include "services/p3discovery2.h"
#include "pqi/p3peermgr.h"
#include "pqi/pqinetwork.h" // for getLocalAddresses
#include "util/rsversioninfo.h"
#include "retroshare/rsiface.h"
#include "rsserver/p3face.h"
#include <vector> // for std::vector
#include <algorithm> // for std::random_shuffle
// Interface pointer.
RsDisc *rsDisc = NULL;
@ -350,41 +346,6 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
peerState detail;
if (mPeerMgr->getOwnNetStatus(detail))
{
/* Workaround to spread multiple local ip addresses when presents. This
* is needed because RS wrongly assumes that there is just one active
* local ip address at time. */
std::vector<sockaddr_storage> addrs;
if(!detail.hiddenNode && getLocalAddresses(addrs))
{
/* To work around MAX_ADDRESS_LIST_SIZE addresses limitation,
* let's shuffle the list of
* local addresses in the hope that with enough time every local
* address is advertised to trusted nodes so they may try to
* connect to all of them including the most convenient if a local
* connection exists.*/
std::random_shuffle(addrs.begin(), addrs.end());
for (auto it = addrs.begin(); it!=addrs.end(); ++it)
{
sockaddr_storage& addr(*it);
if( sockaddr_storage_isValidNet(addr) &&
!sockaddr_storage_isLoopbackNet(addr) &&
!sockaddr_storage_sameip(addr, detail.localaddr) )
{
pqiIpAddress pqiIp;
sockaddr_storage_clear(pqiIp.mAddr);
pqiIp.mAddr.ss_family = addr.ss_family;
sockaddr_storage_copyip(pqiIp.mAddr, addr);
sockaddr_storage_setport(
pqiIp.mAddr,
sockaddr_storage_port(detail.localaddr) );
pqiIp.mSeenTime = time(nullptr);
pqiIp.mSrc = 0;
detail.ipAddrs.updateLocalAddrs(pqiIp);
}
}
}
RsDiscContactItem *pkt = new RsDiscContactItem();
/* Cyril: we dont send our own IP to an hidden node. It will not use it
* anyway. */
@ -513,13 +474,13 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
* permission matrix. Disabling this instead will make life more
* difficult for average user, that moreover whould have no way to
* revert an hardcoded policy. */
pqiIpAddrSet addrsFromPeer;
pqiIpAddrSet addrsFromPeer;
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
addrsFromPeer.mExt.extractFromTlv(item->extAddrList);
#ifdef P3DISC_DEBUG
std::cerr << "Setting address list to peer " << item->sslId << ", to be:" << std::endl ;
std::cerr << "Setting address list to peer " << item->sslId
<< ", to be:" << std::endl ;
std::string addrstr;
addrsFromPeer.printAddrs(addrstr);

View File

@ -50,34 +50,37 @@ virtual bool resetAddress(struct sockaddr_in &local) { return false; }
/*******************************************************/
#include "pqi/pqimonitor.h"
#include "util/rsnet.h"
#include "util/stacktrace.h"
#include <iostream>
class rsUdpStack: public UdpStack, public pqiNetListener
{
public:
rsUdpStack(struct sockaddr_in &local)
:UdpStack(local) { return; }
public:
rsUdpStack(struct sockaddr_in &local) : UdpStack(local) {}
rsUdpStack(int testmode, struct sockaddr_in &local)
:UdpStack(testmode, local) { return; }
rsUdpStack(int testmode, struct sockaddr_in &local) :
UdpStack(testmode, local) {}
/* from pqiNetListener */
virtual bool resetListener(const struct sockaddr_storage &local)
/// @see pqiNetListener
virtual bool resetListener(const sockaddr_storage& local)
{
//std::cerr << "rsUdpStack::resetListener(" << sockaddr_storage_tostring(local) << ")";
//std::cerr << std::endl;
sockaddr_storage temp;
sockaddr_storage_copy(local, temp);
if (local.ss_family != AF_INET)
if (!sockaddr_storage_ipv6_to_ipv4(temp))
{
std::cerr << "rsUdpStack::resetListener() NOT IPv4 ERROR";
std::cerr << std::endl;
abort();
std::cerr << __PRETTY_FUNCTION__ << " Got non IPv4 address ERROR"
<< std::endl;
sockaddr_storage_dump(local);
print_stacktrace();
return -EINVAL;
}
struct sockaddr_in *addr = (struct sockaddr_in *) &local;
sockaddr_in *addr = reinterpret_cast<sockaddr_in*>(&temp);
return resetAddress(*addr);
}
};
class rsFixedUdpStack: public UdpStack, public pqiNetListener

View File

@ -94,7 +94,10 @@ static void getPage(const std::string& server_name,std::string& page)
#endif
std::cerr << "ExtAddrFinder: resolved hostname " << server_name << " to " << rs_inet_ntoa(in) << std::endl;
if(unix_connect(sockfd,(struct sockaddr *)&serveur, sizeof(serveur)) == -1)
sockaddr_storage server;
sockaddr_storage_setipv4(server, &serveur);
sockaddr_storage_setport(server, 80);
if(unix_connect(sockfd, server) == -1)
{
std::cerr << "ExtAddrFinder: Connection error to " << server_name << std::endl ;
unix_close(sockfd);

View File

@ -88,14 +88,26 @@ 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);
int rs_bind(int fd, const sockaddr_storage& addr);
void sockaddr_storage_clear(struct sockaddr_storage &addr);
// mods.
bool sockaddr_storage_zeroip(struct sockaddr_storage &addr);
/**
* @brief Use this function to copy sockaddr_storage.
*
* POSIX does not require that objects of type sockaddr_storage can be copied
* as aggregates thus it is unsafe to aggregate copy ( operator = )
* sockaddr_storage and unexpected behaviors may happens due to padding
* and alignment.
*
* @see https://sourceware.org/bugzilla/show_bug.cgi?id=20111
* @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71120
*/
bool sockaddr_storage_copy(const sockaddr_storage& src, sockaddr_storage& dst);
bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src);
uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr);
bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port);
@ -103,9 +115,14 @@ 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_inet_pton( sockaddr_storage &addr,
const std::string& ipStr );
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);
bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr);
bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr);
// comparisons.
bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b);
@ -131,8 +148,12 @@ 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);
bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr);
bool sockaddr_storage_ipv6_isLinkLocalNet(const sockaddr_storage &addr);
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr);
bool rs_inet_ntop(const sockaddr_storage &addr, std::string &dst);
bool sockaddr_storage_inet_ntop(const sockaddr_storage &addr, std::string &dst);
int rs_setsockopt( int sockfd, int level, int optname,
const uint8_t *optval, uint32_t optlen );
#endif /* RS_UNIVERSAL_NETWORK_HEADER */

View File

@ -26,6 +26,24 @@
#include <sstream>
#include <iomanip>
#include <cstdlib>
#ifdef WINDOWS_SYS
# include <Winsock2.h>
/** Provides Linux like accessor for in6_addr.s6_addr16 for Windows.
* Yet Windows doesn't provide 32 bits accessors so there is no way to use
* in6_addr.s6_addr32 crossplatform.
*/
# define s6_addr16 u.Word
#else
# include <netinet/in.h>
# include <sys/socket.h>
# include <sys/types.h>
# ifdef __APPLE__
/// Provides Linux like accessor for in6_addr.s6_addr16 for Mac.
# define s6_addr16 __u6_addr.__u6_addr16
#endif // __APPLE__
#endif // WINDOWS_SYS
#include "util/rsnet.h"
#include "util/rsstring.h"
@ -90,17 +108,14 @@ 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 rs_bind(int fd, const sockaddr_storage& addr)
{
#ifdef SS_DEBUG
std::cerr << "universal_bind()";
std::cerr << std::endl;
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) addr;
socklen_t len = socklen;
switch (ss_addr->ss_family)
socklen_t len = 0;
switch (addr.ss_family)
{
case AF_INET:
len = sizeof(struct sockaddr_in);
@ -110,13 +125,7 @@ int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen)
break;
}
if (len > socklen)
{
std::cerr << "universal_bind() ERROR len > socklen" << std::endl;
len = socklen;
}
return bind(fd, addr, len);
return bind(fd, reinterpret_cast<const struct sockaddr *>(&addr), len);
}
@ -252,6 +261,58 @@ bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6
return true;
}
#ifdef WINDOWS_SYS
int inet_pton(int af, const char *src, void *dst)
{
sockaddr_storage ss;
int size = sizeof(ss);
char src_copy[INET6_ADDRSTRLEN+1];
ZeroMemory(&ss, sizeof(ss));
/* stupid non-const API */
strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
src_copy[INET6_ADDRSTRLEN] = 0;
if (WSAStringToAddressA(src_copy, af, NULL, (sockaddr *)&ss, &size) == 0)
{
switch(af)
{
case AF_INET:
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
return 1;
case AF_INET6:
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
return 1;
}
}
return 0;
}
#endif
bool sockaddr_storage_inet_pton( sockaddr_storage &addr,
const std::string& ipStr )
{
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
struct sockaddr_in6 * addrv6p = (struct sockaddr_in6 *) &addr;
struct sockaddr_in * addrv4p = (struct sockaddr_in *) &addr;
if ( 1 == inet_pton(AF_INET6, ipStr.c_str(), &(addrv6p->sin6_addr)) )
{
addr.ss_family = AF_INET6;
return true;
}
else if ( 1 == inet_pton(AF_INET, ipStr.c_str(), &(addrv4p->sin_addr)) )
{
addr.ss_family = AF_INET;
return sockaddr_storage_ipv4_to_ipv6(addr);
}
return false;
}
bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name)
{
@ -265,6 +326,71 @@ bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name)
return (1 == inet_aton(name, &(ipv4_ptr->sin_addr)));
}
bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr)
{
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
if ( addr.ss_family == AF_INET6 ) return true;
if ( addr.ss_family == AF_INET )
{
sockaddr_in & addr_ipv4 = (sockaddr_in &) addr;
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
uint32_t ip = addr_ipv4.sin_addr.s_addr;
uint16_t port = addr_ipv4.sin_port;
sockaddr_storage_clear(addr);
addr_ipv6.sin6_family = AF_INET6;
addr_ipv6.sin6_port = port;
addr_ipv6.sin6_addr.s6_addr16[5] = htons(0xffff);
memmove( reinterpret_cast<void*>(&(addr_ipv6.sin6_addr.s6_addr16[6])),
reinterpret_cast<void*>(&ip), 4 );
return true;
}
return false;
}
bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr)
{
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ << std::endl;
#endif
if ( addr.ss_family == AF_INET ) return true;
if ( addr.ss_family == AF_INET6 )
{
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
bool ipv4m = addr_ipv6.sin6_addr.s6_addr16[5] == htons(0xffff);
for ( int i = 0; ipv4m && i < 5 ; ++i )
ipv4m &= addr_ipv6.sin6_addr.s6_addr16[i] == htons(0x0000);
if(ipv4m)
{
uint32_t ip;
memmove( reinterpret_cast<void*>(&ip),
reinterpret_cast<void*>(&(addr_ipv6.sin6_addr.s6_addr16[6])),
4 );
uint16_t port = addr_ipv6.sin6_port;
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;
return true;
}
}
return false;
}
/******************************** Comparisions **********************************/
@ -370,15 +496,20 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &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;
case AF_INET:
output += "=";
output += sockaddr_storage_iptostring(addr);
output += ":";
output += sockaddr_storage_porttostring(addr);
break;
case AF_INET6:
output += "=[";
output += sockaddr_storage_iptostring(addr);
output += "]:";
output += sockaddr_storage_porttostring(addr);
break;
default:
break;
}
return output;
}
@ -406,7 +537,7 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
{
const sockaddr_in6 * in6 = (const sockaddr_in6 *) & addr;
std::string addrStr = "INVALID_IPV6";
rs_inet_ntop(addr, addrStr);
sockaddr_storage_inet_ntop(addr, addrStr);
output << "addr.ss_family = AF_INET6";
output << " in6->sin6_addr = ";
output << addrStr;
@ -422,7 +553,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
const uint8_t * buf = reinterpret_cast<const uint8_t *>(&addr);
for( uint32_t i = 0; i < sizeof(addr); ++i )
output << std::setw(2) << std::setfill('0') << std::hex << +buf[i];
// The unary +buf[i] operation forces a no-op type conversion to an int with the correct sign
/* The unary +buf[i] operation forces a no-op type conversion to an int
* with the correct sign */
}
}
@ -450,6 +582,12 @@ std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr)
break;
default:
output = "AF_INVALID";
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ << " Got invalid address!"
<< std::endl;
sockaddr_storage_dump(addr);
print_stacktrace();
#endif
break;
}
return output;
@ -460,15 +598,18 @@ 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;
case AF_INET:
output = sockaddr_storage_ipv4_iptostring(addr);
break;
case AF_INET6:
output = sockaddr_storage_ipv6_iptostring(addr);
break;
default:
output = "INVALID_IP";
std::cerr << __PRETTY_FUNCTION__ << " Got invalid IP:" << std::endl;
sockaddr_storage_dump(addr);
print_stacktrace();
break;
}
return output;
}
@ -592,9 +733,7 @@ bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
case AF_INET:
return isLinkLocalNet(&(to_const_ipv4_ptr(addr)->sin_addr));
case AF_INET6:
std::cerr << __PRETTY_FUNCTION__ << " for AF_INET6 not implemented"
<< std::endl;
break;
return sockaddr_storage_ipv6_isLinkLocalNet(addr);
default:
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ <<" INVALID Family:" << std::endl;
@ -606,6 +745,16 @@ bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
return false;
}
bool sockaddr_storage_ipv6_isLinkLocalNet(const sockaddr_storage &addr)
{
if(addr.ss_family != AF_INET6) return false;
const sockaddr_in6 * addr6 = (const sockaddr_in6 *) &addr;
uint16_t mask = htons(0xffc0);
uint16_t llPrefix = htons(0xfe80);
return ((addr6->sin6_addr.s6_addr16[0] & mask ) == llPrefix);
}
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr)
{
@ -668,6 +817,51 @@ const struct sockaddr_in6 *to_const_ipv6_ptr(const struct sockaddr_storage &addr
/******************************** Set / Clear ***********************************/
bool sockaddr_storage_copy(const sockaddr_storage& src, sockaddr_storage& dst)
{
if(&src == &dst) return true;
switch(src.ss_family)
{
case AF_INET:
{
sockaddr_storage_clear(dst);
const sockaddr_in& ins(reinterpret_cast<const sockaddr_in&>(src));
sockaddr_in& ind(reinterpret_cast<sockaddr_in&>(dst));
ind.sin_family = AF_INET;
ind.sin_addr.s_addr = ins.sin_addr.s_addr;
ind.sin_port = ins.sin_port;
return true;
}
case AF_INET6:
{
sockaddr_storage_clear(dst);
const sockaddr_in6& ins6(reinterpret_cast<const sockaddr_in6&>(src));
sockaddr_in6& ind6(reinterpret_cast<sockaddr_in6&>(dst));
ind6.sin6_family = AF_INET6;
for(int i=0; i<8; ++i)
ind6.sin6_addr.s6_addr16[i] = ins6.sin6_addr.s6_addr16[i];
ind6.sin6_flowinfo = ins6.sin6_flowinfo;
ind6.sin6_port = ins6.sin6_port;
ind6.sin6_scope_id = ins6.sin6_scope_id;
return true;
}
default:
#ifdef SS_DEBUG
std::cerr << __PRETTY_FUNCTION__ << " Attempt to copy unknown family! "
<< src.ss_family << " defaulting to memmove!" << std::endl;
sockaddr_storage_dump(src);
print_stacktrace();
#endif // SS_DEBUG
memmove(&dst, &src, sizeof(sockaddr_storage));
return true;
}
}
bool sockaddr_storage_ipv4_zeroip(struct sockaddr_storage &addr)
{
#ifdef SS_DEBUG
@ -890,7 +1084,7 @@ std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr
std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & addr)
{
std::string addrStr;
rs_inet_ntop(addr, addrStr);
sockaddr_storage_inet_ntop(addr, addrStr);
return addrStr;
}
@ -979,62 +1173,58 @@ bool sockaddr_storage_ipv4_isExternalNet(const struct sockaddr_storage &addr)
}
bool sockaddr_storage_ipv6_isnull(const struct sockaddr_storage &/*addr*/)
bool sockaddr_storage_ipv6_isnull(const struct sockaddr_storage& addr)
{
#ifdef SS_DEBUG
std::cerr << "sockaddr_storage_ipv6_isnull() TODO";
std::cerr << std::endl;
#endif
const sockaddr_in6& addr6 = reinterpret_cast<const sockaddr_in6&>(addr);
return false;
uint16_t nZero = htons(0); // anyway 0 should be the same in host and net
bool isZero = (addr6.sin6_addr.s6_addr16[7] == nZero);
for (int i=0; isZero && i<7; ++i)
isZero &= (addr6.sin6_addr.s6_addr16[i] == nZero);
return nZero;
}
bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage &/*addr*/)
bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage& addr)
{
#ifdef SS_DEBUG
std::cerr << "sockaddr_storage_ipv6_isValidNet() TODO";
std::cerr << std::endl;
#endif
return false;
return !sockaddr_storage_ipv6_isnull(addr);
}
bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage &/*addr*/)
bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage& addr)
{
const sockaddr_in6& addr6 = reinterpret_cast<const sockaddr_in6&>(addr);
bool isLoopBack = (addr6.sin6_addr.s6_addr16[7] == htons(0x0001));
uint16_t nZero = htons(0); // anyway 0 should be the same in host and net
for (int i=0; isLoopBack && i<7; ++i)
isLoopBack &= (addr6.sin6_addr.s6_addr16[i] == nZero);
#ifdef SS_DEBUG
std::cerr << "sockaddr_storage_ipv6_isLoopbackNet() TODO";
std::cerr << std::endl;
std::cerr << __PRETTY_FUNCTION__ << " " << sockaddr_storage_tostring(addr)
<< " " << isLoopBack << std::endl;
#endif
return false;
return isLoopBack;
}
bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &/*addr*/)
{
#ifdef SS_DEBUG
std::cerr << "sockaddr_storage_ipv6_isPrivateNet() TODO";
std::cerr << std::endl;
#endif
/* It is unlikely that we end up connecting to an IPv6 address behind NAT
* W.R.T. RS it is probably better to consider all IPv6 as internal/local
* addresses as direct connection should be always possible. */
return false;
return true;
}
bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &/*addr*/)
{
#ifdef SS_DEBUG
std::cerr << "sockaddr_storage_ipv6_isExternalNet() TODO";
std::cerr << std::endl;
#endif
/* It is unlikely that we end up connecting to an IPv6 address behind NAT
* W.R.T. RS it is probably better to consider all IPv6 as internal/local
* addresses as direct connection should be always possible. */
return false;
}
#ifdef WINDOWS_SYS
#include <cstdlib>
#include <Winsock2.h>
#endif
bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst)
bool sockaddr_storage_inet_ntop (const sockaddr_storage &addr, std::string &dst)
{
bool success = false;
char ipStr[255];
@ -1071,3 +1261,15 @@ bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst)
dst = ipStr;
return success;
}
int rs_setsockopt( int sockfd, int level, int optname,
const uint8_t *optval, uint32_t optlen )
{
#ifdef WINDOWS_SYS
return setsockopt( sockfd, level, optname,
reinterpret_cast<const char*>(optval), optlen );
#else
return setsockopt( sockfd, level, optname,
reinterpret_cast<const void*>(optval), optlen );
#endif // WINDOWS_SYS
}

View File

@ -169,11 +169,14 @@ void RsTickingThread::fullstop()
void RsThread::start(const std::string &threadName)
{
if(isRunning())
{
std::cerr << "(EE) RsThread \"" << threadName << "\" is already running. Will not start twice!" << std::endl;
return ;
}
if(isRunning())
{
std::cerr << "(EE) RsThread \"" << threadName
<< "\" is already running. Will not start twice!"
<< std::endl;
print_stacktrace();
return;
}
pthread_t tid;
void *data = (void *)this ;