Browse Source

Merge pull request #438 from PurpleI2P/openssl

transort resolvers
pull/464/head
orignal 8 years ago
parent
commit
31ff1372ae
  1. 81
      AddressBook.cpp
  2. 26
      AddressBook.h
  3. 1
      Config.cpp
  4. 8
      Daemon.cpp
  5. 12
      HTTPServer.cpp
  6. 14
      NTCPSession.cpp
  7. 43
      NetDb.cpp
  8. 3
      NetDb.h
  9. 48
      RouterContext.cpp
  10. 3
      RouterContext.h
  11. 130
      RouterInfo.cpp
  12. 15
      RouterInfo.h
  13. 60
      Transports.cpp
  14. 14
      UPnP.cpp
  15. 5
      UPnP.h
  16. 11
      Win32/Win32App.cpp
  17. 2
      docs/build_requirements.md
  18. 10
      docs/family.md
  19. 8
      util.cpp
  20. 2
      version.h

81
AddressBook.cpp

@ -330,8 +330,7 @@ namespace client @@ -330,8 +330,7 @@ namespace client
LoadHostsFromStream (f);
m_IsLoaded = true;
}
// load local
m_Storage->LoadLocal (m_Addresses);
LoadLocal ();
}
void AddressBook::LoadHostsFromStream (std::istream& f)
@ -395,6 +394,40 @@ namespace client @@ -395,6 +394,40 @@ namespace client
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
}
void AddressBook::LoadLocal ()
{
std::map<std::string, i2p::data::IdentHash> localAddresses;
m_Storage->LoadLocal (localAddresses);
for (auto it: localAddresses)
{
auto dot = it.first.find ('.');
if (dot != std::string::npos)
{
auto domain = it.first.substr (dot + 1);
auto it1 = m_Addresses.find (domain); // find domain in our addressbook
if (it1 != m_Addresses.end ())
{
auto dest = context.FindLocalDestination (it1->second);
if (dest)
{
// address is ours
std::shared_ptr<AddressResolver> resolver;
auto it2 = m_Resolvers.find (it1->second);
if (it2 != m_Resolvers.end ())
resolver = it2->second; // resolver exists
else
{
// create new resolver
resolver = std::make_shared<AddressResolver>(dest);
m_Resolvers.insert (std::make_pair(it1->second, resolver));
}
resolver->AddAddress (it.first, it.second);
}
}
}
}
}
bool AddressBook::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified)
{
if (m_Storage)
@ -653,6 +686,50 @@ namespace client @@ -653,6 +686,50 @@ namespace client
m_Book.LoadHostsFromStream (s);
return true;
}
AddressResolver::AddressResolver (std::shared_ptr<ClientDestination> destination):
m_LocalDestination (destination)
{
if (m_LocalDestination)
{
auto datagram = m_LocalDestination->GetDatagramDestination ();
if (!datagram)
datagram = m_LocalDestination->CreateDatagramDestination ();
datagram->SetReceiver (std::bind (&AddressResolver::HandleRequest, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
ADDRESS_RESOLVER_DATAGRAM_PORT);
}
}
void AddressResolver::HandleRequest (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
{
if (len < 9 || len < buf[8] + 9U)
{
LogPrint (eLogError, "Address request is too short ", len);
return;
}
// read requested address
uint8_t l = buf[8];
char address[255];
memcpy (address, buf + 9, l);
address[l] = 0;
// send response
uint8_t response[40];
memset (response, 0, 4); // reserved
memcpy (response + 4, buf + 4, 4); // nonce
auto it = m_LocalAddresses.find (address); // address lookup
if (it != m_LocalAddresses.end ())
memcpy (response + 8, it->second, 32); // ident
else
memset (response + 8, 0, 32); // not found
m_LocalDestination->GetDatagramDestination ()->SendDatagramTo (response, 40, from.GetIdentHash (), toPort, fromPort);
}
void AddressResolver::AddAddress (const std::string& name, const i2p::data::IdentHash& ident)
{
m_LocalAddresses[name] = ident;
}
}
}

26
AddressBook.h

