<commit_before>/*
* Copyright (c) 2013-2021, 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_INFO_H__
#define ROUTER_INFO_H__

#include <inttypes.h>
#include <string>
#include <map>
#include <vector>
#include <list>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include "Identity.h"
#include "Profiling.h"

namespace i2p
{
namespace data
{
	const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
	const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
	const char ROUTER_INFO_PROPERTY_NETID[] = "netId";
	const char ROUTER_INFO_PROPERTY_VERSION[] = "router.version";
	const char ROUTER_INFO_PROPERTY_FAMILY[] = "family";
	const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig";

	const char CAPS_FLAG_FLOODFILL = 'f';
	const char CAPS_FLAG_HIDDEN = 'H';
	const char CAPS_FLAG_REACHABLE = 'R';
	const char CAPS_FLAG_UNREACHABLE = 'U';
	/* bandwidth flags */
	const char CAPS_FLAG_LOW_BANDWIDTH1   = 'K'; /*   < 12 KBps */
	const char CAPS_FLAG_LOW_BANDWIDTH2   = 'L'; /*  12-48 KBps */
	const char CAPS_FLAG_HIGH_BANDWIDTH1  = 'M'; /*  48-64 KBps */
	const char CAPS_FLAG_HIGH_BANDWIDTH2  = 'N'; /*  64-128 KBps */
	const char CAPS_FLAG_HIGH_BANDWIDTH3  = 'O'; /* 128-256 KBps */
	const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */
	const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /*   > 2000 KBps */

	const char CAPS_FLAG_V4 = '4';
	const char CAPS_FLAG_V6 = '6';
	const char CAPS_FLAG_SSU_TESTING = 'B';
	const char CAPS_FLAG_SSU_INTRODUCER = 'C';

	const uint8_t COST_NTCP2_PUBLISHED = 3;
	const uint8_t COST_NTCP2_NON_PUBLISHED = 14;
	const uint8_t COST_SSU_DIRECT = 9;
	const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
	
	const int MAX_RI_BUFFER_SIZE = 2048; // if RouterInfo exceeds 2048 we consider it as malformed, might be changed later
	class RouterInfo: public RoutingDestination
	{
		public:

			enum SupportedTranports
			{
				eNTCP2V4 = 0x01,
				eNTCP2V6 = 0x02,
				eSSUV4 = 0x04,
				eSSUV6 = 0x08,
				eNTCP2V6Mesh = 0x10	
			};

			enum Caps
			{
				eFloodfill = 0x01,
				eHighBandwidth = 0x02,
				eExtraBandwidth = 0x04,
				eReachable = 0x08,
				eHidden = 0x10,
				eUnreachable = 0x20
			};

			enum AddressCaps
			{
				eV4 = 0x01,
				eV6 = 0x02,
				eSSUTesting = 0x04,
				eSSUIntroducer = 0x08
			};
		
			enum TransportStyle
			{
				eTransportUnknown = 0,
				eTransportNTCP,
				eTransportSSU
			};

			typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
			struct Introducer
			{
				Introducer (): iExp (0) {};
				boost::asio::ip::address iHost;
				int iPort;
				IntroKey iKey;
				uint32_t iTag;
				uint32_t iExp;
			};

			struct SSUExt
			{
				int mtu;
				IntroKey key; // intro key for SSU
				std::vector<Introducer> introducers;
			};

			struct NTCP2Ext
			{
				Tag<32> staticKey;
				Tag<16> iv;
				bool isPublished = false;
			};

			struct Address
			{
				TransportStyle transportStyle;
				boost::asio::ip::address host;
				int port;
				uint64_t date;
				uint8_t cost, caps;
				std::unique_ptr<SSUExt> ssu; // not null for SSU
				std::unique_ptr<NTCP2Ext> ntcp2; // not null for NTCP2

				bool IsCompatible (const boost::asio::ip::address& other) const
				{
					return (IsV4 () && other.is_v4 ()) ||
						(IsV6 () && other.is_v6 ());
				}

				bool operator==(const Address& other) const
				{
					return transportStyle == other.transportStyle && IsNTCP2 () == other.IsNTCP2 () &&
						host == other.host && port == other.port;
				}

				bool operator!=(const Address& other) const
				{
					return !(*this == other);
				}

				bool IsNTCP2 () const { return (bool)ntcp2; };
				bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; };
				bool IsReachableSSU () const { return (bool)ssu && (!host.is_unspecified () || !ssu->introducers.empty ()); };
				bool UsesIntroducer () const { return  (bool)ssu && !ssu->introducers.empty (); };
				
				bool IsIntroducer () const { return caps & eSSUIntroducer; };
				bool IsPeerTesting () const { return caps & eSSUTesting; };

				bool IsV4 () const { return (caps & AddressCaps::eV4) || host.is_v4 (); };
				bool IsV6 () const { return (caps & AddressCaps::eV6) || host.is_v6 (); };
			};
			typedef std::list<std::shared_ptr<Address> > Addresses;

			RouterInfo ();
			RouterInfo (const std::string& fullPath);
			RouterInfo (const RouterInfo& ) = default;
			RouterInfo& operator=(const RouterInfo& ) = default;
			RouterInfo (const uint8_t * buf, int len);
			~RouterInfo ();

			std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
			void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
			std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
			uint64_t GetTimestamp () const { return m_Timestamp; };<commit_msg>check if host if unspecified<commit_after>/*
* Copyright (c) 2013-2021, 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_INFO_H__
#define ROUTER_INFO_H__

#include <inttypes.h>
#include <string>
#include <map>
#include <vector>
#include <list>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include "Identity.h"
#include "Profiling.h"

namespace i2p
{
namespace data
{
	const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
	const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
	const char ROUTER_INFO_PROPERTY_NETID[] = "netId";
	const char ROUTER_INFO_PROPERTY_VERSION[] = "router.version";
	const char ROUTER_INFO_PROPERTY_FAMILY[] = "family";
	const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig";

	const char CAPS_FLAG_FLOODFILL = 'f';
	const char CAPS_FLAG_HIDDEN = 'H';
	const char CAPS_FLAG_REACHABLE = 'R';
	const char CAPS_FLAG_UNREACHABLE = 'U';
	/* bandwidth flags */
	const char CAPS_FLAG_LOW_BANDWIDTH1   = 'K'; /*   < 12 KBps */
	const char CAPS_FLAG_LOW_BANDWIDTH2   = 'L'; /*  12-48 KBps */
	const char CAPS_FLAG_HIGH_BANDWIDTH1  = 'M'; /*  48-64 KBps */
	const char CAPS_FLAG_HIGH_BANDWIDTH2  = 'N'; /*  64-128 KBps */
	const char CAPS_FLAG_HIGH_BANDWIDTH3  = 'O'; /* 128-256 KBps */
	const char CAPS_FLAG_EXTRA_BANDWIDTH1 = 'P'; /* 256-2000 KBps */
	const char CAPS_FLAG_EXTRA_BANDWIDTH2 = 'X'; /*   > 2000 KBps */

	const char CAPS_FLAG_V4 = '4';
	const char CAPS_FLAG_V6 = '6';
	const char CAPS_FLAG_SSU_TESTING = 'B';
	const char CAPS_FLAG_SSU_INTRODUCER = 'C';

	const uint8_t COST_NTCP2_PUBLISHED = 3;
	const uint8_t COST_NTCP2_NON_PUBLISHED = 14;
	const uint8_t COST_SSU_DIRECT = 9;
	const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
	
	const int MAX_RI_BUFFER_SIZE = 2048; // if RouterInfo exceeds 2048 we consider it as malformed, might be changed later
	class RouterInfo: public RoutingDestination
	{
		public:

			enum SupportedTranports
			{
				eNTCP2V4 = 0x01,
				eNTCP2V6 = 0x02,
				eSSUV4 = 0x04,
				eSSUV6 = 0x08,
				eNTCP2V6Mesh = 0x10	
			};

			enum Caps
			{
				eFloodfill = 0x01,
				eHighBandwidth = 0x02,
				eExtraBandwidth = 0x04,
				eReachable = 0x08,
				eHidden = 0x10,
				eUnreachable = 0x20
			};

			enum AddressCaps
			{
				eV4 = 0x01,
				eV6 = 0x02,
				eSSUTesting = 0x04,
				eSSUIntroducer = 0x08
			};
		
			enum TransportStyle
			{
				eTransportUnknown = 0,
				eTransportNTCP,
				eTransportSSU
			};

			typedef Tag<32> IntroKey; // should be castable to MacKey and AESKey
			struct Introducer
			{
				Introducer (): iExp (0) {};
				boost::asio::ip::address iHost;
				int iPort;
				IntroKey iKey;
				uint32_t iTag;
				uint32_t iExp;
			};

			struct SSUExt
			{
				int mtu;
				IntroKey key; // intro key for SSU
				std::vector<Introducer> introducers;
			};

			struct NTCP2Ext
			{
				Tag<32> staticKey;
				Tag<16> iv;
				bool isPublished = false;
			};

			struct Address
			{
				TransportStyle transportStyle;
				boost::asio::ip::address host;
				int port;
				uint64_t date;
				uint8_t cost, caps;
				std::unique_ptr<SSUExt> ssu; // not null for SSU
				std::unique_ptr<NTCP2Ext> ntcp2; // not null for NTCP2

				bool IsCompatible (const boost::asio::ip::address& other) const
				{
					return (IsV4 () && other.is_v4 ()) ||
						(IsV6 () && other.is_v6 ());
				}

				bool operator==(const Address& other) const
				{
					return transportStyle == other.transportStyle && IsNTCP2 () == other.IsNTCP2 () &&
						host == other.host && port == other.port;
				}

				bool operator!=(const Address& other) const
				{
					return !(*this == other);
				}

				bool IsNTCP2 () const { return (bool)ntcp2; };
				bool IsPublishedNTCP2 () const { return IsNTCP2 () && ntcp2->isPublished; };
				bool IsReachableSSU () const { return (bool)ssu && (!host.is_unspecified () || !ssu->introducers.empty ()); };
				bool UsesIntroducer () const { return  (bool)ssu && !ssu->introducers.empty (); };
				
				bool IsIntroducer () const { return caps & eSSUIntroducer; };
				bool IsPeerTesting () const { return caps & eSSUTesting; };

				bool IsV4 () const { return (caps & AddressCaps::eV4) || (host.is_v4 () && !host.is_unspecified ()); };
				bool IsV6 () const { return (caps & AddressCaps::eV6) || (host.is_v6 () && !host.is_unspecified ()); };
			};
			typedef std::list<std::shared_ptr<Address> > Addresses;

			RouterInfo ();
			RouterInfo (const std::string& fullPath);
			RouterInfo (const RouterInfo& ) = default;
			RouterInfo& operator=(const RouterInfo& ) = default;
			RouterInfo (const uint8_t * buf, int len);
			~RouterInfo ();

			std::shared_ptr<const IdentityEx> GetRouterIdentity () const { return m_RouterIdentity; };
			void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
			std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
			uint64_t GetTimestamp () const { return m_Timestamp; };
{'fraction_non_alphanumeric': 0.11968377864505153, 'fraction_numerical': 0.03462423696587611, 'mean_word_length': 3.5201266395296247, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1264242', 'n_tokens_mistral': 4503, 'n_tokens_neox': 3668, 'n_words': 882}