Browse Source

Merge pull request #412 from PurpleI2P/openssl

recent changes
pull/436/head
orignal 9 years ago
parent
commit
18cc6a184f
  1. 33
      AddressBook.cpp
  2. 1
      Config.cpp
  3. 61
      DaemonWin32.cpp
  4. 4
      FS.cpp
  5. 20
      HTTPProxy.cpp
  6. 22
      HTTPServer.cpp
  7. 1
      HTTPServer.h
  8. 17
      Identity.cpp
  9. 2
      Makefile
  10. 14
      Makefile.mingw
  11. 2
      Transports.cpp
  12. 41
      UPnP.cpp
  13. 1
      Win32/Resource.rc
  14. 51
      Win32/Win32App.cpp
  15. BIN
      Win32/ictoopie_16.ico
  16. 2
      Win32/resource.h
  17. 6
      appveyor.yml
  18. 15
      build/CMakeLists.txt
  19. 17
      i2pd.cpp

33
AddressBook.cpp

@ -56,7 +56,7 @@ namespace client
f.seekg (0,std::ios::end); f.seekg (0,std::ios::end);
size_t len = f.tellg (); size_t len = f.tellg ();
if (len < i2p::data::DEFAULT_IDENTITY_SIZE) { if (len < i2p::data::DEFAULT_IDENTITY_SIZE) {
LogPrint (eLogError, "Addresbook: File ", filename, " is too short: ", len); LogPrint (eLogError, "Addressbook: File ", filename, " is too short: ", len);
return nullptr; return nullptr;
} }
f.seekg(0, std::ios::beg); f.seekg(0, std::ios::beg);
@ -72,7 +72,7 @@ namespace client
std::string path = storage.Path( address->GetIdentHash().ToBase32() ); std::string path = storage.Path( address->GetIdentHash().ToBase32() );
std::ofstream f (path, std::ofstream::binary | std::ofstream::out); std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
if (!f.is_open ()) { if (!f.is_open ()) {
LogPrint (eLogError, "Addresbook: can't open file ", path); LogPrint (eLogError, "Addressbook: can't open file ", path);
return; return;
} }
size_t len = address->GetFullLen (); size_t len = address->GetFullLen ();
@ -174,17 +174,17 @@ namespace client
} }
if (m_IsDownloading) if (m_IsDownloading)
{ {
LogPrint (eLogInfo, "Addresbook: subscriptions is downloading, abort"); LogPrint (eLogInfo, "Addressbook: subscriptions is downloading, abort");
for (int i = 0; i < 30; i++) for (int i = 0; i < 30; i++)
{ {
if (!m_IsDownloading) if (!m_IsDownloading)
{ {
LogPrint (eLogInfo, "Addresbook: subscriptions download complete"); LogPrint (eLogInfo, "Addressbook: subscriptions download complete");
break; break;
} }
std::this_thread::sleep_for (std::chrono::seconds (1)); // wait for 1 seconds std::this_thread::sleep_for (std::chrono::seconds (1)); // wait for 1 seconds
} }
LogPrint (eLogError, "Addresbook: subscription download timeout"); LogPrint (eLogError, "Addressbook: subscription download timeout");
m_IsDownloading = false; m_IsDownloading = false;
} }
if (m_Storage) if (m_Storage)
@ -303,10 +303,10 @@ namespace client
numAddresses++; numAddresses++;
} }
else else
LogPrint (eLogError, "Addresbook: malformed address ", addr, " for ", name); LogPrint (eLogError, "Addressbook: malformed address ", addr, " for ", name);
} }
} }
LogPrint (eLogInfo, "Addresbook: ", numAddresses, " addresses processed"); LogPrint (eLogInfo, "Addressbook: ", numAddresses, " addresses processed");
if (numAddresses > 0) if (numAddresses > 0)
{ {
m_IsLoaded = true; m_IsLoaded = true;
@ -331,7 +331,7 @@ namespace client
LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded"); LogPrint (eLogInfo, "Addressbook: ", m_Subscriptions.size (), " subscriptions urls loaded");
} }
else else
LogPrint (eLogWarning, "Addresbook: subscriptions.txt not found in datadir"); LogPrint (eLogWarning, "Addressbook: subscriptions.txt not found in datadir");
} }
else else
LogPrint (eLogError, "Addressbook: subscriptions already loaded"); LogPrint (eLogError, "Addressbook: subscriptions already loaded");
@ -340,15 +340,18 @@ namespace client
void AddressBook::DownloadComplete (bool success) void AddressBook::DownloadComplete (bool success)
{ {
m_IsDownloading = false; m_IsDownloading = false;
if (success && m_DefaultSubscription) int nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT;
if (success)
{ {
m_DefaultSubscription.reset (nullptr); if (m_DefaultSubscription) m_DefaultSubscription.reset (nullptr);
if (m_IsLoaded)
nextUpdateTimeout = CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT;
else
m_IsLoaded = true; m_IsLoaded = true;
} }
if (m_SubscriptionsUpdateTimer) if (m_SubscriptionsUpdateTimer)
{ {
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes( m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(nextUpdateTimeout));
success ? CONTINIOUS_SUBSCRIPTION_UPDATE_TIMEOUT : CONTINIOUS_SUBSCRIPTION_RETRY_TIMEOUT));
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer, m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
this, std::placeholders::_1)); this, std::placeholders::_1));
} }
@ -368,7 +371,7 @@ namespace client
this, std::placeholders::_1)); this, std::placeholders::_1));
} }
else else
LogPrint (eLogError, "Addresbook: can't start subscriptions: missing shared local destination"); LogPrint (eLogError, "Addressbook: can't start subscriptions: missing shared local destination");
} }
void AddressBook::StopSubscriptions () void AddressBook::StopSubscriptions ()
@ -429,7 +432,7 @@ namespace client
void AddressBookSubscription::Request () void AddressBookSubscription::Request ()
{ {
// must be run in separate thread // must be run in separate thread
LogPrint (eLogInfo, "Addresbook: Downloading hosts database from ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified); LogPrint (eLogInfo, "Addressbook: Downloading hosts database from ", m_Link, " ETag: ", m_Etag, " Last-Modified: ", m_LastModified);
bool success = false; bool success = false;
i2p::util::http::url u (m_Link); i2p::util::http::url u (m_Link);
i2p::data::IdentHash ident; i2p::data::IdentHash ident;
@ -488,7 +491,7 @@ namespace client
30); // wait for 30 seconds 30); // wait for 30 seconds
std::unique_lock<std::mutex> l(newDataReceivedMutex); std::unique_lock<std::mutex> l(newDataReceivedMutex);
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout)
LogPrint (eLogError, "Addresbook: subscriptions request timeout expired"); LogPrint (eLogError, "Addressbook: subscriptions request timeout expired");
} }
// process remaining buffer // process remaining buffer
while (size_t len = stream->ReadSome (buf, 4096)) while (size_t len = stream->ReadSome (buf, 4096))

