Browse Source

Merge remote-tracking branch 'purple/openssl'

pull/436/head
Jeff Becker 9 years ago
parent
commit
897cc7d355
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B
  1. 192
      AddressBook.cpp
  2. 34
      AddressBook.h
  3. 4
      Base.cpp
  4. 1
      Config.cpp
  5. 2
      Daemon.cpp
  6. 7
      FS.cpp
  7. 17
      FS.h
  8. 2
      HTTPProxy.cpp
  9. 10
      HTTPServer.cpp
  10. 18
      NTCPSession.cpp
  11. 43
      NetDb.cpp
  12. 3
      NetDb.h
  13. 5
      Reseed.cpp
  14. 36
      RouterContext.cpp
  15. 83
      RouterInfo.cpp
  16. 12
      RouterInfo.h
  17. 1
      SSUSession.cpp
  18. 50
      Transports.cpp
  19. 14
      UPnP.cpp
  20. 5
      UPnP.h
  21. BIN
      Win32/Anke_2200px.jpg
  22. BIN
      Win32/Anke_700px.bmp
  23. 6
      Win32/Resource.rc
  24. 50
      Win32/Win32App.cpp
  25. BIN
      Win32/anke.ico
  26. 1
      Win32/resource.h
  27. 75
      docs/build_notes_cross.md
  28. 2
      docs/build_requirements.md
  29. 19
      docs/configuration.md
  30. 111
      docs/i2pd.conf
  31. 8
      util.cpp
  32. 2
      version.h

192
AddressBook.cpp

