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