Browse Source

Merge pull request #2 from PurpleI2P/openssl

sync with main repo
pull/1170/head
Al 7 years ago committed by GitHub
parent
commit
be7a84fdf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      Makefile.linux
  2. 13
      daemon/Daemon.h
  3. 19
      daemon/HTTPServer.cpp
  4. 3
      daemon/HTTPServer.h
  5. 2
      daemon/I2PControl.cpp
  6. 7
      libi2pd/Crypto.cpp
  7. 3
      libi2pd/Crypto.h
  8. 2
      libi2pd/HTTP.cpp
  9. 4
      libi2pd/Streaming.cpp
  10. 3
      libi2pd/Streaming.h
  11. 52
      libi2pd_client/ClientContext.cpp
  12. 8
      libi2pd_client/ClientContext.h
  13. 169
      libi2pd_client/SAM.cpp
  14. 45
      libi2pd_client/SAM.h
  15. 18
      qt/i2pd_qt/ServerTunnelPane.cpp
  16. 13
      qt/i2pd_qt/ServerTunnelPane.h
  17. 3
      qt/i2pd_qt/TunnelConfig.cpp
  18. 6
      qt/i2pd_qt/TunnelConfig.h
  19. 7
      qt/i2pd_qt/i2pd.qrc
  20. 32
      qt/i2pd_qt/i2pd.rc
  21. 29
      qt/i2pd_qt/i2pd_qt.pro
  22. 6
      qt/i2pd_qt/mainwindow.cpp
  23. 4
      qt/i2pd_qt/mainwindow.h
  24. BIN
      qt/i2pd_qt/resources/icons/mask.ico
  25. 0
      qt/i2pd_qt/resources/images/icon.png

5
Makefile.linux

@ -60,7 +60,12 @@ endif
ifeq ($(USE_AESNI),yes) ifeq ($(USE_AESNI),yes)
#check if AES-NI is supported by CPU #check if AES-NI is supported by CPU
ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0) ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0)
machine := $(shell uname -m)
ifeq ($(machine), aarch64)
CXXFLAGS += -DARM64AES
else
CPU_FLAGS += -maes -DAESNI CPU_FLAGS += -maes -DAESNI
endif
endif endif
endif endif

13
daemon/Daemon.h

@ -64,7 +64,18 @@ namespace util
DaemonWin32 ():isGraceful(false) {} 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 #else
#define Daemon i2p::util::DaemonLinux::Instance() #define Daemon i2p::util::DaemonLinux::Instance()
class DaemonLinux : public Daemon_Singleton class DaemonLinux : public Daemon_Singleton

19
daemon/HTTPServer.cpp

