<commit_before>/*
* 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
*/

#include <fstream>
#include <openssl/rand.h>
#include "Config.h"
#include "Crypto.h"
#include "Ed25519.h"
#include "Timestamp.h"
#include "I2NPProtocol.h"
#include "NetDb.hpp"
#include "FS.h"
#include "util.h"
#include "version.h"
#include "Log.h"
#include "Family.h"
#include "ECIESX25519AEADRatchetSession.h"
#include "RouterContext.h"

namespace i2p
{
	RouterContext context;

	RouterContext::RouterContext ():
		m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
		m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
		m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID)
	{
	}

	void RouterContext::Init ()
	{
		srand (i2p::util::GetMillisecondsSinceEpoch () % 1000);
		m_StartupTime = std::chrono::steady_clock::now();

		if (!Load ())
			CreateNewRouter ();
		m_Decryptor = m_Keys.CreateDecryptor (nullptr);
		m_TunnelDecryptor = m_Keys.CreateDecryptor (nullptr);
		UpdateRouterInfo ();
		i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ());
		m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState);
	}

	void RouterContext::CreateNewRouter ()
	{
		m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
			i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
		SaveKeys ();
		NewRouterInfo ();
	}

	void RouterContext::NewRouterInfo ()
	{
		i2p::data::LocalRouterInfo routerInfo;
		routerInfo.SetRouterIdentity (GetIdentity ());
		uint16_t port; i2p::config::GetOption("port", port);
		if (!port)
		{
			port = rand () % (30777 - 9111) + 9111; // I2P network ports range
			if (port == 9150) port = 9151; // Tor browser
		}
		bool ipv4;           i2p::config::GetOption("ipv4", ipv4);
		bool ipv6;           i2p::config::GetOption("ipv6", ipv6);
		bool ssu;            i2p::config::GetOption("ssu", ssu);
		bool ntcp2;          i2p::config::GetOption("ntcp2.enabled", ntcp2);
		bool ssu2;			 i2p::config::GetOption("ssu2.enabled", ssu2);
		bool ygg;            i2p::config::GetOption("meshnets.yggdrasil", ygg);
		bool nat;            i2p::config::GetOption("nat", nat);

		if ((ntcp2 || ygg) && !m_NTCP2Keys)
			NewNTCP2Keys ();
		if (ssu2 && !m_SSU2Keys)
			NewSSU2Keys ();
		bool ntcp2Published = false;
		if (ntcp2)
		{
			i2p::config::GetOption("ntcp2.published", ntcp2Published);
			if (ntcp2Published)
			{
				std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
				if (!ntcp2proxy.empty ()) ntcp2Published = false;
			}
		}
		uint8_t caps = 0, addressCaps = 0;
		if (ipv4)
		{
			std::string host = "127.0.0.1";
			if (!i2p::config::IsDefault("host"))
				i2p::config::GetOption("host", host);
			else if (!nat)
			{
				// we have no NAT so set external address from local address
				std::string address4; i2p::config::GetOption("address4", address4);
				if (!address4.empty ()) host = address4;
			}

			if (ntcp2)
			{
				if (ntcp2Published)
					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v4::from_string (host), port);
				else // add non-published NTCP2 address
				{
					addressCaps = i2p::data::RouterInfo::AddressCaps::eV4;
					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
				}
			}
			if (ssu)
			{
				routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
				caps |= i2p::data::RouterInfo::eReachable; // R
			}
			if (ssu2)
			{
				addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
				routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
			}	
		}
		if (ipv6)
		{
			std::string host = "::1";
			if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only
				i2p::config::GetOption("host", host);
			else
			{
				std::string address6; i2p::config::GetOption("address6", address6);
				if (!address6.empty ()) host = address6;
			}

			if (ntcp2)
			{
				if (ntcp2Published)
				{
					std::string ntcp2Host;
					if (!i2p::config::IsDefault ("ntcp2.addressv6"))
						i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host);
					else
						ntcp2Host = host;
					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (ntcp2Host), port);
				}
				else
				{
					if (!ipv4) // no other ntcp2 addresses yet
						routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
					addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
				}
			}
			if (ssu)
			{
				routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
				caps |= i2p::data::RouterInfo::eReachable; // R
			}
			if (ssu2)
			{
				if (!ipv4) // no other ssu2 addresses yet
					routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
				addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;<commit_msg>create new published SSU2 addresses<commit_after>/*
* 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
*/

#include <fstream>
#include <openssl/rand.h>
#include "Config.h"
#include "Crypto.h"
#include "Ed25519.h"
#include "Timestamp.h"
#include "I2NPProtocol.h"
#include "NetDb.hpp"
#include "FS.h"
#include "util.h"
#include "version.h"
#include "Log.h"
#include "Family.h"
#include "ECIESX25519AEADRatchetSession.h"
#include "RouterContext.h"

namespace i2p
{
	RouterContext context;

	RouterContext::RouterContext ():
		m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
		m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
		m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID)
	{
	}

	void RouterContext::Init ()
	{
		srand (i2p::util::GetMillisecondsSinceEpoch () % 1000);
		m_StartupTime = std::chrono::steady_clock::now();

		if (!Load ())
			CreateNewRouter ();
		m_Decryptor = m_Keys.CreateDecryptor (nullptr);
		m_TunnelDecryptor = m_Keys.CreateDecryptor (nullptr);
		UpdateRouterInfo ();
		i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ());
		m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState);
	}

	void RouterContext::CreateNewRouter ()
	{
		m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
			i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
		SaveKeys ();
		NewRouterInfo ();
	}

	void RouterContext::NewRouterInfo ()
	{
		i2p::data::LocalRouterInfo routerInfo;
		routerInfo.SetRouterIdentity (GetIdentity ());
		uint16_t port; i2p::config::GetOption("port", port);
		if (!port)
		{
			port = rand () % (30777 - 9111) + 9111; // I2P network ports range
			if (port == 9150) port = 9151; // Tor browser
		}
		bool ipv4;           i2p::config::GetOption("ipv4", ipv4);
		bool ipv6;           i2p::config::GetOption("ipv6", ipv6);
		bool ssu;            i2p::config::GetOption("ssu", ssu);
		bool ntcp2;          i2p::config::GetOption("ntcp2.enabled", ntcp2);
		bool ssu2;			 i2p::config::GetOption("ssu2.enabled", ssu2);
		bool ygg;            i2p::config::GetOption("meshnets.yggdrasil", ygg);
		bool nat;            i2p::config::GetOption("nat", nat);

		if ((ntcp2 || ygg) && !m_NTCP2Keys)
			NewNTCP2Keys ();
		if (ssu2 && !m_SSU2Keys)
			NewSSU2Keys ();
		bool ntcp2Published = false;
		if (ntcp2)
		{
			i2p::config::GetOption("ntcp2.published", ntcp2Published);
			if (ntcp2Published)
			{
				std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
				if (!ntcp2proxy.empty ()) ntcp2Published = false;
			}
		}
		bool ssu2Published = false;
		if (ssu2)
			i2p::config::GetOption("ssu2.published", ssu2Published);
		uint8_t caps = 0, addressCaps = 0;
		if (ipv4)
		{
			std::string host = "127.0.0.1";
			if (!i2p::config::IsDefault("host"))
				i2p::config::GetOption("host", host);
			else if (!nat)
			{
				// we have no NAT so set external address from local address
				std::string address4; i2p::config::GetOption("address4", address4);
				if (!address4.empty ()) host = address4;
			}

			if (ntcp2)
			{
				if (ntcp2Published)
					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v4::from_string (host), port);
				else // add non-published NTCP2 address
				{
					addressCaps = i2p::data::RouterInfo::AddressCaps::eV4;
					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
				}
			}
			if (ssu)
			{
				routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
				caps |= i2p::data::RouterInfo::eReachable; // R
			}
			if (ssu2)
			{
				if (ssu2Published)
					routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port);
				else
				{	
					addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
					routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
				}	
			}	
		}
		if (ipv6)
		{
			std::string host = "::1";
			if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only
				i2p::config::GetOption("host", host);
			else
			{
				std::string address6; i2p::config::GetOption("address6", address6);
				if (!address6.empty ()) host = address6;
			}

			if (ntcp2)
			{
				if (ntcp2Published)
				{
					std::string ntcp2Host;
					if (!i2p::config::IsDefault ("ntcp2.addressv6"))
						i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host);
					else
						ntcp2Host = host;
					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (ntcp2Host), port);
				}
				else
				{
					if (!ipv4) // no other ntcp2 addresses yet
						routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
					addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
				}
			}
			if (ssu)
			{
				routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
				caps |= i2p::data::RouterInfo::eReachable; // R
			}
			if (ssu2)
			{
				if (ssu2Published)
					routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port);
				else
				{	
					if (!ipv4) // no other ssu2 addresses yet
						routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
					addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
				}	
{'fraction_non_alphanumeric': 0.15109137295662856, 'fraction_numerical': 0.03855239535103468, 'mean_word_length': 4.147859922178989, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, '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': '5686722', 'n_tokens_mistral': 4722, 'n_tokens_neox': 4033, 'n_words': 722}