@ -24,7 +24,7 @@ namespace client @@ -24,7 +24,7 @@ namespace client
{
private:
i2p::fs::HashedStorage storage;
std::string indexPath;
std::string etagsPath, indexPath, localPath;
public:
AddressBookFilesystemStorage (): storage("addressbook", "b", "", "b32") {};
@ -34,14 +34,34 @@ namespace client @@ -34,14 +34,34 @@ namespace client
bool Init ();
int Load (std::map<std::string, i2p::data::IdentHash>& addresses);
int LoadLocal (std::map<std::string, i2p::data::IdentHash>& addresses);
int Save (const std::map<std::string, i2p::data::IdentHash>& addresses);
void SaveEtag (const i2p::data::IdentHash& subsciption, const std::string& etag, const std::string& lastModified);
bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified);
private:
int LoadFromFile (const std::string& filename, std::map<std::string, i2p::data::IdentHash>& addresses); // returns -1 if can't open file, otherwise number of records
};
bool AddressBookFilesystemStorage::Init()
{
{
storage.SetPlace(i2p::fs::GetDataDir());
indexPath = storage.GetRoot() + i2p::fs::dirSep + "addresses.csv";
return storage.Init(i2p::data::GetBase32SubstitutionTable(), 32);
// init storage
if (storage.Init(i2p::data::GetBase32SubstitutionTable(), 32))
{
// init ETags
etagsPath = i2p::fs::StorageRootPath (storage, "etags");
if (!i2p::fs::Exists (etagsPath))
i2p::fs::CreateDirectory (etagsPath);
// init address files
indexPath = i2p::fs::StorageRootPath (storage, "addresses.csv");
localPath = i2p::fs::StorageRootPath (storage, "local.csv");
return true;
}
return false;
}
std::shared_ptr<const i2p::data::IdentityEx> AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident) const
@ -87,24 +107,18 @@ namespace client @@ -87,24 +107,18 @@ namespace client
storage.Remove( ident.ToBase32() );
}
int AddressBookFilesystemStorage::Load (std::map<std::string, i2p::data::IdentHash>& addresses)
int AddressBookFilesystemStorage::LoadFromFile (const std::string& filename, std::map<std::string, i2p::data::IdentHash>& addresses)
{
int num = 0;
std::string s;
std::ifstream f (indexPath, std::ifstream::in); // in text mode
if (f.is_open ()) {
LogPrint(eLogInfo, "Addressbook: using index file ", indexPath);
} else {
LogPrint(eLogWarning, "Addressbook: Can't open ", indexPath);
return 0;
}
std::ifstream f (filename, std::ifstream::in); // in text mode
if (!f) return -1;
addresses.clear ();
while (!f.eof ()) {
while (!f.eof ())
{
std::string s;
getline(f, s);
if (!s.length())
continue; // skip empty line
if (!s.length()) continue; // skip empty line
std::size_t pos = s.find(',');
if (pos != std::string::npos)
@ -118,8 +132,28 @@ namespace client @@ -118,8 +132,28 @@ namespace client
num++;
}
}
return num;
}
int AddressBookFilesystemStorage::Load (std::map<std::string, i2p::data::IdentHash>& addresses)
{
int num = LoadFromFile (indexPath, addresses);
if (num < 0)
{
LogPrint(eLogWarning, "Addressbook: Can't open ", indexPath);
return 0;
}
LogPrint(eLogInfo, "Addressbook: using index file ", indexPath);
LogPrint (eLogInfo, "Addressbook: ", num, " addresses loaded from storage");
return num;
}
int AddressBookFilesystemStorage::LoadLocal (std::map<std::string, i2p::data::IdentHash>& addresses)
{
int num = LoadFromFile (localPath, addresses);
if (num < 0) return 0;
LogPrint (eLogInfo, "Addressbook: ", num, " local addresses loaded");
return num;
}
@ -146,6 +180,28 @@ namespace client @@ -146,6 +180,28 @@ namespace client
return num;
}
void AddressBookFilesystemStorage::SaveEtag (const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified)
{
std::string fname = etagsPath + i2p::fs::dirSep + subscription.ToBase32 () + ".txt";
std::ofstream f (fname, std::ofstream::out | std::ofstream::trunc);
if (f)
{
f << etag << std::endl;
f<< lastModified << std::endl;
}
}
bool AddressBookFilesystemStorage::GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified)
{
std::string fname = etagsPath + i2p::fs::dirSep + subscription.ToBase32 () + ".txt";
std::ifstream f (fname, std::ofstream::in);
if (!f || f.eof ()) return false;
std::getline (f, etag);
if (f.eof ()) return false;
std::getline (f, lastModified);
return true;
}
//---------------------------------------------------------------------
AddressBook::AddressBook (): m_Storage(new AddressBookFilesystemStorage), m_IsLoaded (false), m_IsDownloading (false),
m_DefaultSubscription (nullptr), m_SubscriptionsUpdateTimer (nullptr)
@ -274,6 +330,7 @@ namespace client @@ -274,6 +330,7 @@ namespace client
LoadHostsFromStream (f);
m_IsLoaded = true;
}
LoadLocal ();
}
void AddressBook::LoadHostsFromStream (std::istream& f)
@ -337,7 +394,49 @@ namespace client @@ -337,7 +394,49 @@ namespace client
LogPrint (eLogError, "Addressbook: subscriptions already loaded");
}
void AddressBook::DownloadComplete (bool success)
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)
return m_Storage->GetEtag (subscription, etag, lastModified);
else
return false;
}
void AddressBook::DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified)
{
m_IsDownloading = false;
int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT;
@ -348,6 +447,7 @@ namespace client @@ -348,6 +447,7 @@ namespace client
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
else
m_IsLoaded = true;
if (m_Storage) m_Storage->SaveEtag (subscription, etag, lastModified);
}
if (m_SubscriptionsUpdateTimer)
{
@ -438,6 +538,12 @@ namespace client @@ -438,6 +538,12 @@ namespace client
i2p::data::IdentHash ident;
if (m_Book.GetIdentHash (u.host_, ident))
{
if (!m_Etag.length ())
{
// load ETag
m_Book.GetEtag (ident, m_Etag, m_LastModified);
LogPrint (eLogInfo, "Addressbook: set ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
}
std::condition_variable newDataReceived;
std::mutex newDataReceivedMutex;
auto leaseSet = i2p::client::context.GetSharedLocalDestination ()->FindLeaseSet (ident);
@ -468,7 +574,7 @@ namespace client @@ -468,7 +574,7 @@ namespace client
<< "X-Accept-Encoding: x-i2p-gzip;q=1.0, identity;q=0.5, deflate;q=0, gzip;q=0, *;q=0\r\n"
<< "Connection: close\r\n";
if (m_Etag.length () > 0) // etag
request << i2p::util::http::IF_NONE_MATCH << ": \"" << m_Etag << "\"\r\n";
request << i2p::util::http::IF_NONE_MATCH << ": " << m_Etag << "\r\n";
if (m_LastModified.length () > 0) // if-modfief-since
request << i2p::util::http::IF_MODIFIED_SINCE << ": " << m_LastModified << "\r\n";
request << "\r\n"; // end of header
@ -529,7 +635,7 @@ namespace client @@ -529,7 +635,7 @@ namespace client
!header.compare (colon + 1, std::string::npos, "x-i2p-gzip");
}
}
LogPrint (eLogInfo, "Addressbook: ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
LogPrint (eLogInfo, "Addressbook: received ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
if (!response.eof ())
{
success = true;
@ -561,7 +667,7 @@ namespace client @@ -561,7 +667,7 @@ namespace client
if (!success)
LogPrint (eLogError, "Addressbook: download hosts.txt from ", m_Link, " failed");
m_Book.DownloadComplete (success);
m_Book.DownloadComplete (success, ident, m_Etag, m_LastModified);
}
bool AddressBookSubscription::ProcessResponse (std::stringstream& s, bool isGzip)
@ -580,6 +686,50 @@ namespace client @@ -580,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;
}
}
}

