mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-29 01:16:20 -05:00
Implement IPv6 listening
With this commit IPv6-v3 surpass v0.6-IPv6-2 in term of features obsoleting it. p3BitDht handle gracefully unwanted non IPv4 addresses rsUdpStack handle gracefully unwanted non IPv4 addresses pqissludp handle gracefully unwanted non IPv4 addresses Move single address limitation workaround from p3discovery2::sendOwnContactInfo to better place p3PeerMgrIMPL::UpdateOwnAddress this way local address list is queried less often and only id there is some suggestion that it may have changed (probably ir will not be called all the times there is a changes in local network interfaces but is good enough) Implement crossplatform rs_setsockopt to avoid too much ifdef around Implement sockaddr_storage_copy to safely copy sockaddr_storage objects
This commit is contained in:
parent
b3c7d195c8
commit
4a138e07b9
@ -4,6 +4,7 @@
|
|||||||
* BitDht interface for RetroShare.
|
* BitDht interface for RetroShare.
|
||||||
*
|
*
|
||||||
* Copyright 2009-2010 by Robert Fernie.
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -184,18 +185,24 @@ bool p3BitDht::dropPeer(const RsPeerId& pid)
|
|||||||
********************************* Basic Peer Details *************************************
|
********************************* 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);
|
//mUdpBitDht->updateKnownPeer(&id, 0, bdflags);
|
||||||
|
|
||||||
struct sockaddr_in addrv4;
|
sockaddr_in addrv4;
|
||||||
if (addr.ss_family != AF_INET)
|
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 << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!"
|
||||||
std::cerr << std::endl;
|
<< std::endl;
|
||||||
abort();
|
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.
|
// convert.
|
||||||
addrv4.sin_family = ap->sin_family;
|
addrv4.sin_family = ap->sin_family;
|
||||||
@ -216,38 +223,29 @@ 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_in addrv4;
|
||||||
sockaddr_clear(&addrv4);
|
sockaddr_clear(&addrv4);
|
||||||
|
|
||||||
if (addr.ss_family != AF_INET)
|
sockaddr_storage tmpaddr;
|
||||||
|
sockaddr_storage_copy(addr, tmpaddr);
|
||||||
|
if( !sockaddr_storage_isnull(addr) &&
|
||||||
|
!sockaddr_storage_ipv6_to_ipv4(tmpaddr) )
|
||||||
{
|
{
|
||||||
if(addr.ss_family != AF_UNSPEC)
|
std::cerr << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!"
|
||||||
{
|
<< std::endl;
|
||||||
std::cerr << "p3BitDht::addKnownPeer() Warning! Non IPv4 Address - Cannot handle IPV6 Yet. addr.ss_family=" << addr.ss_family;
|
sockaddr_storage_dump(addr);
|
||||||
std::cerr << std::endl;
|
print_stacktrace();
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & NETASSIST_KNOWN_PEER_ONLINE)
|
|
||||||
{
|
|
||||||
std::cerr << "p3BitDht::addKnownPeer() Non IPv4 Address & ONLINE. Abort()ing.";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
// convert.
|
// convert.
|
||||||
struct sockaddr_in *ap = (struct sockaddr_in *) &addr;
|
struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr;
|
||||||
|
|
||||||
addrv4.sin_family = ap->sin_family;
|
addrv4.sin_family = ap->sin_family;
|
||||||
addrv4.sin_addr = ap->sin_addr;
|
addrv4.sin_addr = ap->sin_addr;
|
||||||
addrv4.sin_port = ap->sin_port;
|
addrv4.sin_port = ap->sin_port;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int p3type = 0;
|
int p3type = 0;
|
||||||
int bdflags = 0;
|
int bdflags = 0;
|
||||||
@ -295,7 +293,7 @@ int p3BitDht::addKnownPeer(const RsPeerId &pid, const struct sockaddr_storage &a
|
|||||||
|
|
||||||
if (!isOwnId)
|
if (!isOwnId)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
|
RS_STACK_MUTEX(dhtMtx);
|
||||||
DhtPeerDetails *dpd = addInternalPeer_locked(pid, p3type);
|
DhtPeerDetails *dpd = addInternalPeer_locked(pid, p3type);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1038,12 +1038,15 @@ bool p3NetMgrIMPL::checkNetAddress()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If no satisfactory local address has been found yet relax and
|
/* If no satisfactory local address has been found yet relax and
|
||||||
* accept also link local addresses */
|
* accept also IPv4 link local addresses, IPv6 link local is not
|
||||||
|
* accepted because of sin6_scope_id that depends on the host using
|
||||||
|
* it as an outgoing connection endpoint */
|
||||||
if(!validAddr) for (auto it = addrs.begin(); it!=addrs.end(); ++it)
|
if(!validAddr) for (auto it = addrs.begin(); it!=addrs.end(); ++it)
|
||||||
{
|
{
|
||||||
sockaddr_storage& addr(*it);
|
sockaddr_storage& addr(*it);
|
||||||
if( sockaddr_storage_isValidNet(addr) &&
|
if( sockaddr_storage_isValidNet(addr) &&
|
||||||
!sockaddr_storage_isLoopbackNet(addr) )
|
!sockaddr_storage_isLoopbackNet(addr) &&
|
||||||
|
!sockaddr_storage_ipv6_isLinkLocalNet(addr) )
|
||||||
{
|
{
|
||||||
prefAddr = addr;
|
prefAddr = addr;
|
||||||
validAddr = true;
|
validAddr = true;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* 3P/PQI network interface for RetroShare.
|
* 3P/PQI network interface for RetroShare.
|
||||||
*
|
*
|
||||||
* Copyright 2007-2011 by Robert Fernie.
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* 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 "rsserver/p3face.h"
|
||||||
#include "util/rsnet.h"
|
#include "util/rsnet.h"
|
||||||
#include "pqi/authgpg.h"
|
#include "pqi/authgpg.h"
|
||||||
@ -32,6 +36,7 @@
|
|||||||
#include "pqi/p3linkmgr.h"
|
#include "pqi/p3linkmgr.h"
|
||||||
#include "pqi/p3netmgr.h"
|
#include "pqi/p3netmgr.h"
|
||||||
#include "pqi/p3historymgr.h"
|
#include "pqi/p3historymgr.h"
|
||||||
|
#include "pqi/pqinetwork.h" // for getLocalAddresses
|
||||||
|
|
||||||
//#include "pqi/p3dhtmgr.h" // Only need it for constants.
|
//#include "pqi/p3dhtmgr.h" // Only need it for constants.
|
||||||
//#include "tcponudp/tou.h"
|
//#include "tcponudp/tou.h"
|
||||||
@ -1227,24 +1232,28 @@ void p3PeerMgrIMPL::printPeerLists(std::ostream &out)
|
|||||||
* as it doesn't call back to there.
|
* 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& localAddr,
|
||||||
|
const sockaddr_storage& extAddr )
|
||||||
{
|
{
|
||||||
#ifdef PEER_DEBUG
|
#ifdef PEER_DEBUG
|
||||||
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress(";
|
std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress("
|
||||||
std::cerr << sockaddr_storage_tostring(localAddr);
|
<< sockaddr_storage_tostring(localAddr) << ", "
|
||||||
std::cerr << ", ";
|
<< sockaddr_storage_tostring(extAddr) << ")" << std::endl;
|
||||||
std::cerr << sockaddr_storage_tostring(extAddr);
|
|
||||||
std::cerr << ")" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if((rsBanList != NULL) && !rsBanList->isAddressAccepted(localAddr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
|
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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
RS_STACK_MUTEX(mPeerMtx);
|
||||||
|
|
||||||
//update ip address list
|
//update ip address list
|
||||||
pqiIpAddress ipAddressTimed;
|
pqiIpAddress ipAddressTimed;
|
||||||
@ -1253,12 +1262,55 @@ bool p3PeerMgrIMPL::UpdateOwnAddress(const struct sockaddr_storage &localAddr,
|
|||||||
ipAddressTimed.mSrc = 0;
|
ipAddressTimed.mSrc = 0;
|
||||||
mOwnState.ipAddrs.updateLocalAddrs(ipAddressTimed);
|
mOwnState.ipAddrs.updateLocalAddrs(ipAddressTimed);
|
||||||
|
|
||||||
|
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) )
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mOwnState.localaddr = localAddr;
|
mOwnState.localaddr = localAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
RS_STACK_MUTEX(mPeerMtx);
|
||||||
|
|
||||||
//update ip address list
|
//update ip address list
|
||||||
pqiIpAddress ipAddressTimed;
|
pqiIpAddress ipAddressTimed;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "util/rsdebug.h"
|
#include "util/rsdebug.h"
|
||||||
#include "util/rsstring.h"
|
#include "util/rsstring.h"
|
||||||
#include "util/rsnet.h"
|
#include "util/rsnet.h"
|
||||||
|
#include "util/stacktrace.h"
|
||||||
|
|
||||||
static struct RsLog::logInfo pqinetzoneInfo = {RsLog::Default, "pqinet"};
|
static struct RsLog::logInfo pqinetzoneInfo = {RsLog::Default, "pqinet"};
|
||||||
#define pqinetzone &pqinetzoneInfo
|
#define pqinetzone &pqinetzoneInfo
|
||||||
@ -335,7 +336,9 @@ bool getLocalAddresses(std::vector<sockaddr_storage>& addrs)
|
|||||||
struct ifaddrs *ifsaddrs, *ifa;
|
struct ifaddrs *ifsaddrs, *ifa;
|
||||||
if(getifaddrs(&ifsaddrs) != 0)
|
if(getifaddrs(&ifsaddrs) != 0)
|
||||||
{
|
{
|
||||||
std::cerr << "FATAL ERROR: getLocalAddresses failed!" << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ << " FATAL ERROR: " << errno << " "
|
||||||
|
<< strerror(errno) << std::endl;
|
||||||
|
print_stacktrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next )
|
for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next )
|
||||||
|
@ -60,14 +60,15 @@ static struct RsLog::logInfo pqisslzoneInfo = {RsLog::Default, "pqisslzone"};
|
|||||||
#define PQISSL_PASSIVE 0x00
|
#define PQISSL_PASSIVE 0x00
|
||||||
#define PQISSL_ACTIVE 0x01
|
#define PQISSL_ACTIVE 0x01
|
||||||
|
|
||||||
#define PQISSL_DEBUG 1
|
|
||||||
#define PQISSL_LOG_DEBUG 1
|
|
||||||
|
|
||||||
const int PQISSL_LOCAL_FLAG = 0x01;
|
const int PQISSL_LOCAL_FLAG = 0x01;
|
||||||
const int PQISSL_REMOTE_FLAG = 0x02;
|
const int PQISSL_REMOTE_FLAG = 0x02;
|
||||||
const int PQISSL_UDP_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 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)
|
static const time_t PQISSL_MAX_READ_ZERO_TIME = 15; // 15 seconds of no data => reset. (atm HeartBeat pkt sent 5 secs)
|
||||||
|
|
||||||
@ -123,6 +124,7 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) :
|
|||||||
int pqissl::connect(const struct sockaddr_storage &raddr)
|
int pqissl::connect(const struct sockaddr_storage &raddr)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mSslMtx);
|
RS_STACK_MUTEX(mSslMtx);
|
||||||
|
|
||||||
remote_addr = raddr;
|
remote_addr = raddr;
|
||||||
return ConnectAttempt();
|
return ConnectAttempt();
|
||||||
}
|
}
|
||||||
@ -171,8 +173,7 @@ int pqissl::close()
|
|||||||
// put back on the listening queue.
|
// put back on the listening queue.
|
||||||
int pqissl::reset()
|
int pqissl::reset()
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
|
RS_STACK_MUTEX(mSslMtx);
|
||||||
|
|
||||||
return reset_locked();
|
return reset_locked();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +356,7 @@ int pqissl::status()
|
|||||||
|
|
||||||
out += " active: \n";
|
out += " active: \n";
|
||||||
// print out connection.
|
// print out connection.
|
||||||
out += "Connected TO : " + PeerId() + "\n";
|
out += "Connected TO : " + PeerId().toStdString() + "\n";
|
||||||
// print out cipher.
|
// print out cipher.
|
||||||
rs_sprintf_append(out, "\t\tSSL Cipher:%s", SSL_get_cipher(ssl_connection));
|
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);
|
rs_sprintf_append(out, " (%d:%d)", SSL_get_cipher_bits(ssl_connection, &alg), alg);
|
||||||
@ -551,7 +552,7 @@ int pqissl::Delay_Connection()
|
|||||||
#ifdef PQISSL_LOG_DEBUG
|
#ifdef PQISSL_LOG_DEBUG
|
||||||
{
|
{
|
||||||
std::string out;
|
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);
|
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -564,7 +565,7 @@ int pqissl::Delay_Connection()
|
|||||||
#ifdef PQISSL_LOG_DEBUG
|
#ifdef PQISSL_LOG_DEBUG
|
||||||
{
|
{
|
||||||
std::string out;
|
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);
|
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -710,10 +711,12 @@ int pqissl::Initiate_Connection()
|
|||||||
* will support IPv6 only and not IPv4 */
|
* will support IPv6 only and not IPv4 */
|
||||||
#ifdef IPV6_V6ONLY
|
#ifdef IPV6_V6ONLY
|
||||||
int no = 0;
|
int no = 0;
|
||||||
err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&no, sizeof(no));
|
err = rs_setsockopt( osock, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||||
|
reinterpret_cast<uint8_t*>(&no), sizeof(no) );
|
||||||
#ifdef PQISSL_DEBUG
|
#ifdef PQISSL_DEBUG
|
||||||
if (err) std::cerr << __PRETTY_FUNCTION__
|
if (err) std::cerr << __PRETTY_FUNCTION__
|
||||||
<< " Error setting IPv6 socket dual stack" << std::endl;
|
<< " Error setting IPv6 socket dual stack: "
|
||||||
|
<< errno << " " << strerror(errno) << std::endl;
|
||||||
else std::cerr << __PRETTY_FUNCTION__
|
else std::cerr << __PRETTY_FUNCTION__
|
||||||
<< " Setting IPv6 socket dual stack" << std::endl;
|
<< " Setting IPv6 socket dual stack" << std::endl;
|
||||||
#endif // PQISSL_DEBUG
|
#endif // PQISSL_DEBUG
|
||||||
@ -1233,25 +1236,19 @@ int pqissl::Extract_Failed_SSL_Certificate()
|
|||||||
|
|
||||||
int pqissl::Authorise_SSL_Connection()
|
int pqissl::Authorise_SSL_Connection()
|
||||||
{
|
{
|
||||||
#ifdef PQISSL_LOG_DEBUG
|
#ifdef PQISSL_DEBUG
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone,
|
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||||
"pqissl::Authorise_SSL_Connection()");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (time(NULL) > ssl_connect_timeout)
|
if (time(NULL) > ssl_connect_timeout)
|
||||||
{
|
{
|
||||||
rslog(RSL_WARNING, pqisslzone,
|
std::cerr << __PRETTY_FUNCTION__ << " Connection timed out reset!"
|
||||||
"pqissl::Authorise_SSL_Connection() Connection Timed Out!");
|
<< std::endl;
|
||||||
/* as sockfd is valid, this should close it all up */
|
|
||||||
rslog(RSL_ALERT, pqisslzone, "pqissl::Authorise_Connection_Complete() -> calling reset()");
|
|
||||||
reset_locked();
|
reset_locked();
|
||||||
}
|
}
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if (0 >= (err = SSL_Connection_Complete()))
|
if (0 >= (err = SSL_Connection_Complete())) return err;
|
||||||
{
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PQISSL_LOG_DEBUG
|
#ifdef PQISSL_LOG_DEBUG
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone,
|
rslog(RSL_DEBUG_BASIC, pqisslzone,
|
||||||
@ -1336,36 +1333,54 @@ int pqissl::Authorise_SSL_Connection()
|
|||||||
|
|
||||||
|
|
||||||
/* This function is public, and callable from pqilistener - so must be mutex protected */
|
/* 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
|
#ifdef PQISSL_DEBUG
|
||||||
std::cerr << "pqissl::accept()";
|
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/
|
RS_STACK_MUTEX(mSslMtx);
|
||||||
|
|
||||||
return accept_locked(ssl, fd, foreign_addr);
|
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 )
|
||||||
{
|
{
|
||||||
|
#ifdef PQISSL_DEBUG
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t check_result;
|
uint32_t check_result;
|
||||||
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
|
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST;
|
||||||
|
|
||||||
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
|
if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL)
|
||||||
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
|
checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST;
|
||||||
|
|
||||||
if(rsBanList!=NULL && !rsBanList->isAddressAccepted(foreign_addr,checking_flags,&check_result))
|
if( rsBanList && !rsBanList->isAddressAccepted( foreign_addr,
|
||||||
|
checking_flags,
|
||||||
|
&check_result ) )
|
||||||
{
|
{
|
||||||
std::cerr << "(SS) refusing incoming SSL connection from blacklisted foreign address " << sockaddr_storage_iptostring(foreign_addr)
|
std::cerr << __PRETTY_FUNCTION__
|
||||||
|
<< " (SS) refusing incoming SSL connection from blacklisted "
|
||||||
|
<< "foreign address "
|
||||||
|
<< sockaddr_storage_iptostring(foreign_addr)
|
||||||
<< ". Reason: " << check_result << "." << std::endl;
|
<< ". Reason: " << check_result << "." << std::endl;
|
||||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_BLACKLISTED, PeerId().toStdString(), sockaddr_storage_iptostring(foreign_addr), "", "", check_result);
|
|
||||||
|
RsServer::notify()->AddFeedItem(
|
||||||
|
RS_FEED_ITEM_SEC_IP_BLACKLISTED,
|
||||||
|
PeerId().toStdString(),
|
||||||
|
sockaddr_storage_iptostring(foreign_addr), "", "",
|
||||||
|
check_result);
|
||||||
reset_locked();
|
reset_locked();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waiting != WAITING_NOT)
|
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.
|
// outgoing connection in progress.
|
||||||
// shut this baby down.
|
// shut this baby down.
|
||||||
@ -1376,70 +1391,51 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei
|
|||||||
|
|
||||||
switch(waiting)
|
switch(waiting)
|
||||||
{
|
{
|
||||||
|
|
||||||
case WAITING_SOCK_CONNECT:
|
case WAITING_SOCK_CONNECT:
|
||||||
|
#ifdef PQISSL_DEBUG
|
||||||
#ifdef PQISSL_LOG_DEBUG
|
std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting Sock Connect "
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone,
|
<< "- close the socket" << std::endl;
|
||||||
"pqissl::accept() STATE = Waiting Sock Connect - close the socket");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAITING_SSL_CONNECTION:
|
case WAITING_SSL_CONNECTION:
|
||||||
|
#ifdef PQISSL_DEBUG
|
||||||
#ifdef PQISSL_LOG_DEBUG
|
std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting SSL "
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone,
|
<< "Connection - close sockfd + ssl_conn" << std::endl;
|
||||||
"pqissl::accept() STATE = Waiting SSL Connection - close sockfd + ssl_conn");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAITING_SSL_AUTHORISE:
|
case WAITING_SSL_AUTHORISE:
|
||||||
|
#ifdef PQISSL_DEBUG
|
||||||
#ifdef PQISSL_LOG_DEBUG
|
std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting SSL Authorise"
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone,
|
<< " - close sockfd + ssl_conn" << std::endl;
|
||||||
"pqissl::accept() STATE = Waiting SSL Authorise - close sockfd + ssl_conn");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAITING_FAIL_INTERFACE:
|
case WAITING_FAIL_INTERFACE:
|
||||||
|
#ifdef PQISSL_DEBUG
|
||||||
#ifdef PQISSL_LOG_DEBUG
|
std::cerr << __PRETTY_FUNCTION__ << " STATE = Failed, ignore?"
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone,
|
<< std::endl;
|
||||||
"pqissl::accept() STATE = Failed, ignore?");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rslog(RSL_ALERT, pqisslzone,
|
std::cerr << __PRETTY_FUNCTION__ << " STATE = Unknown - resetting!"
|
||||||
"pqissl::accept() STATE = Unknown - ignore?");
|
<< std::endl;
|
||||||
|
|
||||||
rslog(RSL_ALERT, pqisslzone, "pqissl::accept() -> calling reset()");
|
|
||||||
reset_locked();
|
reset_locked();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//waiting = WAITING_FAIL_INTERFACE;
|
|
||||||
//return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shutdown existing - in all cases use the new one */
|
/* shutdown existing - in all cases use the new one */
|
||||||
if ((ssl_connection) && (ssl_connection != ssl))
|
if ((ssl_connection) && (ssl_connection != ssl))
|
||||||
{
|
{
|
||||||
rslog(RSL_ALERT, pqisslzone,
|
std::cerr << __PRETTY_FUNCTION__
|
||||||
"pqissl::accept() closing Previous/Existing ssl_connection");
|
<< " closing Previous/Existing ssl_connection" << std::endl;
|
||||||
SSL_shutdown(ssl_connection);
|
SSL_shutdown(ssl_connection);
|
||||||
SSL_free (ssl_connection);
|
SSL_free (ssl_connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sockfd > -1) && (sockfd != fd))
|
if ((sockfd > -1) && (sockfd != fd))
|
||||||
{
|
{
|
||||||
rslog(RSL_ALERT, pqisslzone,
|
std::cerr << __PRETTY_FUNCTION__ << " closing Previous/Existing sockfd"
|
||||||
"pqissl::accept() closing Previous/Existing sockfd");
|
<< std::endl;
|
||||||
net_internal_close(sockfd);
|
net_internal_close(sockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1452,54 +1448,39 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei
|
|||||||
/* if we connected - then just writing the same over,
|
/* if we connected - then just writing the same over,
|
||||||
* but if from ssllistener then we need to save the address.
|
* 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 */
|
std::cerr << __PRETTY_FUNCTION__ << " SUCCESSFUL connection to: "
|
||||||
|
<< PeerId().toStdString() << " remoteaddr: "
|
||||||
|
<< sockaddr_storage_iptostring(remote_addr) << std::endl;
|
||||||
|
|
||||||
struct sockaddr_storage localaddr;
|
#ifdef PQISSL_DEBUG
|
||||||
mLinkMgr->getLocalAddress(localaddr);
|
|
||||||
|
|
||||||
{
|
|
||||||
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;
|
int alg;
|
||||||
std::string out;
|
std::cerr << __PRETTY_FUNCTION__ << "SSL Cipher: "
|
||||||
rs_sprintf(out, "SSL Cipher:%s\n", SSL_get_cipher(ssl));
|
<< SSL_get_cipher(ssl) << std::endl << "SSL Cipher Bits: "
|
||||||
rs_sprintf_append(out, "SSL Cipher Bits:%d - %d\n", SSL_get_cipher_bits(ssl, &alg), alg);
|
<< SSL_get_cipher_bits(ssl, &alg) << " - " << alg
|
||||||
rs_sprintf_append(out, "SSL Cipher Version:%s\n", SSL_get_cipher_version(ssl));
|
<< std::endl;
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// make non-blocking / or check.....
|
// make non-blocking / or check.....
|
||||||
|
int err;
|
||||||
if ((err = net_internal_fcntl_nonblock(sockfd)) < 0)
|
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;
|
active = false;
|
||||||
waiting = WAITING_FAIL_INTERFACE;
|
waiting = WAITING_FAIL_INTERFACE; // failed completely.
|
||||||
// failed completely.
|
|
||||||
rslog(RSL_ALERT, pqisslzone, "pqissl::accept() -> calling reset()");
|
|
||||||
reset_locked();
|
reset_locked();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
#ifdef PQISSL_DEBUG
|
||||||
{
|
else std::cerr << __PRETTY_FUNCTION__ << " Socket made non-nlocking!"
|
||||||
#ifdef PQISSL_LOG_DEBUG
|
<< std::endl;
|
||||||
rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissl::accept() Socket Made Non-Blocking!");
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// we want to continue listening - incase this socket is crap, and they try again.
|
// we want to continue listening - incase this socket is crap, and they try again.
|
||||||
//stoplistening();
|
//stoplistening();
|
||||||
@ -1508,14 +1489,15 @@ int pqissl::accept_locked(SSL *ssl, int fd, const struct sockaddr_storage &forei
|
|||||||
waiting = WAITING_NOT;
|
waiting = WAITING_NOT;
|
||||||
|
|
||||||
#ifdef PQISSL_DEBUG
|
#ifdef PQISSL_DEBUG
|
||||||
std::cerr << "pqissl::accept_locked() connection complete - notifying parent";
|
std::cerr << __PRETTY_FUNCTION__ << "connection complete - notifying parent"
|
||||||
std::cerr << std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Notify the pqiperson.... (Both Connect/Receive)
|
// Notify the pqiperson.... (Both Connect/Receive)
|
||||||
if (parent())
|
if (parent())
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr = remote_addr;
|
// Is the copy necessary?
|
||||||
|
sockaddr_storage addr; sockaddr_storage_copy(remote_addr, addr);
|
||||||
parent()->notifyEvent(this, NET_CONNECT_SUCCESS, addr);
|
parent()->notifyEvent(this, NET_CONNECT_SUCCESS, addr);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -1612,15 +1594,15 @@ int pqissl::senddata(void *data, int len)
|
|||||||
|
|
||||||
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
|
#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
|
#endif
|
||||||
|
|
||||||
// Safety check. Apparently this avoids some SIGSEGV.
|
// 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
|
// 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
|
// when they are larger than 16384 bytes. Such packets have to be read in
|
||||||
@ -1630,11 +1612,15 @@ int pqissl::readdata(void *data, int len)
|
|||||||
int tmppktlen;
|
int tmppktlen;
|
||||||
|
|
||||||
#ifdef PQISSL_DEBUG
|
#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
|
#endif
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
tmppktlen = SSL_read(ssl_connection, (void*)( &(((uint8_t*)data)[total_len])), len-total_len) ;
|
tmppktlen = SSL_read(ssl_connection,
|
||||||
|
(void*)( &(((uint8_t*)data)[total_len])),
|
||||||
|
len-total_len);
|
||||||
|
|
||||||
#ifdef PQISSL_DEBUG
|
#ifdef PQISSL_DEBUG
|
||||||
std::cerr << "have read " << tmppktlen << " bytes" << std::endl ;
|
std::cerr << "have read " << tmppktlen << " bytes" << std::endl ;
|
||||||
std::cerr << "data[0] = "
|
std::cerr << "data[0] = "
|
||||||
@ -1649,7 +1635,6 @@ int pqissl::readdata(void *data, int len)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Need to catch errors.....
|
// Need to catch errors.....
|
||||||
//
|
|
||||||
if (tmppktlen <= 0) // probably needs a reset.
|
if (tmppktlen <= 0) // probably needs a reset.
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
|
@ -119,12 +119,9 @@ virtual bool bandwidthLimited() { return true ; }
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* Completion of the SSL connection,
|
/// initiate incoming connection.
|
||||||
* this is public, so it can be called by
|
|
||||||
* the listener (should make friends??)
|
|
||||||
*/
|
|
||||||
|
|
||||||
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) ;
|
void getCryptoParams(RsPeerCryptoParams& params) ;
|
||||||
bool actAsServer();
|
bool actAsServer();
|
||||||
|
|
||||||
@ -140,7 +137,10 @@ protected:
|
|||||||
RsMutex mSslMtx; /**** MUTEX protects data and fn below ****/
|
RsMutex mSslMtx; /**** MUTEX protects data and fn below ****/
|
||||||
|
|
||||||
virtual int reset_locked();
|
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
|
// A little bit of information to describe
|
||||||
// the SSL state, this is needed
|
// the SSL state, this is needed
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* 3P/PQI network interface for RetroShare.
|
* 3P/PQI network interface for RetroShare.
|
||||||
*
|
*
|
||||||
* Copyright 2004-2006 by Robert Fernie.
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -106,10 +107,20 @@ int pqissllistenbase::status()
|
|||||||
int pqissllistenbase::setuplisten()
|
int pqissllistenbase::setuplisten()
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (active)
|
if (active) return -1;
|
||||||
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 ******************/
|
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
#ifndef WINDOWS_SYS // ie UNIX
|
#ifndef WINDOWS_SYS // ie UNIX
|
||||||
if (lsock < 0)
|
if (lsock < 0)
|
||||||
@ -199,10 +210,14 @@ int pqissllistenbase::setuplisten()
|
|||||||
|
|
||||||
#ifdef OPEN_UNIVERSAL_PORT
|
#ifdef OPEN_UNIVERSAL_PORT
|
||||||
struct sockaddr_storage tmpaddr = laddr;
|
struct sockaddr_storage tmpaddr = laddr;
|
||||||
if (!mPeerMgr->isHidden()) sockaddr_storage_zeroip(tmpaddr);
|
if (!mPeerMgr->isHidden())
|
||||||
if (0 != (err = universal_bind(lsock, (struct sockaddr *) &tmpaddr, sizeof(tmpaddr))))
|
{
|
||||||
|
tmpaddr.ss_family = PF_INET6;
|
||||||
|
sockaddr_storage_zeroip(tmpaddr);
|
||||||
|
}
|
||||||
|
if (0 != (err = rs_bind(lsock, tmpaddr)))
|
||||||
#else
|
#else
|
||||||
if (0 != (err = universal_bind(lsock, (struct sockaddr *) &laddr, sizeof(laddr))))
|
if (0 != (err = universal_bind(lsock, laddr)))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
std::string out = "pqissllistenbase::setuplisten() Cannot Bind to Local Address!\n";
|
std::string out = "pqissllistenbase::setuplisten() Cannot Bind to Local Address!\n";
|
||||||
|
@ -250,20 +250,36 @@ 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 srcaddr;
|
||||||
struct sockaddr_in proxyaddr;
|
struct sockaddr_in proxyaddr;
|
||||||
struct sockaddr_in remoteaddr;
|
struct sockaddr_in remoteaddr;
|
||||||
|
|
||||||
if ((mConnectSrcAddr.ss_family != AF_INET) ||
|
bool nonIpV4 = false;
|
||||||
(mConnectProxyAddr.ss_family != AF_INET) ||
|
if(!sockaddr_storage_ipv6_to_ipv4(remote_addr))
|
||||||
(remote_addr.ss_family != AF_INET))
|
|
||||||
{
|
{
|
||||||
std::cerr << "Error One Address is not IPv4. aborting";
|
nonIpV4 = true;
|
||||||
std::cerr << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ << "Error: remote_addr is not "
|
||||||
abort();
|
<< "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 *rap = (struct sockaddr_in *) &remote_addr;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* RetroShare C++ Interface.
|
* RetroShare C++ Interface.
|
||||||
*
|
*
|
||||||
* Copyright 2004-2008 by Robert Fernie.
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -900,68 +901,33 @@ bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uin
|
|||||||
return true;
|
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
|
#ifdef P3PEERS_DEBUG
|
||||||
std::cerr << "p3Peers::setLocalAddress() " << id << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " "
|
||||||
|
<< port << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(port < 1024)
|
sockaddr_storage addr;
|
||||||
{
|
if (sockaddr_storage_inet_pton(addr, addr_str))
|
||||||
std::cerr << "(EE) attempt to use a port that is reserved to the system: " << port << std::endl;
|
if (sockaddr_storage_setport(addr, port))
|
||||||
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);
|
return mPeerMgr->setLocalAddress(id, addr);
|
||||||
}
|
|
||||||
return false;
|
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
|
#ifdef P3PEERS_DEBUG
|
||||||
std::cerr << "p3Peers::setExtAddress() " << id << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " "
|
||||||
|
<< port << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if(port < 1024)
|
|
||||||
{
|
|
||||||
std::cerr << "(EE) attempt to use a port that is reserved to the system: " << port << std::endl;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
sockaddr_storage addr;
|
||||||
// NOTE THIS IS IPV4 FOR NOW.
|
if (sockaddr_storage_inet_pton(addr, addr_str))
|
||||||
struct sockaddr_storage addr;
|
if (sockaddr_storage_setport(addr, port))
|
||||||
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);
|
return mPeerMgr->setExtAddress(id, addr);
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,9 @@ RsDisc *rsDisc = NULL;
|
|||||||
* #define P3DISC_DEBUG 1
|
* #define P3DISC_DEBUG 1
|
||||||
****/
|
****/
|
||||||
|
|
||||||
static bool populateContactInfo(const peerState &detail, RsDiscContactItem *pkt,bool include_ip_information)
|
static bool populateContactInfo( const peerState &detail,
|
||||||
|
RsDiscContactItem *pkt,
|
||||||
|
bool include_ip_information )
|
||||||
{
|
{
|
||||||
pkt->clear();
|
pkt->clear();
|
||||||
|
|
||||||
@ -461,6 +463,7 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId()))
|
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId()))
|
||||||
|
{
|
||||||
/* Cyril: we don't store IP addresses if we're a hidden node.
|
/* Cyril: we don't store IP addresses if we're a hidden node.
|
||||||
* Normally they should not be sent to us, except for old peers. */
|
* Normally they should not be sent to us, except for old peers. */
|
||||||
/* G10h4ck: sending IP information also to hidden nodes has proven very
|
/* G10h4ck: sending IP information also to hidden nodes has proven very
|
||||||
@ -471,13 +474,13 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
|
|||||||
* permission matrix. Disabling this instead will make life more
|
* permission matrix. Disabling this instead will make life more
|
||||||
* difficult for average user, that moreover whould have no way to
|
* difficult for average user, that moreover whould have no way to
|
||||||
* revert an hardcoded policy. */
|
* revert an hardcoded policy. */
|
||||||
{
|
|
||||||
pqiIpAddrSet addrsFromPeer;
|
pqiIpAddrSet addrsFromPeer;
|
||||||
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
|
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
|
||||||
addrsFromPeer.mExt.extractFromTlv(item->extAddrList);
|
addrsFromPeer.mExt.extractFromTlv(item->extAddrList);
|
||||||
|
|
||||||
#ifdef P3DISC_DEBUG
|
#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;
|
std::string addrstr;
|
||||||
addrsFromPeer.printAddrs(addrstr);
|
addrsFromPeer.printAddrs(addrstr);
|
||||||
|
@ -50,34 +50,37 @@ virtual bool resetAddress(struct sockaddr_in &local) { return false; }
|
|||||||
/*******************************************************/
|
/*******************************************************/
|
||||||
|
|
||||||
#include "pqi/pqimonitor.h"
|
#include "pqi/pqimonitor.h"
|
||||||
|
#include "util/rsnet.h"
|
||||||
|
#include "util/stacktrace.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
class rsUdpStack: public UdpStack, public pqiNetListener
|
class rsUdpStack: public UdpStack, public pqiNetListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
rsUdpStack(struct sockaddr_in &local)
|
rsUdpStack(struct sockaddr_in &local) : UdpStack(local) {}
|
||||||
:UdpStack(local) { return; }
|
|
||||||
|
|
||||||
rsUdpStack(int testmode, struct sockaddr_in &local)
|
rsUdpStack(int testmode, struct sockaddr_in &local) :
|
||||||
:UdpStack(testmode, local) { return; }
|
UdpStack(testmode, local) {}
|
||||||
|
|
||||||
/* from pqiNetListener */
|
/// @see pqiNetListener
|
||||||
virtual bool resetListener(const struct sockaddr_storage &local)
|
virtual bool resetListener(const sockaddr_storage& local)
|
||||||
{
|
{
|
||||||
//std::cerr << "rsUdpStack::resetListener(" << sockaddr_storage_tostring(local) << ")";
|
sockaddr_storage temp;
|
||||||
//std::cerr << std::endl;
|
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 << __PRETTY_FUNCTION__ << " Got non IPv4 address ERROR"
|
||||||
std::cerr << std::endl;
|
<< std::endl;
|
||||||
abort();
|
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);
|
return resetAddress(*addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class rsFixedUdpStack: public UdpStack, public pqiNetListener
|
class rsFixedUdpStack: public UdpStack, public pqiNetListener
|
||||||
|
@ -88,14 +88,26 @@ std::string rs_inet_ntoa(struct in_addr in);
|
|||||||
/***************************/
|
/***************************/
|
||||||
// sockaddr_storage fns.
|
// sockaddr_storage fns.
|
||||||
|
|
||||||
// Standard bind, on OSX anyway will not accept a longer socklen for IPv4.
|
int rs_bind(int fd, const sockaddr_storage& addr);
|
||||||
// so hidding details behind function.
|
|
||||||
int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen);
|
|
||||||
|
|
||||||
void sockaddr_storage_clear(struct sockaddr_storage &addr);
|
void sockaddr_storage_clear(struct sockaddr_storage &addr);
|
||||||
|
|
||||||
// mods.
|
// mods.
|
||||||
bool sockaddr_storage_zeroip(struct sockaddr_storage &addr);
|
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);
|
bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src);
|
||||||
uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr);
|
uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr);
|
||||||
bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port);
|
bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port);
|
||||||
@ -103,10 +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_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_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_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_setport(struct sockaddr_storage &addr, const uint16_t port);
|
||||||
|
|
||||||
bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr);
|
bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr);
|
||||||
|
bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr);
|
||||||
|
|
||||||
// comparisons.
|
// comparisons.
|
||||||
bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b);
|
bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b);
|
||||||
@ -132,8 +148,12 @@ bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr);
|
|||||||
bool sockaddr_storage_isLoopbackNet(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_isPrivateNet(const struct sockaddr_storage &addr);
|
||||||
bool sockaddr_storage_isLinkLocalNet(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 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 */
|
#endif /* RS_UNIVERSAL_NETWORK_HEADER */
|
||||||
|
@ -26,6 +26,24 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#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/rsnet.h"
|
||||||
#include "util/rsstring.h"
|
#include "util/rsstring.h"
|
||||||
@ -90,17 +108,14 @@ bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &addr);
|
|||||||
/******************************** Socket Fns ***********************************/
|
/******************************** Socket Fns ***********************************/
|
||||||
// Standard bind, on OSX anyway will not accept a longer socklen for IPv4.
|
// Standard bind, on OSX anyway will not accept a longer socklen for IPv4.
|
||||||
// so hidding details behind function.
|
// 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
|
#ifdef SS_DEBUG
|
||||||
std::cerr << "universal_bind()";
|
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) addr;
|
socklen_t len = 0;
|
||||||
socklen_t len = socklen;
|
switch (addr.ss_family)
|
||||||
|
|
||||||
switch (ss_addr->ss_family)
|
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
len = sizeof(struct sockaddr_in);
|
len = sizeof(struct sockaddr_in);
|
||||||
@ -110,13 +125,7 @@ int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > socklen)
|
return bind(fd, reinterpret_cast<const struct sockaddr *>(&addr), len);
|
||||||
{
|
|
||||||
std::cerr << "universal_bind() ERROR len > socklen" << std::endl;
|
|
||||||
len = socklen;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bind(fd, addr, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -252,6 +261,58 @@ bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6
|
|||||||
return true;
|
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)
|
bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name)
|
||||||
{
|
{
|
||||||
@ -278,21 +339,59 @@ bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr)
|
|||||||
sockaddr_in & addr_ipv4 = (sockaddr_in &) addr;
|
sockaddr_in & addr_ipv4 = (sockaddr_in &) addr;
|
||||||
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
|
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
|
||||||
|
|
||||||
u_int32_t ip = addr_ipv4.sin_addr.s_addr;
|
uint32_t ip = addr_ipv4.sin_addr.s_addr;
|
||||||
u_int16_t port = addr_ipv4.sin_port;
|
uint16_t port = addr_ipv4.sin_port;
|
||||||
|
|
||||||
sockaddr_storage_clear(addr);
|
sockaddr_storage_clear(addr);
|
||||||
addr_ipv6.sin6_family = AF_INET6;
|
addr_ipv6.sin6_family = AF_INET6;
|
||||||
addr_ipv6.sin6_port = port;
|
addr_ipv6.sin6_port = port;
|
||||||
addr_ipv6.sin6_addr.s6_addr32[3] = ip;
|
addr_ipv6.sin6_addr.s6_addr16[5] = htons(0xffff);
|
||||||
addr_ipv6.sin6_addr.s6_addr16[5] = (u_int16_t) 0xffff;
|
memmove( reinterpret_cast<void*>(&(addr_ipv6.sin6_addr.s6_addr16[6])),
|
||||||
|
reinterpret_cast<void*>(&ip), 4 );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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 **********************************/
|
/******************************** Comparisions **********************************/
|
||||||
|
|
||||||
bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b)
|
bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b)
|
||||||
@ -398,12 +497,17 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr)
|
|||||||
switch(addr.ss_family)
|
switch(addr.ss_family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
case AF_INET6:
|
|
||||||
output += "=";
|
output += "=";
|
||||||
output += sockaddr_storage_iptostring(addr);
|
output += sockaddr_storage_iptostring(addr);
|
||||||
output += ":";
|
output += ":";
|
||||||
output += sockaddr_storage_porttostring(addr);
|
output += sockaddr_storage_porttostring(addr);
|
||||||
break;
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
output += "=[";
|
||||||
|
output += sockaddr_storage_iptostring(addr);
|
||||||
|
output += "]:";
|
||||||
|
output += sockaddr_storage_porttostring(addr);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -433,7 +537,7 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
|
|||||||
{
|
{
|
||||||
const sockaddr_in6 * in6 = (const sockaddr_in6 *) & addr;
|
const sockaddr_in6 * in6 = (const sockaddr_in6 *) & addr;
|
||||||
std::string addrStr = "INVALID_IPV6";
|
std::string addrStr = "INVALID_IPV6";
|
||||||
rs_inet_ntop(addr, addrStr);
|
sockaddr_storage_inet_ntop(addr, addrStr);
|
||||||
output << "addr.ss_family = AF_INET6";
|
output << "addr.ss_family = AF_INET6";
|
||||||
output << " in6->sin6_addr = ";
|
output << " in6->sin6_addr = ";
|
||||||
output << addrStr;
|
output << addrStr;
|
||||||
@ -449,7 +553,8 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
|
|||||||
const uint8_t * buf = reinterpret_cast<const uint8_t *>(&addr);
|
const uint8_t * buf = reinterpret_cast<const uint8_t *>(&addr);
|
||||||
for( uint32_t i = 0; i < sizeof(addr); ++i )
|
for( uint32_t i = 0; i < sizeof(addr); ++i )
|
||||||
output << std::setw(2) << std::setfill('0') << std::hex << +buf[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 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,6 +582,10 @@ std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
output = "AF_INVALID";
|
output = "AF_INVALID";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Got invalid address!"
|
||||||
|
<< std::endl;
|
||||||
|
sockaddr_storage_dump(addr);
|
||||||
|
print_stacktrace();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
@ -495,6 +604,9 @@ std::string sockaddr_storage_iptostring(const struct sockaddr_storage &addr)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
output = "INVALID_IP";
|
output = "INVALID_IP";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Got invalid IP:" << std::endl;
|
||||||
|
sockaddr_storage_dump(addr);
|
||||||
|
print_stacktrace();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
@ -619,9 +731,7 @@ bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
|
|||||||
case AF_INET:
|
case AF_INET:
|
||||||
return isLinkLocalNet(&(to_const_ipv4_ptr(addr)->sin_addr));
|
return isLinkLocalNet(&(to_const_ipv4_ptr(addr)->sin_addr));
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " for AF_INET6 not implemented"
|
return sockaddr_storage_ipv6_isLinkLocalNet(addr);
|
||||||
<< std::endl;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
#ifdef SS_DEBUG
|
#ifdef SS_DEBUG
|
||||||
std::cerr << __PRETTY_FUNCTION__ <<" INVALID Family:" << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ <<" INVALID Family:" << std::endl;
|
||||||
@ -633,6 +743,16 @@ bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
|
|||||||
return false;
|
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)
|
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr)
|
||||||
{
|
{
|
||||||
@ -695,6 +815,51 @@ const struct sockaddr_in6 *to_const_ipv6_ptr(const struct sockaddr_storage &addr
|
|||||||
|
|
||||||
/******************************** Set / Clear ***********************************/
|
/******************************** 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)
|
bool sockaddr_storage_ipv4_zeroip(struct sockaddr_storage &addr)
|
||||||
{
|
{
|
||||||
#ifdef SS_DEBUG
|
#ifdef SS_DEBUG
|
||||||
@ -917,7 +1082,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 sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & addr)
|
||||||
{
|
{
|
||||||
std::string addrStr;
|
std::string addrStr;
|
||||||
rs_inet_ntop(addr, addrStr);
|
sockaddr_storage_inet_ntop(addr, addrStr);
|
||||||
return addrStr;
|
return addrStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,62 +1171,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
|
const sockaddr_in6& addr6 = reinterpret_cast<const sockaddr_in6&>(addr);
|
||||||
std::cerr << "sockaddr_storage_ipv6_isnull() TODO";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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
|
return !sockaddr_storage_ipv6_isnull(addr);
|
||||||
std::cerr << "sockaddr_storage_ipv6_isValidNet() TODO";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
#ifdef SS_DEBUG
|
||||||
std::cerr << "sockaddr_storage_ipv6_isLoopbackNet() TODO";
|
std::cerr << __PRETTY_FUNCTION__ << " " << sockaddr_storage_tostring(addr)
|
||||||
std::cerr << std::endl;
|
<< " " << isLoopBack << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return isLoopBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &/*addr*/)
|
bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &/*addr*/)
|
||||||
{
|
{
|
||||||
#ifdef SS_DEBUG
|
/* It is unlikely that we end up connecting to an IPv6 address behind NAT
|
||||||
std::cerr << "sockaddr_storage_ipv6_isPrivateNet() TODO";
|
* W.R.T. RS it is probably better to consider all IPv6 as internal/local
|
||||||
std::cerr << std::endl;
|
* addresses as direct connection should be always possible. */
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &/*addr*/)
|
bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &/*addr*/)
|
||||||
{
|
{
|
||||||
#ifdef SS_DEBUG
|
/* It is unlikely that we end up connecting to an IPv6 address behind NAT
|
||||||
std::cerr << "sockaddr_storage_ipv6_isExternalNet() TODO";
|
* W.R.T. RS it is probably better to consider all IPv6 as internal/local
|
||||||
std::cerr << std::endl;
|
* addresses as direct connection should be always possible. */
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WINDOWS_SYS
|
bool sockaddr_storage_inet_ntop (const sockaddr_storage &addr, std::string &dst)
|
||||||
#include <cstdlib>
|
|
||||||
#include <Winsock2.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst)
|
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
char ipStr[255];
|
char ipStr[255];
|
||||||
@ -1098,3 +1259,15 @@ bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst)
|
|||||||
dst = ipStr;
|
dst = ipStr;
|
||||||
return success;
|
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
|
||||||
|
}
|
||||||
|
@ -171,7 +171,10 @@ void RsThread::start(const std::string &threadName)
|
|||||||
{
|
{
|
||||||
if(isRunning())
|
if(isRunning())
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) RsThread \"" << threadName << "\" is already running. Will not start twice!" << std::endl;
|
std::cerr << "(EE) RsThread \"" << threadName
|
||||||
|
<< "\" is already running. Will not start twice!"
|
||||||
|
<< std::endl;
|
||||||
|
print_stacktrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
|
Loading…
Reference in New Issue
Block a user