BIP155 (addrv2)
Tor v3 + i2p
This commit is contained in:
140
src/net.h
140
src/net.h
@@ -20,9 +20,11 @@
|
||||
#ifndef HUSH_NET_H
|
||||
#define HUSH_NET_H
|
||||
|
||||
#include "addrdb.h"
|
||||
#include "bloom.h"
|
||||
#include "compat.h"
|
||||
#include "hash.h"
|
||||
#include "i2p.h"
|
||||
#include "limitedmap.h"
|
||||
#include "mruset.h"
|
||||
#include "netbase.h"
|
||||
@@ -31,7 +33,7 @@
|
||||
#include "streams.h"
|
||||
#include "sync.h"
|
||||
#include "uint256.h"
|
||||
#include "utilstrencodings.h"
|
||||
#include "util/strencodings.h"
|
||||
#include "util.h"
|
||||
#include <deque>
|
||||
#include <stdint.h>
|
||||
@@ -62,6 +64,8 @@ namespace boost {
|
||||
|
||||
/** Time between pings automatically sent out for latency probing and keepalive (in seconds). */
|
||||
static const int PING_INTERVAL = 2 * 60;
|
||||
/** Retry Time between pings automatically sent out for latency probing and keepalive (in seconds). */
|
||||
static const int MAX_PING_RETRY = 20;
|
||||
/** Time after which to disconnect, after waiting for a ping response (or inactivity). */
|
||||
static const int TIMEOUT_INTERVAL = 20 * 60;
|
||||
/** The maximum number of entries in an 'inv' protocol message */
|
||||
@@ -84,6 +88,7 @@ static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 384;
|
||||
static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3;
|
||||
/** Run the feeler connection loop once every 120 seconds. **/
|
||||
static const int FEELER_INTERVAL = 120;
|
||||
extern std::atomic<bool> fNetworkActive;
|
||||
|
||||
unsigned int ReceiveFloodSize();
|
||||
unsigned int SendBufferSize();
|
||||
@@ -99,6 +104,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL);
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false);
|
||||
unsigned short GetListenPort();
|
||||
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fAllowlisted = false);
|
||||
void LoadPeers();
|
||||
void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler);
|
||||
bool StopNode();
|
||||
void SocketSendData(CNode *pnode);
|
||||
@@ -108,11 +114,56 @@ X509 *generate_x509(EVP_PKEY *pkey);
|
||||
bool write_to_disk(EVP_PKEY *pkey, X509 *x509);
|
||||
void configure_context(SSL_CTX *ctx, bool server_side);
|
||||
|
||||
// OpenSSL related variables for metrics.cpp
|
||||
static std::string routingsecrecy;
|
||||
static std::string cipherdescription;
|
||||
static std::string securitylevel;
|
||||
static std::string validationdescription;
|
||||
|
||||
void GetBanned(banmap_t &banmap);
|
||||
void SetBanned(const banmap_t &banmap);
|
||||
|
||||
//!check is the banlist has unwritten changes
|
||||
bool BannedSetIsDirty();
|
||||
//!set the "dirty" flag for the banlist
|
||||
void SetBannedSetDirty(bool dirty=true);
|
||||
//!clean unused entries (if bantime has expired)
|
||||
void SweepBanned();
|
||||
|
||||
void CreateNodeFromAcceptedSocket(SOCKET hSocket,
|
||||
bool whitelisted,
|
||||
const CAddress& addr_bind,
|
||||
const CAddress& addr);
|
||||
typedef int NodeId;
|
||||
|
||||
enum NumConnections {
|
||||
CONNECTIONS_NONE = 0,
|
||||
CONNECTIONS_IN = (1U << 0),
|
||||
CONNECTIONS_OUT = (1U << 1),
|
||||
CONNECTIONS_ALL = (CONNECTIONS_IN | CONNECTIONS_OUT),
|
||||
};
|
||||
|
||||
size_t GetNodeCount(NumConnections num);
|
||||
|
||||
bool GetNetworkActive();
|
||||
void SetNetworkActive(bool active);
|
||||
|
||||
class CNodeStats;
|
||||
void CopyNodeStats(std::vector<CNodeStats>& vstats);
|
||||
|
||||
struct CSerializedNetMsg
|
||||
{
|
||||
CSerializedNetMsg() = default;
|
||||
CSerializedNetMsg(CSerializedNetMsg&&) = default;
|
||||
CSerializedNetMsg& operator=(CSerializedNetMsg&&) = default;
|
||||
// No copying, only moves.
|
||||
CSerializedNetMsg(const CSerializedNetMsg& msg) = delete;
|
||||
CSerializedNetMsg& operator=(const CSerializedNetMsg&) = delete;
|
||||
|
||||
std::vector<unsigned char> data;
|
||||
std::string m_type;
|
||||
};
|
||||
|
||||
struct CombinerAll
|
||||
{
|
||||
typedef bool result_type;
|
||||
@@ -155,17 +206,21 @@ enum
|
||||
|
||||
bool IsPeerAddrLocalGood(CNode *pnode);
|
||||
void AdvertizeLocal(CNode *pnode);
|
||||
void SetLimited(enum Network net, bool fLimited = true);
|
||||
bool IsLimited(enum Network net);
|
||||
bool IsLimited(const CNetAddr& addr);
|
||||
bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
|
||||
bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
|
||||
bool RemoveLocal(const CService& addr);
|
||||
bool SeenLocal(const CService& addr);
|
||||
bool IsLocal(const CService& addr);
|
||||
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
|
||||
/**
|
||||
* Mark a network as reachable or unreachable (no automatic connects to it)
|
||||
* @note Networks are reachable by default
|
||||
*/
|
||||
void SetReachable(enum Network net, bool reachable);
|
||||
/** @returns true if the network is reachable, false otherwise */
|
||||
bool IsReachable(enum Network net);
|
||||
bool IsReachable(const CNetAddr &addr);
|
||||
/** @returns true if the address is in a reachable network, false otherwise */
|
||||
bool IsReachable(const CNetAddr& addr);
|
||||
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
|
||||
|
||||
|
||||
@@ -190,12 +245,14 @@ extern CCriticalSection cs_vAddedNodes;
|
||||
extern NodeId nLastNodeId;
|
||||
extern CCriticalSection cs_nLastNodeId;
|
||||
|
||||
/** Subversion as sent to the P2P network in `version` messages */
|
||||
extern std::string strSubVersion;
|
||||
|
||||
extern SSL_CTX *tls_ctx_server;
|
||||
extern SSL_CTX *tls_ctx_client;
|
||||
|
||||
extern std::unique_ptr<i2p::sam::Session> m_i2p_sam_session;
|
||||
|
||||
/** Subversion as sent to the P2P network in `version` messages */
|
||||
extern std::string strSubVersion;
|
||||
|
||||
struct LocalServiceInfo {
|
||||
int nScore;
|
||||
int nPort;
|
||||
@@ -204,6 +261,8 @@ struct LocalServiceInfo {
|
||||
extern CCriticalSection cs_mapLocalHost;
|
||||
extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
|
||||
|
||||
typedef std::map<std::string, uint64_t> mapMsgCmdSize; //command, total bytes
|
||||
|
||||
class CNodeStats
|
||||
{
|
||||
public:
|
||||
@@ -228,12 +287,19 @@ public:
|
||||
bool fFeeler; // If true this node is being used as a short lived feeler.
|
||||
double dPingTime;
|
||||
double dPingWait;
|
||||
double dMinPing;
|
||||
std::string addrLocal;
|
||||
// Address of this peer
|
||||
CAddress addr;
|
||||
// Bind address of our side of the connection
|
||||
// CAddress addrBind; // https://github.com/bitcoin/bitcoin/commit/a7e3c2814c8e49197889a4679461be42254e5c51
|
||||
uint32_t m_mapped_as; // Mapped ASN for this address
|
||||
uint32_t m_mapped_as;
|
||||
|
||||
/**
|
||||
* Whether the peer has signaled support for receiving ADDRv2 (BIP155)
|
||||
* messages, implying a preference to receive ADDRv2 instead of ADDR ones.
|
||||
*/
|
||||
bool m_wants_addrv2;
|
||||
};
|
||||
|
||||
|
||||
@@ -277,6 +343,22 @@ public:
|
||||
int readData(const char *pch, unsigned int nBytes);
|
||||
};
|
||||
|
||||
|
||||
/** The TransportSerializer prepares messages for the network transport
|
||||
*/
|
||||
class TransportSerializer {
|
||||
public:
|
||||
// prepare message for transport (header construction, error-correction computation, payload encryption, etc.)
|
||||
virtual void prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) = 0;
|
||||
virtual ~TransportSerializer() {}
|
||||
};
|
||||
|
||||
class V1TransportSerializer : public TransportSerializer {
|
||||
public:
|
||||
void prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) override;
|
||||
};
|
||||
|
||||
|
||||
/** Information about a peer */
|
||||
class CNode
|
||||
{
|
||||
@@ -284,6 +366,8 @@ public:
|
||||
// TLS via WolfSSL
|
||||
SSL *ssl;
|
||||
std::string tls_cipher;
|
||||
//Message Transport Serializer
|
||||
std::unique_ptr<TransportSerializer> m_serializer;
|
||||
|
||||
// socket
|
||||
uint64_t nServices;
|
||||
@@ -342,12 +426,19 @@ public:
|
||||
CBloomFilter* pfilter;
|
||||
int nRefCount;
|
||||
NodeId id;
|
||||
|
||||
/**
|
||||
* Whether the peer has signaled support for receiving ADDRv2 (BIP155)
|
||||
* messages, implying a preference to receive ADDRv2 instead of ADDR ones.
|
||||
*/
|
||||
bool m_wants_addrv2{false};
|
||||
|
||||
protected:
|
||||
|
||||
// Denial-of-service detection/prevention
|
||||
// Key is IP address, value is banned-until-time
|
||||
static std::map<CSubNet, int64_t> setBanned;
|
||||
static CCriticalSection cs_setBanned;
|
||||
// static std::map<CSubNet, int64_t> setBanned;
|
||||
// static CCriticalSection cs_setBanned;
|
||||
|
||||
// Allowlisted ranges. Any node connecting from these is automatically
|
||||
// allowlisted (as well as those connecting to allowlisted binds).
|
||||
@@ -393,6 +484,8 @@ public:
|
||||
int64_t nMinPingUsecTime;
|
||||
// Whether a ping is requested.
|
||||
bool fPingQueued;
|
||||
// Times has ping been retried
|
||||
int64_t nPingRetry;
|
||||
|
||||
CNode(SOCKET hSocketIn, const CAddress &addrIn, const std::string &addrNameIn = "", bool fInboundIn = false, SSL *sslIn = NULL);
|
||||
~CNode();
|
||||
@@ -407,6 +500,8 @@ private:
|
||||
CNode(const CNode&);
|
||||
void operator=(const CNode&);
|
||||
|
||||
mapMsgCmdSize mapSendBytesPerMsgCmd GUARDED_BY(cs_vSend);
|
||||
|
||||
public:
|
||||
|
||||
NodeId GetId() const {
|
||||
@@ -452,21 +547,26 @@ public:
|
||||
|
||||
|
||||
|
||||
void AddAddressKnown(const CAddress& addr)
|
||||
void AddAddressKnown(const CAddress& _addr)
|
||||
{
|
||||
addrKnown.insert(addr.GetKey());
|
||||
addrKnown.insert(_addr.GetKey());
|
||||
}
|
||||
|
||||
void PushAddress(const CAddress& addr)
|
||||
void PushAddress(const CAddress& _addr)
|
||||
{
|
||||
// Whether the peer supports the address in `_addr`. For example,
|
||||
// nodes that do not implement BIP155 cannot receive Tor v3 addresses
|
||||
// because they require ADDRv2 (BIP155) encoding.
|
||||
const bool addr_format_supported = m_wants_addrv2 || _addr.IsAddrV1Compatible();
|
||||
|
||||
// Known checking here is only to save space from duplicates.
|
||||
// SendMessages will filter it again for knowns that were added
|
||||
// after addresses were pushed.
|
||||
if (addr.IsValid() && !addrKnown.contains(addr.GetKey())) {
|
||||
if (_addr.IsValid() && !addrKnown.contains(_addr.GetKey()) && addr_format_supported) {
|
||||
if (vAddrToSend.size() >= MAX_ADDR_TO_SEND) {
|
||||
vAddrToSend[insecure_rand() % vAddrToSend.size()] = addr;
|
||||
vAddrToSend[insecure_rand() % vAddrToSend.size()] = _addr;
|
||||
} else {
|
||||
vAddrToSend.push_back(addr);
|
||||
vAddrToSend.push_back(_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -500,6 +600,8 @@ public:
|
||||
// TODO: Document the precondition of this function. Is cs_vSend locked?
|
||||
void EndMessage() UNLOCK_FUNCTION(cs_vSend);
|
||||
|
||||
void PushAddrMessage(CSerializedNetMsg&& msg);
|
||||
|
||||
void PushVersion();
|
||||
|
||||
|
||||
@@ -682,8 +784,8 @@ public:
|
||||
static void ClearBanned(); // needed for unit testing
|
||||
static bool IsBanned(CNetAddr ip);
|
||||
static bool IsBanned(CSubNet subnet);
|
||||
static void Ban(const CNetAddr &ip, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
||||
static void Ban(const CSubNet &subNet, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
||||
static void Ban(const CNetAddr &ip, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
||||
static void Ban(const CSubNet &subNet, const BanReason& reason, int64_t bantimeoffset = 0, bool sinceUnixEpoch = false);
|
||||
static bool Unban(const CNetAddr &ip);
|
||||
static bool Unban(const CSubNet &ip);
|
||||
static void GetBanned(std::map<CSubNet, int64_t> &banmap);
|
||||
|
||||
Reference in New Issue
Block a user