34
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
@ -37,10 +38,15 @@ namespace client @@ -37,10 +38,15 @@ namespace client
virtual bool Init () = 0;
virtual int Load (std::map<std::string, i2p::data::IdentHash>& addresses) = 0;
virtual int LoadLocal (std::map<std::string, i2p::data::IdentHash>& addresses) = 0;
virtual int Save (const std::map<std::string, i2p::data::IdentHash>& addresses) = 0;
virtual void SaveEtag (const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified) = 0;
virtual bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified) = 0;
};
class AddressBookSubscription;
class AddressResolver;
class AddressBook
{
public:
@ -56,10 +62,13 @@ namespace client @@ -56,10 +62,13 @@ namespace client
void InsertAddress (std::shared_ptr<const i2p::data::IdentityEx> address);
void LoadHostsFromStream (std::istream& f);
void DownloadComplete (bool success);
void DownloadComplete (bool success, const i2p::data::IdentHash& subscription, const std::string& etag, const std::string& lastModified);
//This method returns the ".b32.i2p" address
std::string ToAddress(const i2p::data::IdentHash& ident) { return GetB32Address(ident); }
std::string ToAddress(std::shared_ptr<const i2p::data::IdentityEx> ident) { return ToAddress(ident->GetIdentHash ()); }
bool GetEtag (const i2p::data::IdentHash& subscription, std::string& etag, std::string& lastModified);
private:
void StartSubscriptions ();
@ -67,6 +76,7 @@ namespace client @@ -67,6 +76,7 @@ namespace client
void LoadHosts ();
void LoadSubscriptions ();
void LoadLocal ();
void HandleSubscriptionsUpdateTimer (const boost::system::error_code& ecode);
@ -74,6 +84,7 @@ namespace client @@ -74,6 +84,7 @@ namespace client
std::mutex m_AddressBookMutex;
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;
@ -97,6 +108,25 @@ namespace client @@ -97,6 +108,25 @@ namespace client
AddressBook& m_Book;
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;
};
}
}

4
Base.cpp

@ -8,8 +8,8 @@ namespace data @@ -8,8 +8,8 @@ namespace data
{
static const char T32[32] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'k', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 't', 't', 'u', 'v', 'w', 'x',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', '2', '3', '4', '5', '6', '7',
};

1
Config.cpp