@ -198,7 +198,10 @@ namespace http {
s << "<b>ERROR:</b>&nbsp;" << string << "<br>\r\n"; s << "<b>ERROR:</b>&nbsp;" << string << "<br>\r\n";
} }
void ShowStatus (std::stringstream& s, bool includeHiddenContent) void ShowStatus (
std::stringstream& s,
bool includeHiddenContent,
i2p::http::OutputFormatEnum outputFormat)
{ {
s << "<b>Uptime:</b> "; s << "<b>Uptime:</b> ";
ShowUptime(s, i2p::context.GetUptime ()); ShowUptime(s, i2p::context.GetUptime ());
@ -245,7 +248,10 @@ namespace http {
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n"; s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n";
s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n"; s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n";
s << "<div class='slide'><label for='slide-info'>Hidden content. Press on text to see.</label>\r\n<input type='checkbox' id='slide-info'/>\r\n<p class='content'>\r\n"; s << "<div class='slide'>";
if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
s << "<label for='slide-info'>Hidden content. Press on text to see.</label>\r\n<input type='checkbox' id='slide-info'/>\r\n<p class='content'>\r\n";
}
if(includeHiddenContent) { if(includeHiddenContent) {
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n"; s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
s << "<b>Router Family:</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n"; s << "<b>Router Family:</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n";
@ -274,6 +280,9 @@ namespace http {
} }
} }
s << "</p>\r\n</div>\r\n"; s << "</p>\r\n</div>\r\n";
if(outputFormat==OutputFormatEnum::forQtUi) {
s << "<br>";
}
s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " "; s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " "; s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n"; s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n";
@ -285,6 +294,7 @@ namespace http {
s << "<b>Client Tunnels:</b> " << std::to_string(clientTunnelCount) << " "; s << "<b>Client Tunnels:</b> " << std::to_string(clientTunnelCount) << " ";
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n<br>\r\n"; s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n<br>\r\n";
if(outputFormat==OutputFormatEnum::forWebConsole) {
s << "<table><caption>Services</caption><tr><th>Service</th><th>State</th></tr>\r\n"; s << "<table><caption>Services</caption><tr><th>Service</th><th>State</th></tr>\r\n";
s << "<tr><td>" << "HTTP Proxy" << "</td><td><div class='" << ((i2p::client::context.GetHttpProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n"; s << "<tr><td>" << "HTTP Proxy" << "</td><td><div class='" << ((i2p::client::context.GetHttpProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
s << "<tr><td>" << "SOCKS Proxy" << "</td><td><div class='" << ((i2p::client::context.GetSocksProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n"; s << "<tr><td>" << "SOCKS Proxy" << "</td><td><div class='" << ((i2p::client::context.GetSocksProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
@ -295,6 +305,7 @@ namespace http {
s << "<tr><td>" << "I2PControl" << "</td><td><div class='" << ((i2pcontrol) ? "enabled" : "disabled") << "'></div></td></tr>\r\n"; s << "<tr><td>" << "I2PControl" << "</td><td><div class='" << ((i2pcontrol) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
s << "</table>\r\n"; s << "</table>\r\n";
} }
}
void ShowLocalDestinations (std::stringstream& s) void ShowLocalDestinations (std::stringstream& s)
{ {
@ -649,7 +660,7 @@ namespace http {
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n"; s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
s << "<br>\r\n"; s << "<br>\r\n";
s << "<b>Streams:</b><br>\r\n"; s << "<b>Streams:</b><br>\r\n";
for (const auto& it: session->ListSockets()) for (const auto& it: sam->ListSockets(id))
{ {
switch (it->GetSocketType ()) switch (it->GetSocketType ())
{ {
@ -863,7 +874,7 @@ namespace http {
} else if (req.uri.find("cmd=") != std::string::npos) { } else if (req.uri.find("cmd=") != std::string::npos) {
HandleCommand (req, res, s); HandleCommand (req, res, s);
} else { } else {
ShowStatus (s, true); ShowStatus (s, true, i2p::http::OutputFormatEnum::forWebConsole);
res.add_header("Refresh", "10"); res.add_header("Refresh", "10");
} }
ShowPageTail (s); ShowPageTail (s);

3
daemon/HTTPServer.h

@ -80,7 +80,8 @@ namespace http
}; };
//all the below functions are also used by Qt GUI, see mainwindow.cpp -> getStatusPageHtml //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 ShowLocalDestinations (std::stringstream& s);
void ShowLeasesSets(std::stringstream& s); void ShowLeasesSets(std::stringstream& s);
void ShowTunnels (std::stringstream& s); void ShowTunnels (std::stringstream& s);

2
daemon/I2PControl.cpp

@ -727,7 +727,7 @@ namespace client
sam_session.put("name", name); sam_session.put("name", name);
sam_session.put("address", i2p::client::context.GetAddressBook ().ToAddress(ident)); 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; boost::property_tree::ptree stream;
stream.put("type", socket->GetSocketType ()); stream.put("type", socket->GetSocketType ());

7
libi2pd/Crypto.cpp

@ -594,6 +594,13 @@ namespace crypto
// AES // AES
#ifdef AESNI #ifdef AESNI
#ifdef ARM64AES
void init_aesenc(void){
// TODO: Implementation
}
#endif
#define KeyExpansion256(round0,round1) \ #define KeyExpansion256(round0,round1) \
"pshufd $0xff, %%xmm2, %%xmm2 \n" \ "pshufd $0xff, %%xmm2, %%xmm2 \n" \
"movaps %%xmm1, %%xmm4 \n" \ "movaps %%xmm1, %%xmm4 \n" \

3
libi2pd/Crypto.h

@ -124,6 +124,9 @@ namespace crypto
#ifdef AESNI #ifdef AESNI
#ifdef ARM64AES
void init_aesenc(void) __attribute__((constructor));
#endif
class ECBCryptoAESNI class ECBCryptoAESNI
{ {
public: public:

2
libi2pd/HTTP.cpp

@ -96,7 +96,7 @@ namespace http {
pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */ 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)) { if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) {
std::size_t delim = url.find(':', pos_p); 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); user = url.substr(pos_p, delim - pos_p);
delim += 1; delim += 1;
pass = url.substr(delim, pos_c - delim); pass = url.substr(delim, pos_c - delim);

4
libi2pd/Streaming.cpp

@ -578,9 +578,7 @@ namespace stream
if (m_SentPackets.empty () && m_SendBuffer.IsEmpty ()) // nothing to send if (m_SentPackets.empty () && m_SendBuffer.IsEmpty ()) // nothing to send
{ {
m_Status = eStreamStatusClosed; m_Status = eStreamStatusClosed;
// close could be called from another thread so do SendClose from the destination thread SendClose();
// this is so m_LocalDestination.NewPacket () does not trigger a race condition
m_Service.post(std::bind(&Stream::SendClose, shared_from_this()));
} }
break; break;
case eStreamStatusClosed: case eStreamStatusClosed:

3
libi2pd/Streaming.h

@ -165,6 +165,9 @@ namespace stream
void AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout = 0); void AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout = 0);
size_t ReadSome (uint8_t * buf, size_t len) { return ConcatenatePackets (buf, len); }; 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 Close ();
void Cancel () { m_ReceiveTimer.cancel (); }; void Cancel () { m_ReceiveTimer.cancel (); };

52
libi2pd_client/ClientContext.cpp

@ -488,8 +488,8 @@ namespace client
{ {
localDestination = m_SharedLocalDestination; localDestination = m_SharedLocalDestination;
} }
auto clientTunnel = new I2PUDPClientTunnel(name, dest, end, localDestination, destinationPort); auto clientTunnel = std::make_shared<I2PUDPClientTunnel>(name, dest, end, localDestination, destinationPort);
if(m_ClientForwards.insert(std::make_pair(end, std::unique_ptr<I2PUDPClientTunnel>(clientTunnel))).second) if(m_ClientForwards.insert(std::make_pair(end, clientTunnel)).second)
{ {
clientTunnel->Start(); clientTunnel->Start();
} }
@ -498,31 +498,35 @@ namespace client
} else { } else {
boost::asio::ip::tcp::endpoint clientEndpoint; boost::asio::ip::tcp::endpoint clientEndpoint;
I2PService * clientTunnel = nullptr; std::shared_ptr<I2PService> clientTunnel;
if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS) if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS)
{ {
// socks proxy // socks proxy
clientTunnel = new i2p::proxy::SOCKSProxy(name, address, port, false, "", destinationPort, localDestination); auto tun = std::make_shared<i2p::proxy::SOCKSProxy>(name, address, port, false, "", destinationPort, localDestination);
clientEndpoint = ((i2p::proxy::SOCKSProxy*)clientTunnel)->GetLocalEndpoint (); clientTunnel = tun;
clientEndpoint = tun->GetLocalEndpoint ();
} }
else if (type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY) else if (type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)
{ {
// http proxy // http proxy
std::string outproxy = section.second.get("outproxy", ""); std::string outproxy = section.second.get("outproxy", "");
clientTunnel = new i2p::proxy::HTTPProxy(name, address, port, outproxy, localDestination); auto tun = std::make_shared<i2p::proxy::HTTPProxy>(name, address, port, outproxy, localDestination);
clientEndpoint = ((i2p::proxy::HTTPProxy*)clientTunnel)->GetLocalEndpoint (); clientTunnel = tun;
clientEndpoint = tun->GetLocalEndpoint ();
} }
else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS) else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)
{ {
// websocks proxy // websocks proxy
clientTunnel = new WebSocks(address, port, localDestination);; auto tun = std::make_shared<WebSocks>(address, port, localDestination);
clientEndpoint = ((WebSocks*)clientTunnel)->GetLocalEndpoint(); clientTunnel = tun;
clientEndpoint = tun->GetLocalEndpoint();
} }
else else
{ {
// tcp client // tcp client
clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort); auto tun = std::make_shared<I2PClientTunnel> (name, dest, address, port, localDestination, destinationPort);
clientEndpoint = ((I2PClientTunnel*)clientTunnel)->GetLocalEndpoint (); clientTunnel = tun;
clientEndpoint = tun->GetLocalEndpoint ();
} }
uint32_t timeout = section.second.get<uint32_t>(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0); uint32_t timeout = section.second.get<uint32_t>(I2P_CLIENT_TUNNEL_CONNECT_TIMEOUT, 0);
if(timeout) if(timeout)
@ -531,8 +535,7 @@ namespace client
LogPrint(eLogInfo, "Clients: I2P Client tunnel connect timeout set to ", timeout); 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, clientTunnel));
auto ins = m_ClientTunnels.insert (std::make_pair (clientEndpoint, std::unique_ptr<I2PService>(clientTunnel)));
if (ins.second) if (ins.second)
{ {
clientTunnel->Start (); clientTunnel->Start ();
@ -541,10 +544,10 @@ namespace client
else else
{ {
// TODO: update // TODO: update
if (ins.first->second->GetLocalDestination () != clientTunnelDest) if (ins.first->second->GetLocalDestination () != clientTunnel->GetLocalDestination ())
{ {
LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated"); LogPrint (eLogInfo, "Clients: I2P client tunnel destination updated");
ins.first->second->SetLocalDestination (clientTunnelDest); ins.first->second->SetLocalDestination (clientTunnel->GetLocalDestination ());
} }
ins.first->second->isUpdated = true; ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists"); LogPrint (eLogInfo, "Clients: I2P client tunnel for endpoint ", clientEndpoint, " already exists");
@ -589,7 +592,7 @@ namespace client
// TODO: hostnames // TODO: hostnames
auto localAddress = boost::asio::ip::address::from_string(address); auto localAddress = boost::asio::ip::address::from_string(address);
boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address::from_string(host), port); 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<I2PUDPServerTunnel>(name, localDestination, localAddress, endpoint, port);
if(!isUniqueLocal) if(!isUniqueLocal)
{ {
LogPrint(eLogInfo, "Clients: disabling loopback address mapping"); LogPrint(eLogInfo, "Clients: disabling loopback address mapping");
@ -600,7 +603,7 @@ namespace client
std::make_pair( std::make_pair(
std::make_pair( std::make_pair(
localDestination->GetIdentHash(), port), localDestination->GetIdentHash(), port),
std::unique_ptr<I2PUDPServerTunnel>(serverTunnel))).second) serverTunnel)).second)
{ {
serverTunnel->Start(); serverTunnel->Start();
LogPrint(eLogInfo, "Clients: I2P Server Forward created for UDP Endpoint ", host, ":", port, " bound on ", address, " for ",localDestination->GetIdentHash().ToBase32()); 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; continue;
} }
I2PServerTunnel * serverTunnel; std::shared_ptr<I2PServerTunnel> serverTunnel;
if (type == I2P_TUNNELS_SECTION_TYPE_HTTP) if (type == I2P_TUNNELS_SECTION_TYPE_HTTP)
serverTunnel = new I2PServerTunnelHTTP (name, host, port, localDestination, hostOverride, inPort, gzip); serverTunnel = std::make_shared<I2PServerTunnelHTTP> (name, host, port, localDestination, hostOverride, inPort, gzip);
else if (type == I2P_TUNNELS_SECTION_TYPE_IRC) else if (type == I2P_TUNNELS_SECTION_TYPE_IRC)
serverTunnel = new I2PServerTunnelIRC (name, host, port, localDestination, webircpass, inPort, gzip); serverTunnel = std::make_shared<I2PServerTunnelIRC> (name, host, port, localDestination, webircpass, inPort, gzip);
else // regular server tunnel by default else // regular server tunnel by default
serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip); serverTunnel = std::make_shared<I2PServerTunnel> (name, host, port, localDestination, inPort, gzip);
if(!isUniqueLocal) if(!isUniqueLocal)
{ {
@ -640,10 +643,9 @@ namespace client
while (comma != std::string::npos); while (comma != std::string::npos);
serverTunnel->SetAccessList (idents); serverTunnel->SetAccessList (idents);
} }
auto serverTunnelDest = serverTunnel->GetLocalDestination ();
auto ins = m_ServerTunnels.insert (std::make_pair ( auto ins = m_ServerTunnels.insert (std::make_pair (
std::make_pair (localDestination->GetIdentHash (), inPort), std::make_pair (localDestination->GetIdentHash (), inPort),
std::unique_ptr<I2PServerTunnel>(serverTunnel))); serverTunnel));
if (ins.second) if (ins.second)
{ {
serverTunnel->Start (); serverTunnel->Start ();
@ -652,10 +654,10 @@ namespace client
else else
{ {
// TODO: update // TODO: update
if (ins.first->second->GetLocalDestination () != serverTunnelDest) if (ins.first->second->GetLocalDestination () != serverTunnel->GetLocalDestination ())
{ {
LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated"); LogPrint (eLogInfo, "Clients: I2P server tunnel destination updated");
ins.first->second->SetLocalDestination (serverTunnelDest); ins.first->second->SetLocalDestination (serverTunnel->GetLocalDestination ());
} }
ins.first->second->isUpdated = true; ins.first->second->isUpdated = true;
LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists"); LogPrint (eLogInfo, "Clients: I2P server tunnel for destination/port ", m_AddressBook.ToAddress(localDestination->GetIdentHash ()), "/", inPort, " already exists");

8
libi2pd_client/ClientContext.h

@ -113,12 +113,12 @@ namespace client
i2p::proxy::HTTPProxy * m_HttpProxy; i2p::proxy::HTTPProxy * m_HttpProxy;
i2p::proxy::SOCKSProxy * m_SocksProxy; i2p::proxy::SOCKSProxy * m_SocksProxy;
std::map<boost::asio::ip::tcp::endpoint, std::unique_ptr<I2PService> > m_ClientTunnels; // local endpoint->tunnel std::map<boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService> > m_ClientTunnels; // local endpoint->tunnel
std::map<std::pair<i2p::data::IdentHash, int>, std::unique_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port>->tunnel std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port>->tunnel
std::mutex m_ForwardsMutex; std::mutex m_ForwardsMutex;
std::map<boost::asio::ip::udp::endpoint, std::unique_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel
std::map<std::pair<i2p::data::IdentHash, int>, std::unique_ptr<I2PUDPServerTunnel> > m_ServerForwards; // <destination,port> -> udp tunnel std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PUDPServerTunnel> > m_ServerForwards; // <destination,port> -> udp tunnel
SAMBridge * m_SamBridge; SAMBridge * m_SamBridge;
BOBCommandChannel * m_BOBCommandChannel; BOBCommandChannel * m_BOBCommandChannel;

169
libi2pd_client/SAM.cpp

@ -15,8 +15,8 @@ namespace i2p
{ {
namespace client namespace client
{ {
SAMSocket::SAMSocket (SAMBridge& owner, std::shared_ptr<Socket_t> socket): SAMSocket::SAMSocket (SAMBridge& owner):
m_Owner (owner), m_Socket(socket), m_Timer (m_Owner.GetService ()), m_Owner (owner), m_Socket(owner.GetService()), m_Timer (m_Owner.GetService ()),
m_BufferOffset (0), m_BufferOffset (0),
m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false), m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false),
m_IsAccepting (false), m_Stream (nullptr) m_IsAccepting (false), m_Stream (nullptr)
@ -25,51 +25,17 @@ namespace client
SAMSocket::~SAMSocket () SAMSocket::~SAMSocket ()
{ {
if(m_Stream) m_Stream = nullptr;
{
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 ();
} }
void SAMSocket::Terminate (const char* reason) void SAMSocket::Terminate (const char* reason)
{ {
if(m_Stream) if(m_Stream)
{ {
m_Stream->Close (); m_Stream->AsyncClose ();
m_Stream.reset (); m_Stream = nullptr;
} }
auto Session = m_Owner.FindSession(m_ID); auto Session = m_Owner.FindSession(m_ID);
switch (m_SocketType) switch (m_SocketType)
{ {
case eSAMSocketTypeSession: case eSAMSocketTypeSession:
@ -77,15 +43,12 @@ namespace client
break; break;
case eSAMSocketTypeStream: case eSAMSocketTypeStream:
{ {
if (Session)
Session->DelSocket (this);
break; break;
} }
case eSAMSocketTypeAcceptor: case eSAMSocketTypeAcceptor:
{ {
if (Session) if (Session)
{ {
Session->DelSocket (this);
if (m_IsAccepting && Session->localDestination) if (m_IsAccepting && Session->localDestination)
Session->localDestination->StopAcceptingStreams (); Session->localDestination->StopAcceptingStreams ();
} }
@ -95,14 +58,18 @@ namespace client
; ;
} }
m_SocketType = eSAMSocketTypeTerminated; m_SocketType = eSAMSocketTypeTerminated;
if (m_Socket && m_Socket->is_open()) m_Socket->close (); if (m_Socket.is_open ())
m_Socket.reset (); {
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 () void SAMSocket::ReceiveHandshake ()
{ {
if(m_Socket) 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::HandleHandshakeReceived, shared_from_this (), std::bind(&SAMSocket::HandleHandshakeReceived, shared_from_this (),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
@ -184,7 +151,7 @@ namespace client
#else #else
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ());
#endif #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::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
@ -199,6 +166,11 @@ 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) void SAMSocket::HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
{ {
if (ecode) if (ecode)
@ -207,9 +179,9 @@ namespace client
if (ecode != boost::asio::error::operation_aborted) if (ecode != boost::asio::error::operation_aborted)
Terminate ("SAM: handshake reply send error"); 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::bind(&SAMSocket::HandleMessage, shared_from_this (),
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
@ -220,7 +192,7 @@ namespace client
LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg); LogPrint (eLogDebug, "SAMSocket::SendMessageReply, close=",close?"true":"false", " reason: ", msg);
if (!m_IsSilent) 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::bind(&SAMSocket::HandleMessageReplySent, shared_from_this (),
std::placeholders::_1, std::placeholders::_2, close)); std::placeholders::_1, std::placeholders::_2, close));
else else
@ -501,7 +473,6 @@ namespace client
if(session) if(session)
{ {
m_SocketType = eSAMSocketTypeStream; m_SocketType = eSAMSocketTypeStream;
session->AddSocket (shared_from_this ());
m_Stream = session->localDestination->CreateStream (remote); m_Stream = session->localDestination->CreateStream (remote);
m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send
m_BufferOffset = 0; m_BufferOffset = 0;
@ -534,7 +505,6 @@ namespace client
if (session) if (session)
{ {
m_SocketType = eSAMSocketTypeAcceptor; m_SocketType = eSAMSocketTypeAcceptor;
session->AddSocket (shared_from_this ());
if (!session->localDestination->IsAcceptingStreams ()) if (!session->localDestination->IsAcceptingStreams ())
{ {
m_IsAccepting = true; m_IsAccepting = true;
@ -704,17 +674,9 @@ namespace client
void SAMSocket::Receive () void SAMSocket::Receive ()
{ {
if (m_BufferOffset >= SAM_SOCKET_BUFFER_SIZE) m_Socket.async_read_some (boost::asio::buffer(m_Buffer + m_BufferOffset, SAM_SOCKET_BUFFER_SIZE - m_BufferOffset),
{
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, std::bind((m_SocketType == eSAMSocketTypeStream) ? &SAMSocket::HandleReceived : &SAMSocket::HandleMessage,
shared_from_this (), std::placeholders::_1, std::placeholders::_2)); shared_from_this (), std::placeholders::_1, std::placeholders::_2));
else
LogPrint(eLogError, "SAM: receive with no native socket");
} }
void SAMSocket::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred) void SAMSocket::HandleReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred)
@ -731,15 +693,12 @@ namespace client
{ {
bytes_transferred += m_BufferOffset; bytes_transferred += m_BufferOffset;
m_BufferOffset = 0; m_BufferOffset = 0;
auto s = shared_from_this ();
m_Stream->AsyncSend ((uint8_t *)m_Buffer, bytes_transferred, m_Stream->AsyncSend ((uint8_t *)m_Buffer, bytes_transferred,
[s](const boost::system::error_code& ecode) std::bind(&SAMSocket::HandleStreamSend, shared_from_this(), std::placeholders::_1));
{ }
if (!ecode)
s->m_Owner.GetService ().post ([s] { s->Receive (); });
else else
s->m_Owner.GetService ().post ([s] { s->Terminate ("AsyncSend failed"); }); {
}); Terminate("No Stream Remaining");
} }
} }
} }
@ -766,21 +725,21 @@ namespace client
WriteI2PDataImmediate(buff, len); WriteI2PDataImmediate(buff, len);
} }
else // no more data else // no more data
{
delete [] buff;
Terminate ("no more data"); Terminate ("no more data");
} }
} }
} }
}
void SAMSocket::WriteI2PDataImmediate(uint8_t * buff, size_t sz) void SAMSocket::WriteI2PDataImmediate(uint8_t * buff, size_t sz)
{ {
if(m_Socket)
boost::asio::async_write ( boost::asio::async_write (
*m_Socket, m_Socket,
boost::asio::buffer (buff, sz), boost::asio::buffer (buff, sz),
boost::asio::transfer_all(), boost::asio::transfer_all(),
std::bind (&SAMSocket::HandleWriteI2PDataImmediate, shared_from_this (), std::placeholders::_1, buff)); // postpone termination std::bind (&SAMSocket::HandleWriteI2PDataImmediate, shared_from_this (), std::placeholders::_1, buff)); // postpone termination
else
LogPrint(eLogError, "SAM: no native socket");
} }
void SAMSocket::HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff) void SAMSocket::HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff)
@ -790,9 +749,11 @@ namespace client
void SAMSocket::WriteI2PData(size_t sz) void SAMSocket::WriteI2PData(size_t sz)
{ {
uint8_t * sendbuff = new uint8_t[sz]; boost::asio::async_write (
memcpy(sendbuff, m_StreamBuffer, sz); m_Socket,
WriteI2PDataImmediate(sendbuff, sz); 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) void SAMSocket::HandleI2PReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred)
@ -826,6 +787,7 @@ namespace client
{ {
WriteI2PData(bytes_transferred); WriteI2PData(bytes_transferred);
} }
else
I2PReceive(); I2PReceive();
} }
} }
@ -858,7 +820,7 @@ namespace client
if (session) if (session)
{ {
// find more pending acceptors // find more pending acceptors
for (auto it: session->ListSockets ()) for (auto & it: m_Owner.ListSockets (m_ID))
if (it->m_SocketType == eSAMSocketTypeAcceptor) if (it->m_SocketType == eSAMSocketTypeAcceptor)
{ {
it->m_IsAccepting = true; it->m_IsAccepting = true;
@ -930,30 +892,31 @@ namespace client
} }
} }
SAMSession::SAMSession (std::shared_ptr<ClientDestination> 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<ClientDestination> dest):
m_Bridge(parent),
localDestination (dest), localDestination (dest),
UDPEndpoint(nullptr) UDPEndpoint(nullptr),
Name(id)
{ {
} }
SAMSession::~SAMSession () SAMSession::~SAMSession ()
{ {
CloseStreams();
i2p::client::context.DeleteLocalDestination (localDestination); i2p::client::context.DeleteLocalDestination (localDestination);
} }
void SAMSession::CloseStreams () void SAMSession::CloseStreams ()
{ {
std::vector<std::shared_ptr<SAMSocket> > socks; for(const auto & itr : m_Bridge.ListSockets(Name))
{ {
std::lock_guard<std::mutex> lock(m_SocketsMutex); itr->Terminate(nullptr);
for (const auto& sock : m_Sockets) {
socks.push_back(sock);
} }
} }
for (auto & sock : socks ) sock->Terminate("SAMSession::CloseStreams()");
m_Sockets.clear();
}
SAMBridge::SAMBridge (const std::string& address, int port): SAMBridge::SAMBridge (const std::string& address, int port):
m_IsRunning (false), m_Thread (nullptr), m_IsRunning (false), m_Thread (nullptr),
@ -1009,12 +972,17 @@ namespace client
void SAMBridge::Accept () void SAMBridge::Accept ()
{ {
auto native = std::make_shared<boost::asio::ip::tcp::socket>(m_Service); auto newSocket = std::make_shared<SAMSocket>(*this);
auto newSocket = std::make_shared<SAMSocket> (*this, native); m_Acceptor.async_accept (newSocket->GetSocket(), std::bind (&SAMBridge::HandleAccept, this,
m_Acceptor.async_accept (*native, std::bind (&SAMBridge::HandleAccept, this,
std::placeholders::_1, newSocket)); std::placeholders::_1, newSocket));
} }
void SAMBridge::RemoveSocket(const std::shared_ptr<SAMSocket> & socket)
{
std::unique_lock<std::mutex> lock(m_OpenSocketsMutex);
m_OpenSockets.remove_if([socket](const std::shared_ptr<SAMSocket> & item) -> bool { return item == socket; });
}
void SAMBridge::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<SAMSocket> socket) void SAMBridge::HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<SAMSocket> socket)
{ {
if (!ecode) if (!ecode)
@ -1024,6 +992,10 @@ namespace client
if (!ec) if (!ec)
{ {
LogPrint (eLogDebug, "SAM: new connection from ", ep); LogPrint (eLogDebug, "SAM: new connection from ", ep);
{
std::unique_lock<std::mutex> l(m_OpenSocketsMutex);
m_OpenSockets.push_back(socket);
}
socket->ReceiveHandshake (); socket->ReceiveHandshake ();
} }
else else
@ -1066,7 +1038,7 @@ namespace client
if (localDestination) if (localDestination)
{ {
localDestination->Acquire (); localDestination->Acquire ();
auto session = std::make_shared<SAMSession>(localDestination); auto session = std::make_shared<SAMSession>(*this, id, localDestination);
std::unique_lock<std::mutex> l(m_SessionsMutex); std::unique_lock<std::mutex> l(m_SessionsMutex);
auto ret = m_Sessions.insert (std::make_pair(id, session)); auto ret = m_Sessions.insert (std::make_pair(id, session));
if (!ret.second) if (!ret.second)
@ -1105,6 +1077,18 @@ namespace client
return nullptr; return nullptr;
} }
std::list<std::shared_ptr<SAMSocket> > SAMBridge::ListSockets(const std::string & id) const
{
std::list<std::shared_ptr<SAMSocket > > list;
{
std::unique_lock<std::mutex> 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<boost::asio::ip::udp::endpoint> remote) void SAMBridge::SendTo(const uint8_t * buf, size_t len, std::shared_ptr<boost::asio::ip::udp::endpoint> remote)
{ {
if(remote) if(remote)
@ -1127,6 +1111,8 @@ namespace client
{ {
m_DatagramReceiveBuffer[bytes_transferred] = 0; m_DatagramReceiveBuffer[bytes_transferred] = 0;
char * eol = strchr ((char *)m_DatagramReceiveBuffer, '\n'); char * eol = strchr ((char *)m_DatagramReceiveBuffer, '\n');
if(eol)
{
*eol = 0; eol++; *eol = 0; eol++;
size_t payloadLen = bytes_transferred - ((uint8_t *)eol - m_DatagramReceiveBuffer); size_t payloadLen = bytes_transferred - ((uint8_t *)eol - m_DatagramReceiveBuffer);
LogPrint (eLogDebug, "SAM: datagram received ", m_DatagramReceiveBuffer," size=", payloadLen); LogPrint (eLogDebug, "SAM: datagram received ", m_DatagramReceiveBuffer," size=", payloadLen);
@ -1154,6 +1140,9 @@ namespace client
} }
else else
LogPrint (eLogError, "SAM: Missing sessionID"); LogPrint (eLogError, "SAM: Missing sessionID");
}
else
LogPrint(eLogError, "SAM: invalid datagram");
ReceiveDatagram (); ReceiveDatagram ();
} }
else else

45
libi2pd_client/SAM.h

@ -82,17 +82,20 @@ namespace client
public: public:
typedef boost::asio::ip::tcp::socket Socket_t; typedef boost::asio::ip::tcp::socket Socket_t;
SAMSocket (SAMBridge& owner, std::shared_ptr<Socket_t> socket); SAMSocket (SAMBridge& owner);
~SAMSocket (); ~SAMSocket ();
boost::asio::ip::tcp::socket& GetSocket () { return *m_Socket; }; Socket_t& GetSocket () { return m_Socket; };
void ReceiveHandshake (); void ReceiveHandshake ();
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; }; void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
SAMSocketType GetSocketType () const { return m_SocketType; }; SAMSocketType GetSocketType () const { return m_SocketType; };
void Terminate (const char* reason); void Terminate (const char* reason);
bool IsSession(const std::string & id) const;
private: private:
void TerminateClose() { Terminate(nullptr); }
void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred); 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 HandleHandshakeReplySent (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 WriteI2PDataImmediate(uint8_t * ptr, size_t sz);
void HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff); void HandleWriteI2PDataImmediate(const boost::system::error_code & ec, uint8_t * buff);
void HandleStreamSend(const boost::system::error_code & ec);
private: private:
SAMBridge& m_Owner; SAMBridge& m_Owner;
std::shared_ptr<Socket_t> m_Socket; Socket_t m_Socket;
boost::asio::deadline_timer m_Timer; boost::asio::deadline_timer m_Timer;
char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1]; char m_Buffer[SAM_SOCKET_BUFFER_SIZE + 1];
size_t m_BufferOffset; size_t m_BufferOffset;
@ -145,34 +150,12 @@ namespace client
struct SAMSession struct SAMSession
{ {
SAMBridge & m_Bridge;
std::shared_ptr<ClientDestination> localDestination; std::shared_ptr<ClientDestination> localDestination;
std::list<std::shared_ptr<SAMSocket> > m_Sockets;
std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint; std::shared_ptr<boost::asio::ip::udp::endpoint> UDPEndpoint;
std::mutex m_SocketsMutex; std::string Name;
/** safely add a socket to this session */
void AddSocket(std::shared_ptr<SAMSocket> sock) {
std::lock_guard<std::mutex> lock(m_SocketsMutex);
m_Sockets.push_back(sock);
}
/** safely remove a socket from this session */
void DelSocket(SAMSocket * sock) {
std::lock_guard<std::mutex> lock(m_SocketsMutex);
m_Sockets.remove_if([sock](const std::shared_ptr<SAMSocket> s) -> bool { return s.get() == sock; });
}
/** get a list holding a copy of all sam sockets from this session */
std::list<std::shared_ptr<SAMSocket> > ListSockets() {
std::list<std::shared_ptr<SAMSocket> > l;
{
std::lock_guard<std::mutex> lock(m_SocketsMutex);
for(const auto& sock : m_Sockets ) l.push_back(sock);
}
return l;
}
SAMSession (std::shared_ptr<ClientDestination> dest); SAMSession (SAMBridge & parent, const std::string & name, std::shared_ptr<ClientDestination> dest);
~SAMSession (); ~SAMSession ();
void CloseStreams (); void CloseStreams ();
@ -194,9 +177,13 @@ namespace client
void CloseSession (const std::string& id); void CloseSession (const std::string& id);
std::shared_ptr<SAMSession> FindSession (const std::string& id) const; std::shared_ptr<SAMSession> FindSession (const std::string& id) const;
std::list<std::shared_ptr<SAMSocket> > ListSockets(const std::string & id) const;
/** send raw data to remote endpoint from our UDP Socket */ /** send raw data to remote endpoint from our UDP Socket */
void SendTo(const uint8_t * buf, size_t len, std::shared_ptr<boost::asio::ip::udp::endpoint> remote); void SendTo(const uint8_t * buf, size_t len, std::shared_ptr<boost::asio::ip::udp::endpoint> remote);
void RemoveSocket(const std::shared_ptr<SAMSocket> & socket);
private: private:
void Run (); void Run ();
@ -217,6 +204,8 @@ namespace client
boost::asio::ip::udp::socket m_DatagramSocket; boost::asio::ip::udp::socket m_DatagramSocket;
mutable std::mutex m_SessionsMutex; mutable std::mutex m_SessionsMutex;
std::map<std::string, std::shared_ptr<SAMSession> > m_Sessions; std::map<std::string, std::shared_ptr<SAMSession> > m_Sessions;
mutable std::mutex m_OpenSocketsMutex;
std::list<std::shared_ptr<SAMSocket> > m_OpenSockets;
uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1]; uint8_t m_DatagramReceiveBuffer[i2p::datagram::MAX_DATAGRAM_SIZE+1];
public: public:

18
qt/i2pd_qt/ServerTunnelPane.cpp

@ -204,24 +204,6 @@ int ServerTunnelPane::appendServerTunnelForm(
horizontalLayout_2->addItem(horizontalSpacer); horizontalLayout_2->addItem(horizontalSpacer);
tunnelGridLayout->addLayout(horizontalLayout_2); 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(); std::string address = tunnelConfig->getaddress();
QHBoxLayout *horizontalLayout_2 = new QHBoxLayout(); QHBoxLayout *horizontalLayout_2 = new QHBoxLayout();

13
qt/i2pd_qt/ServerTunnelPane.h

@ -81,10 +81,6 @@ private:
QLabel * addressLabel; QLabel * addressLabel;
QLineEdit * addressLineEdit; QLineEdit * addressLineEdit;
//maxConns
QLabel * maxConnsLabel;
QLineEdit * maxConnsLineEdit;
//gzip //gzip
QCheckBox * gzipCheckBox; QCheckBox * gzipCheckBox;
@ -109,7 +105,6 @@ private:
hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0)); hostOverrideLabel->setText(QApplication::translate("srvTunForm", "Host override:", 0));
webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0)); webIRCPassLabel->setText(QApplication::translate("srvTunForm", "WebIRC password:", 0));
addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0)); addressLabel->setText(QApplication::translate("srvTunForm", "Address:", 0));
maxConnsLabel->setText(QApplication::translate("srvTunForm", "Max connections:", 0));
gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0)); gzipCheckBox->setText(QApplication::translate("srvTunForm", "GZip", 0));
isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0)); isUniqueLocalCheckBox->setText(QApplication::translate("srvTunForm", "Is unique local", 0));
@ -152,14 +147,6 @@ protected:
stc->setaddress(addressLineEdit->text().toStdString()); 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->setgzip(gzipCheckBox->isChecked());
stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked()); stc->setisUniqueLocal(isUniqueLocalCheckBox->isChecked());

