BIP155 (addrv2)

Tor v3 + i2p
This commit is contained in:
zanzibar
2023-01-06 15:21:08 +00:00
parent fe9f1ef9e4
commit 512da314a5
108 changed files with 8214 additions and 2173 deletions

140
src/net.h
View File

@@ -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);