@ -126,6 +126,7 @@ namespace config { @@ -126,6 +126,7 @@ namespace config {
#ifdef _WIN32
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
("insomnia", value<bool>()->zero_tokens()->default_value(false), "Prevent system from sleeping")
("close", value<std::string>()->default_value("ask"), "On close action") // minimize, exit, ask TODO: add custom validator or something
#endif
;

2
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 */
}

7
FS.cpp

@ -102,6 +102,13 @@ namespace fs { @@ -102,6 +102,13 @@ namespace fs {
return boost::filesystem::remove(path);
}
bool CreateDirectory (const std::string& path)
{
if (boost::filesystem::exists(path) &&
boost::filesystem::is_directory (boost::filesystem::status (path))) return true;
return boost::filesystem::create_directory(path);
}
void HashedStorage::SetPlace(const std::string &path) {
root = path + i2p::fs::dirSep + name;
}

17
FS.h

@ -48,8 +48,8 @@ namespace fs { @@ -48,8 +48,8 @@ namespace fs {
/** create subdirs in storage */
bool Init(const char* chars, size_t cnt);
const std::string & GetRoot() const { return this->root; }
const std::string & GetName() const { return this->name; }
const std::string & GetRoot() const { return root; }
const std::string & GetName() const { return name; }
/** set directory where to place storage directory */
void SetPlace(const std::string & path);
/** path to file with given ident */
@ -108,6 +108,8 @@ namespace fs { @@ -108,6 +108,8 @@ namespace fs {
* @return true if file exists, false otherwise
*/
bool Exists(const std::string & path);
bool CreateDirectory (const std::string& path);
template<typename T>
void _ExpandPath(std::stringstream & path, T c) {
@ -136,6 +138,17 @@ namespace fs { @@ -136,6 +138,17 @@ namespace fs {
return s.str();
}
template<typename Storage, typename... Filename>
std::string StorageRootPath (const Storage& storage, Filename... filenames)
{
std::stringstream s("");
s << storage.GetRoot ();
_ExpandPath(s, filenames...);
return s.str();
}
} // fs
} // i2p

2
HTTPProxy.cpp

@ -204,7 +204,7 @@ namespace proxy @@ -204,7 +204,7 @@ namespace proxy
if (eol)
{
*eol = 0; eol++;
if (strncmp ((const char *)http_buff, "Referer", 7)) // strip out referer
if (strncmp ((const char *)http_buff, "Referer", 7) && strncmp ((const char *)http_buff, "Connection", 10)) // strip out referer and connection
{
if (!strncmp ((const char *)http_buff, "User-Agent", 10)) // replace UserAgent
m_request.append("User-Agent: MYOB/6.66 (AN/ON)");

10
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 () << " ";

18
NTCPSession.cpp

@ -93,9 +93,7 @@ namespace transport @@ -93,9 +93,7 @@ namespace transport
m_DHKeysPair = nullptr;
SendTimeSyncMessage ();
m_SendQueue.push_back (CreateDatabaseStoreMsg ()); // we tell immediately who we are
SendTimeSyncMessage ();
transports.PeerConnected (shared_from_this ());
}
@ -761,15 +759,15 @@ namespace transport @@ -761,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));
@ -779,10 +777,10 @@ namespace transport @@ -779,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;

5
Reseed.cpp

@ -26,13 +26,12 @@ namespace data @@ -26,13 +26,12 @@ namespace data
static std::vector<std::string> httpsReseedHostList =
{
"https://reseed.i2p-projekt.de/", // Only HTTPS
//"https://i2pseed.zarrenspry.info/", // Only HTTPS and SU3 (v3) support
"https://i2p.mooo.com/netDb/",
"https://netdb.i2p2.no/", // Only SU3 (v3) support, SNI required
"https://us.reseed.i2p2.no:444/",
"https://uk.reseed.i2p2.no:444/",
"https://www.torontocrypto.org:8443/",
"https://i2p-0.manas.ca:8443/"
"https://i2p.manas.ca:8443/",
"https://i2p-0.manas.ca:8443/",
"https://reseed.i2p.vzaws.com:8443/", // Only SU3 (v3) support
"https://user.mx24.eu/", // Only HTTPS and SU3 (v3) support
"https://download.xxlspeed.com/" // Only HTTPS and SU3 (v3) support

36
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 ();
@ -264,19 +264,19 @@ namespace i2p @@ -264,19 +264,19 @@ namespace i2p
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)
{

83
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;
}
}
@ -664,8 +665,8 @@ namespace data @@ -664,8 +665,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 +677,8 @@ namespace data @@ -676,8 +677,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;
@ -691,29 +692,29 @@ namespace data @@ -691,29 +692,29 @@ namespace data
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;

12
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);
@ -182,7 +182,7 @@ namespace data @@ -182,7 +182,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 +192,7 @@ namespace data @@ -192,7 +192,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;

1
SSUSession.cpp

@ -855,7 +855,6 @@ namespace transport @@ -855,7 +855,6 @@ namespace transport
m_DHKeysPair = nullptr;
m_SignedData = nullptr;
m_Data.Start ();
m_Data.Send (CreateDatabaseStoreMsg ());
transports.PeerConnected (shared_from_this ());
if (m_IsPeerTest)
SendPeerTest ();

50
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 ();
}
@ -378,13 +378,18 @@ namespace transport @@ -378,13 +378,18 @@ namespace transport
{
auto address = (*it).endpoint ().address ();
LogPrint (eLogDebug, "Transports: ", (*it).host_name (), " has been resolved to ", address);
auto addr = peer.router->GetNTCPAddress ();
if (addr)
if (address.is_v4 () || context.SupportsV6 ())
{
auto s = std::make_shared<NTCPSession> (*m_NTCPServer, peer.router);
m_NTCPServer->Connect (address, addr->port, s);
return;
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;
}
}
else
LogPrint (eLogInfo, "Can't connect to NTCP ", address, " ipv6 is not supported");
}
LogPrint (eLogError, "Transports: Unable to resolve NTCP address: ", ecode.message ());
std::unique_lock<std::mutex> l(m_PeersMutex);
@ -411,12 +416,17 @@ namespace transport @@ -411,12 +416,17 @@ namespace transport
{
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)
if (address.is_v4 () || context.SupportsV6 ())
{
m_SSUServer->CreateSession (peer.router, address, addr->port);
return;
auto addr = peer.router->GetSSUAddress (); // TODO: take one we requested
if (addr)
{
m_SSUServer->CreateSession (peer.router, address, addr->port);
return;
}
}
else
LogPrint (eLogInfo, "Can't connect to SSU ", address, " ipv6 is not supported");
}
LogPrint (eLogError, "Transports: Unable to resolve SSU address: ", ecode.message ());
std::unique_lock<std::mutex> l(m_PeersMutex);
@ -505,12 +515,24 @@ namespace transport @@ -505,12 +515,24 @@ namespace transport
auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
{
bool sendDatabaseStore = true;
if (it->second.delayedMessages.size () > 0)
{
// check if first message is our DatabaseStore (publishing)
auto firstMsg = it->second.delayedMessages[0];
if (firstMsg && firstMsg->GetTypeID () == eI2NPDatabaseStore &&
i2p::data::IdentHash(firstMsg->GetPayload () + DATABASE_STORE_KEY_OFFSET) == i2p::context.GetIdentHash ())
sendDatabaseStore = false; // we have it in the list already
}
if (sendDatabaseStore)
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () });
it->second.sessions.push_back (session);
session->SendI2NPMessages (it->second.delayedMessages);
it->second.delayedMessages.clear ();
}
else // incoming connection
{
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} }));
}

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__

