mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-30 12:47:48 +02:00
283 lines
9.2 KiB
C++
283 lines
9.2 KiB
C++
/*
|
|
* Copyright (c) 2013-2022, The PurpleI2P Project
|
|
*
|
|
* This file is part of Purple i2pd project and licensed under BSD3
|
|
*
|
|
* See full license text in LICENSE file at top of project tree
|
|
*/
|
|
|
|
#ifndef ROUTER_CONTEXT_H__
|
|
#define ROUTER_CONTEXT_H__
|
|
|
|
#include <inttypes.h>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <chrono>
|
|
#include <boost/asio.hpp>
|
|
#include "Identity.h"
|
|
#include "RouterInfo.h"
|
|
#include "Garlic.h"
|
|
|
|
namespace i2p {
|
|
namespace garlic {
|
|
class RouterIncomingRatchetSession;
|
|
}
|
|
|
|
const char ROUTER_INFO[] = "router.info";
|
|
const char ROUTER_KEYS[] = "router.keys";
|
|
const char NTCP2_KEYS[] = "ntcp2.keys";
|
|
const char SSU2_KEYS[] = "ssu2.keys";
|
|
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
|
|
|
enum RouterStatus {
|
|
eRouterStatusOK = 0,
|
|
eRouterStatusTesting = 1,
|
|
eRouterStatusFirewalled = 2,
|
|
eRouterStatusError = 3,
|
|
eRouterStatusUnknown = 4,
|
|
eRouterStatusProxy = 5,
|
|
eRouterStatusMesh = 6
|
|
};
|
|
|
|
enum RouterError {
|
|
eRouterErrorNone = 0,
|
|
eRouterErrorClockSkew = 1,
|
|
eRouterErrorOffline = 2,
|
|
eRouterErrorSymmetricNAT = 3
|
|
};
|
|
|
|
class RouterContext : public i2p::garlic::GarlicDestination {
|
|
private:
|
|
|
|
struct NTCP2PrivateKeys {
|
|
uint8_t staticPublicKey[32];
|
|
uint8_t staticPrivateKey[32];
|
|
uint8_t iv[16];
|
|
};
|
|
|
|
struct SSU2PrivateKeys {
|
|
uint8_t staticPublicKey[32];
|
|
uint8_t staticPrivateKey[32];
|
|
uint8_t intro[32];
|
|
};
|
|
|
|
public:
|
|
|
|
RouterContext();
|
|
|
|
void Init();
|
|
|
|
const i2p::data::PrivateKeys &GetPrivateKeys() const { return m_Keys; };
|
|
|
|
i2p::data::LocalRouterInfo &GetRouterInfo() { return m_RouterInfo; };
|
|
|
|
std::shared_ptr<i2p::data::RouterInfo> GetSharedRouterInfo() {
|
|
return std::shared_ptr<i2p::data::RouterInfo>(&m_RouterInfo,
|
|
[](i2p::data::RouterInfo *) {});
|
|
}
|
|
|
|
std::shared_ptr<i2p::garlic::GarlicDestination> GetSharedDestination() {
|
|
return std::shared_ptr<i2p::garlic::GarlicDestination>(this,
|
|
[](i2p::garlic::GarlicDestination *) {});
|
|
}
|
|
|
|
const uint8_t *GetNTCP2StaticPublicKey() const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
|
|
|
|
const uint8_t *GetNTCP2StaticPrivateKey() const {
|
|
return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr;
|
|
};
|
|
|
|
const uint8_t *GetNTCP2IV() const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
|
|
|
|
i2p::crypto::X25519Keys &GetNTCP2StaticKeys();
|
|
|
|
const uint8_t *GetSSU2StaticPublicKey() const { return m_SSU2Keys ? m_SSU2Keys->staticPublicKey : nullptr; };
|
|
|
|
const uint8_t *GetSSU2StaticPrivateKey() const { return m_SSU2Keys ? m_SSU2Keys->staticPrivateKey : nullptr; };
|
|
|
|
const uint8_t *GetSSU2IntroKey() const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; };
|
|
|
|
i2p::crypto::X25519Keys &GetSSU2StaticKeys();
|
|
|
|
uint32_t GetUptime() const; // in seconds
|
|
uint64_t GetLastUpdateTime() const { return m_LastUpdateTime; };
|
|
|
|
uint64_t GetBandwidthLimit() const { return m_BandwidthLimit; };
|
|
|
|
uint64_t GetTransitBandwidthLimit() const { return (m_BandwidthLimit * m_ShareRatio) / 100LL; };
|
|
|
|
RouterStatus GetStatus() const { return m_Status; };
|
|
|
|
void SetStatus(RouterStatus status);
|
|
|
|
void SetStatusSSU2(RouterStatus status);
|
|
|
|
RouterError GetError() const { return m_Error; };
|
|
|
|
void SetError(RouterError error) {
|
|
m_Status = eRouterStatusError;
|
|
m_Error = error;
|
|
};
|
|
|
|
RouterStatus GetStatusV6() const { return m_StatusV6; };
|
|
|
|
void SetStatusV6(RouterStatus status);
|
|
|
|
void SetStatusV6SSU2(RouterStatus status);
|
|
|
|
RouterError GetErrorV6() const { return m_ErrorV6; };
|
|
|
|
void SetErrorV6(RouterError error) {
|
|
m_StatusV6 = eRouterStatusError;
|
|
m_ErrorV6 = error;
|
|
};
|
|
|
|
int GetNetID() const { return m_NetID; };
|
|
|
|
void SetNetID(int netID) { m_NetID = netID; };
|
|
|
|
bool DecryptTunnelBuildRecord(const uint8_t *encrypted, uint8_t *data);
|
|
|
|
bool DecryptTunnelShortRequestRecord(const uint8_t *encrypted, uint8_t *data);
|
|
|
|
void UpdatePort(int port); // called from Daemon
|
|
void UpdateAddress(const boost::asio::ip::address &host); // called from SSU or Daemon
|
|
void PublishNTCP2Address(int port, bool publish, bool v4, bool v6, bool ygg);
|
|
|
|
void UpdateNTCP2Address(bool enable);
|
|
|
|
void PublishSSU2Address(int port, bool publish, bool v4, bool v6);
|
|
|
|
void UpdateSSU2Address(bool enable);
|
|
|
|
void RemoveNTCPAddress(bool v4only = true); // delete NTCP address for older routers. TODO: remove later
|
|
void RemoveSSUAddress(); // delete SSU address for older routers
|
|
bool AddIntroducer(const i2p::data::RouterInfo::Introducer &introducer);
|
|
|
|
void RemoveIntroducer(const boost::asio::ip::udp::endpoint &e);
|
|
|
|
bool AddSSU2Introducer(const i2p::data::RouterInfo::Introducer &introducer, bool v4);
|
|
|
|
void RemoveSSU2Introducer(const i2p::data::IdentHash &h, bool v4);
|
|
|
|
void ClearSSU2Introducers(bool v4);
|
|
|
|
bool IsUnreachable() const;
|
|
|
|
void SetUnreachable(bool v4, bool v6);
|
|
|
|
void SetUnreachableSSU2(bool v4, bool v6);
|
|
|
|
void SetReachable(bool v4, bool v6);
|
|
|
|
bool IsFloodfill() const { return m_IsFloodfill; };
|
|
|
|
void SetFloodfill(bool floodfill);
|
|
|
|
void SetFamily(const std::string &family);
|
|
|
|
std::string GetFamily() const;
|
|
|
|
void SetBandwidth(int limit); /* in kilobytes */
|
|
void SetBandwidth(char L); /* by letter */
|
|
void SetShareRatio(int percents); // 0 - 100
|
|
bool AcceptsTunnels() const { return m_AcceptsTunnels; };
|
|
|
|
void SetAcceptsTunnels(bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; };
|
|
|
|
bool SupportsV6() const { return m_RouterInfo.IsV6(); };
|
|
|
|
bool SupportsV4() const { return m_RouterInfo.IsV4(); };
|
|
|
|
bool SupportsMesh() const { return m_RouterInfo.IsMesh(); };
|
|
|
|
void SetSupportsV6(bool supportsV6);
|
|
|
|
void SetSupportsV4(bool supportsV4);
|
|
|
|
void SetSupportsMesh(bool supportsmesh, const boost::asio::ip::address_v6 &host);
|
|
|
|
void SetMTU(int mtu, bool v4);
|
|
|
|
i2p::crypto::NoiseSymmetricState &GetCurrentNoiseState() { return m_CurrentNoiseState; };
|
|
|
|
void UpdateNTCP2V6Address(const boost::asio::ip::address &host); // called from Daemon. TODO: remove
|
|
void UpdateStats();
|
|
|
|
void UpdateTimestamp(uint64_t ts); // in seconds, called from NetDb before publishing
|
|
void CleanupDestination(); // garlic destination
|
|
|
|
// implements LocalDestination
|
|
std::shared_ptr<const i2p::data::IdentityEx> GetIdentity() const { return m_Keys.GetPublic(); };
|
|
|
|
bool Decrypt(const uint8_t *encrypted, uint8_t *data, i2p::data::CryptoKeyType preferredCrypto) const;
|
|
|
|
void Sign(const uint8_t *buf, int len, uint8_t *signature) const { m_Keys.Sign(buf, len, signature); };
|
|
|
|
void SetLeaseSetUpdated() {};
|
|
|
|
// implements GarlicDestination
|
|
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet() { return nullptr; };
|
|
|
|
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool() const;
|
|
|
|
// override GarlicDestination
|
|
void ProcessGarlicMessage(std::shared_ptr<I2NPMessage> msg);
|
|
|
|
void ProcessDeliveryStatusMessage(std::shared_ptr<I2NPMessage> msg);
|
|
|
|
protected:
|
|
|
|
// implements GarlicDestination
|
|
void HandleI2NPMessage(const uint8_t *buf, size_t len);
|
|
|
|
bool HandleCloveI2NPMessage(I2NPMessageType typeID, const uint8_t *payload, size_t len, uint32_t msgID);
|
|
|
|
private:
|
|
|
|
void CreateNewRouter();
|
|
|
|
void NewRouterInfo();
|
|
|
|
void UpdateRouterInfo();
|
|
|
|
void NewNTCP2Keys();
|
|
|
|
void NewSSU2Keys();
|
|
|
|
bool IsSSU2Only() const; // SSU2 and no SSU
|
|
bool Load();
|
|
|
|
void SaveKeys();
|
|
|
|
uint16_t SelectRandomPort() const;
|
|
|
|
bool DecryptECIESTunnelBuildRecord(const uint8_t *encrypted, uint8_t *data, size_t clearTextSize);
|
|
|
|
private:
|
|
|
|
i2p::data::LocalRouterInfo m_RouterInfo;
|
|
i2p::data::PrivateKeys m_Keys;
|
|
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor, m_TunnelDecryptor;
|
|
std::shared_ptr<i2p::garlic::RouterIncomingRatchetSession> m_ECIESSession;
|
|
uint64_t m_LastUpdateTime; // in seconds
|
|
bool m_AcceptsTunnels, m_IsFloodfill;
|
|
std::chrono::time_point<std::chrono::steady_clock> m_StartupTime;
|
|
uint64_t m_BandwidthLimit; // allowed bandwidth
|
|
int m_ShareRatio;
|
|
RouterStatus m_Status, m_StatusV6;
|
|
RouterError m_Error, m_ErrorV6;
|
|
int m_NetID;
|
|
std::mutex m_GarlicMutex;
|
|
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
|
std::unique_ptr<SSU2PrivateKeys> m_SSU2Keys;
|
|
std::unique_ptr<i2p::crypto::X25519Keys> m_NTCP2StaticKeys, m_SSU2StaticKeys;
|
|
// for ECIESx25519
|
|
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
|
|
};
|
|
|
|
extern RouterContext context;
|
|
}
|
|
|
|
#endif
|