3
qt/i2pd_qt/TunnelConfig.cpp

@ -48,7 +48,6 @@ void ServerTunnelConfig::saveToStringStream(std::stringstream& out) {
<< "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n" << "enableuniquelocal=" << (isUniqueLocal?"true":"false") << "\n"
<< "address=" << address << "\n" << "address=" << address << "\n"
<< "hostoverride=" << hostOverride << "\n" << "hostoverride=" << hostOverride << "\n"
<< "webircpassword=" << webircpass << "\n" << "webircpassword=" << webircpass << "\n";
<< "maxconns=" << maxConns << "\n";
} }

6
qt/i2pd_qt/TunnelConfig.h

@ -148,7 +148,6 @@ public:
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); 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); 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<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
# * inport -- optional, i2p service port, if unset - the same as 'port' # * inport -- optional, i2p service port, if unset - the same as 'port'
@ -170,7 +169,6 @@ class ServerTunnelConfig : public TunnelConfig {
std::string webircpass; std::string webircpass;
bool gzip; bool gzip;
i2p::data::SigningKeyType sigType; i2p::data::SigningKeyType sigType;
uint32_t maxConns;
std::string address; std::string address;
bool isUniqueLocal; bool isUniqueLocal;
public: public:
@ -184,7 +182,6 @@ public:
std::string webircpass_, std::string webircpass_,
bool gzip_, bool gzip_,
i2p::data::SigningKeyType sigType_, i2p::data::SigningKeyType sigType_,
uint32_t maxConns_,
std::string address_, std::string address_,
bool isUniqueLocal_): TunnelConfig(name_, type_, i2cpParameters_), bool isUniqueLocal_): TunnelConfig(name_, type_, i2cpParameters_),
host(host_), host(host_),
@ -196,7 +193,6 @@ public:
webircpass(webircpass_), webircpass(webircpass_),
gzip(gzip_), gzip(gzip_),
sigType(sigType_), sigType(sigType_),
maxConns(maxConns_),
address(address_), address(address_),
isUniqueLocal(isUniqueLocal_) {} isUniqueLocal(isUniqueLocal_) {}
std::string& gethost(){return host;} std::string& gethost(){return host;}
@ -208,7 +204,6 @@ public:
std::string& getwebircpass(){return webircpass;} std::string& getwebircpass(){return webircpass;}
bool getgzip(){return gzip;} bool getgzip(){return gzip;}
i2p::data::SigningKeyType getsigType(){return sigType;} i2p::data::SigningKeyType getsigType(){return sigType;}
uint32_t getmaxConns(){return maxConns;}
std::string& getaddress(){return address;} std::string& getaddress(){return address;}
bool getisUniqueLocal(){return isUniqueLocal;} bool getisUniqueLocal(){return isUniqueLocal;}
void sethost(const std::string& host_){host=host_;} void sethost(const std::string& host_){host=host_;}
@ -220,7 +215,6 @@ public:
void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;} void setwebircpass(const std::string& webircpass_){webircpass=webircpass_;}
void setgzip(bool gzip_){gzip=gzip_;} void setgzip(bool gzip_){gzip=gzip_;}
void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;} void setsigType(i2p::data::SigningKeyType sigType_){sigType=sigType_;}
void setmaxConns(uint32_t maxConns_){maxConns=maxConns_;}
void setaddress(const std::string& address_){address=address_;} void setaddress(const std::string& address_){address=address_;}
void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;} void setisUniqueLocal(bool isUniqueLocal_){isUniqueLocal=isUniqueLocal_;}
virtual void saveToStringStream(std::stringstream& out); virtual void saveToStringStream(std::stringstream& out);