@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
#include "Base.h"
#include "Identity.h"
#include "Log.h"
#include "Destination.h"
namespace i2p
{
@ -23,7 +24,7 @@ namespace client @@ -23,7 +24,7 @@ namespace client
const int CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT = 720; // in minutes (12 hours)
const int CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT = 5; // in minutes
const int SUBSCRIPTION_REQUEST_TIMEOUT = 60; //in second
inline std::string GetB32Address(const i2p::data::IdentHash& ident) { return ident.ToBase32().append(".b32.i2p"); }
class AddressBookStorage // interface for storage
@ -45,6 +46,7 @@ namespace client @@ -45,6 +46,7 @@ namespace client
};
class AddressBookSubscription;
class AddressResolver;
class AddressBook
{
public:
@ -74,13 +76,15 @@ namespace client @@ -74,13 +76,15 @@ namespace client
void LoadHosts ();
void LoadSubscriptions ();
void LoadLocal ();
void HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode);
private:
std::mutex m_AddressBookMutex;
std::map<std::string, i2p::data::IdentHash> m_Addresses, m_LocalAddresses;
std::map<std::string, i2p::data::IdentHash> m_Addresses;
std::map<i2p::data::IdentHash, std::shared_ptr<AddressResolver> > m_Resolvers; // local destination->resolver
AddressBookStorage * m_Storage;
volatile bool m_IsLoaded, m_IsDownloading;
std::vector<AddressBookSubscription *> m_Subscriptions;
@ -106,6 +110,24 @@ namespace client @@ -106,6 +110,24 @@ namespace client
std::string m_Link, m_Etag, m_LastModified;
// m_Etag must be surrounded by ""
};
const uint16_t ADDRESS_RESOLVER_DATAGRAM_PORT = 53;
class AddressResolver
{
public:
AddressResolver (std::shared_ptr<ClientDestination> destination);
void AddAddress (const std::string& name, const i2p::data::IdentHash& ident);
private:
void HandleRequest (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
private:
std::shared_ptr<ClientDestination> m_LocalDestination;
std::map<std::string, i2p::data::IdentHash> m_LocalAddresses;
};
}
}

1
Config.cpp

@ -117,6 +117,7 @@ namespace config { @@ -117,6 +117,7 @@ namespace config {
("datadir", value<std::string>()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
("host", value<std::string>()->default_value("0.0.0.0"), "External IP")
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
("ipv4", value<bool>()->zero_tokens()->default_value(true), "Enable communication through ipv4")
("ipv6", value<bool>()->zero_tokens()->default_value(false), "Enable communication through ipv6")
("daemon", value<bool>()->zero_tokens()->default_value(false), "Router will go to background after start")
("service", value<bool>()->zero_tokens()->default_value(false), "Router will use system folders like '/var/lib/i2pd'")

8
Daemon.cpp

@ -72,7 +72,7 @@ namespace i2p @@ -72,7 +72,7 @@ namespace i2p
if (config == "")
{
config = i2p::fs::DataDirPath("i2p.conf");
// use i2p.cong only if exists
// use i2p.conf only if exists
if (!i2p::fs::Exists (config)) config = ""; /* reset */
}
@ -104,9 +104,11 @@ namespace i2p @@ -104,9 +104,11 @@ namespace i2p
i2p::context.UpdateAddress (boost::asio::ip::address::from_string (host));
}
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool ipv4; i2p::config::GetOption("ipv4", ipv4);
bool transit; i2p::config::GetOption("notransit", transit);
i2p::context.SetSupportsV6 (ipv6);
i2p::context.SetSupportsV6 (ipv6);
i2p::context.SetSupportsV4 (ipv4);
i2p::context.SetAcceptsTunnels (!transit);
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);

12
HTTPServer.cpp

@ -427,18 +427,18 @@ namespace util @@ -427,18 +427,18 @@ namespace util
s << " (" << i2p::transport::transports.GetOutBandwidth () <<" Bps)<br>\r\n";
s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n<br>\r\n";
s << "<b>Our external address:</b>" << "<br>\r\n" ;
for (auto& address : i2p::context.GetRouterInfo().GetAddresses())
for (auto address : i2p::context.GetRouterInfo().GetAddresses())
{
switch (address.transportStyle)
switch (address->transportStyle)
{
case i2p::data::RouterInfo::eTransportNTCP:
if (address.host.is_v6 ())
if (address->host.is_v6 ())
s << "NTCP6&nbsp;&nbsp;";
else
s << "NTCP&nbsp;&nbsp;";
break;
case i2p::data::RouterInfo::eTransportSSU:
if (address.host.is_v6 ())
if (address->host.is_v6 ())
s << "SSU6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
else
s << "SSU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
@ -446,7 +446,7 @@ namespace util @@ -446,7 +446,7 @@ namespace util
default:
s << "Unknown&nbsp;&nbsp;";
}
s << address.host.to_string() << ":" << address.port << "<br>\r\n";
s << address->host.to_string() << ":" << address->port << "<br>\r\n";
}
s << "<br>\r\n<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
@ -534,7 +534,7 @@ namespace util @@ -534,7 +534,7 @@ namespace util
auto dest = i2p::client::context.FindLocalDestination (ident);
if (dest)
{
s << "<b>Base64:</b><br>\r\n<textarea readonly=\"readonly\" cols=\"64\" rows=\"1\" wrap=\"off\">";
s << "<b>Base64:</b><br>\r\n<textarea readonly=\"readonly\" cols=\"64\" rows=\"11\" wrap=\"on\">";
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
s << "<b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets () << "</i><br>\r\n";
auto pool = dest->GetTunnelPool ();

14
NTCPSession.cpp

@ -759,15 +759,15 @@ namespace transport @@ -759,15 +759,15 @@ namespace transport
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&NTCPServer::Run, this));
// create acceptors
auto addresses = context.GetRouterInfo ().GetAddresses ();
for (auto& address : addresses)
auto& addresses = context.GetRouterInfo ().GetAddresses ();
for (auto address: addresses)
{
if (address.transportStyle == i2p::data::RouterInfo::eTransportNTCP && address.host.is_v4 ())
if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP && address->host.is_v4 ())
{
m_NTCPAcceptor = new boost::asio::ip::tcp::acceptor (m_Service,
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address.port));
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), address->port));
LogPrint (eLogInfo, "NTCP: Start listening TCP port ", address.port);
LogPrint (eLogInfo, "NTCP: Start listening TCP port ", address->port);
auto conn = std::make_shared<NTCPSession>(*this);
m_NTCPAcceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAccept, this,
conn, std::placeholders::_1));
@ -777,10 +777,10 @@ namespace transport @@ -777,10 +777,10 @@ namespace transport
m_NTCPV6Acceptor = new boost::asio::ip::tcp::acceptor (m_Service);
m_NTCPV6Acceptor->open (boost::asio::ip::tcp::v6());
m_NTCPV6Acceptor->set_option (boost::asio::ip::v6_only (true));
m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address.port));
m_NTCPV6Acceptor->bind (boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), address->port));
m_NTCPV6Acceptor->listen ();
LogPrint (eLogInfo, "NTCP: Start listening V6 TCP port ", address.port);
LogPrint (eLogInfo, "NTCP: Start listening V6 TCP port ", address->port);
auto conn = std::make_shared<NTCPSession> (*this);
m_NTCPV6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCPServer::HandleAcceptV6,
this, conn, std::placeholders::_1));

