Browse Source

* add websocks

* enable socks, websocks and httpproxy as client tunnels

* remove old websocks config
pull/771/head
Jeff Becker 8 years ago
parent
commit
c5d3c0c6f8
  1. 44
      ClientContext.cpp
  2. 5
      ClientContext.h
  3. 7
      Config.cpp
  4. 11
      Daemon.cpp
  5. 3
      I2PService.h
  6. 55
      WebSocks.cpp
  7. 11
      WebSocks.h
  8. 1
      android/jni/Android.mk

44
ClientContext.cpp

@ -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);

5
ClientContext.h

@ -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;

7
Config.cpp

@ -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

@ -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;
} }

3
I2PService.h

@ -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);

55
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

@ -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;
}; };

1
android/jni/Android.mk

@ -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…
Cancel
Save