mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-27 00:19:25 -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.
|
||||
*
|
||||
* Copyright 2009-2010 by Robert Fernie.
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -184,18 +185,24 @@ bool p3BitDht::dropPeer(const RsPeerId& pid)
|
||||
********************************* Basic Peer Details *************************************
|
||||
******************************************************************************************/
|
||||
|
||||
int p3BitDht::addBadPeer(const struct sockaddr_storage &addr, uint32_t /*reason*/, uint32_t /*flags*/, uint32_t /*age*/)
|
||||
int p3BitDht::addBadPeer( const sockaddr_storage &addr, uint32_t /*reason*/,
|
||||
uint32_t /*flags*/, uint32_t /*age*/ )
|
||||
{
|
||||
//mUdpBitDht->updateKnownPeer(&id, 0, bdflags);
|
||||
|
||||
struct sockaddr_in addrv4;
|
||||
if (addr.ss_family != AF_INET)
|
||||
sockaddr_in addrv4;
|
||||
sockaddr_storage tmpaddr;
|
||||
sockaddr_storage_copy(addr, tmpaddr);
|
||||
if(!sockaddr_storage_ipv6_to_ipv4(tmpaddr))
|
||||
{
|
||||
std::cerr << "p3BitDht::addBadPeer() cannot handle IPV6 Yet, aborting";
|
||||
std::cerr << std::endl;
|
||||
abort();
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!"
|
||||
<< std::endl;
|
||||
sockaddr_storage_dump(addr);
|
||||
print_stacktrace();
|
||||
return -EINVAL;
|
||||
}
|
||||
struct sockaddr_in *ap = (struct sockaddr_in *) &addr;
|
||||
|
||||
struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr;
|
||||
|
||||
// convert.
|
||||
addrv4.sin_family = ap->sin_family;
|
||||
@ -216,39 +223,30 @@ int p3BitDht::addBadPeer(const struct sockaddr_storage &addr, uint32_t /*reason*
|
||||
}
|
||||
|
||||
|
||||
int p3BitDht::addKnownPeer(const RsPeerId &pid, const struct sockaddr_storage &addr, uint32_t flags)
|
||||
int p3BitDht::addKnownPeer( const RsPeerId &pid,
|
||||
const sockaddr_storage &addr, uint32_t flags )
|
||||
{
|
||||
struct sockaddr_in addrv4;
|
||||
sockaddr_clear(&addrv4);
|
||||
sockaddr_in addrv4;
|
||||
sockaddr_clear(&addrv4);
|
||||
|
||||
if (addr.ss_family != AF_INET)
|
||||
{
|
||||
if(addr.ss_family != AF_UNSPEC)
|
||||
{
|
||||
std::cerr << "p3BitDht::addKnownPeer() Warning! Non IPv4 Address - Cannot handle IPV6 Yet. addr.ss_family=" << addr.ss_family;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
if (flags & NETASSIST_KNOWN_PEER_ONLINE)
|
||||
{
|
||||
std::cerr << "p3BitDht::addKnownPeer() Non IPv4 Address & ONLINE. Abort()ing.";
|
||||
std::cerr << std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
else
|
||||
sockaddr_storage tmpaddr;
|
||||
sockaddr_storage_copy(addr, tmpaddr);
|
||||
if( !sockaddr_storage_isnull(addr) &&
|
||||
!sockaddr_storage_ipv6_to_ipv4(tmpaddr) )
|
||||
{
|
||||
|
||||
// convert.
|
||||
struct sockaddr_in *ap = (struct sockaddr_in *) &addr;
|
||||
|
||||
addrv4.sin_family = ap->sin_family;
|
||||
addrv4.sin_addr = ap->sin_addr;
|
||||
addrv4.sin_port = ap->sin_port;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!"
|
||||
<< std::endl;
|
||||
sockaddr_storage_dump(addr);
|
||||
print_stacktrace();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// convert.
|
||||
struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr;
|
||||
addrv4.sin_family = ap->sin_family;
|
||||
addrv4.sin_addr = ap->sin_addr;
|
||||
addrv4.sin_port = ap->sin_port;
|
||||
|
||||
int p3type = 0;
|
||||
int bdflags = 0;
|
||||
bdId id;
|
||||
@ -295,7 +293,7 @@ int p3BitDht::addKnownPeer(const RsPeerId &pid, const struct sockaddr_storage &a
|
||||
|
||||
if (!isOwnId)
|
||||
{
|
||||
RsStackMutex stack(dhtMtx); /********* LOCKED *********/
|
||||
RS_STACK_MUTEX(dhtMtx);
|
||||
DhtPeerDetails *dpd = addInternalPeer_locked(pid, p3type);
|
||||
|
||||
|
||||
|
@ -1038,12 +1038,15 @@ bool p3NetMgrIMPL::checkNetAddress()
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
sockaddr_storage& addr(*it);
|
||||
if( sockaddr_storage_isValidNet(addr) &&
|
||||
!sockaddr_storage_isLoopbackNet(addr) )
|
||||
!sockaddr_storage_isLoopbackNet(addr) &&
|
||||
!sockaddr_storage_ipv6_isLinkLocalNet(addr) )
|
||||
{
|
||||
prefAddr = addr;
|
||||
validAddr = true;
|
||||
|
@ -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"
|
||||
@ -1227,38 +1232,85 @@ 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& localAddr,
|
||||
const sockaddr_storage& 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;
|
||||
ipAddressTimed.mAddr = localAddr;
|
||||
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) )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
||||
{
|
||||
RS_STACK_MUTEX(mPeerMtx);
|
||||
|
||||
//update ip address list
|
||||
pqiIpAddress ipAddressTimed;
|
||||
|
@ -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);
|
||||
|
@ -60,14 +60,15 @@ static struct RsLog::logInfo pqisslzoneInfo = {RsLog::Default, "pqisslzone"};
|
||||
#define PQISSL_PASSIVE 0x00
|
||||
#define PQISSL_ACTIVE 0x01
|
||||
|
||||
#define PQISSL_DEBUG 1
|
||||
#define PQISSL_LOG_DEBUG 1
|
||||
|
||||
const int PQISSL_LOCAL_FLAG = 0x01;
|
||||
const int PQISSL_REMOTE_FLAG = 0x02;
|
||||
const int PQISSL_UDP_FLAG = 0x02;
|
||||
***********/
|
||||
|
||||
//#define PQISSL_DEBUG 1
|
||||
//#define PQISSL_LOG_DEBUG 1
|
||||
|
||||
|
||||
static const int PQISSL_MAX_READ_ZERO_COUNT = 20;
|
||||
static const time_t PQISSL_MAX_READ_ZERO_TIME = 15; // 15 seconds of no data => reset. (atm HeartBeat pkt sent 5 secs)
|
||||
|
||||
@ -123,6 +124,7 @@ pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) :
|
||||
int pqissl::connect(const struct sockaddr_storage &raddr)
|
||||
{
|
||||
RS_STACK_MUTEX(mSslMtx);
|
||||
|
||||
remote_addr = raddr;
|
||||
return ConnectAttempt();
|
||||
}
|
||||
@ -171,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;
|
||||
@ -355,7 +356,7 @@ int pqissl::status()
|
||||
|
||||
out += " active: \n";
|
||||
// print out connection.
|
||||
out += "Connected TO : " + PeerId() + "\n";
|
||||
out += "Connected TO : " + PeerId().toStdString() + "\n";
|
||||
// print out cipher.
|
||||
rs_sprintf_append(out, "\t\tSSL Cipher:%s", SSL_get_cipher(ssl_connection));
|
||||
rs_sprintf_append(out, " (%d:%d)", SSL_get_cipher_bits(ssl_connection, &alg), alg);
|
||||
@ -551,7 +552,7 @@ int pqissl::Delay_Connection()
|
||||
#ifdef PQISSL_LOG_DEBUG
|
||||
{
|
||||
std::string out;
|
||||
rs_sprintf(out, "pqissl::Delay_Connection() Delaying Connection to %s for %lu seconds", PeerId().c_str(), mConnectDelay);
|
||||
rs_sprintf(out, "pqissl::Delay_Connection() Delaying Connection to %s for %lu seconds", PeerId().toStdString(), mConnectDelay);
|
||||
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
|
||||
}
|
||||
#endif
|
||||
@ -564,7 +565,7 @@ int pqissl::Delay_Connection()
|
||||
#ifdef PQISSL_LOG_DEBUG
|
||||
{
|
||||
std::string out;
|
||||
rs_sprintf(out, "pqissl::Delay_Connection() Connection to %s starting in %ld seconds", PeerId().c_str(), mConnectTS - time(NULL));
|
||||
rs_sprintf(out, "pqissl::Delay_Connection() Connection to %s starting in %ld seconds", PeerId().toStdString(), mConnectTS - time(NULL));
|
||||
rslog(RSL_DEBUG_BASIC, pqisslzone, out);
|
||||
}
|
||||
#endif
|
||||
@ -710,10 +711,12 @@ int pqissl::Initiate_Connection()
|
||||
* will support IPv6 only and not IPv4 */
|
||||
#ifdef IPV6_V6ONLY
|
||||
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
|
||||
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__
|
||||
<< " Setting IPv6 socket dual stack" << std::endl;
|
||||
#endif // PQISSL_DEBUG
|
||||
@ -1089,7 +1092,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,
|
||||
@ -1231,27 +1234,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,
|
||||
@ -1336,36 +1333,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.
|
||||
@ -1376,70 +1391,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);
|
||||
}
|
||||
|
||||
@ -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,
|
||||
* 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();
|
||||
@ -1508,15 +1489,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;
|
||||
}
|
||||
@ -1610,31 +1592,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] = "
|
||||
@ -1649,7 +1635,6 @@ int pqissl::readdata(void *data, int len)
|
||||
#endif
|
||||
|
||||
// Need to catch errors.....
|
||||
//
|
||||
if (tmppktlen <= 0) // probably needs a reset.
|
||||
{
|
||||
std::string out;
|
||||
|
@ -119,12 +119,9 @@ 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();
|
||||
|
||||
@ -140,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
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -4,6 +4,7 @@
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2004-2008 by Robert Fernie.
|
||||
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
@ -900,68 +901,33 @@ bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uin
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Peers::setLocalAddress(const RsPeerId &id, const std::string &addr_str, uint16_t port)
|
||||
bool p3Peers::setLocalAddress(const RsPeerId &id,
|
||||
const std::string &addr_str, uint16_t port)
|
||||
{
|
||||
#ifdef P3PEERS_DEBUG
|
||||
std::cerr << "p3Peers::setLocalAddress() " << id << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " "
|
||||
<< port << std::endl;
|
||||
#endif
|
||||
|
||||
if(port < 1024)
|
||||
{
|
||||
std::cerr << "(EE) attempt to use a port that is reserved to the system: " << port << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr;
|
||||
addrv4p->sin_family = AF_INET;
|
||||
addrv4p->sin_port = htons(port);
|
||||
|
||||
int ret = 1;
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
if (ret && (0 != inet_aton(addr_str.c_str(), &(addrv4p->sin_addr))))
|
||||
#else
|
||||
addrv4p->sin_addr.s_addr = inet_addr(addr_str.c_str());
|
||||
if (ret)
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
|
||||
{
|
||||
return mPeerMgr->setLocalAddress(id, addr);
|
||||
}
|
||||
sockaddr_storage addr;
|
||||
if (sockaddr_storage_inet_pton(addr, addr_str))
|
||||
if (sockaddr_storage_setport(addr, port))
|
||||
return mPeerMgr->setLocalAddress(id, addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool p3Peers::setExtAddress(const RsPeerId &id, const std::string &addr_str, uint16_t port)
|
||||
bool p3Peers::setExtAddress(const RsPeerId &id,
|
||||
const std::string &addr_str, uint16_t port)
|
||||
{
|
||||
#ifdef P3PEERS_DEBUG
|
||||
std::cerr << "p3Peers::setExtAddress() " << id << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " "
|
||||
<< port << std::endl;
|
||||
#endif
|
||||
if(port < 1024)
|
||||
{
|
||||
std::cerr << "(EE) attempt to use a port that is reserved to the system: " << port << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
|
||||
// NOTE THIS IS IPV4 FOR NOW.
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr;
|
||||
addrv4p->sin_family = AF_INET;
|
||||
addrv4p->sin_port = htons(port);
|
||||
|
||||
int ret = 1;
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
if (ret && (0 != inet_aton(addr_str.c_str(), &(addrv4p->sin_addr))))
|
||||
#else
|
||||
addrv4p->sin_addr.s_addr = inet_addr(addr_str.c_str());
|
||||
if (ret)
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART *******************/
|
||||
{
|
||||
return mPeerMgr->setExtAddress(id, addr);
|
||||
}
|
||||
sockaddr_storage addr;
|
||||
if (sockaddr_storage_inet_pton(addr, addr_str))
|
||||
if (sockaddr_storage_setport(addr, port))
|
||||
return mPeerMgr->setExtAddress(id, addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,9 @@ RsDisc *rsDisc = NULL;
|
||||
* #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();
|
||||
|
||||
@ -342,7 +344,7 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
peerState detail;
|
||||
if (mPeerMgr->getOwnNetStatus(detail))
|
||||
if (mPeerMgr->getOwnNetStatus(detail))
|
||||
{
|
||||
RsDiscContactItem *pkt = new RsDiscContactItem();
|
||||
/* Cyril: we dont send our own IP to an hidden node. It will not use it
|
||||
@ -461,6 +463,7 @@ void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item)
|
||||
{
|
||||
}
|
||||
else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId()))
|
||||
{
|
||||
/* 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. */
|
||||
/* 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
|
||||
* difficult for average user, that moreover whould have no way to
|
||||
* revert an hardcoded policy. */
|
||||
{
|
||||
pqiIpAddrSet addrsFromPeer;
|
||||
pqiIpAddrSet addrsFromPeer;
|
||||
addrsFromPeer.mLocal.extractFromTlv(item->localAddrList);
|
||||
addrsFromPeer.mExt.extractFromTlv(item->extAddrList);
|
||||
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "Setting address list to peer " << item->sslId << ", to be:" << std::endl ;
|
||||
std::cerr << "Setting address list to peer " << item->sslId
|
||||
<< ", to be:" << std::endl ;
|
||||
|
||||
std::string addrstr;
|
||||
addrsFromPeer.printAddrs(addrstr);
|
||||
|
@ -50,34 +50,37 @@ virtual bool resetAddress(struct sockaddr_in &local) { return false; }
|
||||
/*******************************************************/
|
||||
|
||||
#include "pqi/pqimonitor.h"
|
||||
#include "util/rsnet.h"
|
||||
#include "util/stacktrace.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class rsUdpStack: public UdpStack, public pqiNetListener
|
||||
{
|
||||
public:
|
||||
rsUdpStack(struct sockaddr_in &local)
|
||||
:UdpStack(local) { return; }
|
||||
public:
|
||||
rsUdpStack(struct sockaddr_in &local) : UdpStack(local) {}
|
||||
|
||||
rsUdpStack(int testmode, struct sockaddr_in &local)
|
||||
:UdpStack(testmode, local) { return; }
|
||||
rsUdpStack(int testmode, struct sockaddr_in &local) :
|
||||
UdpStack(testmode, local) {}
|
||||
|
||||
/* from pqiNetListener */
|
||||
virtual bool resetListener(const struct sockaddr_storage &local)
|
||||
/// @see pqiNetListener
|
||||
virtual bool resetListener(const sockaddr_storage& local)
|
||||
{
|
||||
//std::cerr << "rsUdpStack::resetListener(" << sockaddr_storage_tostring(local) << ")";
|
||||
//std::cerr << std::endl;
|
||||
sockaddr_storage temp;
|
||||
sockaddr_storage_copy(local, temp);
|
||||
|
||||
if (local.ss_family != AF_INET)
|
||||
if (!sockaddr_storage_ipv6_to_ipv4(temp))
|
||||
{
|
||||
std::cerr << "rsUdpStack::resetListener() NOT IPv4 ERROR";
|
||||
std::cerr << std::endl;
|
||||
abort();
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Got non IPv4 address ERROR"
|
||||
<< std::endl;
|
||||
sockaddr_storage_dump(local);
|
||||
print_stacktrace();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *) &local;
|
||||
sockaddr_in *addr = reinterpret_cast<sockaddr_in*>(&temp);
|
||||
return resetAddress(*addr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class rsFixedUdpStack: public UdpStack, public pqiNetListener
|
||||
|
@ -88,14 +88,26 @@ std::string rs_inet_ntoa(struct in_addr in);
|
||||
/***************************/
|
||||
// sockaddr_storage fns.
|
||||
|
||||
// Standard bind, on OSX anyway will not accept a longer socklen for IPv4.
|
||||
// so hidding details behind function.
|
||||
int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen);
|
||||
int rs_bind(int fd, const sockaddr_storage& addr);
|
||||
|
||||
void sockaddr_storage_clear(struct sockaddr_storage &addr);
|
||||
|
||||
// mods.
|
||||
bool sockaddr_storage_zeroip(struct sockaddr_storage &addr);
|
||||
|
||||
/**
|
||||
* @brief Use this function to copy sockaddr_storage.
|
||||
*
|
||||
* POSIX does not require that objects of type sockaddr_storage can be copied
|
||||
* as aggregates thus it is unsafe to aggregate copy ( operator = )
|
||||
* sockaddr_storage and unexpected behaviors may happens due to padding
|
||||
* and alignment.
|
||||
*
|
||||
* @see https://sourceware.org/bugzilla/show_bug.cgi?id=20111
|
||||
* @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71120
|
||||
*/
|
||||
bool sockaddr_storage_copy(const sockaddr_storage& src, sockaddr_storage& dst);
|
||||
|
||||
bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src);
|
||||
uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port);
|
||||
@ -103,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_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6);
|
||||
|
||||
bool sockaddr_storage_inet_pton( sockaddr_storage &addr,
|
||||
const std::string& ipStr );
|
||||
bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name);
|
||||
|
||||
bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, const uint16_t port);
|
||||
|
||||
bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr);
|
||||
bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr);
|
||||
|
||||
// comparisons.
|
||||
bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b);
|
||||
@ -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_isPrivateNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr);
|
||||
bool sockaddr_storage_ipv6_isLinkLocalNet(const sockaddr_storage &addr);
|
||||
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr);
|
||||
|
||||
bool rs_inet_ntop(const sockaddr_storage &addr, std::string &dst);
|
||||
bool sockaddr_storage_inet_ntop(const sockaddr_storage &addr, std::string &dst);
|
||||
|
||||
int rs_setsockopt( int sockfd, int level, int optname,
|
||||
const uint8_t *optval, uint32_t optlen );
|
||||
|
||||
#endif /* RS_UNIVERSAL_NETWORK_HEADER */
|
||||
|
@ -26,6 +26,24 @@
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
# include <Winsock2.h>
|
||||
/** Provides Linux like accessor for in6_addr.s6_addr16 for Windows.
|
||||
* Yet Windows doesn't provide 32 bits accessors so there is no way to use
|
||||
* in6_addr.s6_addr32 crossplatform.
|
||||
*/
|
||||
# define s6_addr16 u.Word
|
||||
#else
|
||||
# include <netinet/in.h>
|
||||
# include <sys/socket.h>
|
||||
# include <sys/types.h>
|
||||
# ifdef __APPLE__
|
||||
/// Provides Linux like accessor for in6_addr.s6_addr16 for Mac.
|
||||
# define s6_addr16 __u6_addr.__u6_addr16
|
||||
#endif // __APPLE__
|
||||
#endif // WINDOWS_SYS
|
||||
|
||||
#include "util/rsnet.h"
|
||||
#include "util/rsstring.h"
|
||||
@ -90,17 +108,14 @@ bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &addr);
|
||||
/******************************** Socket Fns ***********************************/
|
||||
// Standard bind, on OSX anyway will not accept a longer socklen for IPv4.
|
||||
// so hidding details behind function.
|
||||
int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen)
|
||||
int rs_bind(int fd, const sockaddr_storage& addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "universal_bind()";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||
#endif
|
||||
|
||||
const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) addr;
|
||||
socklen_t len = socklen;
|
||||
|
||||
switch (ss_addr->ss_family)
|
||||
socklen_t len = 0;
|
||||
switch (addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
len = sizeof(struct sockaddr_in);
|
||||
@ -110,13 +125,7 @@ int universal_bind(int fd, const struct sockaddr *addr, socklen_t socklen)
|
||||
break;
|
||||
}
|
||||
|
||||
if (len > socklen)
|
||||
{
|
||||
std::cerr << "universal_bind() ERROR len > socklen" << std::endl;
|
||||
len = socklen;
|
||||
}
|
||||
|
||||
return bind(fd, addr, len);
|
||||
return bind(fd, reinterpret_cast<const struct sockaddr *>(&addr), len);
|
||||
}
|
||||
|
||||
|
||||
@ -252,6 +261,58 @@ bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
sockaddr_storage ss;
|
||||
int size = sizeof(ss);
|
||||
char src_copy[INET6_ADDRSTRLEN+1];
|
||||
|
||||
ZeroMemory(&ss, sizeof(ss));
|
||||
/* stupid non-const API */
|
||||
strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
|
||||
src_copy[INET6_ADDRSTRLEN] = 0;
|
||||
|
||||
if (WSAStringToAddressA(src_copy, af, NULL, (sockaddr *)&ss, &size) == 0)
|
||||
{
|
||||
switch(af)
|
||||
{
|
||||
case AF_INET:
|
||||
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
|
||||
return 1;
|
||||
case AF_INET6:
|
||||
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool sockaddr_storage_inet_pton( sockaddr_storage &addr,
|
||||
const std::string& ipStr )
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||
#endif
|
||||
|
||||
struct sockaddr_in6 * addrv6p = (struct sockaddr_in6 *) &addr;
|
||||
struct sockaddr_in * addrv4p = (struct sockaddr_in *) &addr;
|
||||
|
||||
if ( 1 == inet_pton(AF_INET6, ipStr.c_str(), &(addrv6p->sin6_addr)) )
|
||||
{
|
||||
addr.ss_family = AF_INET6;
|
||||
return true;
|
||||
}
|
||||
else if ( 1 == inet_pton(AF_INET, ipStr.c_str(), &(addrv4p->sin_addr)) )
|
||||
{
|
||||
addr.ss_family = AF_INET;
|
||||
return sockaddr_storage_ipv4_to_ipv6(addr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name)
|
||||
{
|
||||
@ -278,21 +339,59 @@ bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr)
|
||||
sockaddr_in & addr_ipv4 = (sockaddr_in &) addr;
|
||||
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
|
||||
|
||||
u_int32_t ip = addr_ipv4.sin_addr.s_addr;
|
||||
u_int16_t port = addr_ipv4.sin_port;
|
||||
uint32_t ip = addr_ipv4.sin_addr.s_addr;
|
||||
uint16_t port = addr_ipv4.sin_port;
|
||||
|
||||
sockaddr_storage_clear(addr);
|
||||
addr_ipv6.sin6_family = AF_INET6;
|
||||
addr_ipv6.sin6_port = port;
|
||||
addr_ipv6.sin6_addr.s6_addr32[3] = ip;
|
||||
addr_ipv6.sin6_addr.s6_addr16[5] = (u_int16_t) 0xffff;
|
||||
|
||||
addr_ipv6.sin6_addr.s6_addr16[5] = htons(0xffff);
|
||||
memmove( reinterpret_cast<void*>(&(addr_ipv6.sin6_addr.s6_addr16[6])),
|
||||
reinterpret_cast<void*>(&ip), 4 );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__ << std::endl;
|
||||
#endif
|
||||
|
||||
if ( addr.ss_family == AF_INET ) return true;
|
||||
|
||||
if ( addr.ss_family == AF_INET6 )
|
||||
{
|
||||
sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr;
|
||||
bool ipv4m = addr_ipv6.sin6_addr.s6_addr16[5] == htons(0xffff);
|
||||
for ( int i = 0; ipv4m && i < 5 ; ++i )
|
||||
ipv4m &= addr_ipv6.sin6_addr.s6_addr16[i] == htons(0x0000);
|
||||
|
||||
if(ipv4m)
|
||||
{
|
||||
uint32_t ip;
|
||||
memmove( reinterpret_cast<void*>(&ip),
|
||||
reinterpret_cast<void*>(&(addr_ipv6.sin6_addr.s6_addr16[6])),
|
||||
4 );
|
||||
uint16_t port = addr_ipv6.sin6_port;
|
||||
|
||||
sockaddr_in & addr_ipv4 = (sockaddr_in &) addr;
|
||||
|
||||
sockaddr_storage_clear(addr);
|
||||
addr_ipv4.sin_family = AF_INET;
|
||||
addr_ipv4.sin_port = port;
|
||||
addr_ipv4.sin_addr.s_addr = ip;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/******************************** Comparisions **********************************/
|
||||
|
||||
bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b)
|
||||
@ -397,15 +496,20 @@ std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr)
|
||||
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
output += "=";
|
||||
output += sockaddr_storage_iptostring(addr);
|
||||
output += ":";
|
||||
output += sockaddr_storage_porttostring(addr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case AF_INET:
|
||||
output += "=";
|
||||
output += sockaddr_storage_iptostring(addr);
|
||||
output += ":";
|
||||
output += sockaddr_storage_porttostring(addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
output += "=[";
|
||||
output += sockaddr_storage_iptostring(addr);
|
||||
output += "]:";
|
||||
output += sockaddr_storage_porttostring(addr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@ -433,7 +537,7 @@ void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputSt
|
||||
{
|
||||
const sockaddr_in6 * in6 = (const sockaddr_in6 *) & addr;
|
||||
std::string addrStr = "INVALID_IPV6";
|
||||
rs_inet_ntop(addr, addrStr);
|
||||
sockaddr_storage_inet_ntop(addr, addrStr);
|
||||
output << "addr.ss_family = AF_INET6";
|
||||
output << " in6->sin6_addr = ";
|
||||
output << addrStr;
|
||||
@ -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);
|
||||
for( uint32_t i = 0; i < sizeof(addr); ++i )
|
||||
output << std::setw(2) << std::setfill('0') << std::hex << +buf[i];
|
||||
// The unary +buf[i] operation forces a no-op type conversion to an int with the correct sign
|
||||
/* The unary +buf[i] operation forces a no-op type conversion to an int
|
||||
* with the correct sign */
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,6 +582,10 @@ std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr)
|
||||
break;
|
||||
default:
|
||||
output = "AF_INVALID";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Got invalid address!"
|
||||
<< std::endl;
|
||||
sockaddr_storage_dump(addr);
|
||||
print_stacktrace();
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
@ -487,15 +596,18 @@ std::string sockaddr_storage_iptostring(const struct sockaddr_storage &addr)
|
||||
std::string output;
|
||||
switch(addr.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
output = sockaddr_storage_ipv4_iptostring(addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
output = sockaddr_storage_ipv6_iptostring(addr);
|
||||
break;
|
||||
default:
|
||||
output = "INVALID_IP";
|
||||
break;
|
||||
case AF_INET:
|
||||
output = sockaddr_storage_ipv4_iptostring(addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
output = sockaddr_storage_ipv6_iptostring(addr);
|
||||
break;
|
||||
default:
|
||||
output = "INVALID_IP";
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Got invalid IP:" << std::endl;
|
||||
sockaddr_storage_dump(addr);
|
||||
print_stacktrace();
|
||||
break;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@ -619,9 +731,7 @@ bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
|
||||
case AF_INET:
|
||||
return isLinkLocalNet(&(to_const_ipv4_ptr(addr)->sin_addr));
|
||||
case AF_INET6:
|
||||
std::cerr << __PRETTY_FUNCTION__ << " for AF_INET6 not implemented"
|
||||
<< std::endl;
|
||||
break;
|
||||
return sockaddr_storage_ipv6_isLinkLocalNet(addr);
|
||||
default:
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__ <<" INVALID Family:" << std::endl;
|
||||
@ -633,6 +743,16 @@ bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv6_isLinkLocalNet(const sockaddr_storage &addr)
|
||||
{
|
||||
if(addr.ss_family != AF_INET6) return false;
|
||||
|
||||
const sockaddr_in6 * addr6 = (const sockaddr_in6 *) &addr;
|
||||
uint16_t mask = htons(0xffc0);
|
||||
uint16_t llPrefix = htons(0xfe80);
|
||||
return ((addr6->sin6_addr.s6_addr16[0] & mask ) == llPrefix);
|
||||
}
|
||||
|
||||
|
||||
bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr)
|
||||
{
|
||||
@ -695,6 +815,51 @@ const struct sockaddr_in6 *to_const_ipv6_ptr(const struct sockaddr_storage &addr
|
||||
|
||||
/******************************** Set / Clear ***********************************/
|
||||
|
||||
bool sockaddr_storage_copy(const sockaddr_storage& src, sockaddr_storage& dst)
|
||||
{
|
||||
if(&src == &dst) return true;
|
||||
|
||||
switch(src.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
sockaddr_storage_clear(dst);
|
||||
const sockaddr_in& ins(reinterpret_cast<const sockaddr_in&>(src));
|
||||
sockaddr_in& ind(reinterpret_cast<sockaddr_in&>(dst));
|
||||
|
||||
ind.sin_family = AF_INET;
|
||||
ind.sin_addr.s_addr = ins.sin_addr.s_addr;
|
||||
ind.sin_port = ins.sin_port;
|
||||
|
||||
return true;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
sockaddr_storage_clear(dst);
|
||||
const sockaddr_in6& ins6(reinterpret_cast<const sockaddr_in6&>(src));
|
||||
sockaddr_in6& ind6(reinterpret_cast<sockaddr_in6&>(dst));
|
||||
|
||||
ind6.sin6_family = AF_INET6;
|
||||
for(int i=0; i<8; ++i)
|
||||
ind6.sin6_addr.s6_addr16[i] = ins6.sin6_addr.s6_addr16[i];
|
||||
ind6.sin6_flowinfo = ins6.sin6_flowinfo;
|
||||
ind6.sin6_port = ins6.sin6_port;
|
||||
ind6.sin6_scope_id = ins6.sin6_scope_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << __PRETTY_FUNCTION__ << " Attempt to copy unknown family! "
|
||||
<< src.ss_family << " defaulting to memmove!" << std::endl;
|
||||
sockaddr_storage_dump(src);
|
||||
print_stacktrace();
|
||||
#endif // SS_DEBUG
|
||||
memmove(&dst, &src, sizeof(sockaddr_storage));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv4_zeroip(struct sockaddr_storage &addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
@ -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 addrStr;
|
||||
rs_inet_ntop(addr, addrStr);
|
||||
sockaddr_storage_inet_ntop(addr, 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
|
||||
std::cerr << "sockaddr_storage_ipv6_isnull() TODO";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
const sockaddr_in6& addr6 = reinterpret_cast<const sockaddr_in6&>(addr);
|
||||
|
||||
return false;
|
||||
uint16_t nZero = htons(0); // anyway 0 should be the same in host and net
|
||||
bool isZero = (addr6.sin6_addr.s6_addr16[7] == nZero);
|
||||
for (int i=0; isZero && i<7; ++i)
|
||||
isZero &= (addr6.sin6_addr.s6_addr16[i] == nZero);
|
||||
|
||||
return nZero;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage &/*addr*/)
|
||||
bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage& addr)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_isValidNet() TODO";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
return !sockaddr_storage_ipv6_isnull(addr);
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage &/*addr*/)
|
||||
bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage& addr)
|
||||
{
|
||||
const sockaddr_in6& addr6 = reinterpret_cast<const sockaddr_in6&>(addr);
|
||||
bool isLoopBack = (addr6.sin6_addr.s6_addr16[7] == htons(0x0001));
|
||||
uint16_t nZero = htons(0); // anyway 0 should be the same in host and net
|
||||
for (int i=0; isLoopBack && i<7; ++i)
|
||||
isLoopBack &= (addr6.sin6_addr.s6_addr16[i] == nZero);
|
||||
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_isLoopbackNet() TODO";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << __PRETTY_FUNCTION__ << " " << sockaddr_storage_tostring(addr)
|
||||
<< " " << isLoopBack << std::endl;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
return isLoopBack;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &/*addr*/)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_isPrivateNet() TODO";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* It is unlikely that we end up connecting to an IPv6 address behind NAT
|
||||
* W.R.T. RS it is probably better to consider all IPv6 as internal/local
|
||||
* addresses as direct connection should be always possible. */
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &/*addr*/)
|
||||
{
|
||||
#ifdef SS_DEBUG
|
||||
std::cerr << "sockaddr_storage_ipv6_isExternalNet() TODO";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* It is unlikely that we end up connecting to an IPv6 address behind NAT
|
||||
* W.R.T. RS it is probably better to consider all IPv6 as internal/local
|
||||
* addresses as direct connection should be always possible. */
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
#include <cstdlib>
|
||||
#include <Winsock2.h>
|
||||
#endif
|
||||
|
||||
bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst)
|
||||
bool sockaddr_storage_inet_ntop (const sockaddr_storage &addr, std::string &dst)
|
||||
{
|
||||
bool success = false;
|
||||
char ipStr[255];
|
||||
@ -1098,3 +1259,15 @@ bool rs_inet_ntop (const sockaddr_storage &addr, std::string &dst)
|
||||
dst = ipStr;
|
||||
return success;
|
||||
}
|
||||
|
||||
int rs_setsockopt( int sockfd, int level, int optname,
|
||||
const uint8_t *optval, uint32_t optlen )
|
||||
{
|
||||
#ifdef WINDOWS_SYS
|
||||
return setsockopt( sockfd, level, optname,
|
||||
reinterpret_cast<const char*>(optval), optlen );
|
||||
#else
|
||||
return setsockopt( sockfd, level, optname,
|
||||
reinterpret_cast<const void*>(optval), optlen );
|
||||
#endif // WINDOWS_SYS
|
||||
}
|
||||
|
@ -169,11 +169,14 @@ void RsTickingThread::fullstop()
|
||||
|
||||
void RsThread::start(const std::string &threadName)
|
||||
{
|
||||
if(isRunning())
|
||||
{
|
||||
std::cerr << "(EE) RsThread \"" << threadName << "\" is already running. Will not start twice!" << std::endl;
|
||||
return ;
|
||||
}
|
||||
if(isRunning())
|
||||
{
|
||||
std::cerr << "(EE) RsThread \"" << threadName
|
||||
<< "\" is already running. Will not start twice!"
|
||||
<< std::endl;
|
||||
print_stacktrace();
|
||||
return;
|
||||
}
|
||||
pthread_t tid;
|
||||
void *data = (void *)this ;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user