mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-06-01 20:06:24 +02:00
Add settunneltype parameter to BOB API for i2pd to configure proxy tunnel type
This update introduces the settunneltype <socks|httpproxy> command to the BOB API, allowing users to specify the tunnel type as either SOCKS or HTTP proxy. When the tunnel type is set, the corresponding proxy service is automatically started. This enhances flexibility in tunnel configuration through the BOB interface. Signed-off-by: nobs2p <nobs2p@i2pmail.org>
This commit is contained in:
parent
7ec0c98036
commit
1b068618ba
2 changed files with 131 additions and 6 deletions
|
@ -383,6 +383,15 @@ namespace client
|
|||
const auto destExists = [](const BOBDestination * const dest) { return dest != nullptr; };
|
||||
const auto destReady = [](const BOBDestination * const dest) { return dest && dest->IsRunning(); };
|
||||
const auto bool_str = [](const bool v) { return v ? "true" : "false"; }; // bool -> str
|
||||
const auto getProxyType = [](const i2p::client::I2PService* proxy) -> std::string {
|
||||
if (!proxy) return "NONE";
|
||||
if (dynamic_cast<const i2p::proxy::SOCKSProxy*>(proxy)) return "SOCKS";
|
||||
if (dynamic_cast<const i2p::proxy::HTTPProxy*>(proxy)) return "HTTPPROXY";
|
||||
return "UNKNOWN";
|
||||
};
|
||||
const auto isProxyRunning = [](const i2p::client::I2PService* proxy) -> bool {
|
||||
return proxy != nullptr;
|
||||
};
|
||||
|
||||
// tunnel info
|
||||
const std::string nickname = currentTunnel ? m_Nickname : dest->GetNickname();
|
||||
|
@ -395,6 +404,10 @@ namespace client
|
|||
const bool starting = destExists(dest.get ()) && !destReady(dest.get ());
|
||||
const bool running = destExists(dest.get ()) && destReady(dest.get ());
|
||||
const bool stopping = false;
|
||||
|
||||
const i2p::client::I2PService* proxy = m_Owner.GetProxy(nickname);
|
||||
const std::string proxyType = getProxyType(proxy);
|
||||
const bool proxyStatus = isProxyRunning(proxy);
|
||||
|
||||
// build line
|
||||
std::stringstream ss;
|
||||
|
@ -403,7 +416,8 @@ namespace client
|
|||
<< "RUNNING: " << bool_str(running) << " " << "STOPPING: " << bool_str(stopping) << " "
|
||||
<< "KEYS: " << bool_str(keys) << " " << "QUIET: " << bool_str(quiet) << " "
|
||||
<< "INPORT: " << inport << " " << "INHOST: " << inhost << " "
|
||||
<< "OUTPORT: " << outport << " " << "OUTHOST: " << outhost;
|
||||
<< "OUTPORT: " << outport << " " << "OUTHOST: " << outhost << " "
|
||||
<< "PROXYTYPE: "<< proxyType << " " << "PROXYSTART: " << bool_str(proxyStatus);
|
||||
out = ss.str();
|
||||
}
|
||||
|
||||
|
@ -468,11 +482,51 @@ namespace client
|
|||
m_Nickname, m_InHost, m_OutHost, m_InPort, m_OutPort, m_IsQuiet);
|
||||
m_Owner.AddDestination (m_Nickname, m_CurrentDestination);
|
||||
}
|
||||
if (m_InPort)
|
||||
m_CurrentDestination->CreateInboundTunnel (m_InPort, m_InHost);
|
||||
if (m_OutPort && !m_OutHost.empty ())
|
||||
m_CurrentDestination->CreateOutboundTunnel (m_OutHost, m_OutPort, m_IsQuiet);
|
||||
m_CurrentDestination->Start ();
|
||||
if (!m_tunnelType.has_value())
|
||||
{
|
||||
if (m_InPort)
|
||||
m_CurrentDestination->CreateInboundTunnel (m_InPort, m_InHost);
|
||||
if (m_OutPort && !m_OutHost.empty ())
|
||||
m_CurrentDestination->CreateOutboundTunnel (m_OutHost, m_OutPort, m_IsQuiet);
|
||||
m_CurrentDestination->Start ();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*m_tunnelType)
|
||||
{
|
||||
case TunnelType::SOCKS:
|
||||
try
|
||||
{
|
||||
auto SocksProxy = std::make_unique<i2p::proxy::SOCKSProxy>(m_Nickname, m_InHost, m_InPort,
|
||||
false, m_OutHost, m_OutPort, m_CurrentDestination->GetLocalDestination());
|
||||
SocksProxy->Start();
|
||||
m_Owner.SetProxy(m_Nickname, std::move(SocksProxy));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LogPrint(eLogCritical, "Clients: Exception in SOCKS Proxy: ", e.what());
|
||||
ThrowFatal ("Unable to start SOCKS Proxy at ", m_InHost, ":", m_InPort, ": ", e.what ());
|
||||
}
|
||||
break;
|
||||
case TunnelType::HTTP_PROXY:
|
||||
try
|
||||
{
|
||||
auto HttpProxy = std::make_unique<i2p::proxy::HTTPProxy>(m_Nickname, m_InHost, m_InPort,
|
||||
m_OutHost, true, true, m_CurrentDestination->GetLocalDestination());
|
||||
HttpProxy->Start();
|
||||
m_Owner.SetProxy(m_Nickname, std::move(HttpProxy));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LogPrint(eLogCritical, "Clients: Exception in HTTP Proxy: ", e.what());
|
||||
ThrowFatal ("Unable to start HTTP Proxy at ", m_InHost, ":", m_InPort, ": ", e.what ());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SendReplyError("Unsupported tunnel type.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
SendReplyOK ("Tunnel starting");
|
||||
m_IsActive = true;
|
||||
}
|
||||
|
@ -486,10 +540,15 @@ namespace client
|
|||
return;
|
||||
}
|
||||
auto dest = m_Owner.FindDestination (m_Nickname);
|
||||
auto proxy = m_Owner.GetProxy (m_Nickname);
|
||||
if (dest)
|
||||
{
|
||||
dest->StopTunnels ();
|
||||
SendReplyOK ("Tunnel stopping");
|
||||
if (proxy)
|
||||
{
|
||||
m_Owner.RemoveProxy (m_Nickname);
|
||||
}
|
||||
}
|
||||
else
|
||||
SendReplyError ("tunnel not found");
|
||||
|
@ -522,10 +581,13 @@ namespace client
|
|||
if(*operand)
|
||||
{
|
||||
m_CurrentDestination = m_Owner.FindDestination (operand);
|
||||
auto proxy = m_Owner.GetProxy (operand);
|
||||
if (m_CurrentDestination)
|
||||
{
|
||||
m_Keys = m_CurrentDestination->GetKeys ();
|
||||
m_IsActive = m_CurrentDestination->IsRunning ();
|
||||
if(proxy)
|
||||
m_IsActive = true;
|
||||
m_Nickname = operand;
|
||||
}
|
||||
if (m_Nickname == operand)
|
||||
|
@ -843,6 +905,27 @@ namespace client
|
|||
SendReplyError("No such command");
|
||||
}
|
||||
}
|
||||
|
||||
void BOBCommandSession::SetTunnelTypeCommandHandler (const char * operand, size_t len)
|
||||
{
|
||||
std::string_view sv(operand, len);
|
||||
LogPrint (eLogDebug, "BOB: settunneltype ", operand);
|
||||
if (sv == "socks")
|
||||
{
|
||||
m_tunnelType = TunnelType::SOCKS;
|
||||
SendReplyOK ("tunnel type set to SOCKS");
|
||||
}
|
||||
else if (sv == "httpproxy")
|
||||
{
|
||||
m_tunnelType = TunnelType::HTTP_PROXY;
|
||||
SendReplyOK ("tunnel type set to HTTP proxy");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tunnelType.reset();
|
||||
SendReplyError ("no tunnel type has been set");
|
||||
}
|
||||
}
|
||||
|
||||
BOBCommandChannel::BOBCommandChannel (const std::string& address, uint16_t port):
|
||||
RunnableService ("BOB"),
|
||||
|
@ -871,6 +954,7 @@ namespace client
|
|||
m_CommandHandlers[BOB_COMMAND_OPTION] = &BOBCommandSession::OptionCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_STATUS] = &BOBCommandSession::StatusCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_HELP] = &BOBCommandSession::HelpCommandHandler;
|
||||
m_CommandHandlers[BOB_COMMAND_SETTUNNELTYPE] = &BOBCommandSession::SetTunnelTypeCommandHandler;
|
||||
// command -> help string
|
||||
m_HelpStrings[BOB_COMMAND_ZAP] = BOB_HELP_ZAP;
|
||||
m_HelpStrings[BOB_COMMAND_QUIT] = BOB_HELP_QUIT;
|
||||
|
@ -893,6 +977,7 @@ namespace client
|
|||
m_HelpStrings[BOB_COMMAND_OPTION] = BOB_HELP_OPTION;
|
||||
m_HelpStrings[BOB_COMMAND_STATUS] = BOB_HELP_STATUS;
|
||||
m_HelpStrings[BOB_COMMAND_HELP] = BOB_HELP_HELP;
|
||||
m_HelpStrings[BOB_COMMAND_SETTUNNELTYPE] = BOB_HELP_SETTUNNELTYPE;
|
||||
}
|
||||
|
||||
BOBCommandChannel::~BOBCommandChannel ()
|
||||
|
@ -937,6 +1022,28 @@ namespace client
|
|||
return it->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BOBCommandChannel::SetProxy (const std::string& name, std::unique_ptr<I2PService> proxy)
|
||||
{
|
||||
m_proxy[name] = std::move(proxy);
|
||||
}
|
||||
|
||||
const I2PService* BOBCommandChannel::GetProxy(const std::string& name) const
|
||||
{
|
||||
auto it = m_proxy.find(name);
|
||||
if (it != m_proxy.end() && it->second)
|
||||
return it->second.get();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BOBCommandChannel::RemoveProxy(const std::string& name)
|
||||
{
|
||||
auto it = m_proxy.find (name);
|
||||
if (it != m_proxy.end ())
|
||||
{
|
||||
m_proxy.erase (it);
|
||||
}
|
||||
}
|
||||
|
||||
void BOBCommandChannel::Accept ()
|
||||
{
|
||||
|
|
|
@ -14,12 +14,15 @@
|
|||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <boost/asio.hpp>
|
||||
#include "util.h"
|
||||
#include "I2PTunnel.h"
|
||||
#include "I2PService.h"
|
||||
#include "Identity.h"
|
||||
#include "LeaseSet.h"
|
||||
#include "SOCKS.h"
|
||||
#include "HTTPProxy.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
|
@ -48,7 +51,9 @@ namespace client
|
|||
const char BOB_COMMAND_OPTION[] = "option";
|
||||
const char BOB_COMMAND_STATUS[] = "status";
|
||||
const char BOB_COMMAND_HELP[] = "help";
|
||||
const char BOB_COMMAND_SETTUNNELTYPE[] = "settunneltype";
|
||||
|
||||
|
||||
const char BOB_HELP_ZAP[] = "zap - Shuts down BOB.";
|
||||
const char BOB_HELP_QUIT[] = "quit - Quits this session with BOB.";
|
||||
const char BOB_HELP_START[] = "start - Starts the current nicknamed tunnel.";
|
||||
|
@ -70,6 +75,7 @@ namespace client
|
|||
const char BOB_HELP_OPTION[] = "option <KEY>=<VALUE> - Set an option. NOTE: Don't use any spaces.";
|
||||
const char BOB_HELP_STATUS[] = "status <NICKNAME> - Display status of a nicknamed tunnel.";
|
||||
const char BOB_HELP_HELP [] = "help <COMMAND> - Get help on a command.";
|
||||
const char BOB_HELP_SETTUNNELTYPE[] = "settunneltype <socks|httpproxy> - Sets socks or http proxy tunnel type.";
|
||||
|
||||
class BOBI2PTunnelIncomingConnection: public I2PTunnelConnection
|
||||
{
|
||||
|
@ -232,6 +238,7 @@ namespace client
|
|||
void OptionCommandHandler (const char * operand, size_t len);
|
||||
void StatusCommandHandler (const char * operand, size_t len);
|
||||
void HelpCommandHandler (const char * operand, size_t len);
|
||||
void SetTunnelTypeCommandHandler (const char * operand, size_t len);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -258,6 +265,13 @@ namespace client
|
|||
i2p::data::PrivateKeys m_Keys;
|
||||
std::map<std::string, std::string> m_Options;
|
||||
std::shared_ptr<BOBDestination> m_CurrentDestination;
|
||||
|
||||
enum class TunnelType
|
||||
{
|
||||
SOCKS = 0,
|
||||
HTTP_PROXY = 1
|
||||
};
|
||||
std::optional<TunnelType> m_tunnelType;
|
||||
};
|
||||
typedef void (BOBCommandSession::*BOBCommandHandler)(const char * operand, size_t len);
|
||||
|
||||
|
@ -275,6 +289,9 @@ namespace client
|
|||
void AddDestination (const std::string& name, std::shared_ptr<BOBDestination> dest);
|
||||
void DeleteDestination (const std::string& name);
|
||||
std::shared_ptr<BOBDestination> FindDestination (const std::string& name);
|
||||
void SetProxy (const std::string& name, std::unique_ptr<I2PService> proxy);
|
||||
const I2PService* GetProxy(const std::string& name) const;
|
||||
void RemoveProxy(const std::string& name);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -287,6 +304,7 @@ namespace client
|
|||
std::map<std::string, std::shared_ptr<BOBDestination> > m_Destinations;
|
||||
std::map<std::string, BOBCommandHandler> m_CommandHandlers;
|
||||
std::map<std::string, std::string> m_HelpStrings;
|
||||
std::map<std::string, std::unique_ptr<I2PService>> m_proxy;
|
||||
|
||||
public:
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue