1 /*
2 * Copyright (c) 2013-2021, The PurpleI2P Project
3 *
4 * This file is part of Purple i2pd project and licensed under BSD3
5 *
6 * See full license text in LICENSE file at top of project tree
7 */
8 
9 #include <fstream>
10 #include <openssl/rand.h>
11 #include "Config.h"
12 #include "Crypto.h"
13 #include "Ed25519.h"
14 #include "Timestamp.h"
15 #include "I2NPProtocol.h"
16 #include "NetDb.hpp"
17 #include "FS.h"
18 #include "util.h"
19 #include "version.h"
20 #include "Log.h"
21 #include "Family.h"
22 #include "ECIESX25519AEADRatchetSession.h"
23 #include "RouterContext.h"
24 
25 namespace i2p
26 {
27 	RouterContext context;
28 
RouterContext()29 	RouterContext::RouterContext ():
30 		m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
31 		m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
32 		m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID)
33 	{
34 	}
35 
Init()36 	void RouterContext::Init ()
37 	{
38 		srand (i2p::util::GetMillisecondsSinceEpoch () % 1000);
39 		m_StartupTime = std::chrono::steady_clock::now();
40 
41 		if (!Load ())
42 			CreateNewRouter ();
43 		m_Decryptor = m_Keys.CreateDecryptor (nullptr);
44 		m_TunnelDecryptor = m_Keys.CreateDecryptor (nullptr);
45 		UpdateRouterInfo ();
46 		i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ());
47 		m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState);
48 	}
49 
CreateNewRouter()50 	void RouterContext::CreateNewRouter ()
51 	{
52 		m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
53 			i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
54 		SaveKeys ();
55 		NewRouterInfo ();
56 	}
57 
NewRouterInfo()58 	void RouterContext::NewRouterInfo ()
59 	{
60 		i2p::data::RouterInfo routerInfo;
61 		routerInfo.SetRouterIdentity (GetIdentity ());
62 		uint16_t port; i2p::config::GetOption("port", port);
63 		if (!port)
64 		{
65 			port = rand () % (30777 - 9111) + 9111; // I2P network ports range
66 			if (port == 9150) port = 9151; // Tor browser
67 		}
68 		bool ipv4;           i2p::config::GetOption("ipv4", ipv4);
69 		bool ipv6;           i2p::config::GetOption("ipv6", ipv6);
70 		bool ssu;            i2p::config::GetOption("ssu", ssu);
71 		bool ntcp2;          i2p::config::GetOption("ntcp2.enabled", ntcp2);
72 		bool ygg;            i2p::config::GetOption("meshnets.yggdrasil", ygg);
73 		bool nat;            i2p::config::GetOption("nat", nat);
74 
75 		if ((ntcp2 || ygg) && !m_NTCP2Keys)
76 			NewNTCP2Keys ();
77 		bool ntcp2Published = false;
78 		if (ntcp2)
79 		{
80 			i2p::config::GetOption("ntcp2.published", ntcp2Published);
81 			if (ntcp2Published)
82 			{
83 				std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy);
84 				if (!ntcp2proxy.empty ()) ntcp2Published = false;
85 			}
86 		}
87 		uint8_t caps = 0, addressCaps = 0;
88 		if (ipv4)
89 		{
90 			std::string host = "127.0.0.1";
91 			if (!i2p::config::IsDefault("host"))
92 				i2p::config::GetOption("host", host);
93 			else if (!nat)
94 			{
95 				// we have no NAT so set external address from local address
96 				std::string address4; i2p::config::GetOption("address4", address4);
97 				if (!address4.empty ()) host = address4;
98 			}
99 
100 			if (ntcp2)
101 			{
102 				if (ntcp2Published)
103 					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v4::from_string (host), port);
104 				else // add non-published NTCP2 address
105 				{
106 					addressCaps = i2p::data::RouterInfo::AddressCaps::eV4;
107 					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
108 				}
109 			}
110 			if (ssu)
111 			{
112 				routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
113 				caps |= i2p::data::RouterInfo::eReachable; // R
114 			}
115 		}
116 		if (ipv6)
117 		{
118 			std::string host = "::1";
119 			if (!i2p::config::IsDefault("host") && !ipv4) // override if v6 only
120 				i2p::config::GetOption("host", host);
121 			else
122 			{
123 				std::string address6; i2p::config::GetOption("address6", address6);
124 				if (!address6.empty ()) host = address6;
125 			}
126 
127 			if (ntcp2)
128 			{
129 				if (ntcp2Published)
130 				{
131 					std::string ntcp2Host;
132 					if (!i2p::config::IsDefault ("ntcp2.addressv6"))
133 						i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host);
134 					else
135 						ntcp2Host = host;
136 					routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address_v6::from_string (ntcp2Host), port);
137 				}
138 				else
139 				{
140 					if (!ipv4) // no other ntcp2 addresses yet
141 						routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
142 					addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
143 				}
144 			}
145 			if (ssu)
146 			{
147 				routerInfo.AddSSUAddress (host.c_str(), port, nullptr);
148 				caps |= i2p::data::RouterInfo::eReachable; // R
149 			}
150 		}
151 		if (ygg)
152 		{
153 			auto yggaddr = i2p::util::net::GetYggdrasilAddress ();
154 			if (!yggaddr.is_unspecified ())
155 				routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port);
156 		}
157 
158 		if (addressCaps)
159 			routerInfo.SetUnreachableAddressesTransportCaps (addressCaps);
160 		routerInfo.SetCaps (caps); // caps + L
161 		routerInfo.SetProperty ("netId", std::to_string (m_NetID));
162 		routerInfo.SetProperty ("router.version", I2P_VERSION);
163 		routerInfo.CreateBuffer (m_Keys);
164 		m_RouterInfo.SetRouterIdentity (GetIdentity ());
165 		m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ());
166 	}
167 
UpdateRouterInfo()168 	void RouterContext::UpdateRouterInfo ()
169 	{
170 		m_RouterInfo.CreateBuffer (m_Keys);
171 		m_RouterInfo.SaveToFile (i2p::fs::DataDirPath (ROUTER_INFO));
172 		m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch ();
173 	}
174 
NewNTCP2Keys()175 	void RouterContext::NewNTCP2Keys ()
176 	{
177 		m_StaticKeys.reset (new i2p::crypto::X25519Keys ());
178 		m_StaticKeys->GenerateKeys ();
179 		m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
180 		m_StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey);
181 		memcpy (m_NTCP2Keys->staticPublicKey, m_StaticKeys->GetPublicKey (), 32);
182 		RAND_bytes (m_NTCP2Keys->iv, 16);
183 		// save
184 		std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out);
185 		fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
186 	}
187 
SetStatus(RouterStatus status)188 	void RouterContext::SetStatus (RouterStatus status)
189 	{
190 		if (status != m_Status)
191 		{
192 			m_Status = status;
193 			m_Error = eRouterErrorNone;
194 			switch (m_Status)
195 			{
196 				case eRouterStatusOK:
197 					SetReachable (true, false); // ipv4
198 				break;
199 				case eRouterStatusFirewalled:
200 					SetUnreachable (true, false); // ipv4
201 				break;
202 				default:
203 					;
204 			}
205 		}
206 	}
207 
SetStatusV6(RouterStatus status)208 	void RouterContext::SetStatusV6 (RouterStatus status)
209 	{
210 		if (status != m_StatusV6)
211 		{
212 			m_StatusV6 = status;
213 			switch (m_StatusV6)
214 			{
215 				case eRouterStatusOK:
216 					SetReachable (false, true); // ipv6
217 				break;
218 				case eRouterStatusFirewalled:
219 					SetUnreachable (false, true); // ipv6
220 				break;
221 				default:
222 					;
223 			}
224 		}
225 	}
226 
UpdatePort(int port)227 	void RouterContext::UpdatePort (int port)
228 	{
229 		bool updated = false;
230 		for (auto& address : m_RouterInfo.GetAddresses ())
231 		{
232 			if (!address->IsNTCP2 () && address->port != port)
233 			{
234 				address->port = port;
235 				updated = true;
236 			}
237 		}
238 		if (updated)
239 			UpdateRouterInfo ();
240 	}
241 
PublishNTCP2Address(int port,bool publish,bool v4,bool v6,bool ygg)242 	void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg)
243 	{
244 		if (!m_NTCP2Keys) return;
245 		bool updated = false;
246 		for (auto& address : m_RouterInfo.GetAddresses ())
247 		{
248 			if (address->IsNTCP2 () && (address->port != port || address->published != publish))
249 			{
250 				bool isAddr = v4 && address->IsV4 ();
251 				if (!isAddr && (v6 || ygg))
252 				{
253 					if (i2p::util::net::IsYggdrasilAddress (address->host))
254 						isAddr = ygg;
255 					else
256 						isAddr = v6 && address->IsV6 ();
257 				}
258 				if (isAddr)
259 				{
260 					if (!port && !address->port)
261 					{
262 						// select random port only if address's port is not set
263 						port = rand () % (30777 - 9111) + 9111; // I2P network ports range
264 						if (port == 9150) port = 9151; // Tor browser
265 					}
266 					if (port) address->port = port;
267 					address->published = publish;
268 					address->ntcp2->iv = m_NTCP2Keys->iv;
269 					updated = true;
270 				}
271 			}
272 		}
273 		if (updated)
274 			UpdateRouterInfo ();
275 	}
276 
UpdateNTCP2Address(bool enable)277 	void RouterContext::UpdateNTCP2Address (bool enable)
278 	{
279 		auto& addresses = m_RouterInfo.GetAddresses ();
280 		bool found = false, updated = false;
281 		for (auto it = addresses.begin (); it != addresses.end (); ++it)
282 		{
283 			if ((*it)->IsNTCP2 ())
284 			{
285 				found = true;
286 				if (!enable)
287 				{
288 					addresses.erase (it);
289 					updated= true;
290 				}
291 				break;
292 			}
293 		}
294 		if (enable && !found)
295 		{
296 			m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv);
297 			updated = true;
298 		}
299 		if (updated)
300 			UpdateRouterInfo ();
301 	}
302 
UpdateAddress(const boost::asio::ip::address & host)303 	void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
304 	{
305 		bool updated = false;
306 		for (auto& address : m_RouterInfo.GetAddresses ())
307 		{
308 			if (address->host != host && address->IsCompatible (host) &&
309 			    !i2p::util::net::IsYggdrasilAddress (address->host))
310 			{
311 				address->host = host;
312 				if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU)
313 				{
314 					// update MTU
315 					auto mtu = i2p::util::net::GetMTU (host);
316 					if (mtu)
317 					{
318 						LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu);
319 						if (mtu > 1472) { // TODO: magic constant
320 							mtu = 1472;
321 							LogPrint(eLogWarning, "Router: MTU dropped to upper limit of 1472 bytes");
322 						}
323 						if (address->ssu) address->ssu->mtu = mtu;
324 					}
325 				}
326 				updated = true;
327 			}
328 		}
329 		auto ts = i2p::util::GetSecondsSinceEpoch ();
330 		if (updated || ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL)
331 			UpdateRouterInfo ();
332 	}
333 
AddIntroducer(const i2p::data::RouterInfo::Introducer & introducer)334 	bool RouterContext::AddIntroducer (const i2p::data::RouterInfo::Introducer& introducer)
335 	{
336 		bool ret = m_RouterInfo.AddIntroducer (introducer);
337 		if (ret)
338 			UpdateRouterInfo ();
339 		return ret;
340 	}
341 
RemoveIntroducer(const boost::asio::ip::udp::endpoint & e)342 	void RouterContext::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
343 	{
344 		if (m_RouterInfo.RemoveIntroducer (e))
345 			UpdateRouterInfo ();
346 	}
347 
SetFloodfill(bool floodfill)348 	void RouterContext::SetFloodfill (bool floodfill)
349 	{
350 		m_IsFloodfill = floodfill;
351 		if (floodfill)
352 			m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eFloodfill);
353 		else
354 		{
355 			m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eFloodfill);
356 			// we don't publish number of routers and leaseset for non-floodfill
357 			m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS);
358 			m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS);
359 		}
360 		UpdateRouterInfo ();
361 	}
362 
GetFamily() const363 	std::string RouterContext::GetFamily () const
364 	{
365 		return m_RouterInfo.GetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY);
366 	}
367 
SetFamily(const std::string & family)368 	void RouterContext::SetFamily (const std::string& family)
369 	{
370 		std::string signature;
371 		if (family.length () > 0)
372 			signature = i2p::data::CreateFamilySignature (family, GetIdentHash ());
373 		if (signature.length () > 0)
374 		{
375 			m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family);
376 			m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG, signature);
377 		}
378 		else
379 		{
380 			m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY);
381 			m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG);
382 		}
383 	}
384 
SetBandwidth(char L)385 	void RouterContext::SetBandwidth (char L)
386 	{
387 		uint32_t limit = 0;
388 		enum { low, high, extra, unlim } type = high;
389 		/* detect parameters */
390 		switch (L)
391 		{
392 			case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1   : limit =   12; type = low;   break;
393 			case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2   : limit =   48; type = low;   break;
394 			case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH1  : limit =   64; type = high;  break;
395 			case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH2  : limit =  128; type = high;  break;
396 			case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH3  : limit =  256; type = high;  break;
397 			case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = 2048; type = extra; break;
398 			case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 1000000; type = unlim; break; // 1Gbyte/s
399 			default:
400 				limit = 48; type = low;
401 		}
402 		/* update caps & flags in RI */
403 		auto caps = m_RouterInfo.GetCaps ();
404 		caps &= ~i2p::data::RouterInfo::eHighBandwidth;
405 		caps &= ~i2p::data::RouterInfo::eExtraBandwidth;
406 		switch (type)
407 		{
408 			case low   : /* not set */; break;
409 			case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P'
410 			case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth;
411 #if (__cplusplus >= 201703L) // C++ 17 or higher
412 			[[fallthrough]];
413 #endif
414 			// no break here, extra + high means 'X'
415 			case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break;
416 		}
417 		m_RouterInfo.SetCaps (caps);
418 		UpdateRouterInfo ();
419 		m_BandwidthLimit = limit;
420 	}
421 
SetBandwidth(int limit)422 	void RouterContext::SetBandwidth (int limit)
423 	{
424 		if      (limit > 2000) { SetBandwidth('X'); }
425 		else if (limit >  256) { SetBandwidth('P'); }
426 		else if (limit >  128) { SetBandwidth('O'); }
427 		else if (limit >   64) { SetBandwidth('N'); }
428 		else if (limit >   48) { SetBandwidth('M'); }
429 		else if (limit >   12) { SetBandwidth('L'); }
430 		else                   { SetBandwidth('K'); }
431 		m_BandwidthLimit = limit; // set precise limit
432 	}
433 
SetShareRatio(int percents)434 	void RouterContext::SetShareRatio (int percents)
435 	{
436 		if (percents < 0) percents = 0;
437 		if (percents > 100) percents = 100;
438 		m_ShareRatio = percents;
439 	}
440 
IsUnreachable() const441 	bool RouterContext::IsUnreachable () const
442 	{
443 		return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable;
444 	}
445 
RemoveNTCPAddress(bool v4only)446 	void RouterContext::RemoveNTCPAddress (bool v4only)
447 	{
448 		auto& addresses = m_RouterInfo.GetAddresses ();
449 		for (auto it = addresses.begin (); it != addresses.end ();)
450 		{
451 			if ((*it)->transportStyle == i2p::data::RouterInfo::eTransportNTCP && !(*it)->IsNTCP2 () &&
452 				(!v4only || (*it)->host.is_v4 ()))
453 			{
454 				it = addresses.erase (it);
455 				if (v4only) break; // otherwise might be more than one address
456 			}
457 			else
458 				++it;
459 		}
460 	}
461 
SetUnreachable(bool v4,bool v6)462 	void RouterContext::SetUnreachable (bool v4, bool v6)
463 	{
464 		if (v4 || (v6 && !SupportsV4 ()))
465 		{
466 			// set caps
467 			uint8_t caps = m_RouterInfo.GetCaps ();
468 			caps &= ~i2p::data::RouterInfo::eReachable;
469 			caps |= i2p::data::RouterInfo::eUnreachable;
470 			if (v6 || !SupportsV6 ())
471 				caps &= ~i2p::data::RouterInfo::eFloodfill;	// can't be floodfill
472 			m_RouterInfo.SetCaps (caps);
473 		}
474 		uint16_t port = 0;
475 		// delete previous introducers
476 		auto& addresses = m_RouterInfo.GetAddresses ();
477 		for (auto& addr : addresses)
478 			if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
479 			{
480 				addr->published = false;
481 				addr->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; // can't be introducer
482 				addr->ssu->introducers.clear ();
483 				port = addr->port;
484 			}
485 		// unpublish NTCP2 addreeses
486 		bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
487 		if (ntcp2)
488 			PublishNTCP2Address (port, false, v4, v6, false);
489 		// update
490 		m_RouterInfo.UpdateSupportedTransports ();
491 		UpdateRouterInfo ();
492 	}
493 
SetReachable(bool v4,bool v6)494 	void RouterContext::SetReachable (bool v4, bool v6)
495 	{
496 		if (v4 || (v6 && !SupportsV4 ()))
497 		{
498 			// update caps
499 			uint8_t caps = m_RouterInfo.GetCaps ();
500 			caps &= ~i2p::data::RouterInfo::eUnreachable;
501 			caps |= i2p::data::RouterInfo::eReachable;
502 			if (m_IsFloodfill)
503 				caps |= i2p::data::RouterInfo::eFloodfill;
504 			m_RouterInfo.SetCaps (caps);
505 		}
506 		uint16_t port = 0;
507 		// delete previous introducers
508 		auto& addresses = m_RouterInfo.GetAddresses ();
509 		for (auto& addr : addresses)
510 			if (addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ())))
511 			{
512 				addr->published = true;
513 				addr->caps |= i2p::data::RouterInfo::eSSUIntroducer;
514 				addr->ssu->introducers.clear ();
515 				port = addr->port;
516 			}
517 		// publish NTCP2
518 		bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
519 		if (ntcp2)
520 		{
521 			bool published; i2p::config::GetOption ("ntcp2.published", published);
522 			if (published)
523 			{
524 				uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port);
525 				if (!ntcp2Port) ntcp2Port = port;
526 				PublishNTCP2Address (ntcp2Port, true, v4, v6, false);
527 			}
528 		}
529 		// update
530 		m_RouterInfo.UpdateSupportedTransports ();
531 		UpdateRouterInfo ();
532 	}
533 
SetSupportsV6(bool supportsV6)534 	void RouterContext::SetSupportsV6 (bool supportsV6)
535 	{
536 		if (supportsV6)
537 		{
538 			// insert v6 addresses if necessary
539 			bool foundSSU = false, foundNTCP2 = false;
540 			uint16_t port = 0;
541 			auto& addresses = m_RouterInfo.GetAddresses ();
542 			for (auto& addr: addresses)
543 			{
544 				if (addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host))
545 				{
546 					if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU)
547 						foundSSU = true;
548 					else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
549 						foundNTCP2 = true;
550 				}
551 				port = addr->port;
552 			}
553 			if (!port) i2p::config::GetOption("port", port);
554 			// SSU
555 			if (!foundSSU)
556 			{
557 				bool ssu; i2p::config::GetOption("ssu", ssu);
558 				if (ssu)
559 				{
560 					std::string host = "::1"; // TODO: read host
561 					m_RouterInfo.AddSSUAddress (host.c_str (), port, nullptr);
562 				}
563 			}
564 			// NTCP2
565 			if (!foundNTCP2)
566 			{
567 				bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
568 				bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published);
569 				if (ntcp2)
570 				{
571 					if (ntcp2Published)
572 					{
573 						std::string ntcp2Host;
574 						if (!i2p::config::IsDefault ("ntcp2.addressv6"))
575 							i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host);
576 						else
577 							ntcp2Host = "::1";
578 						uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port);
579 						if (!ntcp2Port) ntcp2Port = port;
580 						m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (ntcp2Host), ntcp2Port);
581 					}
582 					else
583 						m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV6);
584 				}
585 			}
586 			m_RouterInfo.EnableV6 ();
587 		}
588 		else
589 			m_RouterInfo.DisableV6 ();
590 		UpdateRouterInfo ();
591 	}
592 
SetSupportsV4(bool supportsV4)593 	void RouterContext::SetSupportsV4 (bool supportsV4)
594 	{
595 		// check if updates
596 		if (supportsV4 && SupportsV4 ()) return;
597 		if (!supportsV4 && !SupportsV4 ()) return;
598 		// update
599 		if (supportsV4)
600 		{
601 			bool foundSSU = false, foundNTCP2 = false;
602 			std::string host = "127.0.0.1";
603 			uint16_t port = 0;
604 			auto& addresses = m_RouterInfo.GetAddresses ();
605 			for (auto& addr: addresses)
606 			{
607 				if (addr->IsV4 ())
608 				{
609 					if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU)
610 						foundSSU = true;
611 					else if (addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
612 						foundNTCP2 = true;
613 				}
614 				if (addr->port) port = addr->port;
615 			}
616 			if (!port) i2p::config::GetOption("port", port);
617 			// SSU
618 			if (!foundSSU)
619 			{
620 				bool ssu; i2p::config::GetOption("ssu", ssu);
621 				if (ssu)
622 					m_RouterInfo.AddSSUAddress (host.c_str (), port, nullptr);
623 			}
624 			// NTCP2
625 			if (!foundNTCP2)
626 			{
627 				bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
628 				if (ntcp2)
629 				{
630 					bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published);
631 					if (ntcp2Published)
632 					{
633 						uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port);
634 						if (!ntcp2Port) ntcp2Port = port;
635 						m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address::from_string (host), ntcp2Port);
636 					}
637 					else
638 						m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, boost::asio::ip::address(), 0, i2p::data::RouterInfo::eV4);
639 				}
640 			}
641 			m_RouterInfo.EnableV4 ();
642 		}
643 		else
644 			m_RouterInfo.DisableV4 ();
645 		UpdateRouterInfo ();
646 	}
647 
SetSupportsMesh(bool supportsmesh,const boost::asio::ip::address_v6 & host)648 	void RouterContext::SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host)
649 	{
650 		if (supportsmesh)
651 		{
652 			m_RouterInfo.EnableMesh ();
653 			uint16_t port = 0;
654 			i2p::config::GetOption ("ntcp2.port", port);
655 			if (!port) i2p::config::GetOption("port", port);
656 			bool foundMesh = false;
657 			auto& addresses = m_RouterInfo.GetAddresses ();
658 			for (auto& addr: addresses)
659 			{
660 				if (!port) port = addr->port;
661 				if (i2p::util::net::IsYggdrasilAddress (addr->host))
662 				{
663 					foundMesh = true;
664 					break;
665 				}
666 			}
667 			if (!foundMesh)
668 				m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port);
669 		}
670 		else
671 			m_RouterInfo.DisableMesh ();
672 		UpdateRouterInfo ();
673 	}
674 
UpdateNTCP2V6Address(const boost::asio::ip::address & host)675 	void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host)
676 	{
677 		bool isYgg = i2p::util::net::IsYggdrasilAddress (host);
678 		bool updated = false;
679 		auto& addresses = m_RouterInfo.GetAddresses ();
680 		for (auto& addr: addresses)
681 		{
682 			if (addr->IsPublishedNTCP2 ())
683 			{
684 				bool isYgg1 = i2p::util::net::IsYggdrasilAddress (addr->host);
685 				if (addr->IsV6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1)))
686 				{
687 					if (addr->host != host)
688 					{
689 						addr->host = host;
690 						updated = true;
691 					}
692 					break;
693 				}
694 			}
695 		}
696 
697 		if (updated)
698 			UpdateRouterInfo ();
699 	}
700 
UpdateStats()701 	void RouterContext::UpdateStats ()
702 	{
703 		if (m_IsFloodfill)
704 		{
705 			// update routers and leasesets
706 			m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS, std::to_string(i2p::data::netdb.GetNumLeaseSets ()));
707 			m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS,   std::to_string(i2p::data::netdb.GetNumRouters ()));
708 			UpdateRouterInfo ();
709 		}
710 	}
711 
UpdateTimestamp(uint64_t ts)712 	void RouterContext::UpdateTimestamp (uint64_t ts)
713 	{
714 		if (ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL)
715 			UpdateRouterInfo ();
716 	}
717 
Load()718 	bool RouterContext::Load ()
719 	{
720 		{
721 			std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary);
722 			if (!fk.is_open ())	return false;
723 			fk.seekg (0, std::ios::end);
724 			size_t len = fk.tellg();
725 			fk.seekg (0, std::ios::beg);
726 
727 			if (len == sizeof (i2p::data::Keys)) // old keys file format
728 			{
729 				i2p::data::Keys keys;
730 				fk.read ((char *)&keys, sizeof (keys));
731 				m_Keys = keys;
732 			}
733 			else // new keys file format
734 			{
735 				uint8_t * buf = new uint8_t[len];
736 				fk.read ((char *)buf, len);
737 				m_Keys.FromBuffer (buf, len);
738 				delete[] buf;
739 			}
740 		}
741 		std::shared_ptr<const i2p::data::IdentityEx> oldIdentity;
742 		if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 ||
743 		    m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
744 		{
745 			// update keys
746 			LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new");
747 			oldIdentity = m_Keys.GetPublic ();
748 			m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519,
749 				i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
750 			SaveKeys ();
751 		}
752 		// read NTCP2 keys if available
753 		std::ifstream n2k (i2p::fs::DataDirPath (NTCP2_KEYS), std::ifstream::in | std::ifstream::binary);
754 		if (n2k)
755 		{
756 			n2k.seekg (0, std::ios::end);
757 			size_t len = n2k.tellg();
758 			n2k.seekg (0, std::ios::beg);
759 			if (len == sizeof (NTCP2PrivateKeys))
760 			{
761 				m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
762 				n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
763 			}
764 			n2k.close ();
765 		}
766 		// read RouterInfo
767 		m_RouterInfo.SetRouterIdentity (oldIdentity ? oldIdentity : GetIdentity ());
768 		i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO));
769 		if (!routerInfo.IsUnreachable ()) // router.info looks good
770 		{
771 			m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ());
772 			if (oldIdentity)
773 				m_RouterInfo.SetRouterIdentity (GetIdentity ()); // from new keys
774 			m_RouterInfo.SetProperty ("router.version", I2P_VERSION);
775 			m_RouterInfo.DeleteProperty ("coreVersion"); // TODO: remove later
776 		}
777 		else
778 		{
779 			LogPrint (eLogError, ROUTER_INFO, " is malformed. Creating new");
780 			NewRouterInfo ();
781 		}
782 
783 		if (IsUnreachable ())
784 			SetReachable (true, true); // we assume reachable until we discover firewall through peer tests
785 
786 		// read NTCP2
787 		bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
788 		bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
789 		if (ntcp2 || ygg)
790 		{
791 			if (!m_NTCP2Keys) NewNTCP2Keys ();
792 			UpdateNTCP2Address (true); // enable NTCP2
793 		}
794 		else
795 			UpdateNTCP2Address (false);	 // disable NTCP2
796 
797 		return true;
798 	}
799 
SaveKeys()800 	void RouterContext::SaveKeys ()
801 	{
802 		// save in the same format as .dat files
803 		std::ofstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ofstream::binary | std::ofstream::out);
804 		size_t len = m_Keys.GetFullLen ();
805 		uint8_t * buf = new uint8_t[len];
806 		m_Keys.ToBuffer (buf, len);
807 		fk.write ((char *)buf, len);
808 		delete[] buf;
809 	}
810 
GetTunnelPool() const811 	std::shared_ptr<i2p::tunnel::TunnelPool> RouterContext::GetTunnelPool () const
812 	{
813 		return i2p::tunnel::tunnels.GetExploratoryPool ();
814 	}
815 
HandleI2NPMessage(const uint8_t * buf,size_t len)816 	void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len)
817 	{
818 		i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len)));
819 	}
820 
HandleCloveI2NPMessage(I2NPMessageType typeID,const uint8_t * payload,size_t len,uint32_t msgID)821 	bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID)
822 	{
823 		auto msg = CreateI2NPMessage (typeID, payload, len, msgID);
824 		if (!msg) return false;
825 		i2p::HandleI2NPMessage (msg);
826 		return true;
827 	}
828 
829 
ProcessGarlicMessage(std::shared_ptr<I2NPMessage> msg)830 	void RouterContext::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
831 	{
832 		std::unique_lock<std::mutex> l(m_GarlicMutex);
833 		uint8_t * buf = msg->GetPayload ();
834 		uint32_t len = bufbe32toh (buf);
835 		if (len > msg->GetLength ())
836 		{
837 			LogPrint (eLogWarning, "Router: garlic message length ", len, " exceeds I2NP message length ", msg->GetLength ());
838 			return;
839 		}
840 		buf += 4;
841 		if (!HandleECIESx25519TagMessage (buf, len)) // try tag first
842 		{
843 			// then Noise_N one-time decryption
844 			if (m_ECIESSession)
845 				m_ECIESSession->HandleNextMessage (buf, len);
846 			else
847 				LogPrint (eLogError, "Router: Session is not set for ECIES router");
848 		}
849 	}
850 
ProcessDeliveryStatusMessage(std::shared_ptr<I2NPMessage> msg)851 	void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg)
852 	{
853 		if (i2p::data::netdb.GetPublishReplyToken () == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET))
854 			i2p::data::netdb.PostI2NPMsg (msg);
855 		else
856 		{
857 			std::unique_lock<std::mutex> l(m_GarlicMutex);
858 			i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg);
859 		}
860 	}
861 
CleanupDestination()862 	void RouterContext::CleanupDestination ()
863 	{
864 		std::unique_lock<std::mutex> l(m_GarlicMutex);
865 		i2p::garlic::GarlicDestination::CleanupExpiredTags ();
866 	}
867 
GetUptime() const868 	uint32_t RouterContext::GetUptime () const
869 	{
870 		return std::chrono::duration_cast<std::chrono::seconds> (std::chrono::steady_clock::now() - m_StartupTime).count ();
871 	}
872 
Decrypt(const uint8_t * encrypted,uint8_t * data,i2p::data::CryptoKeyType preferredCrypto) const873 	bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const
874 	{
875 		return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data) : false;
876 	}
877 
DecryptTunnelBuildRecord(const uint8_t * encrypted,uint8_t * data)878 	bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data)
879 	{
880 		return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE);
881 	}
882 
DecryptECIESTunnelBuildRecord(const uint8_t * encrypted,uint8_t * data,size_t clearTextSize)883 	bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize)
884 	{
885 		// m_InitialNoiseState is h = SHA256(h || hepk)
886 		m_CurrentNoiseState = m_InitialNoiseState;
887 		m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk)
888 		uint8_t sharedSecret[32];
889 		if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret))
890 		{
891 			LogPrint (eLogWarning, "Router: Incorrect ephemeral public key");
892 			return false;
893 		}
894 		m_CurrentNoiseState.MixKey (sharedSecret);
895 		encrypted += 32;
896 		uint8_t nonce[12];
897 		memset (nonce, 0, 12);
898 		if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState.m_H, 32,
899 			m_CurrentNoiseState.m_CK + 32, nonce, data, clearTextSize, false)) // decrypt
900 		{
901 			LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed");
902 			return false;
903 		}
904 		m_CurrentNoiseState.MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext)
905 		return true;
906 	}
907 
DecryptTunnelShortRequestRecord(const uint8_t * encrypted,uint8_t * data)908 	bool RouterContext::DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data)
909 	{
910 		return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE);
911 	}
912 
GetStaticKeys()913 	i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
914 	{
915 		if (!m_StaticKeys)
916 		{
917 			if (!m_NTCP2Keys) NewNTCP2Keys ();
918 			auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey);
919 			if (!m_StaticKeys)
920 				m_StaticKeys.reset (x);
921 			else
922 				delete x;
923 		}
924 		return *m_StaticKeys;
925 	}
926 }
927