RouterContext.cpp
1 /* 2 * Copyright (c) 2013-2026, 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 "Transports.h" 24 #include "Tunnel.h" 25 #include "CryptoKey.h" 26 #include "RouterContext.h" 27 28 namespace i2p 29 { 30 RouterContext context; 31 32 RouterContext::RouterContext (): 33 m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), 34 m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown), 35 m_Error (eRouterErrorNone), m_ErrorV6 (eRouterErrorNone), 36 m_Testing (false), m_TestingV6 (false), m_NetID (I2PD_NET_ID), 37 m_PublishReplyToken (0), m_IsHiddenMode (false), m_IsSaving (false) 38 { 39 } 40 41 void RouterContext::Init () 42 { 43 srand (GetRng ()() % 1000); 44 m_StartupTime = i2p::util::GetMonotonicSeconds (); 45 46 if (!Load ()) 47 CreateNewRouter (); 48 m_Decryptor = m_Keys.CreateDecryptor (nullptr); 49 m_TunnelDecryptor = m_Keys.CreateDecryptor (nullptr); 50 UpdateRouterInfo (); 51 i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ()); 52 m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState); 53 } 54 55 void RouterContext::Start () 56 { 57 if (!m_Service) 58 { 59 m_Service.reset (new RouterService); 60 m_Service->Start (); 61 m_PublishTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); 62 ScheduleInitialPublish (); 63 m_CongestionUpdateTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); 64 ScheduleCongestionUpdate (); 65 m_CleanupTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); 66 ScheduleCleanupTimer (); 67 } 68 } 69 70 void RouterContext::Stop () 71 { 72 if (m_Service) 73 { 74 if (m_PublishTimer) 75 m_PublishTimer->cancel (); 76 if (m_CongestionUpdateTimer) 77 m_CongestionUpdateTimer->cancel (); 78 m_Service->Stop (); 79 CleanUp (); // GarlicDestination 80 } 81 } 82 83 std::shared_ptr<i2p::data::RouterInfo::Buffer> RouterContext::CopyRouterInfoBuffer () const 84 { 85 std::lock_guard<std::mutex> l(m_RouterInfoMutex); 86 return m_RouterInfo.CopyBuffer (); 87 } 88 89 void RouterContext::CreateNewRouter () 90 { 91 m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, 92 i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); 93 SaveKeys (); 94 NewRouterInfo (); 95 } 96 97 void RouterContext::NewRouterInfo () 98 { 99 i2p::data::LocalRouterInfo routerInfo; 100 routerInfo.SetRouterIdentity (GetIdentity ()); 101 uint16_t port; i2p::config::GetOption("port", port); 102 if (!port) port = SelectRandomPort (); 103 bool ipv4; i2p::config::GetOption("ipv4", ipv4); 104 bool ipv6; i2p::config::GetOption("ipv6", ipv6); 105 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); 106 bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); 107 bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); 108 bool nat; i2p::config::GetOption("nat", nat); 109 110 if ((ntcp2 || ygg) && !m_NTCP2Keys) 111 NewNTCP2Keys (); 112 if (ssu2 && !m_SSU2Keys) 113 NewSSU2Keys (); 114 bool ntcp2Published = false; 115 if (ntcp2) 116 { 117 i2p::config::GetOption("ntcp2.published", ntcp2Published); 118 if (ntcp2Published) 119 { 120 std::string ntcp2proxy; i2p::config::GetOption("ntcp2.proxy", ntcp2proxy); 121 if (!ntcp2proxy.empty ()) ntcp2Published = false; 122 } 123 } 124 bool ssu2Published = false; 125 if (ssu2) 126 i2p::config::GetOption("ssu2.published", ssu2Published); 127 uint8_t caps = 0; 128 if (ipv4) 129 { 130 std::string host; 131 if (!nat) 132 // we have no NAT so set external address from local address 133 i2p::config::GetOption("address4", host); 134 if (host.empty ()) i2p::config::GetOption("host", host); 135 136 if (ntcp2) 137 { 138 uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); 139 if (!ntcp2Port) ntcp2Port = port; 140 if (ntcp2Published && ntcp2Port) 141 { 142 boost::asio::ip::address addr; 143 if (!host.empty ()) 144 addr = boost::asio::ip::make_address (host); 145 if (!addr.is_v4()) 146 addr = boost::asio::ip::address_v4 (); 147 routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); 148 } 149 else 150 { 151 // add non-published NTCP2 address 152 uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; 153 if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; 154 routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, addressCaps); 155 } 156 } 157 if (ssu2) 158 { 159 uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); 160 if (!ssu2Port) ssu2Port = port; 161 if (ssu2Published && ssu2Port) 162 { 163 boost::asio::ip::address addr; 164 if (!host.empty ()) 165 addr = boost::asio::ip::make_address (host); 166 if (!addr.is_v4()) 167 addr = boost::asio::ip::address_v4 (); 168 routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); 169 } 170 else 171 { 172 uint8_t addressCaps = i2p::data::RouterInfo::AddressCaps::eV4; 173 if (ipv6) addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; 174 routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, addressCaps); 175 } 176 } 177 } 178 if (ipv6) 179 { 180 auto ipv6addr = i2p::util::net::GetClearnetIPV6Address (); 181 if (!ipv6addr.is_unspecified ()) 182 { 183 std::string host; i2p::config::GetOption("address6", host); 184 if (host.empty () && !ipv4) i2p::config::GetOption("host", host); // use host for ipv6 only if ipv4 is not presented 185 186 if (ntcp2) 187 { 188 uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); 189 if (!ntcp2Port) ntcp2Port = port; 190 if (ntcp2Published && ntcp2Port) 191 { 192 std::string ntcp2Host; 193 if (!i2p::config::IsDefault ("ntcp2.addressv6")) 194 i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); 195 else 196 ntcp2Host = host; 197 boost::asio::ip::address addr; 198 if (!ntcp2Host.empty ()) 199 addr = boost::asio::ip::make_address (ntcp2Host); 200 if (!addr.is_v6()) 201 addr = boost::asio::ip::address_v6 (); 202 routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); 203 } 204 else 205 { 206 if (!ipv4) // no other ntcp2 addresses yet 207 routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::AddressCaps::eV6); 208 } 209 } 210 if (ssu2) 211 { 212 uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); 213 if (!ssu2Port) ssu2Port = port; 214 if (ssu2Published && ssu2Port) 215 { 216 boost::asio::ip::address addr; 217 if (!host.empty ()) 218 addr = boost::asio::ip::make_address (host); 219 if (!addr.is_v6()) 220 addr = boost::asio::ip::address_v6 (); 221 routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); 222 } 223 else 224 { 225 if (!ipv4) // no other ssu2 addresses yet 226 routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::AddressCaps::eV6); 227 } 228 } 229 } 230 } 231 if (ygg) 232 { 233 auto yggaddr = i2p::util::net::GetYggdrasilAddress (); 234 if (!yggaddr.is_unspecified ()) 235 routerInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, yggaddr, port); 236 } 237 238 routerInfo.UpdateCaps (caps); // caps + L 239 routerInfo.SetProperty ("netId", std::to_string (m_NetID)); 240 routerInfo.SetProperty ("router.version", I2P_VERSION); 241 routerInfo.CreateBuffer (m_Keys); 242 m_RouterInfo.SetRouterIdentity (GetIdentity ()); 243 m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); 244 m_RouterInfo.SetUnreachable (false); 245 } 246 247 uint16_t RouterContext::SelectRandomPort () const 248 { 249 uint16_t port; 250 do 251 { 252 port = rand () % (30777 - 9111) + 9111; // I2P network ports range 253 } 254 while(i2p::util::net::IsPortInReservedRange(port)); 255 256 return port; 257 } 258 259 void RouterContext::UpdateRouterInfo () 260 { 261 std::shared_ptr<i2p::data::RouterInfo::Buffer> buffer; 262 { 263 std::lock_guard<std::mutex> l(m_RouterInfoMutex); 264 m_RouterInfo.CreateBuffer (m_Keys); 265 buffer = m_RouterInfo.CopyBuffer (); 266 } 267 { 268 // update save buffer to latest 269 std::lock_guard<std::mutex> l(m_SaveBufferMutex); 270 m_SaveBuffer = buffer; 271 } 272 bool isSaving = false; 273 if (m_IsSaving.compare_exchange_strong (isSaving, true)) // try to save only if not being saved 274 { 275 auto savingRouterInfo = std::async (std::launch::async, [this]() 276 { 277 std::shared_ptr<i2p::data::RouterInfo::Buffer> buffer; 278 while (m_SaveBuffer) 279 { 280 { 281 std::lock_guard<std::mutex> l(m_SaveBufferMutex); 282 buffer = m_SaveBuffer; 283 m_SaveBuffer = nullptr; 284 } 285 if (buffer) 286 i2p::data::RouterInfo::SaveToFile (i2p::fs::DataDirPath (ROUTER_INFO), buffer); 287 } 288 m_IsSaving = false; 289 }); 290 } 291 m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch (); 292 } 293 294 void RouterContext::NewNTCP2Keys () 295 { 296 m_NTCP2StaticKeys.reset (new i2p::crypto::X25519Keys ()); 297 m_NTCP2StaticKeys->GenerateKeys (); 298 m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); 299 m_NTCP2StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey); 300 memcpy (m_NTCP2Keys->staticPublicKey, m_NTCP2StaticKeys->GetPublicKey (), 32); 301 RAND_bytes (m_NTCP2Keys->iv, 16); 302 // save 303 std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out); 304 fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); 305 } 306 307 void RouterContext::NewSSU2Keys () 308 { 309 m_SSU2StaticKeys.reset (new i2p::crypto::X25519Keys ()); 310 m_SSU2StaticKeys->GenerateKeys (); 311 m_SSU2Keys.reset (new SSU2PrivateKeys ()); 312 m_SSU2StaticKeys->GetPrivateKey (m_SSU2Keys->staticPrivateKey); 313 memcpy (m_SSU2Keys->staticPublicKey, m_SSU2StaticKeys->GetPublicKey (), 32); 314 RAND_bytes (m_SSU2Keys->intro, 32); 315 // save 316 std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out); 317 fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys)); 318 } 319 320 void RouterContext::SetTesting (bool testing) 321 { 322 if (testing != m_Testing) 323 { 324 m_Testing = testing; 325 if (m_Testing) 326 m_Error = eRouterErrorNone; 327 } 328 } 329 330 void RouterContext::SetTestingV6 (bool testing) 331 { 332 if (testing != m_TestingV6) 333 { 334 m_TestingV6 = testing; 335 if (m_TestingV6) 336 m_ErrorV6 = eRouterErrorNone; 337 } 338 } 339 340 void RouterContext::SetStatus (RouterStatus status) 341 { 342 SetTesting (false); 343 if (status != m_Status) 344 { 345 LogPrint(eLogInfo, "Router: network status v4 changed ", 346 ROUTER_STATUS_NAMES[m_Status], " -> ", ROUTER_STATUS_NAMES[status]); 347 m_Status = status; 348 switch (m_Status) 349 { 350 case eRouterStatusOK: 351 SetReachable (true, false); // ipv4 352 break; 353 case eRouterStatusFirewalled: 354 SetUnreachable (true, false); // ipv4 355 break; 356 case eRouterStatusMesh: 357 m_RouterInfo.UpdateCaps (m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eReachable); 358 break; 359 case eRouterStatusProxy: 360 case eRouterStatusStan: 361 m_RouterInfo.UpdateCaps ((m_RouterInfo.GetCaps () | i2p::data::RouterInfo::eUnreachable) & ~i2p::data::RouterInfo::eReachable); 362 break; 363 default: 364 ; 365 } 366 } 367 } 368 369 void RouterContext::SetStatusV6 (RouterStatus status) 370 { 371 SetTestingV6 (false); 372 if (status != m_StatusV6) 373 { 374 LogPrint(eLogInfo, "Router: network status v6 changed ", 375 ROUTER_STATUS_NAMES[m_StatusV6], " -> ", ROUTER_STATUS_NAMES[status]); 376 m_StatusV6 = status; 377 switch (m_StatusV6) 378 { 379 case eRouterStatusOK: 380 SetReachable (false, true); // ipv6 381 break; 382 case eRouterStatusFirewalled: 383 SetUnreachable (false, true); // ipv6 384 break; 385 default: 386 ; 387 } 388 } 389 } 390 391 void RouterContext::UpdatePort (int port) 392 { 393 auto addresses = m_RouterInfo.GetAddresses (); 394 if (!addresses) return; 395 bool updated = false; 396 for (auto& address : *addresses) 397 { 398 if (address && address->port != port) 399 { 400 address->port = port; 401 updated = true; 402 } 403 } 404 if (updated) 405 UpdateRouterInfo (); 406 } 407 408 void RouterContext::PublishNTCP2Address (std::shared_ptr<i2p::data::RouterInfo::Address> address, 409 int port, bool publish, int version) const 410 { 411 if (!address) return; 412 if (!port && !address->port) port = SelectRandomPort (); 413 if (port) address->port = port; 414 address->published = publish; 415 address->v = version; 416 memcpy (address->i, m_NTCP2Keys->iv, 16); 417 } 418 419 void RouterContext::PublishNTCP2Address (int port, bool publish, bool v4, bool v6, bool ygg, int version) 420 { 421 if (!m_NTCP2Keys) return; 422 auto addresses = m_RouterInfo.GetAddresses (); 423 if (!addresses) return; 424 bool updated = false; 425 if (v4) 426 { 427 auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V4Idx]; 428 if (addr && (addr->port != port || addr->published != publish || addr->v != version)) 429 { 430 PublishNTCP2Address (addr, port, publish, version); 431 updated = true; 432 } 433 } 434 if (v6) 435 { 436 auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; 437 if (addr && (addr->port != port || addr->published != publish || addr->v != version)) 438 { 439 PublishNTCP2Address (addr, port, publish, version); 440 updated = true; 441 } 442 } 443 if (ygg) 444 { 445 auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]; 446 if (addr && (addr->port != port || addr->published != publish)) 447 { 448 PublishNTCP2Address (addr, port, publish, 2); 449 updated = true; 450 } 451 } 452 453 if (updated) 454 UpdateRouterInfo (); 455 } 456 457 void RouterContext::UpdateNTCP2Keys () 458 { 459 if (!m_NTCP2Keys) return; 460 auto addresses = m_RouterInfo.GetAddresses (); 461 if (!addresses) return; 462 for (auto& it: *addresses) 463 { 464 if (it && it->IsNTCP2 ()) 465 { 466 it->s = m_NTCP2Keys->staticPublicKey; 467 memcpy (it->i, m_NTCP2Keys->iv, 16); 468 } 469 } 470 } 471 472 void RouterContext::PublishSSU2Address (int port, bool publish, bool v4, bool v6) 473 { 474 if (!m_SSU2Keys) return; 475 auto addresses = m_RouterInfo.GetAddresses (); 476 if (!addresses) return; 477 int newPort = 0; 478 if (!port) 479 { 480 for (const auto& address : *addresses) 481 if (address && address->port) 482 { 483 newPort = address->port; 484 break; 485 } 486 if (!newPort) newPort = SelectRandomPort (); 487 } 488 bool updated = false; 489 for (auto& address : *addresses) 490 { 491 if (address && address->IsSSU2 () && (!address->port || address->port != port || address->published != publish) && 492 ((v4 && address->IsV4 ()) || (v6 && address->IsV6 ()))) 493 { 494 if (port) address->port = port; 495 else if (!address->port) address->port = newPort; 496 address->published = publish; 497 if (publish) 498 { 499 UpdateSSU2AddressCapsTesting (address, true); 500 UpdateSSU2AddressCapsIntroducer (address, !m_IsFloodfill); 501 } 502 else 503 { 504 UpdateSSU2AddressCapsTesting (address, false); 505 UpdateSSU2AddressCapsIntroducer (address, false); 506 } 507 updated = true; 508 } 509 } 510 if (updated) 511 UpdateRouterInfo (); 512 } 513 514 void RouterContext::UpdateSSU2AddressCapsIntroducer (std::shared_ptr<i2p::data::RouterInfo::Address> address, bool isIntroducer) const 515 { 516 if (address) 517 { 518 if (isIntroducer) 519 address->caps |= i2p::data::RouterInfo::eSSUIntroducer; 520 else 521 address->caps &= ~i2p::data::RouterInfo::eSSUIntroducer; 522 } 523 } 524 525 void RouterContext::UpdateSSU2AddressCapsTesting (std::shared_ptr<i2p::data::RouterInfo::Address> address, bool isTesting) const 526 { 527 if (address) 528 { 529 if (isTesting) 530 address->caps |= i2p::data::RouterInfo::eSSUTesting; 531 else 532 address->caps &= ~i2p::data::RouterInfo::eSSUTesting; 533 } 534 } 535 536 void RouterContext::UpdateSSU2Keys () 537 { 538 if (!m_SSU2Keys) return; 539 auto addresses = m_RouterInfo.GetAddresses (); 540 if (!addresses) return; 541 for (auto& it: *addresses) 542 { 543 if (it && it->IsSSU2 ()) 544 { 545 it->s = m_SSU2Keys->staticPublicKey; 546 it->i = m_SSU2Keys->intro; 547 } 548 } 549 } 550 551 void RouterContext::UpdateAddress (const boost::asio::ip::address& host) 552 { 553 auto addresses = m_RouterInfo.GetAddresses (); 554 if (!addresses) return; 555 bool updated = false; 556 if (host.is_v4 ()) 557 { 558 auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V4Idx]; 559 if (addr && addr->host != host) 560 { 561 addr->host = host; 562 updated = true; 563 } 564 addr = (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]; 565 if (addr && addr->host != host) 566 { 567 addr->host = host; 568 updated = true; 569 } 570 } 571 else if (host.is_v6 ()) 572 { 573 auto addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; 574 if (addr && addr->host != host) 575 { 576 addr->host = host; 577 updated = true; 578 } 579 addr = (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]; 580 if (addr && (addr->host != host || !addr->ssu->mtu)) 581 { 582 addr->host = host; 583 if (m_StatusV6 != eRouterStatusProxy) 584 { 585 // update MTU 586 auto mtu = i2p::util::net::GetMTU (host); 587 if (mtu) 588 { 589 LogPrint (eLogDebug, "Router: Our v6 MTU=", mtu); 590 int maxMTU = i2p::util::net::GetMaxMTU (host.to_v6 ()); 591 if (mtu > maxMTU) 592 { 593 mtu = maxMTU; 594 LogPrint(eLogWarning, "Router: MTU dropped to upper limit of ", maxMTU, " bytes"); 595 } 596 addr->ssu->mtu = mtu; 597 } 598 } 599 updated = true; 600 } 601 } 602 603 auto ts = i2p::util::GetSecondsSinceEpoch (); 604 if (updated || ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL) 605 UpdateRouterInfo (); 606 } 607 608 bool RouterContext::AddSSU2Introducer (const i2p::data::RouterInfo::Introducer& introducer, bool v4) 609 { 610 bool ret = m_RouterInfo.AddSSU2Introducer (introducer, v4); 611 if (ret) 612 UpdateRouterInfo (); 613 return ret; 614 } 615 616 void RouterContext::RemoveSSU2Introducer (const i2p::data::IdentHash& h, bool v4) 617 { 618 if (m_RouterInfo.RemoveSSU2Introducer (h, v4)) 619 UpdateRouterInfo (); 620 } 621 622 void RouterContext::UpdateSSU2Introducer (const i2p::data::IdentHash& h, bool v4, uint32_t iTag, uint32_t iExp) 623 { 624 if (m_RouterInfo.UpdateSSU2Introducer (h, v4, iTag, iExp)) 625 UpdateRouterInfo (); 626 } 627 628 void RouterContext::ClearSSU2Introducers (bool v4) 629 { 630 auto addr = m_RouterInfo.GetSSU2Address (v4); 631 if (addr && !addr->ssu->introducers.empty ()) 632 { 633 addr->ssu->introducers.clear (); 634 UpdateRouterInfo (); 635 } 636 } 637 638 void RouterContext::SetFloodfill (bool floodfill) 639 { 640 if (m_IsFloodfill != floodfill) 641 { 642 m_IsFloodfill = floodfill; 643 auto addresses = m_RouterInfo.GetAddresses (); 644 if (floodfill) 645 { 646 m_RouterInfo.UpdateFloodfillProperty (true); 647 if (addresses) 648 { 649 // diable introducer for all floodfill's SSU2 addresses 650 UpdateSSU2AddressCapsIntroducer ((*addresses)[i2p::data::RouterInfo::eSSU2V4Idx], false); 651 UpdateSSU2AddressCapsIntroducer ((*addresses)[i2p::data::RouterInfo::eSSU2V6Idx], false); 652 } 653 } 654 else 655 { 656 m_RouterInfo.UpdateFloodfillProperty (false); 657 // we don't publish number of routers and leaseset for non-floodfill 658 m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS); 659 m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS); 660 if (addresses) 661 { 662 // enable introducers for published non-floodfill's SSU2 addresses 663 auto addr = (*addresses)[i2p::data::RouterInfo::eSSU2V4Idx]; 664 if (addr && addr->published) UpdateSSU2AddressCapsIntroducer (addr, true); 665 addr = (*addresses)[i2p::data::RouterInfo::eSSU2V6Idx]; 666 if (addr && addr->published) UpdateSSU2AddressCapsIntroducer (addr, true); 667 } 668 } 669 UpdateRouterInfo (); 670 } 671 } 672 673 std::string RouterContext::GetFamily () const 674 { 675 return m_RouterInfo.GetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY); 676 } 677 678 void RouterContext::SetFamily (const std::string& family) 679 { 680 std::string signature; 681 if (family.length () > 0) 682 signature = i2p::data::CreateFamilySignature (family, GetIdentHash ()); 683 if (signature.length () > 0) 684 { 685 m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family); 686 m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG, signature); 687 } 688 else 689 { 690 m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY); 691 m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG); 692 } 693 } 694 695 void RouterContext::SetBandwidth (char L) 696 { 697 uint32_t limit = 0; 698 enum { low, high, extra, unlim } type = high; 699 /* detect parameters */ 700 switch (L) 701 { 702 case i2p::data::CAPS_FLAG_LOW_BANDWIDTH1 : limit = 12; type = low; break; 703 case i2p::data::CAPS_FLAG_LOW_BANDWIDTH2 : limit = i2p::data::LOW_BANDWIDTH_LIMIT; type = low; break; // 48 704 case i2p::data::CAPS_FLAG_LOW_BANDWIDTH3 : limit = 64; type = low; break; 705 case i2p::data::CAPS_FLAG_LOW_BANDWIDTH4 : limit = 128; type = low; break; 706 case i2p::data::CAPS_FLAG_HIGH_BANDWIDTH : limit = i2p::data::HIGH_BANDWIDTH_LIMIT; type = high; break; // 256 707 case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1 : limit = i2p::data::EXTRA_BANDWIDTH_LIMIT; type = extra; break; // 2048 708 case i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH2 : limit = 1000000; type = unlim; break; // 1Gbyte/s 709 default: 710 limit = i2p::data::LOW_BANDWIDTH_LIMIT; type = low; // 48 711 } 712 /* update caps & flags in RI */ 713 auto caps = m_RouterInfo.GetCaps (); 714 caps &= ~i2p::data::RouterInfo::eHighBandwidth; 715 caps &= ~i2p::data::RouterInfo::eExtraBandwidth; 716 switch (type) 717 { 718 case low : /* not set */; break; 719 case extra : caps |= i2p::data::RouterInfo::eExtraBandwidth; break; // 'P' 720 case unlim : caps |= i2p::data::RouterInfo::eExtraBandwidth; 721 [[fallthrough]]; 722 // no break here, extra + high means 'X' 723 case high : caps |= i2p::data::RouterInfo::eHighBandwidth; break; 724 } 725 m_RouterInfo.UpdateCaps (caps); 726 UpdateRouterInfo (); 727 m_BandwidthLimit = limit; 728 } 729 730 void RouterContext::SetBandwidth (int limit) 731 { 732 if (limit > (int)i2p::data::EXTRA_BANDWIDTH_LIMIT) { SetBandwidth('X'); } 733 else if (limit > (int)i2p::data::HIGH_BANDWIDTH_LIMIT) { SetBandwidth('P'); } 734 else if (limit > 128) { SetBandwidth('O'); } 735 else if (limit > 64) { SetBandwidth('N'); } 736 else if (limit > (int)i2p::data::LOW_BANDWIDTH_LIMIT) { SetBandwidth('M'); } 737 else if (limit > 12) { SetBandwidth('L'); } 738 else { SetBandwidth('K'); } 739 740 741 LogPrint(eLogInfo, "RouterContext: Set bandwidth ", limit, ". kb/s"); 742 m_BandwidthLimit = limit; // set precise limit 743 } 744 745 void RouterContext::SetShareRatio (int percents) 746 { 747 if (percents < 0) percents = 0; 748 if (percents > 100) percents = 100; 749 m_ShareRatio = percents; 750 } 751 752 bool RouterContext::IsUnreachable () const 753 { 754 return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable; 755 } 756 757 void RouterContext::SetUnreachable (bool v4, bool v6) 758 { 759 if (v4 || (v6 && !SupportsV4 ())) 760 { 761 // set caps 762 uint8_t caps = m_RouterInfo.GetCaps (); 763 caps &= ~i2p::data::RouterInfo::eReachable; 764 caps |= i2p::data::RouterInfo::eUnreachable; 765 if (v6 || !SupportsV6 ()) 766 caps &= ~i2p::data::RouterInfo::eFloodfill; // can't be floodfill 767 m_RouterInfo.UpdateCaps (caps); 768 } 769 uint16_t port = 0; 770 // delete previous introducers 771 auto addresses = m_RouterInfo.GetAddresses (); 772 if (addresses) 773 { 774 for (auto& addr : *addresses) 775 if (addr && addr->ssu && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) 776 { 777 addr->published = false; 778 UpdateSSU2AddressCapsIntroducer (addr, false); // can't be introducer 779 addr->ssu->introducers.clear (); 780 port = addr->port; 781 } 782 } 783 // unpublish NTCP2 addreeses 784 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); 785 if (ntcp2) 786 { 787 int ntcp2version = 2; 788 #if OPENSSL_PQ 789 i2p::config::GetOption("ntcp2.version", ntcp2version); 790 #endif 791 PublishNTCP2Address (port, false, v4, v6, false, ntcp2version); 792 } 793 // update 794 m_RouterInfo.UpdateSupportedTransports (); 795 UpdateRouterInfo (); 796 } 797 798 void RouterContext::SetReachable (bool v4, bool v6) 799 { 800 if (v4 || (v6 && !SupportsV4 ())) 801 { 802 // update caps 803 uint8_t caps = m_RouterInfo.GetCaps (); 804 caps &= ~i2p::data::RouterInfo::eUnreachable; 805 caps |= i2p::data::RouterInfo::eReachable; 806 if (m_IsFloodfill) 807 caps |= i2p::data::RouterInfo::eFloodfill; 808 m_RouterInfo.UpdateCaps (caps); 809 } 810 uint16_t port = 0; 811 // delete previous introducers 812 bool isSSU2Published; i2p::config::GetOption ("ssu2.published", isSSU2Published); 813 auto addresses = m_RouterInfo.GetAddresses (); 814 if (addresses) 815 { 816 for (auto& addr : *addresses) 817 if (addr && addr->ssu && isSSU2Published && ((v4 && addr->IsV4 ()) || (v6 && addr->IsV6 ()))) 818 { 819 addr->published = true; 820 UpdateSSU2AddressCapsIntroducer (addr, !m_IsFloodfill); 821 addr->ssu->introducers.clear (); 822 if (addr->port) port = addr->port; 823 } 824 } 825 // publish NTCP2 826 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); 827 if (ntcp2) 828 { 829 bool published; i2p::config::GetOption ("ntcp2.published", published); 830 if (published) 831 { 832 uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); 833 if (!ntcp2Port) ntcp2Port = port; 834 int ntcp2version = 2; 835 #if OPENSSL_PQ 836 i2p::config::GetOption("ntcp2.version", ntcp2version); 837 #endif 838 PublishNTCP2Address (ntcp2Port, true, v4, v6, false, ntcp2version); 839 } 840 } 841 // update 842 m_RouterInfo.UpdateSupportedTransports (); 843 UpdateRouterInfo (); 844 } 845 846 void RouterContext::SetSupportsV6 (bool supportsV6) 847 { 848 if (supportsV6) 849 { 850 // insert v6 addresses if necessary 851 bool foundNTCP2 = false, foundSSU2 = false; 852 uint16_t port = 0; 853 auto addresses = m_RouterInfo.GetAddresses (); 854 if (addresses) 855 { 856 for (auto& addr: *addresses) 857 { 858 if (addr && addr->IsV6 () && !i2p::util::net::IsYggdrasilAddress (addr->host)) 859 { 860 switch (addr->transportStyle) 861 { 862 case i2p::data::RouterInfo::eTransportNTCP2: 863 foundNTCP2 = true; 864 break; 865 case i2p::data::RouterInfo::eTransportSSU2: 866 foundSSU2 = true; 867 break; 868 default: ; 869 } 870 } 871 if (addr) port = addr->port; 872 } 873 } 874 if (!port) 875 { 876 i2p::config::GetOption("port", port); 877 if (!port) port = SelectRandomPort (); 878 } 879 // NTCP2 880 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); 881 if (ntcp2) 882 { 883 if (!foundNTCP2) 884 { 885 uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); 886 if (!ntcp2Port) ntcp2Port = port; 887 bool added = false; 888 bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); 889 if (ntcp2Published) 890 { 891 std::string ntcp2Host; 892 if (!i2p::config::IsDefault ("ntcp2.addressv6")) 893 i2p::config::GetOption ("ntcp2.addressv6", ntcp2Host); 894 else 895 i2p::config::GetOption("host", ntcp2Host); 896 if (!ntcp2Host.empty () && ntcp2Port) 897 { 898 auto addr = boost::asio::ip::make_address (ntcp2Host); 899 if (addr.is_v6 ()) 900 { 901 m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); 902 added = true; 903 } 904 } 905 } 906 if (!added) 907 m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV6); 908 } 909 } 910 else 911 m_RouterInfo.RemoveNTCP2Address (false); 912 // SSU2 913 bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); 914 if (ssu2) 915 { 916 if (!foundSSU2) 917 { 918 uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); 919 if (!ssu2Port) ssu2Port = port; 920 bool added = false; 921 bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); 922 if (ssu2Published && ssu2Port) 923 { 924 std::string host; i2p::config::GetOption("host", host); 925 if (!host.empty ()) 926 { 927 auto addr = boost::asio::ip::make_address (host); 928 if (addr.is_v6 ()) 929 { 930 m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); 931 added = true; 932 } 933 } 934 } 935 if (!added) 936 m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV6); 937 } 938 } 939 else 940 m_RouterInfo.RemoveSSU2Address (false); 941 if (ntcp2 || ssu2) 942 m_RouterInfo.EnableV6 (); 943 } 944 else 945 m_RouterInfo.DisableV6 (); 946 UpdateRouterInfo (); 947 } 948 949 void RouterContext::SetSupportsV4 (bool supportsV4) 950 { 951 if (supportsV4) 952 { 953 bool foundNTCP2 = false, foundSSU2 = false; 954 uint16_t port = 0; 955 auto addresses = m_RouterInfo.GetAddresses (); 956 if (addresses) 957 { 958 for (auto& addr: *addresses) 959 { 960 if (addr && addr->IsV4 ()) 961 { 962 switch (addr->transportStyle) 963 { 964 case i2p::data::RouterInfo::eTransportNTCP2: 965 foundNTCP2 = true; 966 break; 967 case i2p::data::RouterInfo::eTransportSSU2: 968 foundSSU2 = true; 969 break; 970 default: ; 971 } 972 } 973 if (addr && addr->port) port = addr->port; 974 } 975 } 976 if (!port) 977 { 978 i2p::config::GetOption("port", port); 979 if (!port) port = SelectRandomPort (); 980 } 981 // NTCP2 982 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); 983 if (ntcp2) 984 { 985 if (!foundNTCP2) 986 { 987 uint16_t ntcp2Port; i2p::config::GetOption ("ntcp2.port", ntcp2Port); 988 if (!ntcp2Port) ntcp2Port = port; 989 bool added = false; 990 bool ntcp2Published; i2p::config::GetOption("ntcp2.published", ntcp2Published); 991 if (ntcp2Published && ntcp2Port) 992 { 993 std::string host; i2p::config::GetOption("host", host); 994 if (!host.empty ()) 995 { 996 auto addr = boost::asio::ip::make_address (host); 997 if (addr.is_v4 ()) 998 { 999 m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, addr, ntcp2Port); 1000 added = true; 1001 } 1002 } 1003 } 1004 if (!added) 1005 m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, ntcp2Port, i2p::data::RouterInfo::eV4); 1006 } 1007 } 1008 else 1009 m_RouterInfo.RemoveNTCP2Address (true); 1010 // SSU2 1011 bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); 1012 if (ssu2) 1013 { 1014 if (!foundSSU2) 1015 { 1016 uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); 1017 if (!ssu2Port) ssu2Port = port; 1018 bool added = false; 1019 bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); 1020 std::string host; i2p::config::GetOption("host", host); 1021 if (ssu2Published && ssu2Port) 1022 { 1023 std::string host; i2p::config::GetOption("host", host); 1024 if (!host.empty ()) 1025 { 1026 auto addr = boost::asio::ip::make_address (host); 1027 if (addr.is_v4 ()) 1028 { 1029 m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, addr, ssu2Port); 1030 added = true; 1031 } 1032 } 1033 } 1034 if (!added) 1035 m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, ssu2Port, i2p::data::RouterInfo::eV4); 1036 } 1037 } 1038 else 1039 m_RouterInfo.RemoveSSU2Address (true); 1040 if (ntcp2 || ssu2) 1041 m_RouterInfo.EnableV4 (); 1042 } 1043 else 1044 m_RouterInfo.DisableV4 (); 1045 UpdateRouterInfo (); 1046 } 1047 1048 void RouterContext::SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host) 1049 { 1050 if (supportsmesh) 1051 { 1052 auto addresses = m_RouterInfo.GetAddresses (); 1053 if (!addresses) return; 1054 m_RouterInfo.EnableMesh (); 1055 if ((*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]) return; // we have mesh address already 1056 uint16_t port = 0; 1057 i2p::config::GetOption ("ntcp2.port", port); 1058 if (!port) i2p::config::GetOption("port", port); 1059 if (!port) 1060 { 1061 for (auto& addr: *addresses) 1062 { 1063 if (addr && addr->port) 1064 { 1065 port = addr->port; 1066 break; 1067 } 1068 } 1069 } 1070 if (!port) port = SelectRandomPort (); 1071 m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); 1072 } 1073 else 1074 m_RouterInfo.DisableMesh (); 1075 UpdateRouterInfo (); 1076 } 1077 1078 void RouterContext::SetMTU (int mtu, bool v4) 1079 { 1080 if (mtu < 1280 || mtu > 1500) return; 1081 auto addresses = m_RouterInfo.GetAddresses (); 1082 if (!addresses) return; 1083 for (auto& addr: *addresses) 1084 { 1085 if (addr && addr->ssu && ((v4 && addr->IsV4 ()) || (!v4 && addr->IsV6 ()))) 1086 { 1087 addr->ssu->mtu = mtu; 1088 LogPrint (eLogDebug, "Router: MTU for ", v4 ? "ipv4" : "ipv6", " address ", addr->host.to_string(), " is set to ", mtu); 1089 } 1090 } 1091 } 1092 1093 void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) 1094 { 1095 auto addresses = m_RouterInfo.GetAddresses (); 1096 if (!addresses) return; 1097 std::shared_ptr<i2p::data::RouterInfo::Address> addr; 1098 if (i2p::util::net::IsYggdrasilAddress (host)) // yggdrasil 1099 addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6MeshIdx]; 1100 else if (host.is_v6 ()) 1101 addr = (*addresses)[i2p::data::RouterInfo::eNTCP2V6Idx]; 1102 if (addr && addr->IsPublishedNTCP2 () && addr->host != host) 1103 { 1104 addr->host = host; 1105 UpdateRouterInfo (); 1106 } 1107 } 1108 1109 void RouterContext::UpdateStats () 1110 { 1111 if (m_IsFloodfill) 1112 { 1113 // update routers and leasesets 1114 m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS, std::to_string(i2p::data::netdb.GetNumLeaseSets ())); 1115 m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS, std::to_string(i2p::data::netdb.GetNumRouters ())); 1116 UpdateRouterInfo (); 1117 } 1118 } 1119 1120 void RouterContext::UpdateTimestamp (uint64_t ts) 1121 { 1122 if (ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL) 1123 UpdateRouterInfo (); 1124 } 1125 1126 bool RouterContext::Load () 1127 { 1128 { 1129 std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary); 1130 if (!fk.is_open ()) return false; 1131 fk.seekg (0, std::ios::end); 1132 size_t len = fk.tellg(); 1133 fk.seekg (0, std::ios::beg); 1134 1135 if (len == sizeof (i2p::data::Keys)) // old keys file format 1136 { 1137 i2p::data::Keys keys; 1138 fk.read ((char *)&keys, sizeof (keys)); 1139 m_Keys = keys; 1140 } 1141 else // new keys file format 1142 { 1143 uint8_t * buf = new uint8_t[len]; 1144 fk.read ((char *)buf, len); 1145 m_Keys.FromBuffer (buf, len); 1146 delete[] buf; 1147 } 1148 } 1149 std::shared_ptr<const i2p::data::IdentityEx> oldIdentity; 1150 if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 || 1151 m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) 1152 { 1153 // update keys 1154 LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new"); 1155 oldIdentity = m_Keys.GetPublic (); 1156 m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519, 1157 i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); 1158 SaveKeys (); 1159 } 1160 // read NTCP2 keys if available 1161 std::ifstream n2k (i2p::fs::DataDirPath (NTCP2_KEYS), std::ifstream::in | std::ifstream::binary); 1162 if (n2k) 1163 { 1164 n2k.seekg (0, std::ios::end); 1165 size_t len = n2k.tellg(); 1166 n2k.seekg (0, std::ios::beg); 1167 if (len == sizeof (NTCP2PrivateKeys)) 1168 { 1169 m_NTCP2Keys.reset (new NTCP2PrivateKeys ()); 1170 n2k.read ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys)); 1171 } 1172 n2k.close (); 1173 } 1174 // read SSU2 keys if available 1175 std::ifstream s2k (i2p::fs::DataDirPath (SSU2_KEYS), std::ifstream::in | std::ifstream::binary); 1176 if (s2k) 1177 { 1178 s2k.seekg (0, std::ios::end); 1179 size_t len = s2k.tellg(); 1180 s2k.seekg (0, std::ios::beg); 1181 if (len == sizeof (SSU2PrivateKeys)) 1182 { 1183 m_SSU2Keys.reset (new SSU2PrivateKeys ()); 1184 s2k.read ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys)); 1185 } 1186 s2k.close (); 1187 } 1188 // read RouterInfo 1189 m_RouterInfo.SetRouterIdentity (oldIdentity ? oldIdentity : GetIdentity ()); 1190 i2p::data::RouterInfo routerInfo(i2p::fs::DataDirPath (ROUTER_INFO)); 1191 if (!routerInfo.IsUnreachable ()) // router.info looks good 1192 { 1193 m_RouterInfo.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); 1194 if (oldIdentity) 1195 m_RouterInfo.SetRouterIdentity (GetIdentity ()); // from new keys 1196 m_IsFloodfill = m_RouterInfo.IsDeclaredFloodfill (); 1197 m_RouterInfo.SetProperty ("router.version", I2P_VERSION); 1198 m_RouterInfo.DeleteProperty ("coreVersion"); // TODO: remove later 1199 } 1200 else 1201 { 1202 LogPrint (eLogError, ROUTER_INFO, " is malformed. Creating new"); 1203 NewRouterInfo (); 1204 } 1205 1206 if (IsUnreachable ()) 1207 SetReachable (true, true); // we assume reachable until we discover firewall through peer tests 1208 1209 bool updated = false; 1210 // create new NTCP2 keys if required 1211 bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); 1212 bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); 1213 if ((ntcp2 || ygg) && !m_NTCP2Keys) 1214 { 1215 NewNTCP2Keys (); 1216 UpdateNTCP2Keys (); 1217 updated = true; 1218 } 1219 // create new SSU2 keys if required 1220 bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); 1221 if (ssu2 && !m_SSU2Keys) 1222 { 1223 NewSSU2Keys (); 1224 UpdateSSU2Keys (); 1225 updated = true; 1226 } 1227 if (m_RouterInfo.UpdateCongestion (i2p::data::RouterInfo::eLowCongestion)) 1228 updated = true; 1229 if (updated) 1230 UpdateRouterInfo (); 1231 1232 return true; 1233 } 1234 1235 void RouterContext::SaveKeys () 1236 { 1237 // save in the same format as .dat files 1238 std::ofstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ofstream::binary | std::ofstream::out); 1239 size_t len = m_Keys.GetFullLen (); 1240 uint8_t * buf = new uint8_t[len]; 1241 m_Keys.ToBuffer (buf, len); 1242 fk.write ((char *)buf, len); 1243 delete[] buf; 1244 } 1245 1246 std::shared_ptr<i2p::tunnel::TunnelPool> RouterContext::GetTunnelPool () const 1247 { 1248 return i2p::tunnel::tunnels.GetExploratoryPool (); 1249 } 1250 1251 int RouterContext::GetCongestionLevel (bool longTerm) const 1252 { 1253 return std::max ( 1254 i2p::tunnel::tunnels.GetCongestionLevel (), 1255 i2p::transport::transports.GetCongestionLevel (longTerm) 1256 ); 1257 } 1258 1259 void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len) 1260 { 1261 i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); 1262 } 1263 1264 bool RouterContext::HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, 1265 size_t len, uint32_t msgID, i2p::garlic::ECIESX25519AEADRatchetSession * from) 1266 { 1267 if (typeID == eI2NPTunnelTest) 1268 { 1269 // try tunnel test 1270 auto pool = GetTunnelPool (); 1271 if (pool && pool->ProcessTunnelTest (bufbe32toh (payload + TUNNEL_TEST_MSGID_OFFSET), bufbe64toh (payload + TUNNEL_TEST_TIMESTAMP_OFFSET))) 1272 return true; 1273 } 1274 auto msg = CreateI2NPMessage (typeID, payload, len, msgID); 1275 if (!msg) return false; 1276 i2p::HandleI2NPMessage (msg); 1277 return true; 1278 } 1279 1280 void RouterContext::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg) 1281 { 1282 if (m_Service) 1283 boost::asio::post (m_Service->GetService (), std::bind (&RouterContext::PostGarlicMessage, this, msg)); 1284 else 1285 LogPrint (eLogError, "Router: service is NULL"); 1286 } 1287 1288 void RouterContext::PostGarlicMessage (std::shared_ptr<I2NPMessage> msg) 1289 { 1290 uint8_t * buf = msg->GetPayload (); 1291 uint32_t len = bufbe32toh (buf); 1292 if (len > msg->GetLength ()) 1293 { 1294 LogPrint (eLogWarning, "Router: garlic message length ", len, " exceeds I2NP message length ", msg->GetLength ()); 1295 return; 1296 } 1297 buf += 4; 1298 if (!HandleECIESx25519TagMessage (buf, len)) // try tag first 1299 { 1300 // then Noise_N one-time decryption 1301 if (m_ECIESSession) 1302 m_ECIESSession->HandleNextMessage (buf, len); 1303 else 1304 LogPrint (eLogError, "Router: Session is not set for ECIES router"); 1305 } 1306 } 1307 1308 void RouterContext::ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg) 1309 { 1310 if (m_Service) 1311 boost::asio::post (m_Service->GetService (), std::bind (&RouterContext::PostDeliveryStatusMessage, this, msg)); 1312 else 1313 LogPrint (eLogError, "Router: service is NULL"); 1314 } 1315 1316 void RouterContext::PostDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg) 1317 { 1318 if (m_PublishReplyToken == bufbe32toh (msg->GetPayload () + DELIVERY_STATUS_MSGID_OFFSET)) 1319 { 1320 LogPrint (eLogInfo, "Router: Publishing confirmed. reply token=", m_PublishReplyToken); 1321 m_PublishExcluded.clear (); 1322 m_PublishReplyToken = 0; 1323 SchedulePublish (); 1324 } 1325 else 1326 i2p::garlic::GarlicDestination::ProcessDeliveryStatusMessage (msg); 1327 } 1328 1329 void RouterContext::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag) 1330 { 1331 if (m_Service) 1332 { 1333 struct 1334 { 1335 uint8_t k[32]; 1336 uint64_t t; 1337 } data; 1338 memcpy (data.k, key, 32); 1339 data.t = tag; 1340 boost::asio::post (m_Service->GetService (), [this,data](void) 1341 { 1342 AddECIESx25519Key (data.k, data.t); 1343 }); 1344 } 1345 else 1346 LogPrint (eLogError, "Router: service is NULL"); 1347 } 1348 1349 uint32_t RouterContext::GetUptime () const 1350 { 1351 return i2p::util::GetMonotonicSeconds () - m_StartupTime; 1352 } 1353 1354 bool RouterContext::Decrypt (const uint8_t * encrypted, uint8_t * data, i2p::data::CryptoKeyType preferredCrypto) const 1355 { 1356 return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data) : false; 1357 } 1358 1359 bool RouterContext::DecryptTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data) 1360 { 1361 return DecryptECIESTunnelBuildRecord (encrypted, data, ECIES_BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE); 1362 } 1363 1364 bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize) 1365 { 1366 // m_InitialNoiseState is h = SHA256(h || hepk) 1367 m_CurrentNoiseState = m_InitialNoiseState; 1368 m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk) 1369 uint8_t sharedSecret[32]; 1370 if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret)) 1371 { 1372 LogPrint (eLogWarning, "Router: Incorrect ephemeral public key"); 1373 return false; 1374 } 1375 m_CurrentNoiseState.MixKey (sharedSecret); 1376 encrypted += 32; 1377 uint8_t nonce[12]; 1378 memset (nonce, 0, 12); 1379 if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState.m_H, 32, 1380 m_CurrentNoiseState.m_CK + 32, nonce, data, clearTextSize, false)) // decrypt 1381 { 1382 LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed"); 1383 return false; 1384 } 1385 m_CurrentNoiseState.MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext) 1386 return true; 1387 } 1388 1389 bool RouterContext::DecryptTunnelShortRequestRecord (const uint8_t * encrypted, uint8_t * data) 1390 { 1391 return DecryptECIESTunnelBuildRecord (encrypted, data, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE); 1392 } 1393 1394 i2p::crypto::X25519Keys& RouterContext::GetNTCP2StaticKeys () 1395 { 1396 if (!m_NTCP2StaticKeys) 1397 { 1398 if (!m_NTCP2Keys) NewNTCP2Keys (); 1399 auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey); 1400 if (!m_NTCP2StaticKeys) 1401 m_NTCP2StaticKeys.reset (x); 1402 else 1403 delete x; 1404 } 1405 return *m_NTCP2StaticKeys; 1406 } 1407 1408 i2p::crypto::X25519Keys& RouterContext::GetSSU2StaticKeys () 1409 { 1410 if (!m_SSU2StaticKeys) 1411 { 1412 if (!m_SSU2Keys) NewSSU2Keys (); 1413 auto x = new i2p::crypto::X25519Keys (m_SSU2Keys->staticPrivateKey, m_SSU2Keys->staticPublicKey); 1414 if (!m_SSU2StaticKeys) 1415 m_SSU2StaticKeys.reset (x); 1416 else 1417 delete x; 1418 } 1419 return *m_SSU2StaticKeys; 1420 } 1421 1422 void RouterContext::ScheduleInitialPublish () 1423 { 1424 if (m_PublishTimer) 1425 { 1426 m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_INITIAL_PUBLISH_INTERVAL)); 1427 m_PublishTimer->async_wait (std::bind (&RouterContext::HandleInitialPublishTimer, 1428 this, std::placeholders::_1)); 1429 } 1430 else 1431 LogPrint (eLogError, "Router: Publish timer is NULL"); 1432 } 1433 1434 void RouterContext::HandleInitialPublishTimer (const boost::system::error_code& ecode) 1435 { 1436 if (ecode != boost::asio::error::operation_aborted) 1437 { 1438 if (m_RouterInfo.IsReachableBy (i2p::data::RouterInfo::eAllTransports)) 1439 { 1440 UpdateCongestion (); 1441 HandlePublishTimer (ecode); 1442 } 1443 else 1444 { 1445 UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); 1446 ScheduleInitialPublish (); 1447 } 1448 } 1449 } 1450 1451 void RouterContext::SchedulePublish () 1452 { 1453 if (m_PublishTimer) 1454 { 1455 m_PublishTimer->cancel (); 1456 m_PublishTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_PUBLISH_INTERVAL + 1457 GetRng ()() % ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE)); 1458 m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishTimer, 1459 this, std::placeholders::_1)); 1460 } 1461 else 1462 LogPrint (eLogError, "Router: Publish timer is NULL"); 1463 } 1464 1465 void RouterContext::HandlePublishTimer (const boost::system::error_code& ecode) 1466 { 1467 if (ecode != boost::asio::error::operation_aborted) 1468 { 1469 UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); 1470 if (!m_IsHiddenMode && !IsLimitedConnectivity ()) 1471 { 1472 m_PublishExcluded.clear (); 1473 m_PublishReplyToken = 0; 1474 if (IsFloodfill ()) 1475 { 1476 UpdateStats (); // for floodfill 1477 m_PublishExcluded.insert (i2p::context.GetIdentHash ()); // don't publish to ourselves 1478 } 1479 Publish (); 1480 SchedulePublishResend (); 1481 } 1482 else 1483 SchedulePublish (); 1484 } 1485 } 1486 1487 void RouterContext::Publish () 1488 { 1489 if (!i2p::transport::transports.IsOnline ()) return; 1490 if (m_PublishExcluded.size () > ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS) 1491 { 1492 LogPrint (eLogError, "Router: Couldn't publish our RouterInfo to ", ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS, " closest routers. Try again"); 1493 m_PublishExcluded.clear (); 1494 UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); 1495 } 1496 1497 auto floodfill = i2p::data::netdb.GetClosestFloodfill (i2p::context.GetIdentHash (), m_PublishExcluded); 1498 if (floodfill) 1499 { 1500 uint32_t replyToken; 1501 RAND_bytes ((uint8_t *)&replyToken, 4); 1502 LogPrint (eLogInfo, "Router: Publishing our RouterInfo to ", i2p::data::GetIdentHashAbbreviation(floodfill->GetIdentHash ()), ". reply token=", replyToken); 1503 auto onDrop = [this]() 1504 { 1505 if (m_Service) 1506 boost::asio::post (m_Service->GetService (), [this]() { HandlePublishResendTimer (boost::system::error_code ()); }); 1507 }; 1508 if (i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()) || // already connected 1509 (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) && // are we able to connect 1510 !IsLimitedConnectivity () && // and not limited connectivity 1511 !i2p::transport::transports.RoutesRestricted ())) // and routes not restricted 1512 { 1513 // send directly 1514 auto msg = CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken); 1515 msg->onDrop = onDrop; 1516 i2p::transport::transports.SendMessage (floodfill->GetIdentHash (), msg); 1517 } 1518 else 1519 { 1520 // otherwise through exploratory 1521 auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); 1522 auto outbound = exploratoryPool ? exploratoryPool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)) : nullptr; 1523 auto inbound = exploratoryPool ? exploratoryPool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)) : nullptr; 1524 if (inbound && outbound) 1525 { 1526 // encrypt for floodfill 1527 auto msg = CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken, inbound); 1528 msg->onDrop = onDrop; 1529 outbound->SendTunnelDataMsgTo (floodfill->GetIdentHash (), 0, 1530 i2p::garlic::WrapECIESX25519MessageForRouter (msg, floodfill->GetIdentity ()->GetEncryptionPublicKey ())); 1531 } 1532 else 1533 LogPrint (eLogInfo, "Router: Can't publish our RouterInfo. No tunnels. Try again in ", ROUTER_INFO_CONFIRMATION_TIMEOUT, " milliseconds"); 1534 } 1535 m_PublishExcluded.insert (floodfill->GetIdentHash ()); 1536 m_PublishReplyToken = replyToken; 1537 } 1538 else 1539 LogPrint (eLogInfo, "Router: Can't find floodfill to publish our RouterInfo"); 1540 } 1541 1542 void RouterContext::SchedulePublishResend () 1543 { 1544 if (m_PublishTimer) 1545 { 1546 m_PublishTimer->cancel (); 1547 m_PublishTimer->expires_from_now (boost::posix_time::milliseconds(ROUTER_INFO_CONFIRMATION_TIMEOUT)); 1548 m_PublishTimer->async_wait (std::bind (&RouterContext::HandlePublishResendTimer, 1549 this, std::placeholders::_1)); 1550 } 1551 else 1552 LogPrint (eLogError, "Router: Publish timer is NULL"); 1553 } 1554 1555 void RouterContext::HandlePublishResendTimer (const boost::system::error_code& ecode) 1556 { 1557 if (ecode != boost::asio::error::operation_aborted) 1558 { 1559 i2p::context.UpdateTimestamp (i2p::util::GetSecondsSinceEpoch ()); 1560 Publish (); 1561 SchedulePublishResend (); 1562 } 1563 } 1564 1565 void RouterContext::ScheduleCongestionUpdate () 1566 { 1567 if (m_CongestionUpdateTimer) 1568 { 1569 m_CongestionUpdateTimer->cancel (); 1570 m_CongestionUpdateTimer->expires_from_now (boost::posix_time::seconds( 1571 ROUTER_INFO_CONGESTION_UPDATE_INTERVAL + GetRng ()() % ROUTER_INFO_CONGESTION_UPDATE_INTERVAL_VARIANCE)); 1572 m_CongestionUpdateTimer->async_wait (std::bind (&RouterContext::HandleCongestionUpdateTimer, 1573 this, std::placeholders::_1)); 1574 } 1575 else 1576 LogPrint (eLogError, "Router: Congestion update timer is NULL"); 1577 } 1578 1579 void RouterContext::HandleCongestionUpdateTimer (const boost::system::error_code& ecode) 1580 { 1581 if (ecode != boost::asio::error::operation_aborted) 1582 { 1583 UpdateCongestion (); 1584 ScheduleCongestionUpdate (); 1585 } 1586 } 1587 1588 void RouterContext::UpdateCongestion () 1589 { 1590 auto c = i2p::data::RouterInfo::eLowCongestion; 1591 if (!AcceptsTunnels () || !m_ShareRatio) 1592 c = i2p::data::RouterInfo::eRejectAll; 1593 else 1594 { 1595 int congestionLevel = GetCongestionLevel (true); 1596 if (congestionLevel > CONGESTION_LEVEL_HIGH) 1597 c = i2p::data::RouterInfo::eHighCongestion; 1598 else if (congestionLevel > CONGESTION_LEVEL_MEDIUM) 1599 c = i2p::data::RouterInfo::eMediumCongestion; 1600 } 1601 if (m_RouterInfo.UpdateCongestion (c)) 1602 UpdateRouterInfo (); 1603 } 1604 1605 void RouterContext::ScheduleCleanupTimer () 1606 { 1607 if (m_CleanupTimer) 1608 { 1609 m_CleanupTimer->cancel (); 1610 m_CleanupTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CLEANUP_INTERVAL)); 1611 m_CleanupTimer->async_wait (std::bind (&RouterContext::HandleCleanupTimer, 1612 this, std::placeholders::_1)); 1613 } 1614 else 1615 LogPrint (eLogError, "Router: Cleanup timer is NULL"); 1616 } 1617 1618 void RouterContext::HandleCleanupTimer (const boost::system::error_code& ecode) 1619 { 1620 if (ecode != boost::asio::error::operation_aborted) 1621 { 1622 CleanupExpiredTags (); 1623 ScheduleCleanupTimer (); 1624 } 1625 } 1626 }