BIN
Win32/Anke_2200px.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
Win32/Anke_700px.bmp

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

6
Win32/Resource.rc

@ -52,7 +52,11 @@ END @@ -52,7 +52,11 @@ END
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
MAINICON ICON "ictoopie.ico"
//MAINICON ICON "ictoopie.ico"
MAINICON ICON "anke.ico"
MASCOT BITMAP "Anke_700px.bmp"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////

50
Win32/Win32App.cpp

@ -2,8 +2,14 @@ @@ -2,8 +2,14 @@
#include <windows.h>
#include <shellapi.h>
#include "../Config.h"
#include "../version.h"
#include "resource.h"
#include "Win32App.h"
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define ID_ABOUT 2000
#define ID_EXIT 2001
@ -85,7 +91,9 @@ namespace win32 @@ -85,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:
@ -98,7 +106,7 @@ namespace win32 @@ -98,7 +106,7 @@ namespace win32
char buf[30];
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
std::snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort);
snprintf(buf, 30, "http://%s:%d", httpAddr.c_str(), httpPort);
ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL);
return 0;
}
@ -119,6 +127,29 @@ namespace win32 @@ -119,6 +127,29 @@ namespace win32
ShowWindow(hWnd, SW_HIDE);
return 0;
}
case SC_CLOSE:
{
std::string close; i2p::config::GetOption("close", close);
if (0 == close.compare("ask"))
switch(::MessageBox(hWnd, "Would you like to minimize instead of exiting?"
" You can add 'close' configuration option. Valid values are: ask, minimize, exit.",
"Minimize instead of exiting?", MB_ICONQUESTION | MB_YESNOCANCEL | MB_DEFBUTTON1))
{
case IDYES: close = "minimize"; break;
case IDNO: close = "exit"; break;
default: return 0;
}
if (0 == close.compare("minimize"))
{
ShowWindow(hWnd, SW_HIDE);
return 0;
}
if (0 != close.compare("exit"))
{
::MessageBox(hWnd, close.c_str(), "Unknown close action in config", MB_OK | MB_ICONWARNING);
return 0;
}
}
}
}
case WM_TRAYICON:
@ -136,6 +167,19 @@ namespace win32 @@ -136,6 +167,19 @@ namespace win32
}
break;
}
case WM_PAINT:
{
PAINTSTRUCT ps;
auto hDC = BeginPaint (hWnd, &ps);
auto mascot = LoadBitmap (GetModuleHandle(NULL), MAKEINTRESOURCE (MASCOT));
auto mascotDC = CreateCompatibleDC (hDC);
SelectObject (mascotDC, mascot);
BitBlt (hDC, 0,0, 533, 700, mascotDC, 0, 0, SRCCOPY);
DeleteDC (mascotDC);
DeleteObject (mascot);
EndPaint (hWnd, &ps);
break;
}
}
return DefWindowProc( hWnd, uMsg, wParam, lParam);
}
@ -164,7 +208,7 @@ namespace win32 @@ -164,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, 250, 150, 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;

