mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-07 07:44:13 +00:00
commit
be7a84fdf3
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -198,7 +198,10 @@ namespace http {
|
||||
s << "<b>ERROR:</b> " << 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> ";
|
||||
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)<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";
|
||||
if(includeHiddenContent) {
|
||||
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\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) {
|
||||
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 Caps:</b> " << i2p::context.GetRouterInfo().GetProperty("caps") << "<br>\r\n";
|
||||
s << "<b>Our external address:</b>" << "<br>\r\n" ;
|
||||
@ -272,9 +278,12 @@ namespace http {
|
||||
}
|
||||
s << address->host.to_string() << ":" << address->port << "<br>\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
s << "</p>\r\n</div>\r\n";
|
||||
s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
|
||||
if(outputFormat==OutputFormatEnum::forQtUi) {
|
||||
s << "<br>";
|
||||
}
|
||||
s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
|
||||
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
|
||||
s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n";
|
||||
|
||||
@ -285,15 +294,17 @@ namespace http {
|
||||
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 << "<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>" << "SOCKS Proxy" << "</td><td><div class='" << ((i2p::client::context.GetSocksProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "<tr><td>" << "BOB" << "</td><td><div class='" << ((i2p::client::context.GetBOBCommandChannel ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "<tr><td>" << "SAM" << "</td><td><div class='" << ((i2p::client::context.GetSAMBridge ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "<tr><td>" << "I2CP" << "</td><td><div class='" << ((i2p::client::context.GetI2CPServer ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||
s << "<tr><td>" << "I2PControl" << "</td><td><div class='" << ((i2pcontrol) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "</table>\r\n";
|
||||
if(outputFormat==OutputFormatEnum::forWebConsole) {
|
||||
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>" << "SOCKS Proxy" << "</td><td><div class='" << ((i2p::client::context.GetSocksProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "<tr><td>" << "BOB" << "</td><td><div class='" << ((i2p::client::context.GetBOBCommandChannel ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "<tr><td>" << "SAM" << "</td><td><div class='" << ((i2p::client::context.GetSAMBridge ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "<tr><td>" << "I2CP" << "</td><td><div class='" << ((i2p::client::context.GetI2CPServer ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||
s << "<tr><td>" << "I2PControl" << "</td><td><div class='" << ((i2pcontrol) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||
s << "</table>\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
void ShowLocalDestinations (std::stringstream& s)
|
||||
@ -649,7 +660,7 @@ namespace http {
|
||||
s << i2p::client::context.GetAddressBook ().ToAddress(ident) << "</a><br>\r\n";
|
||||
s << "<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 ())
|
||||
{
|
||||
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 ());
|
||||
|
@ -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" \
|
||||
|
@ -124,6 +124,9 @@ namespace crypto
|
||||
|
||||
|
||||
#ifdef AESNI
|
||||
#ifdef ARM64AES
|
||||
void init_aesenc(void) __attribute__((constructor));
|
||||
#endif
|
||||
class ECBCryptoAESNI
|
||||
{
|
||||
public:
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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 (); };
|
||||
|
||||
|
@ -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<I2PUDPClientTunnel>(clientTunnel))).second)
|
||||
auto clientTunnel = std::make_shared<I2PUDPClientTunnel>(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<I2PService> 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<i2p::proxy::SOCKSProxy>(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<i2p::proxy::HTTPProxy>(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<WebSocks>(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<I2PClientTunnel> (name, dest, address, port, localDestination, destinationPort);
|
||||
clientTunnel = tun;
|
||||
clientEndpoint = tun->GetLocalEndpoint ();
|
||||
}
|
||||
uint32_t timeout = section.second.get<uint32_t>(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<I2PService>(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<I2PUDPServerTunnel>(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<I2PUDPServerTunnel>(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<I2PServerTunnel> serverTunnel;
|
||||
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)
|
||||
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
|
||||
serverTunnel = new I2PServerTunnel (name, host, port, localDestination, inPort, gzip);
|
||||
serverTunnel = std::make_shared<I2PServerTunnel> (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<I2PServerTunnel>(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");
|
||||
|
@ -113,12 +113,12 @@ namespace client
|
||||
|
||||
i2p::proxy::HTTPProxy * m_HttpProxy;
|
||||
i2p::proxy::SOCKSProxy * m_SocksProxy;
|
||||
std::map<boost::asio::ip::tcp::endpoint, std::unique_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<boost::asio::ip::tcp::endpoint, std::shared_ptr<I2PService> > m_ClientTunnels; // local endpoint->tunnel
|
||||
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port>->tunnel
|
||||
|
||||
std::mutex m_ForwardsMutex;
|
||||
std::map<boost::asio::ip::udp::endpoint, std::unique_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<boost::asio::ip::udp::endpoint, std::shared_ptr<I2PUDPClientTunnel> > m_ClientForwards; // local endpoint -> udp tunnel
|
||||
std::map<std::pair<i2p::data::IdentHash, int>, std::shared_ptr<I2PUDPServerTunnel> > m_ServerForwards; // <destination,port> -> udp tunnel
|
||||
|
||||
SAMBridge * m_SamBridge;
|
||||
BOBCommandChannel * m_BOBCommandChannel;
|
||||
|
@ -15,8 +15,8 @@ namespace i2p
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
SAMSocket::SAMSocket (SAMBridge& owner, std::shared_ptr<Socket_t> 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<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),
|
||||
UDPEndpoint(nullptr)
|
||||
UDPEndpoint(nullptr),
|
||||
Name(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SAMSession::~SAMSession ()
|
||||
{
|
||||
CloseStreams();
|
||||
i2p::client::context.DeleteLocalDestination (localDestination);
|
||||
}
|
||||
|
||||
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);
|
||||
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<boost::asio::ip::tcp::socket>(m_Service);
|
||||
auto newSocket = std::make_shared<SAMSocket> (*this, native);
|
||||
m_Acceptor.async_accept (*native, std::bind (&SAMBridge::HandleAccept, this,
|
||||
auto newSocket = std::make_shared<SAMSocket>(*this);
|
||||
m_Acceptor.async_accept (newSocket->GetSocket(), std::bind (&SAMBridge::HandleAccept, this,
|
||||
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)
|
||||
{
|
||||
if (!ecode)
|
||||
@ -1024,6 +992,10 @@ namespace client
|
||||
if (!ec)
|
||||
{
|
||||
LogPrint (eLogDebug, "SAM: new connection from ", ep);
|
||||
{
|
||||
std::unique_lock<std::mutex> 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<SAMSession>(localDestination);
|
||||
auto session = std::make_shared<SAMSession>(*this, id, localDestination);
|
||||
std::unique_lock<std::mutex> 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<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)
|
||||
{
|
||||
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
|
||||
|
@ -82,18 +82,21 @@ namespace client
|
||||
public:
|
||||
|
||||
typedef boost::asio::ip::tcp::socket Socket_t;
|
||||
SAMSocket (SAMBridge& owner, std::shared_ptr<Socket_t> 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<Socket_t> 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<ClientDestination> localDestination;
|
||||
std::list<std::shared_ptr<SAMSocket> > m_Sockets;
|
||||
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 ();
|
||||
|
||||
void CloseStreams ();
|
||||
@ -189,14 +172,18 @@ namespace client
|
||||
void Stop ();
|
||||
|
||||
boost::asio::io_service& GetService () { return m_Service; };
|
||||
std::shared_ptr<SAMSession> CreateSession (const std::string& id, const std::string& destination, // empty string means transient
|
||||
std::shared_ptr<SAMSession> CreateSession (const std::string& id, const std::string& destination, // empty string means transient
|
||||
const std::map<std::string, std::string> * params);
|
||||
void CloseSession (const std::string& id);
|
||||
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 */
|
||||
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:
|
||||
|
||||
void Run ();
|
||||
@ -217,6 +204,8 @@ namespace client
|
||||
boost::asio::ip::udp::socket m_DatagramSocket;
|
||||
mutable std::mutex m_SessionsMutex;
|
||||
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];
|
||||
|
||||
public:
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,6 @@ public:
|
||||
std::string webircpass = section.second.get<std::string> (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<std::string> (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);
|
||||
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/">
|
||||
<file>images/icon.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/icons">
|
||||
<file alias="mask">resources/icons/mask.ico</file>
|
||||
<file alias="icon">resources/images/icon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
32
qt/i2pd_qt/i2pd.rc
Normal file
32
qt/i2pd_qt/i2pd.rc
Normal file
@ -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
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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\">";
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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<std::string> (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<std::string> (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);
|
||||
}
|
||||
|
BIN
qt/i2pd_qt/resources/icons/mask.ico
Normal file
BIN
qt/i2pd_qt/resources/icons/mask.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 153 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Loading…
x
Reference in New Issue
Block a user