1
Config.cpp

@ -125,6 +125,7 @@ namespace config {
("bandwidth", value<char>()->default_value('-'), "Bandwidth limiting: L - 32kbps, O - 256Kbps, P - unlimited") ("bandwidth", value<char>()->default_value('-'), "Bandwidth limiting: L - 32kbps, O - 256Kbps, P - unlimited")
#ifdef _WIN32 #ifdef _WIN32
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')") ("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
("insomnia", value<bool>()->zero_tokens()->default_value(false), "Prevent system from sleeping")
#endif #endif
; ;

61
DaemonWin32.cpp

@ -1,3 +1,4 @@
#include <thread>
#include "Config.h" #include "Config.h"
#include "Daemon.h" #include "Daemon.h"
#include "util.h" #include "util.h"
@ -5,7 +6,10 @@
#ifdef _WIN32 #ifdef _WIN32
#include "Win32/Win32Service.h"
#ifdef WIN32_APP
#include "Win32/Win32App.h" #include "Win32/Win32App.h"
#endif
namespace i2p namespace i2p
{ {
@ -16,8 +20,46 @@ namespace i2p
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
SetConsoleCP(1251); SetConsoleCP(1251);
SetConsoleOutputCP(1251); SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian");
return Daemon_Singleton::init(argc, argv); if (!Daemon_Singleton::init(argc, argv))
return false;
std::string serviceControl; i2p::config::GetOption("svcctl", serviceControl);
if (serviceControl == "install")
{
LogPrint(eLogInfo, "WinSVC: installing ", SERVICE_NAME, " as service");
InstallService(
SERVICE_NAME, // Name of service
SERVICE_DISPLAY_NAME, // Name to display
SERVICE_START_TYPE, // Service start type
SERVICE_DEPENDENCIES, // Dependencies
SERVICE_ACCOUNT, // Service running account
SERVICE_PASSWORD // Password of the account
);
return false;
}
else if (serviceControl == "remove")
{
LogPrint(eLogInfo, "WinSVC: uninstalling ", SERVICE_NAME, " service");
UninstallService(SERVICE_NAME);
return false;
}
if (isDaemon == 1)
{
LogPrint(eLogDebug, "Daemon: running as service");
I2PService service(SERVICE_NAME);
if (!I2PService::Run(service))
{
LogPrint(eLogError, "Daemon: Service failed to run w/err 0x%08lx\n", GetLastError());
return false;
}
return false;
}
else
LogPrint(eLogDebug, "Daemon: running as user");
return true;
} }
bool DaemonWin32::start() bool DaemonWin32::start()
@ -26,10 +68,12 @@ namespace i2p
SetConsoleCP(1251); SetConsoleCP(1251);
SetConsoleOutputCP(1251); SetConsoleOutputCP(1251);
setlocale(LC_ALL, "Russian"); setlocale(LC_ALL, "Russian");
#ifdef WIN32_APP
if (!i2p::win32::StartWin32App ()) return false; if (!i2p::win32::StartWin32App ()) return false;
// override log // override log
i2p::config::SetOption("log", std::string ("file")); i2p::config::SetOption("log", std::string ("file"));
#endif
bool ret = Daemon_Singleton::start(); bool ret = Daemon_Singleton::start();
if (ret && IsLogToFile ()) if (ret && IsLogToFile ())
{ {
@ -37,18 +81,31 @@ namespace i2p
SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE); SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE);
SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE); SetStdHandle(STD_ERROR_HANDLE, INVALID_HANDLE_VALUE);
} }
bool insomnia; i2p::config::GetOption("insomnia", insomnia);
if (insomnia)
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED);
return ret; return ret;
} }
bool DaemonWin32::stop() bool DaemonWin32::stop()
{ {
#ifdef WIN32_APP
i2p::win32::StopWin32App (); i2p::win32::StopWin32App ();
#endif
return Daemon_Singleton::stop(); return Daemon_Singleton::stop();
} }
void DaemonWin32::run () void DaemonWin32::run ()
{ {
#ifdef WIN32_APP
i2p::win32::RunWin32App (); i2p::win32::RunWin32App ();
#else
while (running)
{
std::this_thread::sleep_for (std::chrono::seconds(1));
}
#endif
} }
} }
} }

