diff --git a/Makefile.linux b/Makefile.linux
index 4a82591a..2c30bbb0 100644
--- a/Makefile.linux
+++ b/Makefile.linux
@@ -60,7 +60,12 @@ endif
ifeq ($(USE_AESNI),yes)
#check if AES-NI is supported by CPU
ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0)
- CPU_FLAGS += -maes -DAESNI
+ machine := $(shell uname -m)
+ ifeq ($(machine), aarch64)
+ CXXFLAGS += -DARM64AES
+ else
+ CPU_FLAGS += -maes -DAESNI
+ endif
endif
endif
diff --git a/daemon/Daemon.h b/daemon/Daemon.h
index f3e72904..4491d303 100644
--- a/daemon/Daemon.h
+++ b/daemon/Daemon.h
@@ -64,7 +64,18 @@ namespace util
DaemonWin32 ():isGraceful(false) {}
};
-
+#elif defined(ANDROID)
+#define Daemon i2p::util::DaemonAndroid::Instance()
+ // dummy, invoked from android/jni/DaemonAndroid.*
+ class DaemonAndroid: public i2p::util::Daemon_Singleton
+ {
+ public:
+ static DaemonAndroid& Instance()
+ {
+ static DaemonAndroid instance;
+ return instance;
+ }
+ };
#else
#define Daemon i2p::util::DaemonLinux::Instance()
class DaemonLinux : public Daemon_Singleton
diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp
index 6f884a9b..657e6d43 100644
--- a/daemon/HTTPServer.cpp
+++ b/daemon/HTTPServer.cpp
@@ -198,7 +198,10 @@ namespace http {
s << "ERROR: " << string << "
\r\n";
}
- void ShowStatus (std::stringstream& s, bool includeHiddenContent)
+ void ShowStatus (
+ std::stringstream& s,
+ bool includeHiddenContent,
+ i2p::http::OutputFormatEnum outputFormat)
{
s << "Uptime: ";
ShowUptime(s, i2p::context.GetUptime ());
@@ -245,9 +248,12 @@ namespace http {
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)
\r\n";
s << "Data path: " << i2p::fs::GetDataDir() << "
\r\n";
- s << "
\r\n
\r\n
\r\n";
- if(includeHiddenContent) {
- s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n";
+ s << "
";
+ if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
+ s << "
\r\n
\r\n
\r\n";
+ }
+ if(includeHiddenContent) {
+ s << "Router Ident: " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "
\r\n";
s << "Router Family: " << i2p::context.GetRouterInfo().GetProperty("family") << "
\r\n";
s << "Router Caps: " << i2p::context.GetRouterInfo().GetProperty("caps") << "
\r\n";
s << "Our external address:" << "
\r\n" ;
@@ -272,9 +278,12 @@ namespace http {
}
s << address->host.to_string() << ":" << address->port << "
\r\n";
}
- }
+ }
s << "
\r\n
\r\n";
- s << "
Routers: " << i2p::data::netdb.GetNumRouters () << " ";
+ if(outputFormat==OutputFormatEnum::forQtUi) {
+ s << "
";
+ }
+ s << "
Routers: " << i2p::data::netdb.GetNumRouters () << " ";
s << "
Floodfills: " << i2p::data::netdb.GetNumFloodfills () << " ";
s << "
LeaseSets: " << i2p::data::netdb.GetNumLeaseSets () << "
\r\n";
@@ -285,15 +294,17 @@ namespace http {
s << "
Client Tunnels: " << std::to_string(clientTunnelCount) << " ";
s << "
Transit Tunnels: " << std::to_string(transitTunnelCount) << "
\r\n
\r\n";
- s << "
ServicesService | State |
\r\n";
- s << "" << "HTTP Proxy" << " | |
\r\n";
- s << "" << "SOCKS Proxy" << " | |
\r\n";
- s << "" << "BOB" << " | |
\r\n";
- s << "" << "SAM" << " | |
\r\n";
- s << "" << "I2CP" << " | |
\r\n";
- bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
- s << "" << "I2PControl" << " | |
\r\n";
- s << "
\r\n";
+ if(outputFormat==OutputFormatEnum::forWebConsole) {
+ s << "
ServicesService | State |
\r\n";
+ s << "" << "HTTP Proxy" << " | |
\r\n";
+ s << "" << "SOCKS Proxy" << " | |
\r\n";
+ s << "" << "BOB" << " | |
\r\n";
+ s << "" << "SAM" << " | |
\r\n";
+ s << "" << "I2CP" << " | |
\r\n";
+ bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
+ s << "" << "I2PControl" << " | |
\r\n";
+ s << "
\r\n";
+ }
}
void ShowLocalDestinations (std::stringstream& s)
@@ -649,7 +660,7 @@ namespace http {
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "
\r\n";
s << "
\r\n";
s << "
Streams:\r\n";
- for (const auto& it: session->ListSockets())
+ for (const auto& it: sam->ListSockets(id))
{
switch (it->GetSocketType ())
{
@@ -863,7 +874,7 @@ namespace http {
} else if (req.uri.find("cmd=") != std::string::npos) {
HandleCommand (req, res, s);
} else {
- ShowStatus (s, true);
+ ShowStatus (s, true, i2p::http::OutputFormatEnum::forWebConsole);
res.add_header("Refresh", "10");
}
ShowPageTail (s);
diff --git a/daemon/HTTPServer.h b/daemon/HTTPServer.h
index 46477dae..a1b82875 100644
--- a/daemon/HTTPServer.h
+++ b/daemon/HTTPServer.h
@@ -80,7 +80,8 @@ namespace http
};
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml
- void ShowStatus (std::stringstream& s, bool includeHiddenContent);
+ enum OutputFormatEnum { forWebConsole, forQtUi };
+ void ShowStatus (std::stringstream& s, bool includeHiddenContent, OutputFormatEnum outputFormat);
void ShowLocalDestinations (std::stringstream& s);
void ShowLeasesSets(std::stringstream& s);
void ShowTunnels (std::stringstream& s);
diff --git a/daemon/I2PControl.cpp b/daemon/I2PControl.cpp
index fcff78cd..6ac87cbb 100644
--- a/daemon/I2PControl.cpp
+++ b/daemon/I2PControl.cpp
@@ -727,7 +727,7 @@ namespace client
sam_session.put("name", name);
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident));
- for (const auto& socket: it.second->ListSockets())
+ for (const auto& socket: sam->ListSockets(it.first))
{
boost::property_tree::ptree stream;
stream.put("type", socket->GetSocketType ());
diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp
index 5ba3334d..8ba99a15 100644
--- a/libi2pd/Crypto.cpp
+++ b/libi2pd/Crypto.cpp
@@ -594,6 +594,13 @@ namespace crypto
// AES
#ifdef AESNI
+ #ifdef ARM64AES
+ void init_aesenc(void){
+ // TODO: Implementation
+ }
+
+ #endif
+
#define KeyExpansion256(round0,round1) \
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
"movaps %%xmm1, %%xmm4 \n" \
diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h
index 6e4ddb3d..859f2d97 100644
--- a/libi2pd/Crypto.h
+++ b/libi2pd/Crypto.h
@@ -124,6 +124,9 @@ namespace crypto
#ifdef AESNI
+ #ifdef ARM64AES
+ void init_aesenc(void) __attribute__((constructor));
+ #endif
class ECBCryptoAESNI
{
public:
diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp
index 41d7903b..985e1c22 100644
--- a/libi2pd/HTTP.cpp
+++ b/libi2pd/HTTP.cpp
@@ -96,7 +96,7 @@ namespace http {
pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */
if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) {
std::size_t delim = url.find(':', pos_p);
- if (delim != std::string::npos && delim < pos_c) {
+ if (delim && delim != std::string::npos && delim < pos_c) {
user = url.substr(pos_p, delim - pos_p);
delim += 1;
pass = url.substr(delim, pos_c - delim);
diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp
index dd8e3634..e8386b61 100644
--- a/libi2pd/Streaming.cpp
+++ b/libi2pd/Streaming.cpp
@@ -578,9 +578,7 @@ namespace stream
if (m_SentPackets.empty () && m_SendBuffer.IsEmpty ()) // nothing to send
{
m_Status = eStreamStatusClosed;
- // close could be called from another thread so do SendClose from the destination thread
- // this is so m_LocalDestination.NewPacket () does not trigger a race condition
- m_Service.post(std::bind(&Stream::SendClose, shared_from_this()));
+ SendClose();
}
break;
case eStreamStatusClosed:
diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h
index 47f99833..3db8d760 100644
--- a/libi2pd/Streaming.h
+++ b/libi2pd/Streaming.h
@@ -165,6 +165,9 @@ namespace stream
void AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout = 0);
size_t ReadSome (uint8_t * buf, size_t len) { return ConcatenatePackets (buf, len); };
+ void AsyncClose() { m_Service.post(std::bind(&Stream::Close, shared_from_this())); };
+
+ /** only call close from destination thread, use Stream::AsyncClose for other threads */
void Close ();
void Cancel () { m_ReceiveTimer.cancel (); };
diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp
index 6c3a9410..99f34b73 100644
--- a/libi2pd_client/ClientContext.cpp
+++ b/libi2pd_client/ClientContext.cpp
@@ -488,8 +488,8 @@ namespace client
{
localDestination = m_SharedLocalDestination;
}
- auto clientTunnel = new I2PUDPClientTunnel(name, dest, end, localDestination, destinationPort);
- if(m_ClientForwards.insert(std::make_pair(end, std::unique_ptr
(clientTunnel))).second)
+ auto clientTunnel = std::make_shared(name, dest, end, localDestination, destinationPort);
+ if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second)
{
clientTunnel->Start();
}
@@ -498,31 +498,35 @@ namespace client
} else {
boost::asio::ip::tcp::endpoint clientEndpoint;
- I2PService * clientTunnel = nullptr;
+ std::shared_ptr clientTunnel;
if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS)
{
// socks proxy
- clientTunnel = new i2p::proxy::SOCKSProxy(name, address, port, false, "", destinationPort, localDestination);
- clientEndpoint = ((i2p::proxy::SOCKSProxy*)clientTunnel)->GetLocalEndpoint ();
+ auto tun = std::make_shared(name, address, port, false, "", destinationPort, localDestination);
+ clientTunnel = tun;
+ clientEndpoint = tun->GetLocalEndpoint ();
}
else if (type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)
{
// http proxy
std::string outproxy = section.second.get("outproxy", "");
- clientTunnel = new i2p::proxy::HTTPProxy(name, address, port, outproxy, localDestination);
- clientEndpoint = ((i2p::proxy::HTTPProxy*)clientTunnel)->GetLocalEndpoint ();
+ auto tun = std::make_shared(name, address, port, outproxy, localDestination);
+ clientTunnel = tun;
+ clientEndpoint = tun->GetLocalEndpoint ();
}
else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)
{
// websocks proxy
- clientTunnel = new WebSocks(address, port, localDestination);;
- clientEndpoint = ((WebSocks*)clientTunnel)->GetLocalEndpoint();
+ auto tun = std::make_shared(address, port, localDestination);
+ clientTunnel = tun;
+ clientEndpoint = tun->GetLocalEndpoint();
}
else
{
// tcp client
- clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort);
- clientEndpoint = ((I2PClientTunnel*)clientTunnel)->GetLocalEndpoint ();
+ auto tun = std::make_shared (name, dest, address, port, localDestination, destinationPort);
+ clientTunnel = tun;
+ clientEndpoint = tun->GetLocalEndpoint ();
}
uint32_t timeout = section.second.get(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0);
if(timeout)
@@ -531,8 +535,7 @@ namespace client
LogPrint(eLogInfo, "Clients: I2P Client tunnel connect timeout set to ", timeout);
}
- auto clientTunnelDest = clientTunnel->GetLocalDestination (); // make copy of destination for possible update
- auto ins = m_ClientTunnels.insert (std::make_pair (clientEndpoint, std::unique_ptr(clientTunnel)));
+ auto ins = m_ClientTunnels.insert (std::make_pair (clientEndpoint, clientTunnel));
if (ins.second)
{
clientTunnel->Start ();
@@ -541,10 +544,10 @@ namespace client
else
{
// TODO: update
- if (ins.first->second->GetLocalDestination () != clientTunnelDest)
+ if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ())
{
LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated");
- ins.first->second->SetLocalDestination (clientTunnelDest);
+ ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ());
}
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists");
@@ -589,7 +592,7 @@ namespace client
// TODO: hostnames
auto localAddress = boost::asio::ip::address::from_string(address);
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port);
- I2PUDPServerTunnel * serverTunnel = new I2PUDPServerTunnel(name, localDestination, localAddress, endpoint, port);
+ auto serverTunnel = std::make_shared(name, localDestination, localAddress, endpoint, port);
if(!isUniqueLocal)
{
LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
@@ -600,7 +603,7 @@ namespace client
std::make_pair(
std::make_pair(
localDestination->GetIdentHash(), port),
- std::unique_ptr(serverTunnel))).second)
+ serverTunnel)).second)
{
serverTunnel->Start();
LogPrint(eLogInfo, "Clients: I2P Server Forward created for UDP Endpoint ", host, ":", port, " bound on ", address, " for ",localDestination->GetIdentHash().ToBase32());
@@ -611,13 +614,13 @@ namespace client
continue;
}
- I2PServerTunnel * serverTunnel;
+ std::shared_ptr serverTunnel;
if (type == I2P_TUNNELS_SECTION_TYPE_HTTP)
- serverTunnel = new I2PServerTunnelHTTP (name, host, port, localDestination, hostOverride, inPort, gzip);
+ serverTunnel = std::make_shared (name, host, port, localDestination, hostOverride, inPort, gzip);
else if (type == I2P_TUNNELS_SECTION_TYPE_IRC)
- serverTunnel = new I2PServerTunnelIRC (name, host, port, localDestination, webircpass, inPort, gzip);
+ serverTunnel = std::make_shared (name, host, port, localDestination, webircpass, inPort, gzip);
else // regular server tunnel by default
- serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip);
+ serverTunnel = std::make_shared (name, host, port, localDestination, inPort, gzip);
if(!isUniqueLocal)
{
@@ -640,10 +643,9 @@ namespace client
while (comma != std::string::npos);
serverTunnel->SetAccessList (idents);
}
- auto serverTunnelDest = serverTunnel->GetLocalDestination ();
auto ins = m_ServerTunnels.insert (std::make_pair (
- std::make_pair (localDestination->GetIdentHash (), inPort),
- std::unique_ptr(serverTunnel)));
+ std::make_pair (localDestination->GetIdentHash (), inPort),
+ serverTunnel));
if (ins.second)
{
serverTunnel->Start ();
@@ -652,10 +654,10 @@ namespace client
else
{
// TODO: update
- if (ins.first->second->GetLocalDestination () != serverTunnelDest)
+ if (ins.first->second->GetLocalDestination () != serverTunnel->GetLocalDestination ())
{
LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated");
- ins.first->second->SetLocalDestination (serverTunnelDest);
+ ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ());
}
ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists");
diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h
index 922d7acc..06aab3b1 100644
--- a/libi2pd_client/ClientContext.h
+++ b/libi2pd_client/ClientContext.h
@@ -113,12 +113,12 @@ namespace client
i2p::proxy::HTTPProxy * m_HttpProxy;
i2p::proxy::SOCKSProxy * m_SocksProxy;
- std::map > m_ClientTunnels; // local endpoint->tunnel
- std::map, std::unique_ptr > m_ServerTunnels; // ->tunnel
+ std::map > m_ClientTunnels; // local endpoint->tunnel
+ std::map, std::shared_ptr > m_ServerTunnels; // ->tunnel
std::mutex m_ForwardsMutex;
- std::map > m_ClientForwards; // local endpoint -> udp tunnel
- std::map, std::unique_ptr > m_ServerForwards; // -> udp tunnel
+ std::map > m_ClientForwards; // local endpoint -> udp tunnel
+ std::map, std::shared_ptr > m_ServerForwards; // -> udp tunnel
SAMBridge * m_SamBridge;
BOBCommandChannel * m_BOBCommandChannel;
diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp
index 05943981..ac2dd853 100644
--- a/libi2pd_client/SAM.cpp
+++ b/libi2pd_client/SAM.cpp
@@ -15,8 +15,8 @@ namespace i2p
{
namespace client
{
- SAMSocket::SAMSocket (SAMBridge& owner, std::shared_ptr socket):
- m_Owner (owner), m_Socket(socket), m_Timer (m_Owner.GetService ()),
+ SAMSocket::SAMSocket (SAMBridge& owner):
+ m_Owner (owner), m_Socket(owner.GetService()), m_Timer (m_Owner.GetService ()),
m_BufferOffset (0),
m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false),
m_IsAccepting (false), m_Stream (nullptr)
@@ -25,51 +25,17 @@ namespace client
SAMSocket::~SAMSocket ()
{
- if(m_Stream)
- {
- m_Stream->Close ();
- m_Stream.reset ();
- }
- auto Session = m_Owner.FindSession(m_ID);
-
- switch (m_SocketType)
- {
- case eSAMSocketTypeSession:
- m_Owner.CloseSession (m_ID);
- break;
- case eSAMSocketTypeStream:
- {
- if (Session)
- Session->DelSocket (this);
- break;
- }
- case eSAMSocketTypeAcceptor:
- {
- if (Session)
- {
- Session->DelSocket (this);
- if (m_IsAccepting && Session->localDestination)
- Session->localDestination->StopAcceptingStreams ();
- }
- break;
- }
- default:
- ;
- }
- m_SocketType = eSAMSocketTypeTerminated;
- if (m_Socket && m_Socket->is_open()) m_Socket->close ();
- m_Socket.reset ();
+ m_Stream = nullptr;
}
void SAMSocket::Terminate (const char* reason)
{
if(m_Stream)
{
- m_Stream->Close ();
- m_Stream.reset ();
+ m_Stream->AsyncClose ();
+ m_Stream = nullptr;
}
auto Session = m_Owner.FindSession(m_ID);
-
switch (m_SocketType)
{
case eSAMSocketTypeSession:
@@ -77,15 +43,12 @@ namespace client
break;
case eSAMSocketTypeStream:
{
- if (Session)
- Session->DelSocket (this);
break;
}
case eSAMSocketTypeAcceptor:
{
if (Session)
{
- Session->DelSocket (this);
if (m_IsAccepting && Session->localDestination)
Session->localDestination->StopAcceptingStreams ();
}
@@ -95,16 +58,20 @@ namespace client
;
}
m_SocketType = eSAMSocketTypeTerminated;
- if (m_Socket && m_Socket->is_open()) m_Socket->close ();
- m_Socket.reset ();
+ if (m_Socket.is_open ())
+ {
+ boost::system::error_code ec;
+ m_Socket.shutdown (boost::asio::ip::tcp::socket::shutdown_both, ec);
+ m_Socket.close ();
+ }
+ m_Owner.RemoveSocket(shared_from_this());
}
void SAMSocket::ReceiveHandshake ()
- {
- if(m_Socket)
- m_Socket->async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
- std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (),
- std::placeholders::_1, std::placeholders::_2));
+ {
+ m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
+ std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (),
+ std::placeholders::_1, std::placeholders::_2));
}
static bool SAMVersionAcceptable(const std::string & ver)
@@ -125,7 +92,7 @@ namespace client
void SAMSocket::HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
- {
+ {
LogPrint (eLogError, "SAM: handshake read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ("SAM: handshake read error");
@@ -184,7 +151,7 @@ namespace client
#else
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
#endif
- boost::asio::async_write (*m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (),
+ boost::asio::async_write (m_Socket, boost::asio::buffer (m_Buffer, l), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
@@ -199,17 +166,22 @@ namespace client
}
}
+ bool SAMSocket::IsSession(const std::string & id) const
+ {
+ return id == m_ID;
+ }
+
void SAMSocket::HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
- {
+ {
LogPrint (eLogError, "SAM: handshake reply send error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ("SAM: handshake reply send error");
}
- else if(m_Socket)
+ else
{
- m_Socket->async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
+ m_Socket.async_read_some (boost::asio::buffer(m_Buffer, SAM_SOCKET_BUFFER_SIZE),
std::bind(&SAMSocket::HandleMessage, shared_from_this (),
std::placeholders::_1, std::placeholders::_2));
}
@@ -220,7 +192,7 @@ namespace client
LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg);
if (!m_IsSilent)
- boost::asio::async_write (*m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (),
+ boost::asio::async_write (m_Socket, boost::asio::buffer (msg, len), boost::asio::transfer_all (),
std::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, close));
else
@@ -235,7 +207,7 @@ namespace client
void SAMSocket::HandleMessageReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred, bool close)
{
if (ecode)
- {
+ {
LogPrint (eLogError, "SAM: reply send error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ("SAM: reply send error");
@@ -252,7 +224,7 @@ namespace client
void SAMSocket::HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{
if (ecode)
- {
+ {
LogPrint (eLogError, "SAM: read error: ", ecode.message ());
if (ecode != boost::asio::error::operation_aborted)
Terminate ("SAM: read error");
@@ -501,7 +473,6 @@ namespace client
if(session)
{
m_SocketType = eSAMSocketTypeStream;
- session->AddSocket (shared_from_this ());
m_Stream = session->localDestination->CreateStream (remote);
m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send
m_BufferOffset = 0;
@@ -534,7 +505,6 @@ namespace client
if (session)
{
m_SocketType = eSAMSocketTypeAcceptor;
- session->AddSocket (shared_from_this ());
if (!session->localDestination->IsAcceptingStreams ())
{
m_IsAccepting = true;
@@ -599,7 +569,7 @@ namespace client
keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
#else
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY,
- keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
+ keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
#endif
SendMessageReply (m_Buffer, l, false);
}
@@ -704,17 +674,9 @@ namespace client
void SAMSocket::Receive ()
{
- if (m_BufferOffset >= SAM_SOCKET_BUFFER_SIZE)
- {
- LogPrint (eLogError, "SAM: Buffer is full, terminate");
- Terminate ("Buffer is full");
- return;
- } else if (m_Socket)
- m_Socket->async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset),
- std::bind((m_SocketType == eSAMSocketTypeStream) ? &SAMSocket::HandleReceived : &SAMSocket::HandleMessage,
- shared_from_this (), std::placeholders::_1, std::placeholders::_2));
- else
- LogPrint(eLogError, "SAM: receive with no native socket");
+ m_Socket.async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset),
+ std::bind((m_SocketType == eSAMSocketTypeStream) ? &SAMSocket::HandleReceived : &SAMSocket::HandleMessage,
+ shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
void SAMSocket::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
@@ -731,15 +693,12 @@ namespace client
{
bytes_transferred += m_BufferOffset;
m_BufferOffset = 0;
- auto s = shared_from_this ();
m_Stream->AsyncSend ((uint8_t *)m_Buffer, bytes_transferred,
- [s](const boost::system::error_code& ecode)
- {
- if (!ecode)
- s->m_Owner.GetService ().post ([s] { s->Receive (); });
- else
- s->m_Owner.GetService ().post ([s] { s->Terminate ("AsyncSend failed"); });
- });
+ std::bind(&SAMSocket::HandleStreamSend, shared_from_this(), std::placeholders::_1));
+ }
+ else
+ {
+ Terminate("No Stream Remaining");
}
}
}
@@ -766,21 +725,21 @@ namespace client
WriteI2PDataImmediate(buff, len);
}
else // no more data
+ {
+ delete [] buff;
Terminate ("no more data");
+ }
}
}
}
void SAMSocket::WriteI2PDataImmediate(uint8_t * buff, size_t sz)
{
- if(m_Socket)
- boost::asio::async_write (
- *m_Socket,
- boost::asio::buffer (buff, sz),
- boost::asio::transfer_all(),
- std::bind (&SAMSocket::HandleWriteI2PDataImmediate, shared_from_this (), std::placeholders::_1, buff)); // postpone termination
- else
- LogPrint(eLogError, "SAM: no native socket");
+ boost::asio::async_write (
+ m_Socket,
+ boost::asio::buffer (buff, sz),
+ boost::asio::transfer_all(),
+ std::bind (&SAMSocket::HandleWriteI2PDataImmediate, shared_from_this (), std::placeholders::_1, buff)); // postpone termination
}
void SAMSocket::HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff)
@@ -790,9 +749,11 @@ namespace client
void SAMSocket::WriteI2PData(size_t sz)
{
- uint8_t * sendbuff = new uint8_t[sz];
- memcpy(sendbuff, m_StreamBuffer, sz);
- WriteI2PDataImmediate(sendbuff, sz);
+ boost::asio::async_write (
+ m_Socket,
+ boost::asio::buffer (m_StreamBuffer, sz),
+ boost::asio::transfer_all(),
+ std::bind(&SAMSocket::HandleWriteI2PData, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}
void SAMSocket::HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
@@ -826,7 +787,8 @@ namespace client
{
WriteI2PData(bytes_transferred);
}
- I2PReceive();
+ else
+ I2PReceive();
}
}
}
@@ -858,7 +820,7 @@ namespace client
if (session)
{
// find more pending acceptors
- for (auto it: session->ListSockets ())
+ for (auto & it: m_Owner.ListSockets (m_ID))
if (it->m_SocketType == eSAMSocketTypeAcceptor)
{
it->m_IsAccepting = true;
@@ -930,29 +892,30 @@ namespace client
}
}
- SAMSession::SAMSession (std::shared_ptr dest):
+ void SAMSocket::HandleStreamSend(const boost::system::error_code & ec)
+ {
+ m_Owner.GetService ().post (std::bind( !ec ? &SAMSocket::Receive : &SAMSocket::TerminateClose, shared_from_this()));
+ }
+
+ SAMSession::SAMSession (SAMBridge & parent, const std::string & id, std::shared_ptr dest):
+ m_Bridge(parent),
localDestination (dest),
- UDPEndpoint(nullptr)
+ UDPEndpoint(nullptr),
+ Name(id)
{
}
-
+
SAMSession::~SAMSession ()
{
- CloseStreams();
i2p::client::context.DeleteLocalDestination (localDestination);
}
void SAMSession::CloseStreams ()
{
- std::vector > socks;
+ for(const auto & itr : m_Bridge.ListSockets(Name))
{
- std::lock_guard lock(m_SocketsMutex);
- for (const auto& sock : m_Sockets) {
- socks.push_back(sock);
- }
+ itr->Terminate(nullptr);
}
- for (auto & sock : socks ) sock->Terminate("SAMSession::CloseStreams()");
- m_Sockets.clear();
}
SAMBridge::SAMBridge (const std::string& address, int port):
@@ -1009,12 +972,17 @@ namespace client
void SAMBridge::Accept ()
{
- auto native = std::make_shared(m_Service);
- auto newSocket = std::make_shared (*this, native);
- m_Acceptor.async_accept (*native, std::bind (&SAMBridge::HandleAccept, this,
+ auto newSocket = std::make_shared(*this);
+ m_Acceptor.async_accept (newSocket->GetSocket(), std::bind (&SAMBridge::HandleAccept, this,
std::placeholders::_1, newSocket));
}
+ void SAMBridge::RemoveSocket(const std::shared_ptr & socket)
+ {
+ std::unique_lock lock(m_OpenSocketsMutex);
+ m_OpenSockets.remove_if([socket](const std::shared_ptr & item) -> bool { return item == socket; });
+ }
+
void SAMBridge::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr socket)
{
if (!ecode)
@@ -1024,6 +992,10 @@ namespace client
if (!ec)
{
LogPrint (eLogDebug, "SAM: new connection from ", ep);
+ {
+ std::unique_lock l(m_OpenSocketsMutex);
+ m_OpenSockets.push_back(socket);
+ }
socket->ReceiveHandshake ();
}
else
@@ -1066,7 +1038,7 @@ namespace client
if (localDestination)
{
localDestination->Acquire ();
- auto session = std::make_shared(localDestination);
+ auto session = std::make_shared(*this, id, localDestination);
std::unique_lock l(m_SessionsMutex);
auto ret = m_Sessions.insert (std::make_pair(id, session));
if (!ret.second)
@@ -1105,6 +1077,18 @@ namespace client
return nullptr;
}
+ std::list > SAMBridge::ListSockets(const std::string & id) const
+ {
+ std::list > list;
+ {
+ std::unique_lock l(m_OpenSocketsMutex);
+ for (const auto & itr : m_OpenSockets)
+ if (itr->IsSession(id))
+ list.push_back(itr);
+ }
+ return list;
+ }
+
void SAMBridge::SendTo(const uint8_t * buf, size_t len, std::shared_ptr remote)
{
if(remote)
@@ -1127,33 +1111,38 @@ namespace client
{
m_DatagramReceiveBuffer[bytes_transferred] = 0;
char * eol = strchr ((char *)m_DatagramReceiveBuffer, '\n');
- *eol = 0; eol++;
- size_t payloadLen = bytes_transferred - ((uint8_t *)eol - m_DatagramReceiveBuffer);
- LogPrint (eLogDebug, "SAM: datagram received ", m_DatagramReceiveBuffer," size=", payloadLen);
- char * sessionID = strchr ((char *)m_DatagramReceiveBuffer, ' ');
- if (sessionID)
+ if(eol)
{
- sessionID++;
- char * destination = strchr (sessionID, ' ');
- if (destination)
+ *eol = 0; eol++;
+ size_t payloadLen = bytes_transferred - ((uint8_t *)eol - m_DatagramReceiveBuffer);
+ LogPrint (eLogDebug, "SAM: datagram received ", m_DatagramReceiveBuffer," size=", payloadLen);
+ char * sessionID = strchr ((char *)m_DatagramReceiveBuffer, ' ');
+ if (sessionID)
{
- *destination = 0; destination++;
- auto session = FindSession (sessionID);
- if (session)
+ sessionID++;
+ char * destination = strchr (sessionID, ' ');
+ if (destination)
{
- i2p::data::IdentityEx dest;
- dest.FromBase64 (destination);
- session->localDestination->GetDatagramDestination ()->
- SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ());
+ *destination = 0; destination++;
+ auto session = FindSession (sessionID);
+ if (session)
+ {
+ i2p::data::IdentityEx dest;
+ dest.FromBase64 (destination);
+ session->localDestination->GetDatagramDestination ()->
+ SendDatagramTo ((uint8_t *)eol, payloadLen, dest.GetIdentHash ());
+ }
+ else
+ LogPrint (eLogError, "SAM: Session ", sessionID, " not found");
}
else
- LogPrint (eLogError, "SAM: Session ", sessionID, " not found");
+ LogPrint (eLogError, "SAM: Missing destination key");
}
else
- LogPrint (eLogError, "SAM: Missing destination key");
+ LogPrint (eLogError, "SAM: Missing sessionID");
}
else
- LogPrint (eLogError, "SAM: Missing sessionID");
+ LogPrint(eLogError, "SAM: invalid datagram");
ReceiveDatagram ();
}
else
diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h
index 6ecd14a4..953af1cd 100644
--- a/libi2pd_client/SAM.h
+++ b/libi2pd_client/SAM.h
@@ -82,18 +82,21 @@ namespace client
public:
typedef boost::asio::ip::tcp::socket Socket_t;
- SAMSocket (SAMBridge& owner, std::shared_ptr socket);
+ SAMSocket (SAMBridge& owner);
~SAMSocket ();
- boost::asio::ip::tcp::socket& GetSocket () { return *m_Socket; };
+ Socket_t& GetSocket () { return m_Socket; };
void ReceiveHandshake ();
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
SAMSocketType GetSocketType () const { return m_SocketType; };
void Terminate (const char* reason);
+ bool IsSession(const std::string & id) const;
+
private:
-
+ void TerminateClose() { Terminate(nullptr); }
+
void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
void HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred);
@@ -128,10 +131,12 @@ namespace client
void WriteI2PDataImmediate(uint8_t * ptr, size_t sz);
void HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff);
+ void HandleStreamSend(const boost::system::error_code & ec);
+
private:
SAMBridge& m_Owner;
- std::shared_ptr m_Socket;
+ Socket_t m_Socket;
boost::asio::deadline_timer m_Timer;
char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1];
size_t m_BufferOffset;
@@ -145,34 +150,12 @@ namespace client
struct SAMSession
{
+ SAMBridge & m_Bridge;
std::shared_ptr localDestination;
- std::list > m_Sockets;
std::shared_ptr UDPEndpoint;
- std::mutex m_SocketsMutex;
+ std::string Name;
- /** safely add a socket to this session */
- void AddSocket(std::shared_ptr sock) {
- std::lock_guard lock(m_SocketsMutex);
- m_Sockets.push_back(sock);
- }
-
- /** safely remove a socket from this session */
- void DelSocket(SAMSocket * sock) {
- std::lock_guard lock(m_SocketsMutex);
- m_Sockets.remove_if([sock](const std::shared_ptr s) -> bool { return s.get() == sock; });
- }
-
- /** get a list holding a copy of all sam sockets from this session */
- std::list > ListSockets() {
- std::list > l;
- {
- std::lock_guard lock(m_SocketsMutex);
- for(const auto& sock : m_Sockets ) l.push_back(sock);
- }
- return l;
- }
-
- SAMSession (std::shared_ptr dest);
+ SAMSession (SAMBridge & parent, const std::string & name, std::shared_ptr dest);
~SAMSession ();
void CloseStreams ();
@@ -189,14 +172,18 @@ namespace client
void Stop ();
boost::asio::io_service& GetService () { return m_Service; };
- std::shared_ptr CreateSession (const std::string& id, const std::string& destination, // empty string means transient
+ std::shared_ptr CreateSession (const std::string& id, const std::string& destination, // empty string means transient
const std::map * params);
void CloseSession (const std::string& id);
std::shared_ptr FindSession (const std::string& id) const;
+ std::list > ListSockets(const std::string & id) const;
+
/** send raw data to remote endpoint from our UDP Socket */
void SendTo(const uint8_t * buf, size_t len, std::shared_ptr remote);
+ void RemoveSocket(const std::shared_ptr & socket);
+
private:
void Run ();
@@ -217,6 +204,8 @@ namespace client
boost::asio::ip::udp::socket m_DatagramSocket;
mutable std::mutex m_SessionsMutex;
std::map > m_Sessions;
+ mutable std::mutex m_OpenSocketsMutex;
+ std::list > m_OpenSockets;
uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1];
public:
diff --git a/qt/i2pd_qt/ServerTunnelPane.cpp b/qt/i2pd_qt/ServerTunnelPane.cpp
index 029a3ea2..bc6389a9 100644
--- a/qt/i2pd_qt/ServerTunnelPane.cpp
+++ b/qt/i2pd_qt/ServerTunnelPane.cpp
@@ -204,24 +204,6 @@ int ServerTunnelPane::appendServerTunnelForm(
horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2);
}
- {
- uint32_t maxConns = tunnelConfig->getmaxConns();
- QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
- horizontalLayout_2->setObjectName(QStringLiteral("horizontalLayout_2"));
- ui.maxConnsLabel = new QLabel(gridLayoutWidget_2);
- maxConnsLabel->setObjectName(QStringLiteral("maxConnsLabel"));
- horizontalLayout_2->addWidget(maxConnsLabel);
- ui.maxConnsLineEdit = new QLineEdit(gridLayoutWidget_2);
- maxConnsLineEdit->setObjectName(QStringLiteral("maxConnsLineEdit"));
- maxConnsLineEdit->setText(QString::number(maxConns));
- maxConnsLineEdit->setMaximumWidth(80);
- QObject::connect(maxConnsLineEdit, SIGNAL(textChanged(const QString &)),
- this, SLOT(updated()));
- horizontalLayout_2->addWidget(maxConnsLineEdit);
- QSpacerItem * horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- horizontalLayout_2->addItem(horizontalSpacer);
- tunnelGridLayout->addLayout(horizontalLayout_2);
- }
{
std::string address = tunnelConfig->getaddress();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();
diff --git a/qt/i2pd_qt/ServerTunnelPane.h b/qt/i2pd_qt/ServerTunnelPane.h
index 556c8473..0a07267b 100644
--- a/qt/i2pd_qt/ServerTunnelPane.h
+++ b/qt/i2pd_qt/ServerTunnelPane.h
@@ -81,10 +81,6 @@ private:
QLabel * addressLabel;
QLineEdit * addressLineEdit;
- //maxConns
- QLabel * maxConnsLabel;
- QLineEdit * maxConnsLineEdit;
-
//gzip
QCheckBox * gzipCheckBox;
@@ -109,7 +105,6 @@ private:
hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0));
webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0));
addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0));
- maxConnsLabel->setText(QApplication::translate("srvTunForm", "Max connections:", 0));
gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0));
isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0));
@@ -152,14 +147,6 @@ protected:
stc->setaddress(addressLineEdit->text().toStdString());
- auto mcStr=maxConnsLineEdit->text();
- uint32_t mcInt=(uint32_t)mcStr.toInt(&ok);
- if(!ok){
- highlightWrongInput(QApplication::tr("Bad maxConns, must be int.")+" "+cannotSaveSettings,maxConnsLineEdit);
- return false;
- }
- stc->setmaxConns(mcInt);
-
stc->setgzip(gzipCheckBox->isChecked());
stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked());
diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp
index 81216c0b..e4354b62 100644
--- a/qt/i2pd_qt/TunnelConfig.cpp
+++ b/qt/i2pd_qt/TunnelConfig.cpp
@@ -48,7 +48,6 @@ void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
<< "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n"
<< "address=" << address << "\n"
<< "hostoverride=" << hostOverride << "\n"
- << "webircpassword=" << webircpass << "\n"
- << "maxconns=" << maxConns << "\n";
+ << "webircpassword=" << webircpass << "\n";
}
diff --git a/qt/i2pd_qt/TunnelConfig.h b/qt/i2pd_qt/TunnelConfig.h
index c714a4f5..58a1fa0b 100644
--- a/qt/i2pd_qt/TunnelConfig.h
+++ b/qt/i2pd_qt/TunnelConfig.h
@@ -148,7 +148,6 @@ public:
std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
- uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
# * inport -- optional, i2p service port, if unset - the same as 'port'
@@ -170,7 +169,6 @@ class ServerTunnelConfig : public TunnelConfig {
std::string webircpass;
bool gzip;
i2p::data::SigningKeyType sigType;
- uint32_t maxConns;
std::string address;
bool isUniqueLocal;
public:
@@ -184,7 +182,6 @@ public:
std::string webircpass_,
bool gzip_,
i2p::data::SigningKeyType sigType_,
- uint32_t maxConns_,
std::string address_,
bool isUniqueLocal_): TunnelConfig(name_, type_, i2cpParameters_),
host(host_),
@@ -196,7 +193,6 @@ public:
webircpass(webircpass_),
gzip(gzip_),
sigType(sigType_),
- maxConns(maxConns_),
address(address_),
isUniqueLocal(isUniqueLocal_) {}
std::string& gethost(){return host;}
@@ -208,7 +204,6 @@ public:
std::string& getwebircpass(){return webircpass;}
bool getgzip(){return gzip;}
i2p::data::SigningKeyType getsigType(){return sigType;}
- uint32_t getmaxConns(){return maxConns;}
std::string& getaddress(){return address;}
bool getisUniqueLocal(){return isUniqueLocal;}
void sethost(const std::string& host_){host=host_;}
@@ -220,7 +215,6 @@ public:
void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;}
void setgzip(bool gzip_){gzip=gzip_;}
void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;}
- void setmaxConns(uint32_t maxConns_){maxConns=maxConns_;}
void setaddress(const std::string& address_){address=address_;}
void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;}
virtual void saveToStringStream(std::stringstream& out);
diff --git a/qt/i2pd_qt/i2pd.qrc b/qt/i2pd_qt/i2pd.qrc
index 2abdeb05..4e5523e9 100644
--- a/qt/i2pd_qt/i2pd.qrc
+++ b/qt/i2pd_qt/i2pd.qrc
@@ -1,5 +1,6 @@
-
- images/icon.png
-
+
+ resources/icons/mask.ico
+ resources/images/icon.png
+
diff --git a/qt/i2pd_qt/i2pd.rc b/qt/i2pd_qt/i2pd.rc
new file mode 100644
index 00000000..bebdf1d6
--- /dev/null
+++ b/qt/i2pd_qt/i2pd.rc
@@ -0,0 +1,32 @@
+IDI_ICON1 ICON DISCARDABLE "resources/icons/mask.ico"
+
+#include // needed for VERSIONINFO
+#include "../../libi2pd/version.h"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION I2PD_VERSION_MAJOR,I2PD_VERSION_MINOR,I2PD_VERSION_MICRO,I2PD_VERSION_PATCH
+PRODUCTVERSION I2P_VERSION_MAJOR,I2P_VERSION_MINOR,I2P_VERSION_MICRO,I2P_VERSION_PATCH
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4" // U.S. English - multilingual (hex)
+ BEGIN
+ VALUE "CompanyName", "PurpleI2P"
+ VALUE "FileDescription", "I2Pd Qt"
+ VALUE "FileVersion", I2PD_VERSION
+ VALUE "InternalName", "i2pd-qt"
+ VALUE "LegalCopyright", "Copyright (C) 2013-2018, The PurpleI2P Project"
+ VALUE "LegalTrademarks1", "Distributed under the BSD 3-Clause software license, see the accompanying file COPYING or https://opensource.org/licenses/BSD-3-Clause."
+ VALUE "OriginalFilename", "i2pd_qt.exe"
+ VALUE "ProductName", "i2pd-qt"
+ VALUE "ProductVersion", I2P_VERSION
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
+ END
+END
diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro
index 941dfff3..12d13a17 100644
--- a/qt/i2pd_qt/i2pd_qt.pro
+++ b/qt/i2pd_qt/i2pd_qt.pro
@@ -1,289 +1,310 @@
-QT += core gui
-
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
-
-TARGET = i2pd_qt
-TEMPLATE = app
-QMAKE_CXXFLAGS *= -std=c++11
-DEFINES += USE_UPNP
-
-# change to your own path, where you will store all needed libraries with 'git clone' commands below.
-MAIN_PATH = /path/to/libraries
-
-# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
-# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
-# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
-# git clone https://github.com/PurpleI2P/android-ifaddrs.git
-BOOST_PATH = $$MAIN_PATH/Boost-for-Android-Prebuilt
-OPENSSL_PATH = $$MAIN_PATH/OpenSSL-for-Android-Prebuilt
-MINIUPNP_PATH = $$MAIN_PATH/MiniUPnP-for-Android-Prebuilt
-IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs
-
-# Steps in Android SDK manager:
-# 1) Check Extras/Google Support Library https://developer.android.com/topic/libraries/support-library/setup.html
-# 2) Check API 11
-# Finally, click Install.
-
-SOURCES += DaemonQT.cpp mainwindow.cpp \
- ../../libi2pd/api.cpp \
- ../../libi2pd/Base.cpp \
- ../../libi2pd/BloomFilter.cpp \
- ../../libi2pd/Config.cpp \
- ../../libi2pd/CPU.cpp \
- ../../libi2pd/Crypto.cpp \
- ../../libi2pd/CryptoKey.cpp \
- ../../libi2pd/Datagram.cpp \
- ../../libi2pd/Destination.cpp \
- ../../libi2pd/Event.cpp \
- ../../libi2pd/Family.cpp \
- ../../libi2pd/FS.cpp \
- ../../libi2pd/Garlic.cpp \
- ../../libi2pd/Gost.cpp \
- ../../libi2pd/Gzip.cpp \
- ../../libi2pd/HTTP.cpp \
- ../../libi2pd/I2NPProtocol.cpp \
- ../../libi2pd/I2PEndian.cpp \
- ../../libi2pd/Identity.cpp \
- ../../libi2pd/LeaseSet.cpp \
- ../../libi2pd/Log.cpp \
- ../../libi2pd/NetDb.cpp \
- ../../libi2pd/NetDbRequests.cpp \
- ../../libi2pd/NTCPSession.cpp \
- ../../libi2pd/Profiling.cpp \
- ../../libi2pd/Reseed.cpp \
- ../../libi2pd/RouterContext.cpp \
- ../../libi2pd/RouterInfo.cpp \
- ../../libi2pd/Signature.cpp \
- ../../libi2pd/SSU.cpp \
- ../../libi2pd/SSUData.cpp \
- ../../libi2pd/SSUSession.cpp \
- ../../libi2pd/Streaming.cpp \
- ../../libi2pd/Timestamp.cpp \
- ../../libi2pd/TransitTunnel.cpp \
- ../../libi2pd/Transports.cpp \
- ../../libi2pd/Tunnel.cpp \
- ../../libi2pd/TunnelEndpoint.cpp \
- ../../libi2pd/TunnelGateway.cpp \
- ../../libi2pd/TunnelPool.cpp \
- ../../libi2pd/util.cpp \
- ../../libi2pd_client/AddressBook.cpp \
- ../../libi2pd_client/BOB.cpp \
- ../../libi2pd_client/ClientContext.cpp \
- ../../libi2pd_client/HTTPProxy.cpp \
- ../../libi2pd_client/I2CP.cpp \
- ../../libi2pd_client/I2PService.cpp \
- ../../libi2pd_client/I2PTunnel.cpp \
- ../../libi2pd_client/MatchedDestination.cpp \
- ../../libi2pd_client/SAM.cpp \
- ../../libi2pd_client/SOCKS.cpp \
- ../../libi2pd_client/Websocket.cpp \
- ../../libi2pd_client/WebSocks.cpp \
- ClientTunnelPane.cpp \
- MainWindowItems.cpp \
- ServerTunnelPane.cpp \
- SignatureTypeComboboxFactory.cpp \
- TunnelConfig.cpp \
- TunnelPane.cpp \
- ../../daemon/Daemon.cpp \
- ../../daemon/HTTPServer.cpp \
- ../../daemon/i2pd.cpp \
- ../../daemon/I2PControl.cpp \
- ../../daemon/UnixDaemon.cpp \
- ../../daemon/UPnP.cpp \
- textbrowsertweaked1.cpp \
- pagewithbackbutton.cpp \
- widgetlock.cpp \
- widgetlockregistry.cpp
-
-#qt creator does not handle this well
-#SOURCES += $$files(../../libi2pd/*.cpp)
-#SOURCES += $$files(../../libi2pd_client/*.cpp)
-#SOURCES += $$files(../../daemon/*.cpp)
-#SOURCES += $$files(./*.cpp)
-
-SOURCES -= ../../daemon/UnixDaemon.cpp
-
-HEADERS += DaemonQT.h mainwindow.h \
- ../../libi2pd/api.h \
- ../../libi2pd/Base.h \
- ../../libi2pd/BloomFilter.h \
- ../../libi2pd/Config.h \
- ../../libi2pd/Crypto.h \
- ../../libi2pd/CryptoKey.h \
- ../../libi2pd/Datagram.h \
- ../../libi2pd/Destination.h \
- ../../libi2pd/Event.h \
- ../../libi2pd/Family.h \
- ../../libi2pd/FS.h \
- ../../libi2pd/Garlic.h \
- ../../libi2pd/Gost.h \
- ../../libi2pd/Gzip.h \
- ../../libi2pd/HTTP.h \
- ../../libi2pd/I2NPProtocol.h \
- ../../libi2pd/I2PEndian.h \
- ../../libi2pd/Identity.h \
- ../../libi2pd/LeaseSet.h \
- ../../libi2pd/LittleBigEndian.h \
- ../../libi2pd/Log.h \
- ../../libi2pd/NetDb.hpp \
- ../../libi2pd/NetDbRequests.h \
- ../../libi2pd/NTCPSession.h \
- ../../libi2pd/Profiling.h \
- ../../libi2pd/Queue.h \
- ../../libi2pd/Reseed.h \
- ../../libi2pd/RouterContext.h \
- ../../libi2pd/RouterInfo.h \
- ../../libi2pd/Signature.h \
- ../../libi2pd/SSU.h \
- ../../libi2pd/SSUData.h \
- ../../libi2pd/SSUSession.h \
- ../../libi2pd/Streaming.h \
- ../../libi2pd/Tag.h \
- ../../libi2pd/Timestamp.h \
- ../../libi2pd/TransitTunnel.h \
- ../../libi2pd/Transports.h \
- ../../libi2pd/TransportSession.h \
- ../../libi2pd/Tunnel.h \
- ../../libi2pd/TunnelBase.h \
- ../../libi2pd/TunnelConfig.h \
- ../../libi2pd/TunnelEndpoint.h \
- ../../libi2pd/TunnelGateway.h \
- ../../libi2pd/TunnelPool.h \
- ../../libi2pd/util.h \
- ../../libi2pd/version.h \
- ../../libi2pd_client/AddressBook.h \
- ../../libi2pd_client/BOB.h \
- ../../libi2pd_client/ClientContext.h \
- ../../libi2pd_client/HTTPProxy.h \
- ../../libi2pd_client/I2CP.h \
- ../../libi2pd_client/I2PService.h \
- ../../libi2pd_client/I2PTunnel.h \
- ../../libi2pd_client/MatchedDestination.h \
- ../../libi2pd_client/SAM.h \
- ../../libi2pd_client/SOCKS.h \
- ../../libi2pd_client/Websocket.h \
- ../../libi2pd_client/WebSocks.h \
- ClientTunnelPane.h \
- MainWindowItems.h \
- ServerTunnelPane.h \
- SignatureTypeComboboxFactory.h \
- TunnelConfig.h \
- TunnelPane.h \
- TunnelsPageUpdateListener.h \
- ../../daemon/Daemon.h \
- ../../daemon/HTTPServer.h \
- ../../daemon/I2PControl.h \
- ../../daemon/UPnP.h \
- textbrowsertweaked1.h \
- pagewithbackbutton.h \
- widgetlock.h \
- widgetlockregistry.h
-
-INCLUDEPATH += ../../libi2pd
-INCLUDEPATH += ../../libi2pd_client
-INCLUDEPATH += ../../daemon
-INCLUDEPATH += .
-
-FORMS += mainwindow.ui \
- tunnelform.ui \
- statusbuttons.ui \
- routercommandswidget.ui \
- generalsettingswidget.ui
-
-LIBS += -lz
-
-macx {
- message("using mac os x target")
- BREWROOT=/usr/local
- BOOSTROOT=$$BREWROOT/opt/boost
- SSLROOT=$$BREWROOT/opt/libressl
- UPNPROOT=$$BREWROOT/opt/miniupnpc
- INCLUDEPATH += $$BOOSTROOT/include
- INCLUDEPATH += $$SSLROOT/include
- INCLUDEPATH += $$UPNPROOT/include
- LIBS += $$SSLROOT/lib/libcrypto.a
- LIBS += $$SSLROOT/lib/libssl.a
- LIBS += $$BOOSTROOT/lib/libboost_system.a
- LIBS += $$BOOSTROOT/lib/libboost_date_time.a
- LIBS += $$BOOSTROOT/lib/libboost_filesystem.a
- LIBS += $$BOOSTROOT/lib/libboost_program_options.a
- LIBS += $$UPNPROOT/lib/libminiupnpc.a
-}
-
-android {
- message("Using Android settings")
- DEFINES += ANDROID=1
- DEFINES += __ANDROID__
-
- CONFIG += mobility
-
- MOBILITY =
-
- INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \
- $$OPENSSL_PATH/openssl-1.0.2/include \
- $$MINIUPNP_PATH/miniupnp-2.0/include \
- $$IFADDRS_PATH
- DISTFILES += android/AndroidManifest.xml
-
- ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
-
- SOURCES += $$IFADDRS_PATH/ifaddrs.c
- HEADERS += $$IFADDRS_PATH/ifaddrs.h
-
- equals(ANDROID_TARGET_ARCH, armeabi-v7a){
- DEFINES += ANDROID_ARM7A
- # http://stackoverflow.com/a/30235934/529442
- LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \
- -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \
- -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \
- -L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \
- -L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc
-
- PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \
- $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a
- DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include
-
- ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \
- $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \
- $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so
- }
-
- equals(ANDROID_TARGET_ARCH, x86){
- # http://stackoverflow.com/a/30235934/529442
- LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \
- -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \
- -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \
- -L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \
- -L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc
-
- PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \
- $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a
-
- DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include
-
- ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \
- $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \
- $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so
- }
-}
-
-linux:!android {
- message("Using Linux settings")
- LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
-}
-
-windows:!android {
- message("Using Windows settings")
- DEFINES += BOOST_USE_WINDOWS_H WINDOWS
- LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
-}
-
-!android:!symbian:!maemo5:!simulator {
- message("Build with a system tray icon")
- # see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince*
- #sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images
- RESOURCES = i2pd.qrc
- QT += xml
- #INSTALLS += sources
-}
-
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = i2pd_qt
+TEMPLATE = app
+QMAKE_CXXFLAGS *= -std=c++11
+DEFINES += USE_UPNP
+
+# change to your own path, where you will store all needed libraries with 'git clone' commands below.
+MAIN_PATH = /path/to/libraries
+
+# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
+# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git
+# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git
+# git clone https://github.com/PurpleI2P/android-ifaddrs.git
+BOOST_PATH = $$MAIN_PATH/Boost-for-Android-Prebuilt
+OPENSSL_PATH = $$MAIN_PATH/OpenSSL-for-Android-Prebuilt
+MINIUPNP_PATH = $$MAIN_PATH/MiniUPnP-for-Android-Prebuilt
+IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs
+
+# Steps in Android SDK manager:
+# 1) Check Extras/Google Support Library https://developer.android.com/topic/libraries/support-library/setup.html
+# 2) Check API 11
+# Finally, click Install.
+
+SOURCES += DaemonQT.cpp mainwindow.cpp \
+ ../../libi2pd/api.cpp \
+ ../../libi2pd/Base.cpp \
+ ../../libi2pd/BloomFilter.cpp \
+ ../../libi2pd/Config.cpp \
+ ../../libi2pd/CPU.cpp \
+ ../../libi2pd/Crypto.cpp \
+ ../../libi2pd/CryptoKey.cpp \
+ ../../libi2pd/Datagram.cpp \
+ ../../libi2pd/Destination.cpp \
+ ../../libi2pd/Event.cpp \
+ ../../libi2pd/Family.cpp \
+ ../../libi2pd/FS.cpp \
+ ../../libi2pd/Garlic.cpp \
+ ../../libi2pd/Gost.cpp \
+ ../../libi2pd/Gzip.cpp \
+ ../../libi2pd/HTTP.cpp \
+ ../../libi2pd/I2NPProtocol.cpp \
+ ../../libi2pd/I2PEndian.cpp \
+ ../../libi2pd/Identity.cpp \
+ ../../libi2pd/LeaseSet.cpp \
+ ../../libi2pd/Log.cpp \
+ ../../libi2pd/NetDb.cpp \
+ ../../libi2pd/NetDbRequests.cpp \
+ ../../libi2pd/NTCPSession.cpp \
+ ../../libi2pd/Profiling.cpp \
+ ../../libi2pd/Reseed.cpp \
+ ../../libi2pd/RouterContext.cpp \
+ ../../libi2pd/RouterInfo.cpp \
+ ../../libi2pd/Signature.cpp \
+ ../../libi2pd/SSU.cpp \
+ ../../libi2pd/SSUData.cpp \
+ ../../libi2pd/SSUSession.cpp \
+ ../../libi2pd/Streaming.cpp \
+ ../../libi2pd/Timestamp.cpp \
+ ../../libi2pd/TransitTunnel.cpp \
+ ../../libi2pd/Transports.cpp \
+ ../../libi2pd/Tunnel.cpp \
+ ../../libi2pd/TunnelEndpoint.cpp \
+ ../../libi2pd/TunnelGateway.cpp \
+ ../../libi2pd/TunnelPool.cpp \
+ ../../libi2pd/util.cpp \
+ ../../libi2pd_client/AddressBook.cpp \
+ ../../libi2pd_client/BOB.cpp \
+ ../../libi2pd_client/ClientContext.cpp \
+ ../../libi2pd_client/HTTPProxy.cpp \
+ ../../libi2pd_client/I2CP.cpp \
+ ../../libi2pd_client/I2PService.cpp \
+ ../../libi2pd_client/I2PTunnel.cpp \
+ ../../libi2pd_client/MatchedDestination.cpp \
+ ../../libi2pd_client/SAM.cpp \
+ ../../libi2pd_client/SOCKS.cpp \
+ ../../libi2pd_client/Websocket.cpp \
+ ../../libi2pd_client/WebSocks.cpp \
+ ClientTunnelPane.cpp \
+ MainWindowItems.cpp \
+ ServerTunnelPane.cpp \
+ SignatureTypeComboboxFactory.cpp \
+ TunnelConfig.cpp \
+ TunnelPane.cpp \
+ ../../daemon/Daemon.cpp \
+ ../../daemon/HTTPServer.cpp \
+ ../../daemon/i2pd.cpp \
+ ../../daemon/I2PControl.cpp \
+ ../../daemon/UnixDaemon.cpp \
+ ../../daemon/UPnP.cpp \
+ textbrowsertweaked1.cpp \
+ pagewithbackbutton.cpp \
+ widgetlock.cpp \
+ widgetlockregistry.cpp
+
+#qt creator does not handle this well
+#SOURCES += $$files(../../libi2pd/*.cpp)
+#SOURCES += $$files(../../libi2pd_client/*.cpp)
+#SOURCES += $$files(../../daemon/*.cpp)
+#SOURCES += $$files(./*.cpp)
+
+SOURCES -= ../../daemon/UnixDaemon.cpp
+
+HEADERS += DaemonQT.h mainwindow.h \
+ ../../libi2pd/api.h \
+ ../../libi2pd/Base.h \
+ ../../libi2pd/BloomFilter.h \
+ ../../libi2pd/Config.h \
+ ../../libi2pd/Crypto.h \
+ ../../libi2pd/CryptoKey.h \
+ ../../libi2pd/Datagram.h \
+ ../../libi2pd/Destination.h \
+ ../../libi2pd/Event.h \
+ ../../libi2pd/Family.h \
+ ../../libi2pd/FS.h \
+ ../../libi2pd/Garlic.h \
+ ../../libi2pd/Gost.h \
+ ../../libi2pd/Gzip.h \
+ ../../libi2pd/HTTP.h \
+ ../../libi2pd/I2NPProtocol.h \
+ ../../libi2pd/I2PEndian.h \
+ ../../libi2pd/Identity.h \
+ ../../libi2pd/LeaseSet.h \
+ ../../libi2pd/LittleBigEndian.h \
+ ../../libi2pd/Log.h \
+ ../../libi2pd/NetDb.hpp \
+ ../../libi2pd/NetDbRequests.h \
+ ../../libi2pd/NTCPSession.h \
+ ../../libi2pd/Profiling.h \
+ ../../libi2pd/Queue.h \
+ ../../libi2pd/Reseed.h \
+ ../../libi2pd/RouterContext.h \
+ ../../libi2pd/RouterInfo.h \
+ ../../libi2pd/Signature.h \
+ ../../libi2pd/SSU.h \
+ ../../libi2pd/SSUData.h \
+ ../../libi2pd/SSUSession.h \
+ ../../libi2pd/Streaming.h \
+ ../../libi2pd/Tag.h \
+ ../../libi2pd/Timestamp.h \
+ ../../libi2pd/TransitTunnel.h \
+ ../../libi2pd/Transports.h \
+ ../../libi2pd/TransportSession.h \
+ ../../libi2pd/Tunnel.h \
+ ../../libi2pd/TunnelBase.h \
+ ../../libi2pd/TunnelConfig.h \
+ ../../libi2pd/TunnelEndpoint.h \
+ ../../libi2pd/TunnelGateway.h \
+ ../../libi2pd/TunnelPool.h \
+ ../../libi2pd/util.h \
+ ../../libi2pd/version.h \
+ ../../libi2pd_client/AddressBook.h \
+ ../../libi2pd_client/BOB.h \
+ ../../libi2pd_client/ClientContext.h \
+ ../../libi2pd_client/HTTPProxy.h \
+ ../../libi2pd_client/I2CP.h \
+ ../../libi2pd_client/I2PService.h \
+ ../../libi2pd_client/I2PTunnel.h \
+ ../../libi2pd_client/MatchedDestination.h \
+ ../../libi2pd_client/SAM.h \
+ ../../libi2pd_client/SOCKS.h \
+ ../../libi2pd_client/Websocket.h \
+ ../../libi2pd_client/WebSocks.h \
+ ClientTunnelPane.h \
+ MainWindowItems.h \
+ ServerTunnelPane.h \
+ SignatureTypeComboboxFactory.h \
+ TunnelConfig.h \
+ TunnelPane.h \
+ TunnelsPageUpdateListener.h \
+ ../../daemon/Daemon.h \
+ ../../daemon/HTTPServer.h \
+ ../../daemon/I2PControl.h \
+ ../../daemon/UPnP.h \
+ textbrowsertweaked1.h \
+ pagewithbackbutton.h \
+ widgetlock.h \
+ widgetlockregistry.h \
+ i2pd.rc \
+ i2pd.rc
+
+INCLUDEPATH += ../../libi2pd
+INCLUDEPATH += ../../libi2pd_client
+INCLUDEPATH += ../../daemon
+INCLUDEPATH += .
+
+FORMS += mainwindow.ui \
+ tunnelform.ui \
+ statusbuttons.ui \
+ routercommandswidget.ui \
+ generalsettingswidget.ui
+
+LIBS += -lz
+
+macx {
+ message("using mac os x target")
+ BREWROOT=/usr/local
+ BOOSTROOT=$$BREWROOT/opt/boost
+ SSLROOT=$$BREWROOT/opt/libressl
+ UPNPROOT=$$BREWROOT/opt/miniupnpc
+ INCLUDEPATH += $$BOOSTROOT/include
+ INCLUDEPATH += $$SSLROOT/include
+ INCLUDEPATH += $$UPNPROOT/include
+ LIBS += $$SSLROOT/lib/libcrypto.a
+ LIBS += $$SSLROOT/lib/libssl.a
+ LIBS += $$BOOSTROOT/lib/libboost_system.a
+ LIBS += $$BOOSTROOT/lib/libboost_date_time.a
+ LIBS += $$BOOSTROOT/lib/libboost_filesystem.a
+ LIBS += $$BOOSTROOT/lib/libboost_program_options.a
+ LIBS += $$UPNPROOT/lib/libminiupnpc.a
+}
+
+android {
+ message("Using Android settings")
+ DEFINES += ANDROID=1
+ DEFINES += __ANDROID__
+
+ CONFIG += mobility
+
+ MOBILITY =
+
+ INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \
+ $$OPENSSL_PATH/openssl-1.0.2/include \
+ $$MINIUPNP_PATH/miniupnp-2.0/include \
+ $$IFADDRS_PATH
+ DISTFILES += android/AndroidManifest.xml
+
+ ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
+
+ SOURCES += $$IFADDRS_PATH/ifaddrs.c
+ HEADERS += $$IFADDRS_PATH/ifaddrs.h
+
+ equals(ANDROID_TARGET_ARCH, armeabi-v7a){
+ DEFINES += ANDROID_ARM7A
+ # http://stackoverflow.com/a/30235934/529442
+ LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \
+ -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \
+ -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \
+ -L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \
+ -L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc
+
+ PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \
+ $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a
+ DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include
+
+ ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \
+ $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \
+ $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so
+ }
+
+ equals(ANDROID_TARGET_ARCH, x86){
+ # http://stackoverflow.com/a/30235934/529442
+ LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \
+ -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \
+ -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \
+ -L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \
+ -L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc
+
+ PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \
+ $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a
+
+ DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include
+
+ ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \
+ $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \
+ $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so
+ }
+}
+
+linux:!android {
+ message("Using Linux settings")
+ LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
+}
+
+windows {
+ message("Using Windows settings")
+ RC_FILE = i2pd.rc
+ DEFINES += BOOST_USE_WINDOWS_H WINDOWS _WINDOWS WIN32_LEAN_AND_MEAN MINIUPNP_STATICLIB
+ DEFINES -= UNICODE _UNICODE
+ BOOST_SUFFIX = -mt
+ QMAKE_CXXFLAGS = -Os
+ QMAKE_LFLAGS = -s -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows
+
+ LIBS = -lminiupnpc \
+ -lboost_system$$BOOST_SUFFIX \
+ -lboost_date_time$$BOOST_SUFFIX \
+ -lboost_filesystem$$BOOST_SUFFIX \
+ -lboost_program_options$$BOOST_SUFFIX \
+ -lssl \
+ -lcrypto \
+ -lz \
+ -lwsock32 \
+ -lws2_32 \
+ -lgdi32 \
+ -liphlpapi \
+ -lstdc++ \
+ -lpthread
+}
+
+!android:!symbian:!maemo5:!simulator {
+ message("Build with a system tray icon")
+ # see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince*
+ #sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images
+ RESOURCES = i2pd.qrc
+ QT += xml
+ #INSTALLS += sources
+}
+
diff --git a/qt/i2pd_qt/mainwindow.cpp b/qt/i2pd_qt/mainwindow.cpp
index fc1e5985..a095f78c 100644
--- a/qt/i2pd_qt/mainwindow.cpp
+++ b/qt/i2pd_qt/mainwindow.cpp
@@ -349,7 +349,9 @@ QString MainWindow::getStatusPageHtml(bool showHiddenInfo) {
s << "";
switch (statusPage) {
- case main_page: i2p::http::ShowStatus(s, showHiddenInfo);break;
+ case main_page:
+ i2p::http::ShowStatus(s, showHiddenInfo, i2p::http::OutputFormatEnum::forQtUi);
+ break;
case commands: break;
case local_destinations: i2p::http::ShowLocalDestinations(s);break;
case leasesets: i2p::http::ShowLeasesSets(s); break;
@@ -449,7 +451,7 @@ void MainWindow::createTrayIcon() {
}
void MainWindow::setIcon() {
- QIcon icon(":/images/icon.png");
+ QIcon icon(":icons/mask");
trayIcon->setIcon(icon);
setWindowIcon(icon);
diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h
index cac97a1f..c5f0c902 100644
--- a/qt/i2pd_qt/mainwindow.h
+++ b/qt/i2pd_qt/mainwindow.h
@@ -628,7 +628,6 @@ private:
std::string webircpass = "";
bool gzip = true;
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256;
- uint32_t maxConns = i2p::stream::DEFAULT_MAX_CONNS_PER_MIN;
std::string address = "127.0.0.1";
bool isUniqueLocal = true;
@@ -646,7 +645,6 @@ private:
webircpass,
gzip,
sigType,
- maxConns,
address,
isUniqueLocal);
@@ -734,7 +732,6 @@ private:
std::string webircpass = section.second.get (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true);
i2p::data::SigningKeyType sigType = section.second.get (I2P_SERVER_TUNNEL_SIGNATURE_TYPE, i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256);
- uint32_t maxConns = section.second.get(i2p::stream::I2CP_PARAM_STREAMING_MAX_CONNS_PER_MIN, i2p::stream::DEFAULT_MAX_CONNS_PER_MIN);
std::string address = section.second.get (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
@@ -769,7 +766,6 @@ private:
webircpass,
gzip,
sigType,
- maxConns,
address,
isUniqueLocal);
}
diff --git a/qt/i2pd_qt/resources/icons/mask.ico b/qt/i2pd_qt/resources/icons/mask.ico
new file mode 100644
index 00000000..f5807de5
Binary files /dev/null and b/qt/i2pd_qt/resources/icons/mask.ico differ
diff --git a/qt/i2pd_qt/images/icon.png b/qt/i2pd_qt/resources/images/icon.png
similarity index 100%
rename from qt/i2pd_qt/images/icon.png
rename to qt/i2pd_qt/resources/images/icon.png