Merge branch 'master' into logshutup1

This commit is contained in:
Pooh 2018-04-01 17:40:44 +03:00 committed by GitHub
commit c0834cf232
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 838 additions and 690 deletions

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
@ -1349,8 +1350,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"
@ -327,8 +332,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;
}
@ -813,15 +818,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;
@ -830,27 +832,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);
@ -861,7 +860,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;
@ -1229,45 +1228,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
@ -1287,8 +1342,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";
@ -1298,8 +1353,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,15 +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
#define PQISSL_LOG_DEBUG2 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
//#define PQISSL_LOG_DEBUG2 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)
@ -97,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()
{
@ -152,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();
}
@ -204,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;
@ -390,7 +358,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);
@ -586,7 +554,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
@ -599,7 +567,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
@ -611,35 +579,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
{
@ -665,7 +628,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;
@ -741,66 +704,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;
@ -1116,7 +1060,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,
@ -1258,27 +1202,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,
@ -1363,36 +1301,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.
@ -1403,70 +1359,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);
}
@ -1479,54 +1416,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();
@ -1535,15 +1457,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;
}
@ -1637,31 +1560,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] = "
@ -1676,7 +1603,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;