7
qt/i2pd_qt/i2pd.qrc

@ -1,5 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0"> <!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/"> <qresource prefix="/icons">
<file>images/icon.png</file> <file alias="mask">resources/icons/mask.ico</file>
</qresource> <file alias="icon">resources/images/icon.png</file>
</qresource>
</RCC> </RCC>

32
qt/i2pd_qt/i2pd.rc

@ -0,0 +1,32 @@
IDI_ICON1 ICON DISCARDABLE "resources/icons/mask.ico"
#include <windows.h> // 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

29
qt/i2pd_qt/i2pd_qt.pro

@ -177,7 +177,9 @@ HEADERS += DaemonQT.h mainwindow.h \
textbrowsertweaked1.h \ textbrowsertweaked1.h \
pagewithbackbutton.h \ pagewithbackbutton.h \
widgetlock.h \ widgetlock.h \
widgetlockregistry.h widgetlockregistry.h \
i2pd.rc \
i2pd.rc
INCLUDEPATH += ../../libi2pd INCLUDEPATH += ../../libi2pd
INCLUDEPATH += ../../libi2pd_client INCLUDEPATH += ../../libi2pd_client
@ -272,10 +274,29 @@ linux:!android {
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc
} }
windows:!android { windows {
message("Using Windows settings") message("Using Windows settings")
DEFINES += BOOST_USE_WINDOWS_H WINDOWS RC_FILE = i2pd.rc
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc 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 { !android:!symbian:!maemo5:!simulator {

6
qt/i2pd_qt/mainwindow.cpp

@ -349,7 +349,9 @@ QString MainWindow::getStatusPageHtml(bool showHiddenInfo) {
s << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">"; s << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">";
switch (statusPage) { 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 commands: break;
case local_destinations: i2p::http::ShowLocalDestinations(s);break; case local_destinations: i2p::http::ShowLocalDestinations(s);break;
case leasesets: i2p::http::ShowLeasesSets(s); break; case leasesets: i2p::http::ShowLeasesSets(s); break;
@ -449,7 +451,7 @@ void MainWindow::createTrayIcon() {
} }
void MainWindow::setIcon() { void MainWindow::setIcon() {
QIcon icon(":/images/icon.png"); QIcon icon(":icons/mask");
trayIcon->setIcon(icon); trayIcon->setIcon(icon);
setWindowIcon(icon); setWindowIcon(icon);

4
qt/i2pd_qt/mainwindow.h

@ -628,7 +628,6 @@ private:
std::string webircpass = ""; std::string webircpass = "";
bool gzip = true; bool gzip = true;
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256; 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"; std::string address = "127.0.0.1";
bool isUniqueLocal = true; bool isUniqueLocal = true;
@ -646,7 +645,6 @@ private:
webircpass, webircpass,
gzip, gzip,
sigType, sigType,
maxConns,
address, address,
isUniqueLocal); isUniqueLocal);
@ -734,7 +732,6 @@ private:
std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, ""); std::string webircpass = section.second.get<std::string> (I2P_SERVER_TUNNEL_WEBIRC_PASSWORD, "");
bool gzip = section.second.get (I2P_SERVER_TUNNEL_GZIP, true); 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); 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<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1"); std::string address = section.second.get<std::string> (I2P_SERVER_TUNNEL_ADDRESS, "127.0.0.1");
bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true); bool isUniqueLocal = section.second.get(I2P_SERVER_TUNNEL_ENABLE_UNIQUE_LOCAL, true);
@ -769,7 +766,6 @@ private:
webircpass, webircpass,
gzip, gzip,
sigType, sigType,
maxConns,
address, address,
isUniqueLocal); isUniqueLocal);
} }

BIN
qt/i2pd_qt/resources/icons/mask.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

0
qt/i2pd_qt/images/icon.png → qt/i2pd_qt/resources/images/icon.png

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Loading…
Cancel
Save