4
FS.cpp

@ -9,7 +9,7 @@
#include <algorithm> #include <algorithm>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#ifdef WIN32 #ifdef _WIN32
#include <shlobj.h> #include <shlobj.h>
#endif #endif
@ -108,7 +108,7 @@ namespace fs {
bool HashedStorage::Init(const char * chars, size_t count) { bool HashedStorage::Init(const char * chars, size_t count) {
if (!boost::filesystem::exists(root)) { if (!boost::filesystem::exists(root)) {
boost::filesystem::create_directory(root); boost::filesystem::create_directories(root);
} }
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {

20
HTTPProxy.cpp

@ -12,6 +12,7 @@
#include "ClientContext.h" #include "ClientContext.h"
#include "I2PEndian.h" #include "I2PEndian.h"
#include "I2PTunnel.h" #include "I2PTunnel.h"
#include "Config.h"
namespace i2p namespace i2p
{ {
@ -36,6 +37,7 @@ namespace proxy
void Terminate(); void Terminate();
void AsyncSockRead(); void AsyncSockRead();
void HTTPRequestFailed(/*std::string message*/); void HTTPRequestFailed(/*std::string message*/);
void RedirectToJumpService();
void ExtractRequest(); void ExtractRequest();
bool ValidateHTTPRequest(); bool ValidateHTTPRequest();
void HandleJumpServices(); void HandleJumpServices();
@ -95,6 +97,17 @@ namespace proxy
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1)); std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
} }
void HTTPProxyHandler::RedirectToJumpService(/*HTTPProxyHandler::errTypes error*/)
{
std::stringstream response;
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort);
response << "HTTP/1.1 302 Found\r\nLocation: http://" << httpAddr << ":" << httpPort << "/?jumpservices=&address=" << m_address << "\r\n\r\n";
boost::asio::async_write(*m_sock, boost::asio::buffer(response.str (),response.str ().length ()),
std::bind(&HTTPProxyHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
}
void HTTPProxyHandler::EnterState(HTTPProxyHandler::state nstate) void HTTPProxyHandler::EnterState(HTTPProxyHandler::state nstate)
{ {
m_state = nstate; m_state = nstate;
@ -168,6 +181,13 @@ namespace proxy
ExtractRequest(); //TODO: parse earlier ExtractRequest(); //TODO: parse earlier
if (!ValidateHTTPRequest()) return false; if (!ValidateHTTPRequest()) return false;
HandleJumpServices(); HandleJumpServices();
i2p::data::IdentHash identHash;
if (!i2p::client::context.GetAddressBook ().GetIdentHash (m_address, identHash)){
RedirectToJumpService();
return false;
}
m_request = m_method; m_request = m_method;
m_request.push_back(' '); m_request.push_back(' ');
m_request += m_path; m_request += m_path;

22
HTTPServer.cpp

@ -203,6 +203,9 @@ namespace util
const char HTTP_COMMAND_SAM_SESSION[] = "sam_session"; const char HTTP_COMMAND_SAM_SESSION[] = "sam_session";
const char HTTP_PARAM_SAM_SESSION_ID[] = "id"; const char HTTP_PARAM_SAM_SESSION_ID[] = "id";
const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels"; const char HTTP_COMMAND_I2P_TUNNELS[] = "i2p_tunnels";
const char HTTP_COMMAND_JUMPSERVICES[] = "jumpservices=";
const char HTTP_PARAM_ADDRESS[] = "address";
namespace misc_strings namespace misc_strings
{ {
@ -393,6 +396,7 @@ namespace util
else else
s << "<a href=/?" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n<br>\r\n"; s << "<a href=/?" << HTTP_COMMAND_START_ACCEPTING_TUNNELS << ">Start accepting tunnels</a><br>\r\n<br>\r\n";
s << "<a href=/?" << HTTP_COMMAND_RUN_PEER_TEST << ">Run peer test</a><br>\r\n<br>\r\n"; s << "<a href=/?" << HTTP_COMMAND_RUN_PEER_TEST << ">Run peer test</a><br>\r\n<br>\r\n";
s << "<a href=/?" << HTTP_COMMAND_JUMPSERVICES << "&address=example.i2p>Jump services</a><br>\r\n<br>\r\n";
s << "</div><div class=right>"; s << "</div><div class=right>";
if (address.length () > 1) if (address.length () > 1)
HandleCommand (address.substr (2), s); HandleCommand (address.substr (2), s);
@ -464,7 +468,13 @@ namespace util
ShowTransports (s); ShowTransports (s);
else if (cmd == HTTP_COMMAND_TUNNELS) else if (cmd == HTTP_COMMAND_TUNNELS)
ShowTunnels (s); ShowTunnels (s);
else if (cmd == HTTP_COMMAND_TRANSIT_TUNNELS) else if (cmd == HTTP_COMMAND_JUMPSERVICES)
{
std::map<std::string, std::string> params;
ExtractParams (command.substr (paramsPos), params);
auto address = params[HTTP_PARAM_ADDRESS];
ShowJumpServices (address, s);
} else if (cmd == HTTP_COMMAND_TRANSIT_TUNNELS)
ShowTransitTunnels (s); ShowTransitTunnels (s);
else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS) else if (cmd == HTTP_COMMAND_START_ACCEPTING_TUNNELS)
StartAcceptingTunnels (s); StartAcceptingTunnels (s);
@ -494,6 +504,16 @@ namespace util
ShowI2PTunnels (s); ShowI2PTunnels (s);
} }
void HTTPConnection::ShowJumpServices (const std::string& address, std::stringstream& s)
{
s << "<form type=\"get\" action=\"/\">";
s << "<input type=\"hidden\" name=\"jumpservices\">";
s << "<input type=\"text\" value=\"" << address << "\" name=\"address\"> </form><br>\r\n";
s << "<b>Jump services for " << address << "</b>";
s << "<ul><li><a href=\"http://inr.i2p/search/?q=" << address << "\">inr.i2p jump service</a> <br>\r\n";
s << "<li><a href=\"http://stats.i2p/cgi-bin/jump.cgi?a=" << address << "\">stats.i2p jump service</a></ul>";
}
void HTTPConnection::ShowLocalDestinations (std::stringstream& s) void HTTPConnection::ShowLocalDestinations (std::stringstream& s)
{ {
s << "<b>Local Destinations:</b><br>\r\n<br>\r\n"; s << "<b>Local Destinations:</b><br>\r\n<br>\r\n";

1
HTTPServer.h

@ -62,6 +62,7 @@ namespace util
void HandleRequest (const std::string& address); void HandleRequest (const std::string& address);
void HandleCommand (const std::string& command, std::stringstream& s); void HandleCommand (const std::string& command, std::stringstream& s);
void ShowJumpServices (const std::string& address, std::stringstream& s);
void ShowTransports (std::stringstream& s); void ShowTransports (std::stringstream& s);
void ShowTunnels (std::stringstream& s); void ShowTunnels (std::stringstream& s);
void ShowTransitTunnels (std::stringstream& s); void ShowTransitTunnels (std::stringstream& s);

17
Identity.cpp

@ -244,21 +244,20 @@ namespace data
size_t IdentityEx::FromBase64(const std::string& s) size_t IdentityEx::FromBase64(const std::string& s)
{ {
const size_t slen = s.length(); const size_t slen = s.length();
uint8_t buf[slen]; // binary data can't exceed base64 std::vector<uint8_t> buf(slen); // binary data can't exceed base64
const size_t len = Base64ToByteStream (s.c_str(), slen, buf, slen); const size_t len = Base64ToByteStream (s.c_str(), slen, buf.data(), slen);
return FromBuffer (buf, len); return FromBuffer (buf.data(), len);
} }
std::string IdentityEx::ToBase64 () const std::string IdentityEx::ToBase64 () const
{ {
const size_t bufLen = GetFullLen(); const size_t bufLen = GetFullLen();
const size_t strLen = Base64EncodingBufferSize(bufLen); const size_t strLen = Base64EncodingBufferSize(bufLen);
uint8_t buf[bufLen]; std::vector<uint8_t> buf(bufLen);
char str[strLen]; std::vector<char> str(strLen);
size_t l = ToBuffer (buf, bufLen); size_t l = ToBuffer (buf.data(), bufLen);
size_t l1 = i2p::data::ByteStreamToBase64 (buf, l, str, strLen); size_t l1 = i2p::data::ByteStreamToBase64 (buf.data(), l, str.data(), strLen);
str[l1] = 0; return std::string (str.data(), l1);
return std::string (str);
} }
size_t IdentityEx::GetSigningPublicKeyLen () const size_t IdentityEx::GetSigningPublicKeyLen () const

2
Makefile

@ -22,7 +22,7 @@ else ifeq ($(UNAME),Linux)
DAEMON_SRC += DaemonLinux.cpp DAEMON_SRC += DaemonLinux.cpp
include Makefile.linux include Makefile.linux
else # win32 mingw else # win32 mingw
DAEMON_SRC += DaemonWin32.cpp Win32/Win32App.cpp DAEMON_SRC += DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp
include Makefile.mingw include Makefile.mingw
endif endif

14
Makefile.mingw

@ -1,10 +1,11 @@
USE_WIN32_APP=yes
CXX = g++ CXX = g++
WINDRES = windres WINDRES = windres
CXXFLAGS = -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN CXXFLAGS = -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN
NEEDED_CXXFLAGS = -std=c++11 NEEDED_CXXFLAGS = -std=c++11
BOOST_SUFFIX = -mt BOOST_SUFFIX = -mt
INCFLAGS = -I/usr/include/ -I/usr/local/include/ INCFLAGS = -I/usr/include/ -I/usr/local/include/
LDFLAGS = -mwindows -Wl,-rpath,/usr/local/lib \ LDFLAGS = -Wl,-rpath,/usr/local/lib \
-L/usr/local/lib \ -L/usr/local/lib \
-L/c/dev/openssl \ -L/c/dev/openssl \
-L/c/dev/boost/lib -L/c/dev/boost/lib
@ -24,8 +25,13 @@ LDLIBS = \
-static-libgcc -static-libstdc++ \ -static-libgcc -static-libstdc++ \
-Wl,-Bstatic -lstdc++ \ -Wl,-Bstatic -lstdc++ \
-Wl,-Bstatic -lpthread -Wl,-Bstatic -lpthread
DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC)) ifeq ($(USE_WIN32_APP), yes)
CXXFLAGS += -DWIN32_APP
LDFLAGS += -mwindows -s
DAEMON_RC += Win32/Resource.rc
DAEMON_OBJS += $(patsubst %.rc,obj/%.o,$(DAEMON_RC))
endif
ifeq ($(USE_AESNI),1) ifeq ($(USE_AESNI),1)
CPU_FLAGS = -maes -DAESNI CPU_FLAGS = -maes -DAESNI

2
Transports.cpp

@ -261,7 +261,7 @@ namespace transport
{ {
peer.numAttempts++; peer.numAttempts++;
auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ());
if (address) if (address && m_NTCPServer)
{ {
#if BOOST_VERSION >= 104900 #if BOOST_VERSION >= 104900
if (!address->host.is_unspecified ()) // we have address now if (!address->host.is_unspecified ()) // we have address now

41
UPnP.cpp

@ -19,27 +19,19 @@
#include "UPnP.h" #include "UPnP.h"
#include "NetDb.h" #include "NetDb.h"
#include "util.h" #include "util.h"
#include "RouterInfo.h"
#include <miniupnpc/miniupnpc.h> #include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnpcommands.h> #include <miniupnpc/upnpcommands.h>
// These are per-process and are safe to reuse for all threads // These are per-process and are safe to reuse for all threads
#ifndef UPNPDISCOVER_SUCCESS decltype(upnpDiscover) *upnpDiscoverFunc;
/* miniupnpc 1.5 */ decltype(UPNP_AddPortMapping) *UPNP_AddPortMappingFunc;
UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int); decltype(UPNP_GetValidIGD) *UPNP_GetValidIGDFunc;
int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *, decltype(UPNP_GetExternalIPAddress) *UPNP_GetExternalIPAddressFunc;
const char *, const char *, const char *, const char *); decltype(UPNP_DeletePortMapping) *UPNP_DeletePortMappingFunc;
#else decltype(freeUPNPDevlist) *freeUPNPDevlistFunc;
/* miniupnpc 1.6 */ decltype(FreeUPNPUrls) *FreeUPNPUrlsFunc;
UPNPDev* (*upnpDiscoverFunc) (int, const char *, const char *, int, int, int *);
int (*UPNP_AddPortMappingFunc) (const char *, const char *, const char *, const char *,
const char *, const char *, const char *, const char *, const char *);
#endif
int (*UPNP_GetValidIGDFunc) (struct UPNPDev *, struct UPNPUrls *, struct IGDdatas *, char *, int);
int (*UPNP_GetExternalIPAddressFunc) (const char *, const char *, char *);
int (*UPNP_DeletePortMappingFunc) (const char *, const char *, const char *, const char *, const char *);
void (*freeUPNPDevlistFunc) (struct UPNPDev *);
void (*FreeUPNPUrlsFunc) (struct UPNPUrls *);
// Nice approach http://stackoverflow.com/a/21517513/673826 // Nice approach http://stackoverflow.com/a/21517513/673826
template<class M, typename F> template<class M, typename F>
@ -109,7 +101,8 @@ namespace transport
void UPnP::Run () void UPnP::Run ()
{ {
for (auto& address : context.GetRouterInfo ().GetAddresses ()) std::vector<data::RouterInfo::Address> a = context.GetRouterInfo().GetAddresses();
for (auto& address : a)
{ {
if (!address.host.is_v6 ()) if (!address.host.is_v6 ())
{ {
@ -128,12 +121,10 @@ namespace transport
void UPnP::Discover () void UPnP::Discover ()
{ {
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0);
#else
/* miniupnpc 1.6 */
int nerror = 0; int nerror = 0;
#if MINIUPNPC_API_VERSION >= 14
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror);
#else
m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror); m_Devlist = upnpDiscoverFunc (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
#endif #endif
@ -180,13 +171,7 @@ namespace transport
std::string strDesc = "I2Pd"; std::string strDesc = "I2Pd";
try { try {
for (;;) { for (;;) {
#ifndef UPNPDISCOVER_SUCCESS
/* miniupnpc 1.5 */
r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0);
#else
/* miniupnpc 1.6 */
r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0"); r = UPNP_AddPortMappingFunc (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0");
#endif
if (r!=UPNPCOMMAND_SUCCESS) if (r!=UPNPCOMMAND_SUCCESS)
{ {
LogPrint (eLogError, "UPnP: AddPortMapping (", strPort.c_str () ,", ", strPort.c_str () ,", ", m_NetworkAddr, ") failed with code ", r); LogPrint (eLogError, "UPnP: AddPortMapping (", strPort.c_str () ,", ", strPort.c_str () ,", ", m_NetworkAddr, ") failed with code ", r);

1
Win32/Resource.rc

@ -53,7 +53,6 @@ END
// Icon with lowest ID value placed first to ensure application icon // Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems. // remains consistent on all systems.
MAINICON ICON "ictoopie.ico" MAINICON ICON "ictoopie.ico"
IDI_ICON1 ICON "ictoopie_16.ico"
#endif // English (United States) resources #endif // English (United States) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

51
Win32/Win32App.cpp

@ -1,12 +1,14 @@
#include <string.h> #include <string.h>
#include <windows.h> #include <windows.h>
#include <shellapi.h> #include <shellapi.h>
//#include "../Daemon.h" #include "../Config.h"
#include "resource.h" #include "resource.h"
#include "Win32App.h" #include "Win32App.h"
#define ID_ABOUT 2000 #define ID_ABOUT 2000
#define ID_EXIT 2001 #define ID_EXIT 2001
#define ID_CONSOLE 2002
#define ID_APP 2003
#define ID_TRAY_ICON 2050 #define ID_TRAY_ICON 2050
#define WM_TRAYICON (WM_USER + 1) #define WM_TRAYICON (WM_USER + 1)
@ -18,10 +20,12 @@ namespace win32
static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem) static void ShowPopupMenu (HWND hWnd, POINT *curpos, int wDefaultItem)
{ {
HMENU hPopup = CreatePopupMenu(); HMENU hPopup = CreatePopupMenu();
InsertMenu (hPopup, 0, MF_BYPOSITION | MF_STRING, ID_ABOUT, "About..."); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_CONSOLE, "Open &console");
InsertMenu (hPopup, 1, MF_BYPOSITION | MF_STRING, ID_EXIT , "Exit"); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_APP, "Show app");
SetMenuDefaultItem (hPopup, ID_ABOUT, FALSE); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_ABOUT, "&About...");
SetFocus (hWnd); InsertMenu (hPopup, -1, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);
InsertMenu (hPopup, -1, MF_BYPOSITION | MF_STRING, ID_EXIT, "E&xit");
SetMenuDefaultItem (hPopup, ID_CONSOLE, FALSE);
SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0); SendMessage (hWnd, WM_INITMENUPOPUP, (WPARAM)hPopup, 0);
POINT p; POINT p;
@ -44,10 +48,11 @@ namespace win32
nid.cbSize = sizeof(nid); nid.cbSize = sizeof(nid);
nid.hWnd = hWnd; nid.hWnd = hWnd;
nid.uID = ID_TRAY_ICON; nid.uID = ID_TRAY_ICON;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
nid.uCallbackMessage = WM_TRAYICON; nid.uCallbackMessage = WM_TRAYICON;
nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (IDI_ICON1)); nid.hIcon = LoadIcon (GetModuleHandle(NULL), MAKEINTRESOURCE (MAINICON));
strcpy (nid.szTip, "i2pd"); strcpy (nid.szTip, "i2pd");
strcpy (nid.szInfo, "i2pd is running");
Shell_NotifyIcon(NIM_ADD, &nid ); Shell_NotifyIcon(NIM_ADD, &nid );
} }
@ -88,14 +93,39 @@ namespace win32
PostMessage (hWnd, WM_CLOSE, 0, 0); PostMessage (hWnd, WM_CLOSE, 0, 0);
return 0; return 0;
} }
case ID_CONSOLE:
{
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);
ShellExecute(NULL, "open", buf, NULL, NULL, SW_SHOWNORMAL);
return 0;
}
case ID_APP:
{
ShowWindow(hWnd, SW_SHOW);
return 0;
}
} }
break; break;
} }
case WM_SYSCOMMAND:
{
switch (wParam)
{
case SC_MINIMIZE:
{
ShowWindow(hWnd, SW_HIDE);
return 0;
}
}
}
case WM_TRAYICON: case WM_TRAYICON:
{ {
SetForegroundWindow (hWnd);
switch (lParam) switch (lParam)
{ {
case WM_LBUTTONUP:
case WM_RBUTTONUP: case WM_RBUTTONUP:
{ {
SetForegroundWindow (hWnd); SetForegroundWindow (hWnd);
@ -127,15 +157,14 @@ namespace win32
wclx.cbClsExtra = 0; wclx.cbClsExtra = 0;
wclx.cbWndExtra = 0; wclx.cbWndExtra = 0;
wclx.hInstance = hInst; wclx.hInstance = hInst;
wclx.hIcon = LoadIcon (hInst, IDI_APPLICATION); wclx.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(MAINICON));
wclx.hIconSm = LoadIcon (hInst, IDI_APPLICATION);
wclx.hCursor = LoadCursor (NULL, IDC_ARROW); wclx.hCursor = LoadCursor (NULL, IDC_ARROW);
wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wclx.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wclx.lpszMenuName = NULL; wclx.lpszMenuName = NULL;
wclx.lpszClassName = I2PD_WIN32_CLASSNAME; wclx.lpszClassName = I2PD_WIN32_CLASSNAME;
RegisterClassEx (&wclx); RegisterClassEx (&wclx);
// create new window // create new window
if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 100, 250, 150, NULL, NULL, hInst, NULL)) if (!CreateWindow(I2PD_WIN32_CLASSNAME, TEXT("i2pd"), WS_OVERLAPPEDWINDOW, 100, 100, 250, 150, NULL, NULL, hInst, NULL))
{ {
MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST);
return false; return false;

BIN
Win32/ictoopie_16.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

2
Win32/resource.h

@ -2,7 +2,7 @@
// Microsoft Visual C++ generated include file. // Microsoft Visual C++ generated include file.
// Used by Resource.rc // Used by Resource.rc
// //
#define IDI_ICON1 101 #define MAINICON 101
// Next default values for new objects // Next default values for new objects
// //

6
appveyor.yml

@ -142,9 +142,9 @@ install:
- if not defined msvc ( - if not defined msvc (
C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel" C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel"
&& if "%x64%" == "1" ( && if "%x64%" == "1" (
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-openssl mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc"
) else ( ) else (
C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-boost mingw-w64-i686-miniupnpc" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-openssl mingw-w64-i686-boost mingw-w64-i686-miniupnpc"
) )
) )
cache: cache:
@ -167,7 +167,7 @@ build_script:
echo "bitness=%bitness%; static=%static%; dll=%dll%; type=%type%; generator=%generator%; variant=%variant%; cmake=%cmake%; cmake_extra=%cmake_extra%" echo "bitness=%bitness%; static=%static%; dll=%dll%; type=%type%; generator=%generator%; variant=%variant%; cmake=%cmake%; cmake_extra=%cmake_extra%"
- if not defined msvc ( - if not defined msvc (
C:\msys64\usr\bin\bash -lc "export PATH=/mingw%bitness%/bin:/usr/bin && cd /c/projects/build && cmake /c/projects/i2pd/build -G 'Unix Makefiles' -DWITH_AESNI=ON -DWITH_UPNP=ON %cmake% %cmake_extra% -DWITH_STATIC=%static% -DWITH_HARDENING=ON -DCMAKE_INSTALL_PREFIX:PATH=/c/projects/instdir -DCMAKE_FIND_ROOT_PATH=/mingw%bitness% && make install" C:\msys64\usr\bin\bash -lc "export PATH=/mingw%bitness%/bin:/usr/bin && cd /c/projects/build && CC=/mingw%bitness%/bin/gcc.exe CXX=/mingw%bitness%/bin/g++.exe /usr/bin/cmake /c/projects/i2pd/build -G 'Unix Makefiles' -DWITH_AESNI=ON -DWITH_UPNP=ON %cmake% %cmake_extra% -DWITH_STATIC=%static% -DWITH_HARDENING=ON -DCMAKE_INSTALL_PREFIX:PATH=/c/projects/instdir -DCMAKE_FIND_ROOT_PATH=/mingw%bitness% && make install"
&& 7z a -tzip -mx9 -mmt C:\projects\i2pd\i2pd-mingw-win%bitness%-%type%.zip C:\projects\instdir\* C:\msys64\mingw%bitness%\bin\zlib1.dll C:\msys64\mingw%bitness%\bin\*eay32.dll && 7z a -tzip -mx9 -mmt C:\projects\i2pd\i2pd-mingw-win%bitness%-%type%.zip C:\projects\instdir\* C:\msys64\mingw%bitness%\bin\zlib1.dll C:\msys64\mingw%bitness%\bin\*eay32.dll
) )
- rem We are fine with multiple generated configurations in MS solution. Will use later - rem We are fine with multiple generated configurations in MS solution. Will use later

15
build/CMakeLists.txt

@ -11,6 +11,7 @@ option(WITH_BINARY "Build binary" ON)
option(WITH_STATIC "Static build" OFF) option(WITH_STATIC "Static build" OFF)
option(WITH_UPNP "Include support for UPnP client" OFF) option(WITH_UPNP "Include support for UPnP client" OFF)
option(WITH_PCH "Use precompiled header" OFF) option(WITH_PCH "Use precompiled header" OFF)
option(WITH_GUI "Include GUI (currently MS Windows only)" ON)
# paths # paths
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ) set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
@ -56,7 +57,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
endif () endif ()
add_library(libi2pd ${LIBI2PD_SRC}) add_library(libi2pd ${LIBI2PD_SRC})
set_target_properties(libi2pd PROPERTIES OUTPUT_NAME "i2pd") set_target_properties(libi2pd PROPERTIES PREFIX "")
install(TARGETS libi2pd install(TARGETS libi2pd
EXPORT libi2pd EXPORT libi2pd
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
@ -95,7 +96,7 @@ endif ()
# compiler flags customization (by vendor) # compiler flags customization (by vendor)
if (MSVC) if (MSVC)
add_definitions( -D_WIN32_WINNT=_WIN32_WINNT_WINXP -DWIN32_LEAN_AND_MEAN -DNOMINMAX ) #-DOPENSSL_NO_SSL2 -DOPENSSL_USE_DEPRECATED add_definitions( -DWIN32_LEAN_AND_MEAN -DNOMINMAX )
# TODO Check & report to Boost dev, there should be no need for these two # TODO Check & report to Boost dev, there should be no need for these two
add_definitions( -DBOOST_THREAD_NO_LIB -DBOOST_CHRONO_NO_LIB ) add_definitions( -DBOOST_THREAD_NO_LIB -DBOOST_CHRONO_NO_LIB )
set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL" ) set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL" )
@ -157,6 +158,11 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.cpp") list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonLinux.cpp")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS) elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonWin32.cpp") list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/DaemonWin32.cpp")
if (WITH_GUI)
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32App.cpp")
set_source_files_properties("${CMAKE_SOURCE_DIR}/DaemonWin32.cpp"
PROPERTIES COMPILE_DEFINITIONS WIN32_APP)
endif ()
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32Service.cpp") list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Win32Service.cpp")
list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Resource.rc") list (APPEND DAEMON_SRC "${CMAKE_SOURCE_DIR}/Win32/Resource.rc")
endif () endif ()
@ -309,7 +315,10 @@ include(GNUInstallDirs)
if (WITH_BINARY) if (WITH_BINARY)
add_executable ( "${PROJECT_NAME}" ${DAEMON_SRC} ) add_executable ( "${PROJECT_NAME}" ${DAEMON_SRC} )
if(NOT MSVC) # FIXME: incremental linker file name (.ilk) collision for dll & exe if (WIN32 AND WITH_GUI)
set_target_properties("${PROJECT_NAME}" PROPERTIES WIN32_EXECUTABLE TRUE )
endif()
if(NOT MSVC)
if (WITH_STATIC) if (WITH_STATIC)
set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static" ) set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static" )
endif () endif ()

17
i2pd.cpp

@ -3,10 +3,25 @@
int main( int argc, char* argv[] ) int main( int argc, char* argv[] )
{ {
Daemon.init(argc, argv); if (Daemon.init(argc, argv))
{
if (Daemon.start()) if (Daemon.start())
Daemon.run (); Daemon.run ();
Daemon.stop(); Daemon.stop();
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
#ifdef _WIN32
#include <windows.h>
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
return main(__argc, __argv);
}
#endif

Loading…
Cancel
Save