43
NetDb.cpp

@ -118,6 +118,7 @@ namespace data @@ -118,6 +118,7 @@ namespace data
{
SaveUpdated ();
ManageLeaseSets ();
ManageLookupResponses ();
}
lastSave = ts;
}
@ -671,13 +672,31 @@ namespace data @@ -671,13 +672,31 @@ namespace data
if (!replyMsg)
{
LogPrint (eLogWarning, "NetDb: Requested ", key, " not found. ", numExcluded, " excluded");
std::set<IdentHash> excludedRouters;
for (int i = 0; i < numExcluded; i++)
{
excludedRouters.insert (excluded);
excluded += 32;
// find or cleate response
std::vector<IdentHash> closestFloodfills;
bool found = false;
if (!numExcluded)
{
auto it = m_LookupResponses.find (ident);
if (it != m_LookupResponses.end ())
{
closestFloodfills = it->second.first;
found = true;
}
}
if (!found)
{
std::set<IdentHash> excludedRouters;
for (int i = 0; i < numExcluded; i++)
{
excludedRouters.insert (excluded);
excluded += 32;
}
closestFloodfills = GetClosestFloodfills (ident, 3, excludedRouters, true);
if (!numExcluded) // save if no excluded
m_LookupResponses[ident] = std::make_pair(closestFloodfills, i2p::util::GetSecondsSinceEpoch ());
}
replyMsg = CreateDatabaseSearchReply (ident, GetClosestFloodfills (ident, 3, excludedRouters, true));
replyMsg = CreateDatabaseSearchReply (ident, closestFloodfills);
}
}
@ -972,5 +991,17 @@ namespace data @@ -972,5 +991,17 @@ namespace data
it++;
}
}
void NetDb::ManageLookupResponses ()
{
auto ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it = m_LookupResponses.begin (); it != m_LookupResponses.end ();)
{
if (ts > it->second.second + 180) // 3 minutes
it = m_LookupResponses.erase (it);
else
it++;
}
}
}
}

3
NetDb.h

@ -84,6 +84,7 @@ namespace data @@ -84,6 +84,7 @@ namespace data
void Publish ();
void ManageLeaseSets ();
void ManageRequests ();
void ManageLookupResponses ();
template<typename Filter>
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
@ -108,6 +109,8 @@ namespace data @@ -108,6 +109,8 @@ namespace data
friend class NetDbRequests;
NetDbRequests m_Requests;
std::map<IdentHash, std::pair<std::vector<IdentHash>, uint64_t> > m_LookupResponses; // ident->(closest FFs, timestamp)
};
extern NetDb netdb;

