mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
* add websocks
* enable socks, websocks and httpproxy as client tunnels * remove old websocks config
This commit is contained in:
parent
43c1a87c48
commit
c5d3c0c6f8
|
@ -8,6 +8,8 @@
|
||||||
#include "Identity.h"
|
#include "Identity.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "ClientContext.h"
|
#include "ClientContext.h"
|
||||||
|
#include "SOCKS.h"
|
||||||
|
#include "WebSocks.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -424,7 +426,11 @@ namespace client
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
|
std::string type = section.second.get<std::string> (I2P_TUNNELS_SECTION_TYPE);
|
||||||
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT || type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
|
if (type == I2P_TUNNELS_SECTION_TYPE_CLIENT
|
||||||
|
|| type == I2P_TUNNELS_SECTION_TYPE_SOCKS
|
||||||
|
|| type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS
|
||||||
|
|| type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY
|
||||||
|
|| type == I2P_TUNNELS_SECTION_TYPE_UDPCLIENT)
|
||||||
{
|
{
|
||||||
// mandatory params
|
// mandatory params
|
||||||
std::string dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
|
std::string dest = section.second.get<std::string> (I2P_CLIENT_TUNNEL_DESTINATION);
|
||||||
|
@ -466,19 +472,45 @@ namespace client
|
||||||
LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists");
|
LogPrint(eLogError, "Clients: I2P Client forward for endpoint ", end, " already exists");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
boost::asio::ip::tcp::endpoint clientEndpoint;
|
||||||
|
I2PService * clientTunnel = nullptr;
|
||||||
|
if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS)
|
||||||
|
{
|
||||||
|
// socks proxy
|
||||||
|
clientTunnel = new i2p::proxy::SOCKSProxy(address, port, "", destinationPort, localDestination);
|
||||||
|
clientEndpoint = ((i2p::proxy::SOCKSProxy*)clientTunnel)->GetAcceptor().local_endpoint();
|
||||||
|
}
|
||||||
|
else if (type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)
|
||||||
|
{
|
||||||
|
// http proxy
|
||||||
|
clientTunnel = new i2p::proxy::HTTPProxy(address, port, localDestination);
|
||||||
|
clientEndpoint = ((i2p::proxy::HTTPProxy*)clientTunnel)->GetAcceptor().local_endpoint();
|
||||||
|
}
|
||||||
|
else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)
|
||||||
|
{
|
||||||
|
// websocks proxy
|
||||||
|
clientTunnel = new WebSocks(address, port, localDestination);;
|
||||||
|
clientEndpoint = ((WebSocks*)clientTunnel)->GetLocalEndpoint();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// tcp client
|
// tcp client
|
||||||
auto clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort);
|
clientTunnel = new I2PClientTunnel (name, dest, address, port, localDestination, destinationPort);
|
||||||
if (m_ClientTunnels.insert (std::make_pair (clientTunnel->GetAcceptor ().local_endpoint (),
|
clientEndpoint = ((I2PClientTunnel*)clientTunnel)->GetAcceptor().local_endpoint();
|
||||||
std::unique_ptr<I2PClientTunnel>(clientTunnel))).second)
|
}
|
||||||
|
if (m_ClientTunnels.insert (std::make_pair (clientEndpoint, std::unique_ptr<I2PService>(clientTunnel))).second)
|
||||||
{
|
{
|
||||||
clientTunnel->Start ();
|
clientTunnel->Start ();
|
||||||
numClientTunnels++;
|
numClientTunnels++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Clients: I2P client tunnel for endpoint ", clientTunnel->GetAcceptor ().local_endpoint (), " already exists");
|
LogPrint (eLogError, "Clients: I2P client tunnel for endpoint ", clientEndpoint, "already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER || type == I2P_TUNNELS_SECTION_TYPE_HTTP || type == I2P_TUNNELS_SECTION_TYPE_IRC || type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
|
else if (type == I2P_TUNNELS_SECTION_TYPE_SERVER
|
||||||
|
|| type == I2P_TUNNELS_SECTION_TYPE_HTTP
|
||||||
|
|| type == I2P_TUNNELS_SECTION_TYPE_IRC
|
||||||
|
|| type == I2P_TUNNELS_SECTION_TYPE_UDPSERVER)
|
||||||
{
|
{
|
||||||
// mandatory params
|
// mandatory params
|
||||||
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
|
std::string host = section.second.get<std::string> (I2P_SERVER_TUNNEL_HOST);
|
||||||
|
|
|
@ -26,6 +26,9 @@ namespace client
|
||||||
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
|
const char I2P_TUNNELS_SECTION_TYPE_IRC[] = "irc";
|
||||||
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
|
const char I2P_TUNNELS_SECTION_TYPE_UDPCLIENT[] = "udpclient";
|
||||||
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
|
const char I2P_TUNNELS_SECTION_TYPE_UDPSERVER[] = "udpserver";
|
||||||
|
const char I2P_TUNNELS_SECTION_TYPE_SOCKS[] = "socks";
|
||||||
|
const char I2P_TUNNELS_SECTION_TYPE_WEBSOCKS[] = "websocks";
|
||||||
|
const char I2P_TUNNELS_SECTION_TYPE_HTTPPROXY[] = "httpproxy";
|
||||||
const char I2P_CLIENT_TUNNEL_PORT[] = "port";
|
const char I2P_CLIENT_TUNNEL_PORT[] = "port";
|
||||||
const char I2P_CLIENT_TUNNEL_ADDRESS[] = "address";
|
const char I2P_CLIENT_TUNNEL_ADDRESS[] = "address";
|
||||||
const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination";
|
const char I2P_CLIENT_TUNNEL_DESTINATION[] = "destination";
|
||||||
|
@ -93,7 +96,7 @@ 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<I2PClientTunnel> > m_ClientTunnels; // local endpoint->tunnel
|
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<std::pair<i2p::data::IdentHash, int>, std::unique_ptr<I2PServerTunnel> > m_ServerTunnels; // <destination,port>->tunnel
|
||||||
|
|
||||||
std::mutex m_ForwardsMutex;
|
std::mutex m_ForwardsMutex;
|
||||||
|
|
|
@ -203,12 +203,6 @@ namespace config {
|
||||||
("websockets.address", value<std::string>()->default_value("127.0.0.1"), "address to bind websocket server on")
|
("websockets.address", value<std::string>()->default_value("127.0.0.1"), "address to bind websocket server on")
|
||||||
("websockets.port", value<uint16_t>()->default_value(7666), "port to bind websocket server on");
|
("websockets.port", value<uint16_t>()->default_value(7666), "port to bind websocket server on");
|
||||||
|
|
||||||
options_description websocks("WebSOCKS options");
|
|
||||||
websocks.add_options()
|
|
||||||
("websocks.enabled", value<bool>()->default_value(false), "enable WebSOCKS server")
|
|
||||||
("websocks.address", value<std::string>()->default_value("127.0.0.1"), "address to bind WebSOCKS server on")
|
|
||||||
("websocks.port", value<uint16_t>()->default_value(7666), "port to bind WebSOCKS server on");
|
|
||||||
|
|
||||||
m_OptionsDesc
|
m_OptionsDesc
|
||||||
.add(general)
|
.add(general)
|
||||||
.add(limits)
|
.add(limits)
|
||||||
|
@ -225,7 +219,6 @@ namespace config {
|
||||||
.add(addressbook)
|
.add(addressbook)
|
||||||
.add(trust)
|
.add(trust)
|
||||||
.add(websocket)
|
.add(websocket)
|
||||||
.add(websocks)
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
Daemon.cpp
11
Daemon.cpp
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "Websocket.h"
|
#include "Websocket.h"
|
||||||
#include "WebSocks.h"
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -44,7 +43,6 @@ namespace i2p
|
||||||
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
||||||
#ifdef WITH_EVENTS
|
#ifdef WITH_EVENTS
|
||||||
std::unique_ptr<i2p::event::WebsocketServer> m_WebsocketServer;
|
std::unique_ptr<i2p::event::WebsocketServer> m_WebsocketServer;
|
||||||
std::unique_ptr<i2p::client::WebSocks> m_WebSocksServer;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -309,15 +307,6 @@ namespace i2p
|
||||||
d.m_WebsocketServer->Start();
|
d.m_WebsocketServer->Start();
|
||||||
i2p::event::core.SetListener(d.m_WebsocketServer->ToListener());
|
i2p::event::core.SetListener(d.m_WebsocketServer->ToListener());
|
||||||
}
|
}
|
||||||
bool websocks; i2p::config::GetOption("websocks.enabled", websocks);
|
|
||||||
if (websocks) {
|
|
||||||
std::string websocksAddr; i2p::config::GetOption("websocks.address", websocksAddr);
|
|
||||||
uint16_t websocksPort; i2p::config::GetOption("websocks.port", websocksPort);
|
|
||||||
LogPrint(eLogInfo, "Daemon: starting up WebSOCKS server at ", websocksAddr, ":", websocksPort);
|
|
||||||
d.m_WebSocksServer = std::unique_ptr<i2p::client::WebSocks>(new i2p::client::WebSocks(websocksAddr, websocksPort));
|
|
||||||
d.m_WebSocksServer->Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,9 +122,10 @@ namespace client
|
||||||
|
|
||||||
const boost::asio::ip::tcp::acceptor& GetAcceptor () const { return m_Acceptor; };
|
const boost::asio::ip::tcp::acceptor& GetAcceptor () const { return m_Acceptor; };
|
||||||
|
|
||||||
|
virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket) = 0;
|
virtual std::shared_ptr<I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket) = 0;
|
||||||
virtual const char* GetName() { return "Generic TCP/IP accepting daemon"; }
|
|
||||||
private:
|
private:
|
||||||
void Accept();
|
void Accept();
|
||||||
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
void HandleAccept(const boost::system::error_code& ecode, std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
|
|
57
WebSocks.cpp
57
WebSocks.cpp
|
@ -27,8 +27,9 @@ namespace client
|
||||||
typedef std::function<void(std::shared_ptr<i2p::stream::Stream>)> StreamConnectFunc;
|
typedef std::function<void(std::shared_ptr<i2p::stream::Stream>)> StreamConnectFunc;
|
||||||
|
|
||||||
|
|
||||||
struct IWebSocksConn
|
struct IWebSocksConn : public I2PServiceHandler
|
||||||
{
|
{
|
||||||
|
IWebSocksConn(I2PService * parent) : I2PServiceHandler(parent) {}
|
||||||
virtual void Close() = 0;
|
virtual void Close() = 0;
|
||||||
virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg) = 0;
|
virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg) = 0;
|
||||||
};
|
};
|
||||||
|
@ -50,6 +51,7 @@ namespace client
|
||||||
typedef ServerImpl::message_ptr MessagePtr;
|
typedef ServerImpl::message_ptr MessagePtr;
|
||||||
|
|
||||||
WebSocksImpl(const std::string & addr, int port) :
|
WebSocksImpl(const std::string & addr, int port) :
|
||||||
|
Parent(nullptr),
|
||||||
m_Run(false),
|
m_Run(false),
|
||||||
m_Addr(addr),
|
m_Addr(addr),
|
||||||
m_Port(port),
|
m_Port(port),
|
||||||
|
@ -57,8 +59,12 @@ namespace client
|
||||||
{
|
{
|
||||||
m_Server.init_asio();
|
m_Server.init_asio();
|
||||||
m_Server.set_open_handler(std::bind(&WebSocksImpl::ConnOpened, this, std::placeholders::_1));
|
m_Server.set_open_handler(std::bind(&WebSocksImpl::ConnOpened, this, std::placeholders::_1));
|
||||||
i2p::data::PrivateKeys k = i2p::data::PrivateKeys::CreateRandomKeys(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519);
|
}
|
||||||
m_Dest = std::make_shared<ClientDestination>(k, false);
|
|
||||||
|
void InitializeDestination(WebSocks * parent)
|
||||||
|
{
|
||||||
|
Parent = parent;
|
||||||
|
m_Dest = Parent->GetLocalDestination();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerImpl::connection_ptr GetConn(const websocketpp::connection_hdl & conn)
|
ServerImpl::connection_ptr GetConn(const websocketpp::connection_hdl & conn)
|
||||||
|
@ -87,7 +93,9 @@ namespace client
|
||||||
|
|
||||||
void ConnOpened(websocketpp::connection_hdl conn)
|
void ConnOpened(websocketpp::connection_hdl conn)
|
||||||
{
|
{
|
||||||
m_Conns.push_back(CreateWebSocksConn(conn, this));
|
auto ptr = CreateWebSocksConn(conn, this);
|
||||||
|
Parent->AddHandler(ptr);
|
||||||
|
m_Conns.push_back(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
|
@ -123,6 +131,13 @@ namespace client
|
||||||
m_Thread = nullptr;
|
m_Thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::asio::ip::tcp::endpoint GetLocalEndpoint()
|
||||||
|
{
|
||||||
|
return boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(m_Addr), m_Port);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebSocks * Parent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<WebSocksConn_ptr> m_Conns;
|
std::vector<WebSocksConn_ptr> m_Conns;
|
||||||
bool m_Run;
|
bool m_Run;
|
||||||
|
@ -133,7 +148,7 @@ namespace client
|
||||||
Destination_t m_Dest;
|
Destination_t m_Dest;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WebSocksConn : public IWebSocksConn
|
struct WebSocksConn : public IWebSocksConn , public std::enable_shared_from_this<WebSocksConn>
|
||||||
{
|
{
|
||||||
enum ConnState
|
enum ConnState
|
||||||
{
|
{
|
||||||
|
@ -161,6 +176,7 @@ namespace client
|
||||||
uint8_t m_RecvBuf[2048];
|
uint8_t m_RecvBuf[2048];
|
||||||
|
|
||||||
WebSocksConn(const ServerConn & conn, WebSocksImpl * parent) :
|
WebSocksConn(const ServerConn & conn, WebSocksImpl * parent) :
|
||||||
|
IWebSocksConn(parent->Parent),
|
||||||
m_Conn(conn),
|
m_Conn(conn),
|
||||||
m_Stream(nullptr),
|
m_Stream(nullptr),
|
||||||
m_State(eWSCInitial),
|
m_State(eWSCInitial),
|
||||||
|
@ -240,6 +256,9 @@ namespace client
|
||||||
case eWSCClose:
|
case eWSCClose:
|
||||||
if(state == eWSCEnd) {
|
if(state == eWSCEnd) {
|
||||||
LogPrint(eLogDebug, "websocks: socket ended");
|
LogPrint(eLogDebug, "websocks: socket ended");
|
||||||
|
Kill();
|
||||||
|
auto me = shared_from_this();
|
||||||
|
Done(me);
|
||||||
} else {
|
} else {
|
||||||
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
||||||
}
|
}
|
||||||
|
@ -383,7 +402,7 @@ namespace client
|
||||||
class WebSocksImpl
|
class WebSocksImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebSocksImpl(const std::string & addr, int port)
|
WebSocksImpl(const std::string & addr, int port) : m_Addr(addr), m_Port(port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,9 +417,20 @@ namespace client
|
||||||
|
|
||||||
void Stop()
|
void Stop()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitializeDestination(WebSocks * parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::ip::tcp::endpoint GetLocalEndpoint()
|
||||||
|
{
|
||||||
|
return boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(m_Addr), m_Port);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string m_Addr;
|
||||||
|
int m_Port;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,17 +440,28 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace client
|
namespace client
|
||||||
{
|
{
|
||||||
WebSocks::WebSocks(const std::string & addr, int port) : m_Impl(new WebSocksImpl(addr, port)) {}
|
WebSocks::WebSocks(const std::string & addr, int port, std::shared_ptr<ClientDestination> localDestination) : m_Impl(new WebSocksImpl(addr, port))
|
||||||
|
{
|
||||||
|
m_Impl->InitializeDestination(this);
|
||||||
|
}
|
||||||
WebSocks::~WebSocks() { delete m_Impl; }
|
WebSocks::~WebSocks() { delete m_Impl; }
|
||||||
|
|
||||||
void WebSocks::Start()
|
void WebSocks::Start()
|
||||||
{
|
{
|
||||||
m_Impl->Start();
|
m_Impl->Start();
|
||||||
|
GetLocalDestination()->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::ip::tcp::endpoint WebSocks::GetLocalEndpoint() const
|
||||||
|
{
|
||||||
|
return m_Impl->GetLocalEndpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebSocks::Stop()
|
void WebSocks::Stop()
|
||||||
{
|
{
|
||||||
m_Impl->Stop();
|
m_Impl->Stop();
|
||||||
|
GetLocalDestination()->Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
WebSocks.h
11
WebSocks.h
|
@ -1,6 +1,9 @@
|
||||||
#ifndef WEBSOCKS_H_
|
#ifndef WEBSOCKS_H_
|
||||||
#define WEBSOCKS_H_
|
#define WEBSOCKS_H_
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include "I2PService.h"
|
||||||
|
#include "Destination.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -10,15 +13,19 @@ namespace client
|
||||||
class WebSocksImpl;
|
class WebSocksImpl;
|
||||||
|
|
||||||
/** @brief websocket socks proxy server */
|
/** @brief websocket socks proxy server */
|
||||||
class WebSocks
|
class WebSocks : public i2p::client::I2PService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WebSocks(const std::string & addr, int port);
|
WebSocks(const std::string & addr, int port, std::shared_ptr<ClientDestination> localDestination);
|
||||||
~WebSocks();
|
~WebSocks();
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
|
boost::asio::ip::tcp::endpoint GetLocalEndpoint() const;
|
||||||
|
|
||||||
|
const char * GetName() { return "WebSOCKS Proxy"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WebSocksImpl * m_Impl;
|
WebSocksImpl * m_Impl;
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,6 +59,7 @@ LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp \
|
||||||
../../TunnelPool.cpp \
|
../../TunnelPool.cpp \
|
||||||
../../Timestamp.cpp \
|
../../Timestamp.cpp \
|
||||||
../../Event.cpp \
|
../../Event.cpp \
|
||||||
|
../../WebSocks.cpp \
|
||||||
../../BloomFilter.cpp \
|
../../BloomFilter.cpp \
|
||||||
../../util.cpp \
|
../../util.cpp \
|
||||||
../../i2pd.cpp ../../UPnP.cpp
|
../../i2pd.cpp ../../UPnP.cpp
|
||||||
|
|
Loading…
Reference in a new issue