BIN
Win32/anke.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

1
Win32/resource.h

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
// Used by Resource.rc
//
#define MAINICON 101
#define MASCOT 201
// Next default values for new objects
//

75
docs/build_notes_cross.md

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
Cross compilation notes
=======================
Static 64 bit windows binary on Ubuntu 15.10 (Wily Werewolf)
---------------------------------------------------------------------
Install cross compiler and friends
```sh
sudo apt-get install g++-mingw-w64-x86-64
```
Default is to use Win32 threading model which lacks std::mutex and such. So we change defaults
```sh
sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
```
From now on we assume we have everything in `~/dev/`. Get Boost sources unpacked into `~/dev/boost_1_60_0/`
and change directory to it.
Now add out cross compiler configuration. Warning: the following will wipe out whatever you had in there.
```sh
echo "using gcc : mingw : x86_64-w64-mingw32-g++ ;" > ~/user-config.jam
```
Proceed with building Boost normal way, but let's define dedicated staging directory
```sh
./bootstrap.sh
./b2 toolset=gcc-mingw target-os=windows variant=release link=static runtime-link=static address-model=64 \
--build-type=minimal --with-filesystem --with-program_options --with-regex --with-date_time \
--stagedir=stage-mingw-64
cd ..
```
Now we get & build OpenSSL
```sh
git clone https://github.com/openssl/openssl
cd openssl
git checkout OpenSSL_1_0_2g
./Configure mingw64 no-rc2 no-rc4 no-rc5 no-idea no-bf no-cast no-whirlpool no-md2 no-md4 no-ripemd no-mdc2 \
no-camellia no-seed no-comp no-krb5 no-gmp no-rfc3779 no-ec2m no-ssl2 no-jpake no-srp no-sctp no-srtp \
--prefix=~/dev/stage --cross-compile-prefix=x86_64-w64-mingw32-
make depend
make
make install
cd ..
```
and Zlib
```sh
git clone https://github.com/madler/zlib
cd zlib
git checkout v1.2.8
CC=x86_64-w64-mingw32-gcc CFLAGS=-O3 ./configure --static --64 --prefix=~/dev/stage
make
make install
cd ..
```
Now we prepare cross toolchain hint file for CMake, let's name it `~/dev/toolchain-mingw.cmake`
```cmake
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
```
Download miniupnpc, unpack, and symlink it into `~/dev/miniupnpc/`.
Finally, we can build i2pd with all that goodness
```sh
git clone https://github.com/PurpleI2P/i2pd
mkdir i2pd-mingw-64-build
cd i2pd-mingw-64-build
BOOST_ROOT=~/dev/boost_1_60_0 cmake -G 'Unix Makefiles' ~/dev/i2pd/build -DBUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=~/dev/toolchain-mingw.cmake -DWITH_AESNI=ON -DWITH_UPNP=ON -DWITH_STATIC=ON \
-DWITH_HARDENING=ON -DCMAKE_INSTALL_PREFIX:PATH=~/dev/i2pd-mingw-64-static \
-DZLIB_ROOT=~/dev/stage -DBOOST_LIBRARYDIR:PATH=~/dev/boost_1_60_0/stage-mingw-64/lib \
-DOPENSSL_ROOT_DIR:PATH=~/dev/stage
make
x86_64-w64-mingw32-strip i2pd.exe
```
By now, you should have a release build with stripped symbols.

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
-------