48
RouterContext.cpp

@ -92,11 +92,11 @@ namespace i2p @@ -92,11 +92,11 @@ namespace i2p
void RouterContext::UpdatePort (int port)
{
bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ())
for (auto address : m_RouterInfo.GetAddresses ())
{
if (address.port != port)
if (address->port != port)
{
address.port = port;
address->port = port;
updated = true;
}
}
@ -107,11 +107,11 @@ namespace i2p @@ -107,11 +107,11 @@ namespace i2p
void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
{
bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ())
for (auto address : m_RouterInfo.GetAddresses ())
{
if (address.host != host && address.IsCompatible (host))
if (address->host != host && address->IsCompatible (host))
{
address.host = host;
address->host = host;
updated = true;
}
}
@ -206,15 +206,15 @@ namespace i2p @@ -206,15 +206,15 @@ namespace i2p
auto& addresses = m_RouterInfo.GetAddresses ();
for (size_t i = 0; i < addresses.size (); i++)
{
if (addresses[i].transportStyle == i2p::data::RouterInfo::eTransportNTCP)
if (addresses[i]->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
{
addresses.erase (addresses.begin () + i);
break;
}
}
// delete previous introducers
for (auto& addr : addresses)
addr.introducers.clear ();
for (auto addr : addresses)
addr->introducers.clear ();
// update
UpdateRouterInfo ();
@ -235,16 +235,16 @@ namespace i2p @@ -235,16 +235,16 @@ namespace i2p
auto& addresses = m_RouterInfo.GetAddresses ();
for (size_t i = 0; i < addresses.size (); i++)
{
if (addresses[i].transportStyle == i2p::data::RouterInfo::eTransportSSU)
if (addresses[i]->transportStyle == i2p::data::RouterInfo::eTransportSSU)
{
// insert NTCP address with host/port from SSU
m_RouterInfo.AddNTCPAddress (addresses[i].host.to_string ().c_str (), addresses[i].port);
m_RouterInfo.AddNTCPAddress (addresses[i]->host.to_string ().c_str (), addresses[i]->port);
break;
}
}
// delete previous introducers
for (auto& addr : addresses)
addr.introducers.clear ();
for (auto addr : addresses)
addr->introducers.clear ();
// update
UpdateRouterInfo ();
@ -257,26 +257,36 @@ namespace i2p @@ -257,26 +257,36 @@ namespace i2p
else
m_RouterInfo.DisableV6 ();
UpdateRouterInfo ();
}
}
void RouterContext::SetSupportsV4 (bool supportsV4)
{
if (supportsV4)
m_RouterInfo.EnableV4 ();
else
m_RouterInfo.DisableV4 ();
UpdateRouterInfo ();
}
void RouterContext::UpdateNTCPV6Address (const boost::asio::ip::address& host)
{
bool updated = false, found = false;
int port = 0;
auto& addresses = m_RouterInfo.GetAddresses ();
for (auto& addr : addresses)
for (auto addr: addresses)
{
if (addr.host.is_v6 () && addr.transportStyle == i2p::data::RouterInfo::eTransportNTCP)
if (addr->host.is_v6 () && addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP)
{
if (addr.host != host)
if (addr->host != host)
{
addr.host = host;
addr->host = host;
updated = true;
}
found = true;
}
else
port = addr.port;
port = addr->port;
}
if (!found)
{

3
RouterContext.h

@ -64,7 +64,10 @@ namespace i2p @@ -64,7 +64,10 @@ namespace i2p
bool AcceptsTunnels () const { return m_AcceptsTunnels; };
void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; };
bool SupportsV6 () const { return m_RouterInfo.IsV6 (); };
bool SupportsV4 () const { return m_RouterInfo.IsV4 (); };
void SetSupportsV6 (bool supportsV6);
void SetSupportsV4 (bool supportsV4);
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
void UpdateStats ();

130
RouterInfo.cpp

@ -232,7 +232,7 @@ namespace data @@ -232,7 +232,7 @@ namespace data
}
if (isValidAddress)
{
m_Addresses.push_back(address);
m_Addresses.push_back(std::make_shared<Address>(address));
m_SupportedTransports |= supportedTransports;
}
}
@ -359,8 +359,9 @@ namespace data @@ -359,8 +359,9 @@ namespace data
// addresses
uint8_t numAddresses = m_Addresses.size ();
s.write ((char *)&numAddresses, sizeof (numAddresses));
for (auto& address : m_Addresses)
for (auto addr : m_Addresses)
{
Address& address = *addr;
s.write ((char *)&address.cost, sizeof (address.cost));
s.write ((char *)&address.date, sizeof (address.date));
std::stringstream properties;
@ -543,46 +544,46 @@ namespace data @@ -543,46 +544,46 @@ namespace data
void RouterInfo::AddNTCPAddress (const char * host, int port)
{
Address addr;
addr.host = boost::asio::ip::address::from_string (host);
addr.port = port;
addr.transportStyle = eTransportNTCP;
addr.cost = 2;
addr.date = 0;
addr.mtu = 0;
auto addr = std::make_shared<Address>();
addr->host = boost::asio::ip::address::from_string (host);
addr->port = port;
addr->transportStyle = eTransportNTCP;
addr->cost = 2;
addr->date = 0;
addr->mtu = 0;
for (auto it: m_Addresses) // don't insert same address twice
if (it == addr) return;
if (*it == *addr) return;
m_Addresses.push_back(addr);
m_SupportedTransports |= addr.host.is_v6 () ? eNTCPV6 : eNTCPV4;
m_SupportedTransports |= addr->host.is_v6 () ? eNTCPV6 : eNTCPV4;
}
void RouterInfo::AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu)
{
Address addr;
addr.host = boost::asio::ip::address::from_string (host);
addr.port = port;
addr.transportStyle = eTransportSSU;
addr.cost = 10; // NTCP should have priority over SSU
addr.date = 0;
addr.mtu = mtu;
memcpy (addr.key, key, 32);
auto addr = std::make_shared<Address>();
addr->host = boost::asio::ip::address::from_string (host);
addr->port = port;
addr->transportStyle = eTransportSSU;
addr->cost = 10; // NTCP should have priority over SSU
addr->date = 0;
addr->mtu = mtu;
memcpy (addr->key, key, 32);
for (auto it: m_Addresses) // don't insert same address twice
if (it == addr) return;
if (*it == *addr) return;
m_Addresses.push_back(addr);
m_SupportedTransports |= addr.host.is_v6 () ? eSSUV6 : eSSUV4;
m_SupportedTransports |= addr->host.is_v6 () ? eSSUV6 : eSSUV4;
m_Caps |= eSSUTesting;
m_Caps |= eSSUIntroducer;
}
bool RouterInfo::AddIntroducer (const Introducer& introducer)
{
for (auto& addr : m_Addresses)
for (auto addr : m_Addresses)
{
if (addr.transportStyle == eTransportSSU && addr.host.is_v4 ())
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
{
for (auto intro: addr.introducers)
for (auto intro: addr->introducers)
if (intro.iTag == introducer.iTag) return false; // already presented
addr.introducers.push_back (introducer);
addr->introducers.push_back (introducer);
return true;
}
}
@ -591,14 +592,14 @@ namespace data @@ -591,14 +592,14 @@ namespace data
bool RouterInfo::RemoveIntroducer (const boost::asio::ip::udp::endpoint& e)
{
for (auto& addr : m_Addresses)
for (auto addr: m_Addresses)
{
if (addr.transportStyle == eTransportSSU && addr.host.is_v4 ())
if (addr->transportStyle == eTransportSSU && addr->host.is_v4 ())
{
for (std::vector<Introducer>::iterator it = addr.introducers.begin (); it != addr.introducers.end (); it++)
for (std::vector<Introducer>::iterator it = addr->introducers.begin (); it != addr->introducers.end (); it++)
if ( boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
{
addr.introducers.erase (it);
addr->introducers.erase (it);
return true;
}
}
@ -650,12 +651,24 @@ namespace data @@ -650,12 +651,24 @@ namespace data
return m_SupportedTransports & (eNTCPV6 | eSSUV6);
}
bool RouterInfo::IsV4 () const
{
return m_SupportedTransports & (eNTCPV4 | eSSUV4);
}
void RouterInfo::EnableV6 ()
{
if (!IsV6 ())
m_SupportedTransports |= eNTCPV6 | eSSUV6;
}
void RouterInfo::EnableV4 ()
{
if (!IsV4 ())
m_SupportedTransports |= eNTCPV4 | eSSUV4;
}
void RouterInfo::DisableV6 ()
{
if (IsV6 ())
@ -664,8 +677,8 @@ namespace data @@ -664,8 +677,8 @@ namespace data
m_SupportedTransports &= ~eNTCPV6;
for (size_t i = 0; i < m_Addresses.size (); i++)
{
if (m_Addresses[i].transportStyle == i2p::data::RouterInfo::eTransportNTCP &&
m_Addresses[i].host.is_v6 ())
if (m_Addresses[i]->transportStyle == i2p::data::RouterInfo::eTransportNTCP &&
m_Addresses[i]->host.is_v6 ())
{
m_Addresses.erase (m_Addresses.begin () + i);
break;
@ -676,8 +689,8 @@ namespace data @@ -676,8 +689,8 @@ namespace data
m_SupportedTransports &= ~eSSUV6;
for (size_t i = 0; i < m_Addresses.size (); i++)
{
if (m_Addresses[i].transportStyle == i2p::data::RouterInfo::eTransportSSU &&
m_Addresses[i].host.is_v6 ())
if (m_Addresses[i]->transportStyle == i2p::data::RouterInfo::eTransportSSU &&
m_Addresses[i]->host.is_v6 ())
{
m_Addresses.erase (m_Addresses.begin () + i);
break;
@ -685,35 +698,66 @@ namespace data @@ -685,35 +698,66 @@ namespace data
}
}
}
void RouterInfo::DisableV4 ()
{
if (IsV4 ())
{
// NTCP
m_SupportedTransports &= ~eNTCPV4;
for (size_t i = 0; i < m_Addresses.size (); i++)
{
if (m_Addresses[i]->transportStyle == i2p::data::RouterInfo::eTransportNTCP &&
m_Addresses[i]->host.is_v4 ())
{
m_Addresses.erase (m_Addresses.begin () + i);
break;
}
}
// SSU
m_SupportedTransports &= ~eSSUV4;
for (size_t i = 0; i < m_Addresses.size (); i++)
{
if (m_Addresses[i]->transportStyle == i2p::data::RouterInfo::eTransportSSU &&
m_Addresses[i]->host.is_v4 ())
{
m_Addresses.erase (m_Addresses.begin () + i);
break;
}
}
}
}
bool RouterInfo::UsesIntroducer () const
{
return m_Caps & Caps::eUnreachable; // non-reachable
}
const RouterInfo::Address * RouterInfo::GetNTCPAddress (bool v4only) const
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetNTCPAddress (bool v4only) const
{
return GetAddress (eTransportNTCP, v4only);
}
const RouterInfo::Address * RouterInfo::GetSSUAddress (bool v4only) const
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUAddress (bool v4only) const
{
return GetAddress (eTransportSSU, v4only);
}
const RouterInfo::Address * RouterInfo::GetSSUV6Address () const
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSUV6Address () const
{
return GetAddress (eTransportSSU, false, true);
}
const RouterInfo::Address * RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (TransportStyle s, bool v4only, bool v6only) const
{
for (auto& address : m_Addresses)
for (auto address : m_Addresses)
{
if (address.transportStyle == s)
if (address->transportStyle == s)
{
if ((!v4only || address.host.is_v4 ()) && (!v6only || address.host.is_v6 ()))
return &address;
if ((!v4only || address->host.is_v4 ()) && (!v6only || address->host.is_v6 ()))
return address;
}
}
return nullptr;

15
RouterInfo.h

@ -116,10 +116,10 @@ namespace data @@ -116,10 +116,10 @@ namespace data
void SetRouterIdentity (std::shared_ptr<const IdentityEx> identity);
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
uint64_t GetTimestamp () const { return m_Timestamp; };
std::vector<Address>& GetAddresses () { return m_Addresses; };
const Address * GetNTCPAddress (bool v4only = true) const;
const Address * GetSSUAddress (bool v4only = true) const;
const Address * GetSSUV6Address () const;
std::vector<std::shared_ptr<Address> >& GetAddresses () { return m_Addresses; };
std::shared_ptr<const Address> GetNTCPAddress (bool v4only = true) const;
std::shared_ptr<const Address> GetSSUAddress (bool v4only = true) const;
std::shared_ptr<const Address> GetSSUV6Address () const;
void AddNTCPAddress (const char * host, int port);
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
@ -133,8 +133,11 @@ namespace data @@ -133,8 +133,11 @@ namespace data
bool IsNTCP (bool v4only = true) const;
bool IsSSU (bool v4only = true) const;
bool IsV6 () const;
bool IsV4 () const;
void EnableV6 ();
void DisableV6 ();
void EnableV4 ();
void DisableV4 ();
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
bool UsesIntroducer () const;
bool IsIntroducer () const { return m_Caps & eSSUIntroducer; };
@ -182,7 +185,7 @@ namespace data @@ -182,7 +185,7 @@ namespace data
size_t ReadString (char * str, std::istream& s);
void WriteString (const std::string& str, std::ostream& s);
void ExtractCaps (const char * value);
const Address * GetAddress (TransportStyle s, bool v4only, bool v6only = false) const;
std::shared_ptr<const Address> GetAddress (TransportStyle s, bool v4only, bool v6only = false) const;
void UpdateCapsProperty ();
private:
@ -192,7 +195,7 @@ namespace data @@ -192,7 +195,7 @@ namespace data
uint8_t * m_Buffer;
size_t m_BufferLen;
uint64_t m_Timestamp;
std::vector<Address> m_Addresses;
std::vector<std::shared_ptr<Address> > m_Addresses;
std::map<std::string, std::string> m_Properties;
bool m_IsUpdated, m_IsUnreachable;
uint8_t m_SupportedTransports, m_Caps;

60
Transports.cpp

@ -112,8 +112,8 @@ namespace transport @@ -112,8 +112,8 @@ namespace transport
m_IsRunning = true;
m_Thread = new std::thread (std::bind (&Transports::Run, this));
// create acceptors
auto addresses = context.GetRouterInfo ().GetAddresses ();
for (auto& address : addresses)
auto& addresses = context.GetRouterInfo ().GetAddresses ();
for (auto address : addresses)
{
if (!m_NTCPServer)
{
@ -121,12 +121,12 @@ namespace transport @@ -121,12 +121,12 @@ namespace transport
m_NTCPServer->Start ();
}
if (address.transportStyle == RouterInfo::eTransportSSU && address.host.is_v4 ())
if (address->transportStyle == RouterInfo::eTransportSSU && address->host.is_v4 ())
{
if (!m_SSUServer)
{
m_SSUServer = new SSUServer (address.port);
LogPrint (eLogInfo, "Transports: Start listening UDP port ", address.port);
m_SSUServer = new SSUServer (address->port);
LogPrint (eLogInfo, "Transports: Start listening UDP port ", address->port);
m_SSUServer->Start ();
DetectExternalIP ();
}
@ -376,14 +376,24 @@ namespace transport @@ -376,14 +376,24 @@ namespace transport
auto& peer = it1->second;
if (!ecode && peer.router)
{
auto address = (*it).endpoint ().address ();
LogPrint (eLogDebug, "Transports: ", (*it).host_name (), " has been resolved to ", address);
auto addr = peer.router->GetNTCPAddress ();
if (addr)
{
auto s = std::make_shared<NTCPSession> (*m_NTCPServer, peer.router);
m_NTCPServer->Connect (address, addr->port, s);
return;
while (it != boost::asio::ip::tcp::resolver::iterator())
{
auto address = (*it).endpoint ().address ();
LogPrint (eLogDebug, "Transports: ", (*it).host_name (), " has been resolved to ", address);
if (address.is_v4 () || context.SupportsV6 ())
{
auto addr = peer.router->GetNTCPAddress (); // TODO: take one we requested
if (addr)
{
auto s = std::make_shared<NTCPSession> (*m_NTCPServer, peer.router);
m_NTCPServer->Connect (address, addr->port, s);
return;
}
break;
}
else
LogPrint (eLogInfo, "Transports: NTCP ", address, " is not supported");
it++;
}
}
LogPrint (eLogError, "Transports: Unable to resolve NTCP address: ", ecode.message ());
@ -409,13 +419,23 @@ namespace transport @@ -409,13 +419,23 @@ namespace transport
auto& peer = it1->second;
if (!ecode && peer.router)
{
auto address = (*it).endpoint ().address ();
LogPrint (eLogDebug, "Transports: ", (*it).host_name (), " has been resolved to ", address);
auto addr = peer.router->GetSSUAddress (!context.SupportsV6 ());;
if (addr)
{
m_SSUServer->CreateSession (peer.router, address, addr->port);
return;
while (it != boost::asio::ip::tcp::resolver::iterator())
{
auto address = (*it).endpoint ().address ();
LogPrint (eLogDebug, "Transports: ", (*it).host_name (), " has been resolved to ", address);
if (address.is_v4 () || context.SupportsV6 ())
{
auto addr = peer.router->GetSSUAddress (); // TODO: take one we requested
if (addr)
{
m_SSUServer->CreateSession (peer.router, address, addr->port);
return;
}
break;
}
else
LogPrint (eLogInfo, "Transports: SSU ", address, " is not supported");
it++;
}
}
LogPrint (eLogError, "Transports: Unable to resolve SSU address: ", ecode.message ());

14
UPnP.cpp

@ -101,19 +101,19 @@ namespace transport @@ -101,19 +101,19 @@ namespace transport
void UPnP::Run ()
{
std::vector<data::RouterInfo::Address> a = context.GetRouterInfo().GetAddresses();
for (auto& address : a)
const std::vector<std::shared_ptr<i2p::data::RouterInfo::Address> > a = context.GetRouterInfo().GetAddresses();
for (auto address : a)
{
if (!address.host.is_v6 ())
if (!address->host.is_v6 ())
{
Discover ();
if (address.transportStyle == data::RouterInfo::eTransportSSU )
if (address->transportStyle == data::RouterInfo::eTransportSSU )
{
TryPortMapping (I2P_UPNP_UDP, address.port);
TryPortMapping (I2P_UPNP_UDP, address->port);
}
else if (address.transportStyle == data::RouterInfo::eTransportNTCP )
else if (address->transportStyle == data::RouterInfo::eTransportNTCP )
{
TryPortMapping (I2P_UPNP_TCP, address.port);
TryPortMapping (I2P_UPNP_TCP, address->port);
}
}
}

5
UPnP.h

@ -58,6 +58,5 @@ namespace transport @@ -58,6 +58,5 @@ namespace transport
}
}
#endif
#endif
#endif // USE_UPNP
#endif // __UPNP_H__

11
Win32/Win32App.cpp

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
#include <windows.h>
#include <shellapi.h>
#include "../Config.h"
#include "../version.h"
#include "resource.h"
#include "Win32App.h"
#include <stdio.h>
@ -90,7 +91,9 @@ namespace win32 @@ -90,7 +91,9 @@ namespace win32
{
case ID_ABOUT:
{
MessageBox( hWnd, TEXT("i2pd"), TEXT("About"), MB_ICONINFORMATION | MB_OK );
std::stringstream text;
text << "Version: " << I2PD_VERSION << " " << CODENAME;
MessageBox( hWnd, TEXT(text.str ().c_str ()), TEXT("i2pd"), MB_ICONINFORMATION | MB_OK );
return 0;
}
case ID_EXIT:
@ -171,12 +174,12 @@ namespace win32 @@ -171,12 +174,12 @@ namespace win32
auto mascot = LoadBitmap (GetModuleHandle(NULL), MAKEINTRESOURCE (MASCOT));
auto mascotDC = CreateCompatibleDC (hDC);
SelectObject (mascotDC, mascot);
BitBlt (hDC, 0,0, 533, 700, mascotDC, 0, 0, SRCCOPY);
BitBlt (hDC, 0,0, 533, 700, mascotDC, 0, 0, SRCCOPY);
DeleteDC (mascotDC);
DeleteObject (mascot);
EndPaint (hWnd, &ps);
break;
}
}
}
return DefWindowProc( hWnd, uMsg, wParam, lParam);
}
@ -205,7 +208,7 @@ namespace win32 @@ -205,7 +208,7 @@ namespace win32
wclx.lpszClassName = I2PD_WIN32_CLASSNAME;
RegisterClassEx (&wclx);
// create new window
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW, 100, 100, 533, 700, NULL, NULL, hInst, NULL))
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW, 100, 100, 549, 738, NULL, NULL, hInst, NULL))
{
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
return false;

2
docs/build_requirements.md

@ -4,7 +4,7 @@ Build requirements @@ -4,7 +4,7 @@ Build requirements
Linux/FreeBSD/OSX
-----------------
GCC 4.6 or newer, Boost 1.46 or newer, openssl, zlib. Clang can be used instead of GCC.
GCC 4.8 or newer, Boost 1.49 or newer, openssl, zlib. Clang can be used instead of GCC.
Windows
-------

10
docs/family.md

@ -8,11 +8,11 @@ New family @@ -8,11 +8,11 @@ New family
-----------
You must create family self-signed certificate and key.
The only key type supposted is prime256v1.
Use the following list of commands:
openssl ecparam -name prime256v1 -genkey -out <your family name>.key
openssl req -new -key <your family name>.key -out <your family name>.csr
touch v3.ext
openssl x509 -req -days 3650 -in <your family name>.csr -signkey <your family name>.key -out <your family name>.crt -extfile v3.ext
Use the following list of commands:
openssl ecparam -name prime256v1 -genkey -out <your family name>.key
openssl req -new -key <your family name>.key -out <your family name>.csr
touch v3.ext
openssl x509 -req -days 3650 -in <your family name>.csr -signkey <your family name>.key -out <your family name>.crt -extfile v3.ext
specify <your family name>.family.i2p.net for CN.

8
util.cpp

@ -106,11 +106,15 @@ namespace http @@ -106,11 +106,15 @@ namespace http
while (!response.eof ())
{
std::string hexLen;
int len;
size_t len;
std::getline (response, hexLen);
std::istringstream iss (hexLen);
iss >> std::hex >> len;
if (!len) break;
if (!len || len > 10000000L) // 10M
{
LogPrint (eLogError, "Unexpected chunk length ", len);
break;
}
char * buf = new char[len];
response.read (buf, len);
merged.write (buf, len);

2
version.h

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
#define I2P_VERSION_MAJOR 0
#define I2P_VERSION_MINOR 9
#define I2P_VERSION_MICRO 24
#define I2P_VERSION_MICRO 25
#define I2P_VERSION_PATCH 0
#define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO)

Loading…
Cancel
Save