diff --git a/RouterContext.cpp b/RouterContext.cpp index 3c37e88c..966da6ac 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -266,8 +266,9 @@ namespace i2p } } // delete previous introducers - for (auto& addr : addresses) - addr->introducers.clear (); + for (auto& addr : addresses) + if (addr->ssu) + addr->ssu->introducers.clear (); // update UpdateRouterInfo (); @@ -298,7 +299,8 @@ namespace i2p } // delete previous introducers for (auto& addr : addresses) - addr->introducers.clear (); + if (addr->ssu) + addr->ssu->introducers.clear (); // update UpdateRouterInfo (); diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 4ae2f9e5..08d46ecb 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -175,11 +175,14 @@ namespace data if (!strcmp (transportStyle, "NTCP")) address->transportStyle = eTransportNTCP; else if (!strcmp (transportStyle, "SSU")) + { address->transportStyle = eTransportSSU; + address->ssu.reset (new SSUExt ()); + address->ssu->mtu = 0; + } else address->transportStyle = eTransportUnknown; address->port = 0; - address->mtu = 0; uint16_t size, r = 0; s.read ((char *)&size, sizeof (size)); if (!s) return; size = be16toh (size); @@ -220,9 +223,19 @@ namespace data else if (!strcmp (key, "port")) address->port = boost::lexical_cast(value); else if (!strcmp (key, "mtu")) - address->mtu = boost::lexical_cast(value); + { + if (address->ssu) + address->ssu->mtu = boost::lexical_cast(value); + else + LogPrint (eLogWarning, "RouterInfo: Unexpected field 'mtu' for NTCP"); + } else if (!strcmp (key, "key")) - Base64ToByteStream (value, strlen (value), address->key, 32); + { + if (address->ssu) + Base64ToByteStream (value, strlen (value), address->ssu->key, 32); + else + LogPrint (eLogWarning, "RouterInfo: Unexpected field 'key' for NTCP"); + } else if (!strcmp (key, "caps")) ExtractCaps (value); else if (key[0] == 'i') @@ -237,9 +250,9 @@ namespace data LogPrint (eLogError, "RouterInfo: Unexpected introducer's index ", index, " skipped"); if (s) continue; else return; } - if (index >= address->introducers.size ()) - address->introducers.resize (index + 1); - Introducer& introducer = address->introducers.at (index); + if (index >= address->ssu->introducers.size ()) + address->ssu->introducers.resize (index + 1); + Introducer& introducer = address->ssu->introducers.at (index); if (!strcmp (key, "ihost")) { boost::system::error_code ecode; @@ -417,10 +430,10 @@ namespace data if (address.transportStyle == eTransportSSU) { // write introducers if any - if (address.introducers.size () > 0) + if (address.ssu->introducers.size () > 0) { int i = 0; - for (const auto& introducer: address.introducers) + for (const auto& introducer: address.ssu->introducers) { WriteString ("ihost" + boost::lexical_cast(i), properties); properties << '='; @@ -429,7 +442,7 @@ namespace data i++; } i = 0; - for (const auto& introducer: address.introducers) + for (const auto& introducer: address.ssu->introducers) { WriteString ("ikey" + boost::lexical_cast(i), properties); properties << '='; @@ -441,7 +454,7 @@ namespace data i++; } i = 0; - for (const auto& introducer: address.introducers) + for (const auto& introducer: address.ssu->introducers) { WriteString ("iport" + boost::lexical_cast(i), properties); properties << '='; @@ -450,7 +463,7 @@ namespace data i++; } i = 0; - for (const auto& introducer: address.introducers) + for (const auto& introducer: address.ssu->introducers) { WriteString ("itag" + boost::lexical_cast(i), properties); properties << '='; @@ -463,16 +476,16 @@ namespace data WriteString ("key", properties); properties << '='; char value[64]; - size_t l = ByteStreamToBase64 (address.key, 32, value, 64); + size_t l = ByteStreamToBase64 (address.ssu->key, 32, value, 64); value[l] = 0; WriteString (value, properties); properties << ';'; // write mtu - if (address.mtu) + if (address.ssu->mtu) { WriteString ("mtu", properties); properties << '='; - WriteString (boost::lexical_cast(address.mtu), properties); + WriteString (boost::lexical_cast(address.ssu->mtu), properties); properties << ';'; } } @@ -589,7 +602,6 @@ namespace data addr->transportStyle = eTransportNTCP; addr->cost = 2; addr->date = 0; - addr->mtu = 0; for (const auto& it: *m_Addresses) // don't insert same address twice if (*it == *addr) return; m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4; @@ -604,8 +616,9 @@ namespace data addr->transportStyle = eTransportSSU; addr->cost = 10; // NTCP should have priority over SSU addr->date = 0; - addr->mtu = mtu; - memcpy (addr->key, key, 32); + addr->ssu.reset (new SSUExt ()); + addr->ssu->mtu = mtu; + memcpy (addr->ssu->key, key, 32); for (const auto& it: *m_Addresses) // don't insert same address twice if (*it == *addr) return; m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4; @@ -621,9 +634,9 @@ namespace data { if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ()) { - for (auto& intro: addr->introducers) + for (auto& intro: addr->ssu->introducers) if (intro.iTag == introducer.iTag) return false; // already presented - addr->introducers.push_back (introducer); + addr->ssu->introducers.push_back (introducer); return true; } } @@ -636,10 +649,10 @@ namespace data { if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ()) { - for (auto it = addr->introducers.begin (); it != addr->introducers.end (); ++it) + for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it) if ( boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e) { - addr->introducers.erase (it); + addr->ssu->introducers.erase (it); return true; } } diff --git a/RouterInfo.h b/RouterInfo.h index c51d3ce4..7300e579 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -79,17 +79,22 @@ namespace data uint32_t iTag; }; + struct SSUExt + { + int mtu; + IntroKey key; // intro key for SSU + std::vector introducers; + }; + struct Address { TransportStyle transportStyle; boost::asio::ip::address host; std::string addressString; - int port, mtu; + int port; uint64_t date; uint8_t cost; - // SSU only - IntroKey key; // intro key for SSU - std::vector introducers; + std::unique_ptr ssu; // not null for SSU bool IsCompatible (const boost::asio::ip::address& other) const { diff --git a/SSU.cpp b/SSU.cpp index 9f74185f..9dc05608 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -417,7 +417,7 @@ namespace transport return; } // create new session - int numIntroducers = address->introducers.size (); + int numIntroducers = address->ssu->introducers.size (); if (numIntroducers > 0) { std::shared_ptr introducerSession; @@ -425,7 +425,7 @@ namespace transport // we might have a session to introducer already for (int i = 0; i < numIntroducers; i++) { - auto intr = &(address->introducers[i]); + auto intr = &(address->ssu->introducers[i]); boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort); if (ep.address ().is_v4 ()) // ipv4 only { diff --git a/SSUData.cpp b/SSUData.cpp index ad38cf25..1782da26 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -54,23 +54,23 @@ namespace transport { if (remoteRouter) return; auto ssuAddress = remoteRouter->GetSSUAddress (); - if (ssuAddress && ssuAddress->mtu) + if (ssuAddress && ssuAddress->ssu->mtu) { if (m_Session.IsV6 ()) - m_PacketSize = ssuAddress->mtu - IPV6_HEADER_SIZE - UDP_HEADER_SIZE; + m_PacketSize = ssuAddress->ssu->mtu - IPV6_HEADER_SIZE - UDP_HEADER_SIZE; else - m_PacketSize = ssuAddress->mtu - IPV4_HEADER_SIZE - UDP_HEADER_SIZE; + m_PacketSize = ssuAddress->ssu->mtu - IPV4_HEADER_SIZE - UDP_HEADER_SIZE; if (m_PacketSize > 0) { // make sure packet size multiple of 16 m_PacketSize >>= 4; m_PacketSize <<= 4; if (m_PacketSize > m_MaxPacketSize) m_PacketSize = m_MaxPacketSize; - LogPrint (eLogDebug, "SSU: MTU=", ssuAddress->mtu, " packet size=", m_PacketSize); + LogPrint (eLogDebug, "SSU: MTU=", ssuAddress->ssu->mtu, " packet size=", m_PacketSize); } else { - LogPrint (eLogWarning, "SSU: Unexpected MTU ", ssuAddress->mtu); + LogPrint (eLogWarning, "SSU: Unexpected MTU ", ssuAddress->ssu->mtu); m_PacketSize = m_MaxPacketSize; } } diff --git a/SSUSession.cpp b/SSUSession.cpp index a47295fa..540cf907 100644 --- a/SSUSession.cpp +++ b/SSUSession.cpp @@ -22,14 +22,14 @@ namespace transport { // we are client auto address = router->GetSSUAddress (false); - if (address) m_IntroKey = address->key; + if (address) m_IntroKey = address->ssu->key; m_Data.AdjustPacketSize (router); // mtu } else { // we are server auto address = i2p::context.GetRouterInfo ().GetSSUAddress (false); - if (address) m_IntroKey = address->key; + if (address) m_IntroKey = address->ssu->key; } m_CreationTime = i2p::util::GetSecondsSinceEpoch (); } @@ -115,8 +115,8 @@ namespace transport LogPrint (eLogInfo, "SSU is not supported"); return; } - if (Validate (buf, len, address->key)) - Decrypt (buf, len, address->key); + if (Validate (buf, len, address->ssu->key)) + Decrypt (buf, len, address->ssu->key); else { LogPrint (eLogWarning, "SSU: MAC verification failed ", len, " bytes from ", senderEndpoint); @@ -402,7 +402,7 @@ namespace transport payload += 2; *payload = 0; // challenge payload++; - memcpy (payload, (const uint8_t *)address->key, 32); + memcpy (payload, (const uint8_t *)address->ssu->key, 32); payload += 32; htobe32buf (payload, nonce); // nonce @@ -1075,7 +1075,7 @@ namespace transport // send our intro key to address instead it's own auto addr = i2p::context.GetRouterInfo ().GetSSUAddress (); if (addr) - memcpy (payload, addr->key, 32); // intro key + memcpy (payload, addr->ssu->key, 32); // intro key else LogPrint (eLogInfo, "SSU is not supported. Can't send peer test"); } @@ -1114,7 +1114,7 @@ namespace transport if (!nonce) nonce = 1; m_IsPeerTest = false; m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1, shared_from_this ()); - SendPeerTest (nonce, boost::asio::ip::address(), 0, address->key, false, false); // address and port always zero for Alice + SendPeerTest (nonce, boost::asio::ip::address(), 0, address->ssu->key, false, false); // address and port always zero for Alice } void SSUSession::SendKeepAlive ()