19
docs/configuration.md

@ -17,9 +17,9 @@ Command line options @@ -17,9 +17,9 @@ Command line options
* --port= - The port to listen on
* --daemon - Router will go to background after start
* --service - Router will use system folders like '/var/lib/i2pd'
* --ipv6 - Enable communication through ipv6
* --notransit - Router will not accept transit tunnels at startup
* --floodfill - Router will be floodfill
* --ipv6 - Enable communication through ipv6. false by default
* --notransit - Router will not accept transit tunnels at startup. false by default
* --floodfill - Router will be floodfill. false by default
* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited
* --family= - Name of a family, router belongs to
* --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove")
@ -30,21 +30,26 @@ Command line options @@ -30,21 +30,26 @@ Command line options
* --httpproxy.address= - The address to listen on (HTTP Proxy)
* --httpproxy.port= - The port to listen on (HTTP Proxy) 4446 by default
* --httpproxy.keys= - optional keys file for proxy local destination (both HTTP and SOCKS)
* --httpproxy.enabled= - If HTTP proxy is enabled. true by default
* --socksproxy.address= - The address to listen on (SOCKS Proxy)
* --socksproxy.port= - The port to listen on (SOCKS Proxy). 4447 by default
* --socksproxy.keys= - optional keys file for proxy local destination (both HTTP and SOCKS)
* --socksproxy.outproxy= - Address of outproxy. requests outside i2p will go there
* --socksproxy.enabled= - If SOCKS proxy is enabled. true by default
* --socksproxy.outproxy= - Address of outproxy. requests outside i2p will go there
* --socksproxy.outproxyport= - Outproxy remote port
* --sam.address= - The address to listen on (SAM bridge)
* --sam.port= - Port of SAM bridge. Usually 7656. SAM is off if not specified
* --sam.enabled= - If SAM is enabled. false by default
* --bob.address= - The address to listen on (BOB command channel)
* --bob.port= - Port of BOB command channel. Usually 2827. BOB is off if not specified
* --sam.enabled= - If BOB is enabled. false by default
* --i2pcontrol.address= - The address to listen on (I2P control service)
* --i2pcontrol.port= - Port of I2P control service. Usually 7650. I2PControl is off if not specified
* --i2pcontrol.enabled= - If I2P control is enabled. false by default
Config files
------------
@ -58,15 +63,15 @@ For example: @@ -58,15 +63,15 @@ For example:
i2p.conf:
# comment
log = yes
ipv6 = yes
log = true
ipv6 = true
# settings for specific module
[httpproxy]
port = 4444
# ^^ this will be --httproxy.port= in cmdline
# another one
[sam]
enabled = yes
enabled = true
tunnels.cfg (filename of this config is subject of change):

