Browse Source

publish and handle SSU addreses without host

pull/1638/head
orignal 3 years ago
parent
commit
11c924bbe7
  1. 4
      libi2pd/RouterInfo.cpp
  2. 117
      libi2pd/SSU.cpp
  3. 3
      libi2pd/SSU.h

4
libi2pd/RouterInfo.cpp

@ -329,7 +329,7 @@ namespace data @@ -329,7 +329,7 @@ namespace data
if (isHost)
supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6;
else
if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented
if (introducers) supportedTransports |= eSSUV4; // in case if host is not presented
}
}
if (supportedTransports)
@ -545,7 +545,7 @@ namespace data @@ -545,7 +545,7 @@ namespace data
std::string caps;
if (address.IsPeerTesting ()) caps += CAPS_FLAG_SSU_TESTING;
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
if (address.ssu && address.ssu->introducers.empty ())
if (IsReachable ())
isPublished = true;
else
caps += CAPS_FLAG_V4;

117
libi2pd/SSU.cpp

@ -445,7 +445,7 @@ namespace transport @@ -445,7 +445,7 @@ namespace transport
if (router && address)
{
if (router->UsesIntroducer ())
m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, peerTest)); // always V4 thread
m_Service.post (std::bind (&SSUServer::CreateSessionThroughIntroducer, this, router, address, peerTest)); // always V4 thread
else
{
boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port);
@ -477,13 +477,13 @@ namespace transport @@ -477,13 +477,13 @@ namespace transport
}
}
void SSUServer::CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest)
void SSUServer::CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
std::shared_ptr<const i2p::data::RouterInfo::Address> address, bool peerTest)
{
if (router && router->UsesIntroducer ())
{
auto address = router->GetSSUAddress (true); // v4 only for now
if (address)
{
if (router && router->UsesIntroducer () && address)
{
if (!address->host.is_unspecified () && address->port)
{
boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port);
auto it = m_Sessions.find (remoteEndpoint);
// check if session is presented already
@ -494,70 +494,67 @@ namespace transport @@ -494,70 +494,67 @@ namespace transport
session->SendPeerTest ();
return;
}
// create new session
int numIntroducers = address->ssu->introducers.size ();
if (numIntroducers > 0)
}
// create new session
int numIntroducers = address->ssu->introducers.size ();
if (numIntroducers > 0)
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
std::shared_ptr<SSUSession> introducerSession;
const i2p::data::RouterInfo::Introducer * introducer = nullptr;
// we might have a session to introducer already
for (int i = 0; i < numIntroducers; i++)
{
uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
std::shared_ptr<SSUSession> introducerSession;
const i2p::data::RouterInfo::Introducer * introducer = nullptr;
// we might have a session to introducer already
for (int i = 0; i < numIntroducers; i++)
auto intr = &(address->ssu->introducers[i]);
if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer
boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort);
if (ep.address ().is_v4 ()) // ipv4 only
{
auto intr = &(address->ssu->introducers[i]);
if (intr->iExp > 0 && ts > intr->iExp) continue; // skip expired introducer
boost::asio::ip::udp::endpoint ep (intr->iHost, intr->iPort);
if (ep.address ().is_v4 ()) // ipv4 only
if (!introducer) introducer = intr; // we pick first one for now
auto it = m_Sessions.find (ep);
if (it != m_Sessions.end ())
{
if (!introducer) introducer = intr; // we pick first one for now
it = m_Sessions.find (ep);
if (it != m_Sessions.end ())
{
introducerSession = it->second;
break;
}
introducerSession = it->second;
break;
}
}
if (!introducer)
{
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 non-expired introducers presented");
return;
}
}
if (!introducer)
{
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no ipv4 non-expired introducers presented");
return;
}
if (introducerSession) // session found
LogPrint (eLogWarning, "SSU: Session to introducer already exists");
else // create new
{
LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost);
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
m_Sessions[introducerEndpoint] = introducerSession;
}
#if BOOST_VERSION >= 104900
if (!address->host.is_unspecified () && address->port)
#endif
if (introducerSession) // session found
LogPrint (eLogWarning, "SSU: Session to introducer already exists");
else // create new
{
LogPrint (eLogDebug, "SSU: Creating new session to introducer ", introducer->iHost);
boost::asio::ip::udp::endpoint introducerEndpoint (introducer->iHost, introducer->iPort);
introducerSession = std::make_shared<SSUSession> (*this, introducerEndpoint, router);
m_Sessions[introducerEndpoint] = introducerSession;
}
if (!address->host.is_unspecified () && address->port)
{
// create session
boost::asio::ip::udp::endpoint remoteEndpoint (address->host, address->port);
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
m_Sessions[remoteEndpoint] = session;
// introduce
LogPrint (eLogInfo, "SSU: Introduce new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()),
"] through introducer ", introducer->iHost, ":", introducer->iPort);
session->WaitForIntroduction ();
if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable
{
// create session
auto session = std::make_shared<SSUSession> (*this, remoteEndpoint, router, peerTest);
m_Sessions[remoteEndpoint] = session;
// introduce
LogPrint (eLogInfo, "SSU: Introduce new session to [", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()),
"] through introducer ", introducer->iHost, ":", introducer->iPort);
session->WaitForIntroduction ();
if (i2p::context.GetRouterInfo ().UsesIntroducer ()) // if we are unreachable
{
uint8_t buf[1];
Send (buf, 0, remoteEndpoint); // send HolePunch
}
uint8_t buf[1];
Send (buf, 0, remoteEndpoint); // send HolePunch
}
introducerSession->Introduce (*introducer, router);
}
else
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no introducers present");
introducerSession->Introduce (*introducer, router);
}
else
LogPrint (eLogWarning, "SSU: Router ", i2p::data::GetIdentHashAbbreviation (router->GetIdentHash ()), " doesn't have SSU address");
LogPrint (eLogWarning, "SSU: Can't connect to unreachable router and no introducers present");
}
}

3
libi2pd/SSU.h

@ -90,7 +90,8 @@ namespace transport @@ -90,7 +90,8 @@ namespace transport
void HandleReceivedPackets (std::vector<SSUPacket *> packets,
std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSUSession> >* sessions);
void CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, bool peerTest = false);
void CreateSessionThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
std::shared_ptr<const i2p::data::RouterInfo::Address> address, bool peerTest = false);
template<typename Filter>
std::shared_ptr<SSUSession> GetRandomV4Session (Filter filter);
template<typename Filter>

Loading…
Cancel
Save