111
docs/i2pd.conf

@ -0,0 +1,111 @@ @@ -0,0 +1,111 @@
## Configuration file for a typical i2pd user
## See https://i2pd.readthedocs.org/en/latest/configuration.html
## for more options you can use in this file.
## Lines that begin with "## " try to explain what's going on. Lines
## that begin with just "#" are disabled commands: you can enable them
## by removing the "#" symbol.
## Tunnels config file
## Default: ~/.i2pd/tunnels.cfg or /var/lib/i2pd/tunnels.cfg
#tunconf = /var/lib/i2pd/tunnels.cfg
## Where to write pidfile (don't write by default)
#pidfile = /var/run/i2pd.pid
## Logging configuration section
## By default logs go to stdout with level info
##
## Logs destination (stdout, file)
#log = file
## Path to logfile (default - autodetect)
#logfile = /var/log/i2pd.log
## Log messages above this level (debug, *info, warn, error)
#loglevel = info
## Path to storage of i2pd data (RI, keys, peer profiles, ...)
## Default: ~/.i2pd or /var/lib/i2pd
#datadir = /var/lib/i2pd
## Daemon mode. Router will go to background after start
#daemon
## Run as a service. Router will use system folders like ‘/var/lib/i2pd’
#service
## External IP address to listen for connections
## By default i2pd sets IP automatically
#host = 1.2.3.4
## Port to listen for connections
## By default i2pd picks random port. You MUST pick a random number too,
## don't just uncomment this
#port = 4321
##Enable communication through ipv6
ipv6
## Bandwidth configuration
## L limit bandwidth to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited
## Default is P for floodfill, L for regular node
#bandwidth = L
## Router will not accept transit tunnels at startup
#notransit
## Router will be floodfill
#floodfill
## Section for Web Console
## By default it's available at 127.0.0.1:7070 even if it's not configured
[http]
## The address to listen on
address = 127.0.0.1
## The port to listen on
port = 7070
## Section for HTTP proxy
## By default it's available at 127.0.0.1:4444 even if it's not configured
[httpproxy]
## The address to listen on
address = 127.0.0.1
## The port to listen on
port = 4444
## Optional keys file for proxy local destination
#keys = http-proxy-keys.dat
## Uncomment if you want to disable HTTP proxy
#enabled=false
## Section for Socks proxy
## By default it's available at 127.0.0.1:4447 even if it's not configured
#[socksproxy]
## The address to listen on
#address = 127.0.0.1
## The port to listen on
#port = 4447
## Optional keys file for proxy local destination
#keys = socks-proxy-keys.dat
## Uncomment if you want to disable Socks proxy
#enabled=false
## Socks outproxy. Example below is set to use Tor for all connections except i2p
## Address of outproxy
#outproxy = 127.0.0.1
## Outproxy remote port
#outproxyport = 9050
## Section for SAM bridge
#[sam]
## The address to listen on
#address = 127.0.0.1
## Port of SAM bridge
#port = 7656
## Section for BOB command channel
#[bob]
## The address to listen on
#address = 127.0.0.1
## Port of BOB command channel. Usually 2827. BOB is off if not specified
#port = 2827
## Section for I2PControl protocol
#[i2pcontrol]
## The address to listen on
#address = 127.0.0.1
## Port of I2P control service
#port = 7650

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