mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
drop websockets support
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
a0d6c654cc
commit
00db527377
4
Makefile
4
Makefile
@ -27,10 +27,6 @@ else
|
|||||||
LD_DEBUG = -s
|
LD_DEBUG = -s
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(WEBSOCKETS),1)
|
|
||||||
NEEDED_CXXFLAGS += -DWITH_EVENTS
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq (, $(findstring darwin, $(SYS)))
|
ifneq (, $(findstring darwin, $(SYS)))
|
||||||
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp
|
||||||
ifeq ($(HOMEBREW),1)
|
ifeq ($(HOMEBREW),1)
|
||||||
|
@ -20,7 +20,6 @@ option(WITH_MESHNET "Build for cjdns test network" OFF)
|
|||||||
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
|
option(WITH_ADDRSANITIZER "Build with address sanitizer unix only" OFF)
|
||||||
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
|
option(WITH_THREADSANITIZER "Build with thread sanitizer unix only" OFF)
|
||||||
option(WITH_I2LUA "Build for i2lua" OFF)
|
option(WITH_I2LUA "Build for i2lua" OFF)
|
||||||
option(WITH_WEBSOCKETS "Build with websocket ui" OFF)
|
|
||||||
|
|
||||||
# paths
|
# paths
|
||||||
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
set ( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" )
|
||||||
@ -86,11 +85,6 @@ set (LIBI2PD_SRC
|
|||||||
"${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp"
|
"${LIBI2PD_SRC_DIR}/ECIESX25519AEADRatchetSession.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WITH_WEBSOCKETS)
|
|
||||||
add_definitions(-DWITH_EVENTS)
|
|
||||||
find_package(websocketpp REQUIRED)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (WIN32 OR MSYS)
|
if (WIN32 OR MSYS)
|
||||||
list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp")
|
list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp")
|
||||||
endif ()
|
endif ()
|
||||||
@ -127,10 +121,6 @@ set (CLIENT_SRC
|
|||||||
"${LIBI2PD_CLIENT_SRC_DIR}/WebSocks.cpp"
|
"${LIBI2PD_CLIENT_SRC_DIR}/WebSocks.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WITH_WEBSOCKETS)
|
|
||||||
list (APPEND CLIENT_SRC "${LIBI2PD_CLIENT_SRC_DIR}/Websocket.cpp")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
add_library(libi2pdclient ${CLIENT_SRC})
|
add_library(libi2pdclient ${CLIENT_SRC})
|
||||||
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
|
set_target_properties(libi2pdclient PROPERTIES PREFIX "")
|
||||||
|
|
||||||
@ -427,7 +417,6 @@ message(STATUS " MESHNET : ${WITH_MESHNET}")
|
|||||||
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
||||||
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
|
message(STATUS " THREADSANITIZER : ${WITH_THREADSANITIZER}")
|
||||||
message(STATUS " I2LUA : ${WITH_I2LUA}")
|
message(STATUS " I2LUA : ${WITH_I2LUA}")
|
||||||
message(STATUS " WEBSOCKETS : ${WITH_WEBSOCKETS}")
|
|
||||||
message(STATUS "---------------------------------------")
|
message(STATUS "---------------------------------------")
|
||||||
|
|
||||||
#Handle paths nicely
|
#Handle paths nicely
|
||||||
|
@ -26,9 +26,6 @@
|
|||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#include "Event.h"
|
|
||||||
#include "Websocket.h"
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
@ -43,9 +40,6 @@ namespace i2p
|
|||||||
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
|
||||||
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
std::unique_ptr<i2p::transport::UPnP> UPnP;
|
||||||
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
|
std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
std::unique_ptr<i2p::event::WebsocketServer> m_WebsocketServer;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {}
|
Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {}
|
||||||
@ -273,6 +267,7 @@ namespace i2p
|
|||||||
if(!restricted)
|
if(!restricted)
|
||||||
LogPrint(eLogError, "Daemon: no trusted routers of families specififed");
|
LogPrint(eLogError, "Daemon: no trusted routers of families specififed");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidden; i2p::config::GetOption("trust.hidden", hidden);
|
bool hidden; i2p::config::GetOption("trust.hidden", hidden);
|
||||||
if (hidden)
|
if (hidden)
|
||||||
{
|
{
|
||||||
@ -344,26 +339,11 @@ namespace i2p
|
|||||||
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
|
d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
|
||||||
d.m_I2PControlService->Start ();
|
d.m_I2PControlService->Start ();
|
||||||
}
|
}
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
|
|
||||||
bool websocket; i2p::config::GetOption("websockets.enabled", websocket);
|
|
||||||
if(websocket) {
|
|
||||||
std::string websocketAddr; i2p::config::GetOption("websockets.address", websocketAddr);
|
|
||||||
uint16_t websocketPort; i2p::config::GetOption("websockets.port", websocketPort);
|
|
||||||
LogPrint(eLogInfo, "Daemon: starting Websocket server at ", websocketAddr, ":", websocketPort);
|
|
||||||
d.m_WebsocketServer = std::unique_ptr<i2p::event::WebsocketServer>(new i2p::event::WebsocketServer (websocketAddr, websocketPort));
|
|
||||||
d.m_WebsocketServer->Start();
|
|
||||||
i2p::event::core.SetListener(d.m_WebsocketServer->ToListener());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Daemon_Singleton::stop()
|
bool Daemon_Singleton::stop()
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
i2p::event::core.SetListener(nullptr);
|
|
||||||
#endif
|
|
||||||
LogPrint(eLogInfo, "Daemon: shutting down");
|
LogPrint(eLogInfo, "Daemon: shutting down");
|
||||||
LogPrint(eLogInfo, "Daemon: stopping Client");
|
LogPrint(eLogInfo, "Daemon: stopping Client");
|
||||||
i2p::client::context.Stop();
|
i2p::client::context.Stop();
|
||||||
@ -397,13 +377,6 @@ namespace i2p
|
|||||||
d.m_I2PControlService->Stop ();
|
d.m_I2PControlService->Stop ();
|
||||||
d.m_I2PControlService = nullptr;
|
d.m_I2PControlService = nullptr;
|
||||||
}
|
}
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
if (d.m_WebsocketServer) {
|
|
||||||
LogPrint(eLogInfo, "Daemon: stopping Websocket server");
|
|
||||||
d.m_WebsocketServer->Stop();
|
|
||||||
d.m_WebsocketServer = nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
i2p::crypto::TerminateCrypto ();
|
i2p::crypto::TerminateCrypto ();
|
||||||
i2p::log::Logger().Stop();
|
i2p::log::Logger().Stop();
|
||||||
|
|
||||||
|
@ -218,13 +218,6 @@ namespace config {
|
|||||||
("trust.hidden", value<bool>()->default_value(false), "Should we hide our router from other routers?")
|
("trust.hidden", value<bool>()->default_value(false), "Should we hide our router from other routers?")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description websocket("Websocket Options");
|
|
||||||
websocket.add_options()
|
|
||||||
("websockets.enabled", value<bool>()->default_value(false), "Enable websocket server")
|
|
||||||
("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")
|
|
||||||
;
|
|
||||||
|
|
||||||
options_description exploratory("Exploratory Options");
|
options_description exploratory("Exploratory Options");
|
||||||
exploratory.add_options()
|
exploratory.add_options()
|
||||||
("exploratory.inbound.length", value<int>()->default_value(2), "Exploratory inbound tunnel length")
|
("exploratory.inbound.length", value<int>()->default_value(2), "Exploratory inbound tunnel length")
|
||||||
@ -274,7 +267,6 @@ namespace config {
|
|||||||
.add(reseed)
|
.add(reseed)
|
||||||
.add(addressbook)
|
.add(addressbook)
|
||||||
.add(trust)
|
.add(trust)
|
||||||
.add(websocket)
|
|
||||||
.add(exploratory)
|
.add(exploratory)
|
||||||
.add(ntcp2)
|
.add(ntcp2)
|
||||||
.add(nettime)
|
.add(nettime)
|
||||||
|
@ -5,10 +5,6 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace event
|
namespace event
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EventCore core;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void EventCore::SetListener(EventListener * l)
|
void EventCore::SetListener(EventListener * l)
|
||||||
{
|
{
|
||||||
m_listener = l;
|
m_listener = l;
|
||||||
@ -44,18 +40,3 @@ namespace i2p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueIntEvent(const std::string & type, const std::string & ident, uint64_t val)
|
|
||||||
{
|
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
i2p::event::core.CollectEvent(type, ident, val);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitEvent(const EventType & e)
|
|
||||||
{
|
|
||||||
#if WITH_EVENTS
|
|
||||||
i2p::event::core.QueueEvent(e);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -41,13 +41,6 @@ namespace i2p
|
|||||||
std::map<std::string, CollectedEvent> m_collected;
|
std::map<std::string, CollectedEvent> m_collected;
|
||||||
EventListener * m_listener = nullptr;
|
EventListener * m_listener = nullptr;
|
||||||
};
|
};
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
extern EventCore core;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueIntEvent(const std::string & type, const std::string & ident, uint64_t val);
|
|
||||||
void EmitEvent(const EventType & ev);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,9 +14,6 @@
|
|||||||
#include "NTCPSession.h"
|
#include "NTCPSession.h"
|
||||||
#include "HTTP.h"
|
#include "HTTP.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
#include "Event.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace i2p::crypto;
|
using namespace i2p::crypto;
|
||||||
|
|
||||||
@ -649,9 +646,6 @@ namespace transport
|
|||||||
{
|
{
|
||||||
if (!m_NextMessage->IsExpired ())
|
if (!m_NextMessage->IsExpired ())
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
QueueIntEvent("transport.recvmsg", GetIdentHashBase64(), 1);
|
|
||||||
#endif
|
|
||||||
m_Handler.PutNextMessage (m_NextMessage);
|
m_Handler.PutNextMessage (m_NextMessage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5,9 +5,6 @@
|
|||||||
#include "NetDb.hpp"
|
#include "NetDb.hpp"
|
||||||
#include "SSU.h"
|
#include "SSU.h"
|
||||||
#include "SSUData.h"
|
#include "SSUData.h"
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
#include "Event.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@ -241,9 +238,6 @@ namespace transport
|
|||||||
m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch ();
|
m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (!msg->IsExpired ())
|
if (!msg->IsExpired ())
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
QueueIntEvent("transport.recvmsg", m_Session.GetIdentHashBase64(), 1);
|
|
||||||
#endif
|
|
||||||
m_Handler.PutNextMessage (msg);
|
m_Handler.PutNextMessage (msg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6,10 +6,6 @@
|
|||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "HTTP.h"
|
#include "HTTP.h"
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
#include "Event.h"
|
|
||||||
#include "util.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace i2p::data;
|
using namespace i2p::data;
|
||||||
|
|
||||||
@ -346,9 +342,6 @@ namespace transport
|
|||||||
|
|
||||||
void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector<std::shared_ptr<i2p::I2NPMessage> >& msgs)
|
void Transports::SendMessages (const i2p::data::IdentHash& ident, const std::vector<std::shared_ptr<i2p::I2NPMessage> >& msgs)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
QueueIntEvent("transport.send", ident.ToBase64(), msgs.size());
|
|
||||||
#endif
|
|
||||||
m_Service->post (std::bind (&Transports::PostMessages, this, ident, msgs));
|
m_Service->post (std::bind (&Transports::PostMessages, this, ident, msgs));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,9 +590,6 @@ namespace transport
|
|||||||
auto it = m_Peers.find (ident);
|
auto it = m_Peers.find (ident);
|
||||||
if (it != m_Peers.end ())
|
if (it != m_Peers.end ())
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitEvent({{"type" , "transport.connected"}, {"ident", ident.ToBase64()}, {"inbound", "false"}});
|
|
||||||
#endif
|
|
||||||
bool sendDatabaseStore = true;
|
bool sendDatabaseStore = true;
|
||||||
if (it->second.delayedMessages.size () > 0)
|
if (it->second.delayedMessages.size () > 0)
|
||||||
{
|
{
|
||||||
@ -625,9 +615,6 @@ namespace transport
|
|||||||
session->Done();
|
session->Done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitEvent({{"type" , "transport.connected"}, {"ident", ident.ToBase64()}, {"inbound", "true"}});
|
|
||||||
#endif
|
|
||||||
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
|
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
|
||||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||||
m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} }));
|
m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} }));
|
||||||
@ -642,9 +629,6 @@ namespace transport
|
|||||||
auto remoteIdentity = session->GetRemoteIdentity ();
|
auto remoteIdentity = session->GetRemoteIdentity ();
|
||||||
if (!remoteIdentity) return;
|
if (!remoteIdentity) return;
|
||||||
auto ident = remoteIdentity->GetIdentHash ();
|
auto ident = remoteIdentity->GetIdentHash ();
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitEvent({{"type" , "transport.disconnected"}, {"ident", ident.ToBase64()}});
|
|
||||||
#endif
|
|
||||||
auto it = m_Peers.find (ident);
|
auto it = m_Peers.find (ident);
|
||||||
if (it != m_Peers.end ())
|
if (it != m_Peers.end ())
|
||||||
{
|
{
|
||||||
|
@ -14,9 +14,6 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
#include "TunnelPool.h"
|
#include "TunnelPool.h"
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
#include "Event.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@ -35,9 +32,6 @@ namespace tunnel
|
|||||||
|
|
||||||
void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> outboundTunnel)
|
void Tunnel::Build (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> outboundTunnel)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
std::string peers = i2p::context.GetIdentity()->GetIdentHash().ToBase64();
|
|
||||||
#endif
|
|
||||||
auto numHops = m_Config->GetNumHops ();
|
auto numHops = m_Config->GetNumHops ();
|
||||||
int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops;
|
int numRecords = numHops <= STANDARD_NUM_RECORDS ? STANDARD_NUM_RECORDS : numHops;
|
||||||
auto msg = NewI2NPShortMessage ();
|
auto msg = NewI2NPShortMessage ();
|
||||||
@ -64,15 +58,9 @@ namespace tunnel
|
|||||||
hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx);
|
hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID, ctx);
|
||||||
hop->recordIndex = idx;
|
hop->recordIndex = idx;
|
||||||
i++;
|
i++;
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
peers += ":" + hop->ident->GetIdentHash().ToBase64();
|
|
||||||
#endif
|
|
||||||
hop = hop->next;
|
hop = hop->next;
|
||||||
}
|
}
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnel.build", this, peers);
|
|
||||||
#endif
|
|
||||||
// fill up fake records with random data
|
// fill up fake records with random data
|
||||||
for (int i = numHops; i < numRecords; i++)
|
for (int i = numHops; i < numRecords; i++)
|
||||||
{
|
{
|
||||||
@ -207,9 +195,6 @@ namespace tunnel
|
|||||||
void Tunnel::SetState(TunnelState state)
|
void Tunnel::SetState(TunnelState state)
|
||||||
{
|
{
|
||||||
m_State = state;
|
m_State = state;
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnel.state", this, state);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -614,9 +599,6 @@ namespace tunnel
|
|||||||
hop = hop->next;
|
hop = hop->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed);
|
|
||||||
#endif
|
|
||||||
// for i2lua
|
// for i2lua
|
||||||
if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout);
|
if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultTimeout);
|
||||||
// delete
|
// delete
|
||||||
@ -628,9 +610,6 @@ namespace tunnel
|
|||||||
break;
|
break;
|
||||||
case eTunnelStateBuildFailed:
|
case eTunnelStateBuildFailed:
|
||||||
LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted");
|
LogPrint (eLogDebug, "Tunnel: pending build request ", it->first, " failed, deleted");
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed);
|
|
||||||
#endif
|
|
||||||
// for i2lua
|
// for i2lua
|
||||||
if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected);
|
if(pool) pool->OnTunnelBuildResult(tunnel, eBuildResultRejected);
|
||||||
|
|
||||||
|
@ -25,43 +25,29 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename TunnelT>
|
template<typename TunnelT>
|
||||||
static void EmitTunnelEvent(const std::string & ev, const TunnelT & t)
|
static void EmitTunnelEvent(const std::string & ev, const TunnelT & t)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}});
|
|
||||||
#else
|
|
||||||
(void) ev;
|
(void) ev;
|
||||||
(void) t;
|
(void) t;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TunnelT, typename T>
|
template<typename TunnelT, typename T>
|
||||||
static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val)
|
static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const T & val)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", std::to_string(val)}, {"inbound", std::to_string(t->IsInbound())}});
|
|
||||||
#else
|
|
||||||
(void) ev;
|
(void) ev;
|
||||||
(void) t;
|
(void) t;
|
||||||
(void) val;
|
(void) val;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename TunnelT>
|
template<typename TunnelT>
|
||||||
static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val)
|
static void EmitTunnelEvent(const std::string & ev, TunnelT * t, const std::string & val)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitEvent({{"type", ev}, {"tid", std::to_string(t->GetTunnelID())}, {"value", val}, {"inbound", std::to_string(t->IsInbound())}});
|
|
||||||
#else
|
|
||||||
(void) ev;
|
(void) ev;
|
||||||
(void) t;
|
(void) t;
|
||||||
(void) val;
|
(void) val;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
|
const int TUNNEL_EXPIRATION_TIMEOUT = 660; // 11 minutes
|
||||||
const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
|
const int TUNNEL_EXPIRATION_THRESHOLD = 60; // 1 minute
|
||||||
const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes
|
const int TUNNEL_RECREATION_THRESHOLD = 90; // 1.5 minutes
|
||||||
|
@ -11,9 +11,6 @@
|
|||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
#include "TunnelPool.h"
|
#include "TunnelPool.h"
|
||||||
#include "Destination.h"
|
#include "Destination.h"
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
#include "Event.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@ -86,9 +83,6 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
if (!m_IsActive) return;
|
if (!m_IsActive) return;
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnels.created", createdTunnel);
|
|
||||||
#endif
|
|
||||||
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
||||||
m_InboundTunnels.insert (createdTunnel);
|
m_InboundTunnels.insert (createdTunnel);
|
||||||
}
|
}
|
||||||
@ -102,9 +96,6 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
if (expiredTunnel)
|
if (expiredTunnel)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnels.expired", expiredTunnel);
|
|
||||||
#endif
|
|
||||||
expiredTunnel->SetTunnelPool (nullptr);
|
expiredTunnel->SetTunnelPool (nullptr);
|
||||||
for (auto& it: m_Tests)
|
for (auto& it: m_Tests)
|
||||||
if (it.second.second == expiredTunnel) it.second.second = nullptr;
|
if (it.second.second == expiredTunnel) it.second.second = nullptr;
|
||||||
@ -118,9 +109,6 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
if (!m_IsActive) return;
|
if (!m_IsActive) return;
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnels.created", createdTunnel);
|
|
||||||
#endif
|
|
||||||
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
std::unique_lock<std::mutex> l(m_OutboundTunnelsMutex);
|
||||||
m_OutboundTunnels.insert (createdTunnel);
|
m_OutboundTunnels.insert (createdTunnel);
|
||||||
}
|
}
|
||||||
@ -133,9 +121,6 @@ namespace tunnel
|
|||||||
{
|
{
|
||||||
if (expiredTunnel)
|
if (expiredTunnel)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
EmitTunnelEvent("tunnels.expired", expiredTunnel);
|
|
||||||
#endif
|
|
||||||
expiredTunnel->SetTunnelPool (nullptr);
|
expiredTunnel->SetTunnelPool (nullptr);
|
||||||
for (auto& it: m_Tests)
|
for (auto& it: m_Tests)
|
||||||
if (it.second.first == expiredTunnel) it.second.first = nullptr;
|
if (it.second.first == expiredTunnel) it.second.first = nullptr;
|
||||||
|
@ -2,491 +2,6 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef WITH_EVENTS
|
|
||||||
#include "ClientContext.h"
|
|
||||||
#include "Identity.h"
|
|
||||||
#include "Destination.h"
|
|
||||||
#include "Streaming.h"
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include <websocketpp/config/asio_no_tls.hpp>
|
|
||||||
#include <websocketpp/server.hpp>
|
|
||||||
|
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
|
||||||
#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))
|
|
||||||
#if !GCC47_BOOST149
|
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace client
|
|
||||||
{
|
|
||||||
typedef websocketpp::server<websocketpp::config::asio> WebSocksServerImpl;
|
|
||||||
|
|
||||||
typedef std::function<void(std::shared_ptr<i2p::stream::Stream>)> StreamConnectFunc;
|
|
||||||
|
|
||||||
|
|
||||||
struct IWebSocksConn : public I2PServiceHandler
|
|
||||||
{
|
|
||||||
IWebSocksConn(I2PService * parent) : I2PServiceHandler(parent) {}
|
|
||||||
virtual void Close() = 0;
|
|
||||||
virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<IWebSocksConn> WebSocksConn_ptr;
|
|
||||||
|
|
||||||
WebSocksConn_ptr CreateWebSocksConn(const websocketpp::connection_hdl & conn, WebSocksImpl * parent);
|
|
||||||
|
|
||||||
class WebSocksImpl
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef std::mutex mutex_t;
|
|
||||||
typedef std::unique_lock<mutex_t> lock_t;
|
|
||||||
|
|
||||||
typedef std::shared_ptr<ClientDestination> Destination_t;
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef WebSocksServerImpl ServerImpl;
|
|
||||||
typedef ServerImpl::message_ptr MessagePtr;
|
|
||||||
|
|
||||||
WebSocksImpl(const std::string & addr, int port) :
|
|
||||||
Parent(nullptr),
|
|
||||||
m_Run(false),
|
|
||||||
m_Addr(addr),
|
|
||||||
m_Port(port),
|
|
||||||
m_Thread(nullptr)
|
|
||||||
{
|
|
||||||
m_Server.init_asio();
|
|
||||||
m_Server.set_open_handler(std::bind(&WebSocksImpl::ConnOpened, this, std::placeholders::_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitializeDestination(WebSocks * parent)
|
|
||||||
{
|
|
||||||
Parent = parent;
|
|
||||||
m_Dest = Parent->GetLocalDestination();
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerImpl::connection_ptr GetConn(const websocketpp::connection_hdl & conn)
|
|
||||||
{
|
|
||||||
return m_Server.get_con_from_hdl(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloseConn(const websocketpp::connection_hdl & conn)
|
|
||||||
{
|
|
||||||
auto c = GetConn(conn);
|
|
||||||
if(c) c->close(websocketpp::close::status::normal, "closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateStreamTo(const std::string & addr, int port, StreamConnectFunc complete)
|
|
||||||
{
|
|
||||||
auto & addressbook = i2p::client::context.GetAddressBook();
|
|
||||||
auto a = addressbook.GetAddress (addr);
|
|
||||||
if (a && a->IsIdentHash ())
|
|
||||||
{
|
|
||||||
// address found
|
|
||||||
m_Dest->CreateStream(complete, a->identHash, port);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// not found
|
|
||||||
complete(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnOpened(websocketpp::connection_hdl conn)
|
|
||||||
{
|
|
||||||
auto ptr = CreateWebSocksConn(conn, this);
|
|
||||||
Parent->AddHandler(ptr);
|
|
||||||
m_Conns.push_back(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
if(m_Run) return; // already started
|
|
||||||
m_Server.listen(boost::asio::ip::address::from_string(m_Addr), m_Port);
|
|
||||||
m_Server.start_accept();
|
|
||||||
m_Run = true;
|
|
||||||
m_Thread = new std::thread([&] (){
|
|
||||||
while(m_Run) {
|
|
||||||
try {
|
|
||||||
m_Server.run();
|
|
||||||
} catch( std::exception & ex) {
|
|
||||||
LogPrint(eLogError, "Websocks runtime exception: ", ex.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
m_Dest->Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop()
|
|
||||||
{
|
|
||||||
for(const auto & conn : m_Conns)
|
|
||||||
conn->Close();
|
|
||||||
|
|
||||||
m_Dest->Stop();
|
|
||||||
m_Run = false;
|
|
||||||
m_Server.stop();
|
|
||||||
if(m_Thread) {
|
|
||||||
m_Thread->join();
|
|
||||||
delete m_Thread;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
i2p::datagram::DatagramDestination * GetDatagramDest() const
|
|
||||||
{
|
|
||||||
auto dgram = m_Dest->GetDatagramDestination();
|
|
||||||
if(!dgram) dgram = m_Dest->CreateDatagramDestination();
|
|
||||||
return dgram;
|
|
||||||
}
|
|
||||||
|
|
||||||
WebSocks * Parent;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<WebSocksConn_ptr> m_Conns;
|
|
||||||
bool m_Run;
|
|
||||||
ServerImpl m_Server;
|
|
||||||
std::string m_Addr;
|
|
||||||
int m_Port;
|
|
||||||
std::thread * m_Thread;
|
|
||||||
Destination_t m_Dest;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WebSocksConn : public IWebSocksConn , public std::enable_shared_from_this<WebSocksConn>
|
|
||||||
{
|
|
||||||
enum ConnState
|
|
||||||
{
|
|
||||||
eWSCInitial,
|
|
||||||
eWSCTryConnect,
|
|
||||||
eWSCFailConnect,
|
|
||||||
eWSCOkayConnect,
|
|
||||||
eWSCDatagram,
|
|
||||||
eWSCClose,
|
|
||||||
eWSCEnd
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef WebSocksServerImpl ServerImpl;
|
|
||||||
typedef ServerImpl::message_ptr Message_t;
|
|
||||||
typedef websocketpp::connection_hdl ServerConn;
|
|
||||||
typedef std::shared_ptr<ClientDestination> Destination_t;
|
|
||||||
typedef std::shared_ptr<i2p::stream::StreamingDestination> StreamDest_t;
|
|
||||||
typedef std::shared_ptr<i2p::stream::Stream> Stream_t;
|
|
||||||
|
|
||||||
ServerConn m_Conn;
|
|
||||||
Stream_t m_Stream;
|
|
||||||
ConnState m_State;
|
|
||||||
WebSocksImpl * m_Parent;
|
|
||||||
std::string m_RemoteAddr;
|
|
||||||
int m_RemotePort;
|
|
||||||
uint8_t m_RecvBuf[2048];
|
|
||||||
bool m_IsDatagram;
|
|
||||||
i2p::datagram::DatagramDestination * m_Datagram;
|
|
||||||
|
|
||||||
WebSocksConn(const ServerConn & conn, WebSocksImpl * parent) :
|
|
||||||
IWebSocksConn(parent->Parent),
|
|
||||||
m_Conn(conn),
|
|
||||||
m_Stream(nullptr),
|
|
||||||
m_State(eWSCInitial),
|
|
||||||
m_Parent(parent),
|
|
||||||
m_IsDatagram(false),
|
|
||||||
m_Datagram(nullptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
~WebSocksConn()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleDatagram(const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
|
|
||||||
{
|
|
||||||
auto conn = m_Parent->GetConn(m_Conn);
|
|
||||||
if(conn)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << from.GetIdentHash().ToBase32();
|
|
||||||
ss << ".b32.i2p:";
|
|
||||||
ss << std::to_string(fromPort);
|
|
||||||
ss << "\n";
|
|
||||||
ss.write((char *)buf, len);
|
|
||||||
conn->send(ss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BeginDatagram()
|
|
||||||
{
|
|
||||||
m_Datagram = m_Parent->GetDatagramDest();
|
|
||||||
m_Datagram->SetReceiver(
|
|
||||||
std::bind(
|
|
||||||
&WebSocksConn::HandleDatagram,
|
|
||||||
this,
|
|
||||||
std::placeholders::_1,
|
|
||||||
std::placeholders::_2,
|
|
||||||
std::placeholders::_3,
|
|
||||||
std::placeholders::_4,
|
|
||||||
std::placeholders::_5), m_RemotePort);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnterState(ConnState state)
|
|
||||||
{
|
|
||||||
LogPrint(eLogDebug, "websocks: state ", m_State, " -> ", state);
|
|
||||||
switch(m_State)
|
|
||||||
{
|
|
||||||
case eWSCInitial:
|
|
||||||
if (state == eWSCClose) {
|
|
||||||
m_State = eWSCClose;
|
|
||||||
// connection was opened but never used
|
|
||||||
LogPrint(eLogInfo, "websocks: connection closed but never used");
|
|
||||||
Close();
|
|
||||||
return;
|
|
||||||
} else if (state == eWSCTryConnect) {
|
|
||||||
// we will try to connect
|
|
||||||
m_State = eWSCTryConnect;
|
|
||||||
m_Parent->CreateStreamTo(m_RemoteAddr, m_RemotePort, std::bind(&WebSocksConn::ConnectResult, this, std::placeholders::_1));
|
|
||||||
} else if (state == eWSCDatagram) {
|
|
||||||
if (m_RemotePort >= 0 && m_RemotePort <= 65535)
|
|
||||||
{
|
|
||||||
LogPrint(eLogDebug, "websocks: datagram mode initiated");
|
|
||||||
m_State = eWSCDatagram;
|
|
||||||
BeginDatagram();
|
|
||||||
SendResponse("");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SendResponse("invalid port");
|
|
||||||
} else {
|
|
||||||
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case eWSCTryConnect:
|
|
||||||
if(state == eWSCOkayConnect) {
|
|
||||||
// we connected okay
|
|
||||||
LogPrint(eLogDebug, "websocks: connected to ", m_RemoteAddr, ":", m_RemotePort);
|
|
||||||
SendResponse("");
|
|
||||||
m_State = eWSCOkayConnect;
|
|
||||||
} else if(state == eWSCFailConnect) {
|
|
||||||
// we did not connect okay
|
|
||||||
LogPrint(eLogDebug, "websocks: failed to connect to ", m_RemoteAddr, ":", m_RemotePort);
|
|
||||||
SendResponse("failed to connect");
|
|
||||||
m_State = eWSCFailConnect;
|
|
||||||
EnterState(eWSCInitial);
|
|
||||||
} else if(state == eWSCClose) {
|
|
||||||
// premature close
|
|
||||||
LogPrint(eLogWarning, "websocks: websocket connection closed prematurely");
|
|
||||||
m_State = eWSCClose;
|
|
||||||
} else {
|
|
||||||
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case eWSCFailConnect:
|
|
||||||
if (state == eWSCInitial) {
|
|
||||||
// reset to initial state so we can try connecting again
|
|
||||||
m_RemoteAddr = "";
|
|
||||||
m_RemotePort = 0;
|
|
||||||
LogPrint(eLogDebug, "websocks: reset websocket conn to initial state");
|
|
||||||
m_State = eWSCInitial;
|
|
||||||
} else if (state == eWSCClose) {
|
|
||||||
// we are going to close the connection
|
|
||||||
m_State = eWSCClose;
|
|
||||||
Close();
|
|
||||||
} else {
|
|
||||||
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case eWSCDatagram:
|
|
||||||
if(state != eWSCClose) {
|
|
||||||
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
|
||||||
}
|
|
||||||
m_State = eWSCClose;
|
|
||||||
Close();
|
|
||||||
return;
|
|
||||||
case eWSCOkayConnect:
|
|
||||||
if(state == eWSCClose) {
|
|
||||||
// graceful close
|
|
||||||
m_State = eWSCClose;
|
|
||||||
Close();
|
|
||||||
} else {
|
|
||||||
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case eWSCClose:
|
|
||||||
if(state == eWSCEnd) {
|
|
||||||
LogPrint(eLogDebug, "websocks: socket ended");
|
|
||||||
Kill();
|
|
||||||
auto me = shared_from_this();
|
|
||||||
Done(me);
|
|
||||||
} else {
|
|
||||||
LogPrint(eLogWarning, "websocks: invalid state change ", m_State, " -> ", state);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
LogPrint(eLogError, "websocks: bad state ", m_State);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartForwarding()
|
|
||||||
{
|
|
||||||
LogPrint(eLogDebug, "websocks: begin forwarding data");
|
|
||||||
uint8_t b[1];
|
|
||||||
m_Stream->Send(b, 0);
|
|
||||||
AsyncRecv();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleAsyncRecv(const boost::system::error_code &ec, std::size_t n)
|
|
||||||
{
|
|
||||||
if(ec) {
|
|
||||||
// error
|
|
||||||
LogPrint(eLogWarning, "websocks: connection error ", ec.message());
|
|
||||||
EnterState(eWSCClose);
|
|
||||||
} else {
|
|
||||||
// forward data
|
|
||||||
LogPrint(eLogDebug, "websocks recv ", n);
|
|
||||||
|
|
||||||
std::string str((char*)m_RecvBuf, n);
|
|
||||||
auto conn = m_Parent->GetConn(m_Conn);
|
|
||||||
if(!conn) {
|
|
||||||
LogPrint(eLogWarning, "websocks: connection is gone");
|
|
||||||
EnterState(eWSCClose);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
conn->send(str);
|
|
||||||
AsyncRecv();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AsyncRecv()
|
|
||||||
{
|
|
||||||
m_Stream->AsyncReceive(
|
|
||||||
boost::asio::buffer(m_RecvBuf, sizeof(m_RecvBuf)),
|
|
||||||
std::bind(&WebSocksConn::HandleAsyncRecv, this, std::placeholders::_1, std::placeholders::_2), 60);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @brief send error message or empty string for success */
|
|
||||||
void SendResponse(const std::string & errormsg)
|
|
||||||
{
|
|
||||||
boost::property_tree::ptree resp;
|
|
||||||
if(errormsg.size()) {
|
|
||||||
resp.put("error", errormsg);
|
|
||||||
resp.put("success", 0);
|
|
||||||
} else {
|
|
||||||
resp.put("success", 1);
|
|
||||||
}
|
|
||||||
std::ostringstream ss;
|
|
||||||
write_json(ss, resp);
|
|
||||||
auto conn = m_Parent->GetConn(m_Conn);
|
|
||||||
if(conn) conn->send(ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnectResult(Stream_t stream)
|
|
||||||
{
|
|
||||||
m_Stream = stream;
|
|
||||||
if(m_State == eWSCClose) {
|
|
||||||
// premature close of websocket
|
|
||||||
Close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(m_Stream) {
|
|
||||||
// connect good
|
|
||||||
EnterState(eWSCOkayConnect);
|
|
||||||
StartForwarding();
|
|
||||||
} else {
|
|
||||||
// connect failed
|
|
||||||
EnterState(eWSCFailConnect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void GotMessage(const websocketpp::connection_hdl & conn, WebSocksServerImpl::message_ptr msg)
|
|
||||||
{
|
|
||||||
(void) conn;
|
|
||||||
std::string payload = msg->get_payload();
|
|
||||||
if(m_State == eWSCOkayConnect)
|
|
||||||
{
|
|
||||||
// forward to server
|
|
||||||
LogPrint(eLogDebug, "websocks: forward ", payload.size());
|
|
||||||
m_Stream->Send((uint8_t*)payload.c_str(), payload.size());
|
|
||||||
} else if (m_State == eWSCInitial) {
|
|
||||||
// recv connect request
|
|
||||||
auto itr = payload.find(":");
|
|
||||||
if(itr == std::string::npos) {
|
|
||||||
// no port
|
|
||||||
m_RemotePort = 0;
|
|
||||||
m_RemoteAddr = payload;
|
|
||||||
} else {
|
|
||||||
// includes port
|
|
||||||
m_RemotePort = std::stoi(payload.substr(itr+1));
|
|
||||||
m_RemoteAddr = payload.substr(0, itr);
|
|
||||||
}
|
|
||||||
m_IsDatagram = m_RemoteAddr == "DATAGRAM";
|
|
||||||
if(m_IsDatagram)
|
|
||||||
EnterState(eWSCDatagram);
|
|
||||||
else
|
|
||||||
EnterState(eWSCTryConnect);
|
|
||||||
} else if (m_State == eWSCDatagram) {
|
|
||||||
// send datagram
|
|
||||||
// format is "host:port\npayload"
|
|
||||||
auto idx = payload.find("\n");
|
|
||||||
std::string line = payload.substr(0, idx);
|
|
||||||
auto itr = line.find(":");
|
|
||||||
auto & addressbook = i2p::client::context.GetAddressBook();
|
|
||||||
std::string addr;
|
|
||||||
int port = 0;
|
|
||||||
if (itr == std::string::npos)
|
|
||||||
{
|
|
||||||
addr = line;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addr = line.substr(0, itr);
|
|
||||||
port = std::atoi(line.substr(itr+1).c_str());
|
|
||||||
}
|
|
||||||
auto a = addressbook.GetAddress (addr);
|
|
||||||
if (a && a->IsIdentHash ())
|
|
||||||
{
|
|
||||||
const char * data = payload.c_str() + idx + 1;
|
|
||||||
size_t len = payload.size() - (1 + line.size());
|
|
||||||
m_Datagram->SendDatagramTo((const uint8_t*)data, len, a->identHash, m_RemotePort, port);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// wtf?
|
|
||||||
LogPrint(eLogWarning, "websocks: got message in invalid state ", m_State);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Close()
|
|
||||||
{
|
|
||||||
if(m_State == eWSCClose) {
|
|
||||||
LogPrint(eLogDebug, "websocks: closing connection");
|
|
||||||
if(m_Stream) m_Stream->Close();
|
|
||||||
if(m_Datagram) m_Datagram->ResetReceiver(m_RemotePort);
|
|
||||||
m_Parent->CloseConn(m_Conn);
|
|
||||||
EnterState(eWSCEnd);
|
|
||||||
} else {
|
|
||||||
EnterState(eWSCClose);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
WebSocksConn_ptr CreateWebSocksConn(const websocketpp::connection_hdl & conn, WebSocksImpl * parent)
|
|
||||||
{
|
|
||||||
auto ptr = std::make_shared<WebSocksConn>(conn, parent);
|
|
||||||
auto c = parent->GetConn(conn);
|
|
||||||
c->set_message_handler(std::bind(&WebSocksConn::GotMessage, ptr.get(), std::placeholders::_1, std::placeholders::_2));
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
// no websocket support
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace client
|
namespace client
|
||||||
@ -504,7 +19,7 @@ namespace client
|
|||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "WebSockets not enabled on compile time");
|
LogPrint(eLogInfo, "[Tunnels] starting websocks tunnel at %s:%d is rejected: WebSockets is deprecated", m_Addr, m_Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stop()
|
void Stop()
|
||||||
@ -527,7 +42,6 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace client
|
namespace client
|
||||||
|
@ -1,195 +0,0 @@
|
|||||||
#ifdef WITH_EVENTS
|
|
||||||
#include "Websocket.h"
|
|
||||||
#include "Log.h"
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include <websocketpp/config/asio_no_tls.hpp>
|
|
||||||
#include <websocketpp/server.hpp>
|
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
|
||||||
#define GCC47_BOOST149 ((BOOST_VERSION == 104900) && (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))
|
|
||||||
#if !GCC47_BOOST149
|
|
||||||
#include <boost/property_tree/json_parser.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace event
|
|
||||||
{
|
|
||||||
|
|
||||||
typedef websocketpp::server<websocketpp::config::asio> ServerImpl;
|
|
||||||
typedef websocketpp::connection_hdl ServerConn;
|
|
||||||
|
|
||||||
class WebsocketServerImpl : public EventListener
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef ServerImpl::message_ptr MessagePtr;
|
|
||||||
public:
|
|
||||||
|
|
||||||
WebsocketServerImpl(const std::string & addr, int port) :
|
|
||||||
m_run(false),
|
|
||||||
m_ws_thread(nullptr),
|
|
||||||
m_ev_thread(nullptr),
|
|
||||||
m_WebsocketTicker(m_Service)
|
|
||||||
{
|
|
||||||
m_server.init_asio();
|
|
||||||
m_server.set_open_handler(std::bind(&WebsocketServerImpl::ConnOpened, this, std::placeholders::_1));
|
|
||||||
m_server.set_close_handler(std::bind(&WebsocketServerImpl::ConnClosed, this, std::placeholders::_1));
|
|
||||||
m_server.set_message_handler(std::bind(&WebsocketServerImpl::OnConnMessage, this, std::placeholders::_1, std::placeholders::_2));
|
|
||||||
|
|
||||||
m_server.listen(boost::asio::ip::address::from_string(addr), port);
|
|
||||||
}
|
|
||||||
|
|
||||||
~WebsocketServerImpl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Start() {
|
|
||||||
m_run = true;
|
|
||||||
m_server.start_accept();
|
|
||||||
m_ws_thread = new std::thread([&] () {
|
|
||||||
while(m_run) {
|
|
||||||
try {
|
|
||||||
m_server.run();
|
|
||||||
} catch (std::exception & e ) {
|
|
||||||
LogPrint(eLogError, "Websocket server: ", e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
m_ev_thread = new std::thread([&] () {
|
|
||||||
while(m_run) {
|
|
||||||
try {
|
|
||||||
m_Service.run();
|
|
||||||
break;
|
|
||||||
} catch (std::exception & e ) {
|
|
||||||
LogPrint(eLogError, "Websocket service: ", e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ScheduleTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop() {
|
|
||||||
m_run = false;
|
|
||||||
m_Service.stop();
|
|
||||||
m_server.stop();
|
|
||||||
|
|
||||||
if(m_ev_thread) {
|
|
||||||
m_ev_thread->join();
|
|
||||||
delete m_ev_thread;
|
|
||||||
}
|
|
||||||
m_ev_thread = nullptr;
|
|
||||||
|
|
||||||
if(m_ws_thread) {
|
|
||||||
m_ws_thread->join();
|
|
||||||
delete m_ws_thread;
|
|
||||||
}
|
|
||||||
m_ws_thread = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnOpened(ServerConn c)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(m_connsMutex);
|
|
||||||
m_conns.insert(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConnClosed(ServerConn c)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(m_connsMutex);
|
|
||||||
m_conns.erase(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnConnMessage(ServerConn conn, ServerImpl::message_ptr msg)
|
|
||||||
{
|
|
||||||
(void) conn;
|
|
||||||
(void) msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleTick(const boost::system::error_code & ec)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(ec != boost::asio::error::operation_aborted)
|
|
||||||
LogPrint(eLogError, "Websocket ticker: ", ec.message());
|
|
||||||
// pump collected events to us
|
|
||||||
i2p::event::core.PumpCollected(this);
|
|
||||||
ScheduleTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScheduleTick()
|
|
||||||
{
|
|
||||||
LogPrint(eLogDebug, "Websocket schedule tick");
|
|
||||||
boost::posix_time::seconds dlt(1);
|
|
||||||
m_WebsocketTicker.expires_from_now(dlt);
|
|
||||||
m_WebsocketTicker.async_wait(std::bind(&WebsocketServerImpl::HandleTick, this, std::placeholders::_1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @brief called from m_ev_thread */
|
|
||||||
void HandlePumpEvent(const EventType & ev, const uint64_t & val)
|
|
||||||
{
|
|
||||||
EventType e;
|
|
||||||
for (const auto & i : ev)
|
|
||||||
e[i.first] = i.second;
|
|
||||||
|
|
||||||
e["number"] = std::to_string(val);
|
|
||||||
HandleEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @brief called from m_ws_thread */
|
|
||||||
void HandleEvent(const EventType & ev)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(m_connsMutex);
|
|
||||||
boost::property_tree::ptree event;
|
|
||||||
for (const auto & item : ev) {
|
|
||||||
event.put(item.first, item.second);
|
|
||||||
}
|
|
||||||
std::ostringstream ss;
|
|
||||||
write_json(ss, event);
|
|
||||||
std::string s = ss.str();
|
|
||||||
|
|
||||||
ConnList::iterator it;
|
|
||||||
for (it = m_conns.begin(); it != m_conns.end(); ++it) {
|
|
||||||
ServerImpl::connection_ptr con = m_server.get_con_from_hdl(*it);
|
|
||||||
con->send(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::set<ServerConn, std::owner_less<ServerConn> > ConnList;
|
|
||||||
bool m_run;
|
|
||||||
std::thread * m_ws_thread;
|
|
||||||
std::thread * m_ev_thread;
|
|
||||||
std::mutex m_connsMutex;
|
|
||||||
ConnList m_conns;
|
|
||||||
ServerImpl m_server;
|
|
||||||
boost::asio::io_service m_Service;
|
|
||||||
boost::asio::deadline_timer m_WebsocketTicker;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
WebsocketServer::WebsocketServer(const std::string & addr, int port) : m_impl(new WebsocketServerImpl(addr, port)) {}
|
|
||||||
WebsocketServer::~WebsocketServer()
|
|
||||||
{
|
|
||||||
delete m_impl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WebsocketServer::Start()
|
|
||||||
{
|
|
||||||
m_impl->Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebsocketServer::Stop()
|
|
||||||
{
|
|
||||||
m_impl->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
EventListener * WebsocketServer::ToListener()
|
|
||||||
{
|
|
||||||
return m_impl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,28 +0,0 @@
|
|||||||
#ifndef WEBSOCKET_H__
|
|
||||||
#define WEBSOCKET_H__
|
|
||||||
#include "Event.h"
|
|
||||||
namespace i2p
|
|
||||||
{
|
|
||||||
namespace event
|
|
||||||
{
|
|
||||||
|
|
||||||
class WebsocketServerImpl;
|
|
||||||
|
|
||||||
class WebsocketServer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WebsocketServer(const std::string & addr, int port);
|
|
||||||
~WebsocketServer();
|
|
||||||
|
|
||||||
void Start();
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
EventListener * ToListener();
|
|
||||||
|
|
||||||
private:
|
|
||||||
WebsocketServerImpl * m_impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -2135,121 +2135,6 @@ Comma separated list of base64 identities:</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="25" column="0">
|
|
||||||
<widget class="QGroupBox" name="groupBox_websock">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>105</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>16777215</width>
|
|
||||||
<height>105</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Websockets server</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QCheckBox" name="checkBoxWebsocketsEnable">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>20</y>
|
|
||||||
<width>85</width>
|
|
||||||
<height>21</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="horizontalLayoutWidget_32">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>40</y>
|
|
||||||
<width>661</width>
|
|
||||||
<height>31</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_38">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_40">
|
|
||||||
<property name="text">
|
|
||||||
<string>Address to bind websocket server on:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="lineEdit_webSock_addr"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_26">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="horizontalLayoutWidget_33">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>70</y>
|
|
||||||
<width>661</width>
|
|
||||||
<height>31</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_39">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_41">
|
|
||||||
<property name="text">
|
|
||||||
<string>Port to bind websocket server on:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="lineEdit_webSock_port">
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>80</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_27">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="11" column="0">
|
<item row="11" column="0">
|
||||||
<widget class="QGroupBox" name="webconsoleGroupBox">
|
<widget class="QGroupBox" name="webconsoleGroupBox">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
|
@ -74,7 +74,6 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
|
|||||||
../../libi2pd_client/MatchedDestination.cpp \
|
../../libi2pd_client/MatchedDestination.cpp \
|
||||||
../../libi2pd_client/SAM.cpp \
|
../../libi2pd_client/SAM.cpp \
|
||||||
../../libi2pd_client/SOCKS.cpp \
|
../../libi2pd_client/SOCKS.cpp \
|
||||||
../../libi2pd_client/Websocket.cpp \
|
|
||||||
../../libi2pd_client/WebSocks.cpp \
|
../../libi2pd_client/WebSocks.cpp \
|
||||||
../../daemon/Daemon.cpp \
|
../../daemon/Daemon.cpp \
|
||||||
../../daemon/HTTPServer.cpp \
|
../../daemon/HTTPServer.cpp \
|
||||||
@ -161,7 +160,6 @@ HEADERS += DaemonQT.h mainwindow.h \
|
|||||||
../../libi2pd_client/MatchedDestination.h \
|
../../libi2pd_client/MatchedDestination.h \
|
||||||
../../libi2pd_client/SAM.h \
|
../../libi2pd_client/SAM.h \
|
||||||
../../libi2pd_client/SOCKS.h \
|
../../libi2pd_client/SOCKS.h \
|
||||||
../../libi2pd_client/Websocket.h \
|
|
||||||
../../libi2pd_client/WebSocks.h \
|
../../libi2pd_client/WebSocks.h \
|
||||||
../../daemon/Daemon.h \
|
../../daemon/Daemon.h \
|
||||||
../../daemon/HTTPServer.h \
|
../../daemon/HTTPServer.h \
|
||||||
|
@ -258,10 +258,6 @@ MainWindow::MainWindow(std::shared_ptr<std::iostream> logStream_, QWidget *paren
|
|||||||
initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters);
|
initStringBox( OPTION("trust","routers",[]{return "";}), uiSettings->lineEditTrustRouters);
|
||||||
initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden);
|
initCheckBox( OPTION("trust","hidden",[]{return "false";}), uiSettings->checkBoxTrustHidden);
|
||||||
|
|
||||||
initCheckBox( OPTION("websockets","enabled",[]{return "false";}), uiSettings->checkBoxWebsocketsEnable);
|
|
||||||
initIPAddressBox( OPTION("websockets","address",[]{return "127.0.0.1";}), uiSettings->lineEdit_webSock_addr, tr("Websocket server -> IP address"));
|
|
||||||
initTCPPortBox( OPTION("websockets","port",[]{return "7666";}), uiSettings->lineEdit_webSock_port, tr("Websocket server -> Port"));
|
|
||||||
|
|
||||||
# undef OPTION
|
# undef OPTION
|
||||||
|
|
||||||
//widgetlocks.add(new widgetlock(widget,lockbtn));
|
//widgetlocks.add(new widgetlock(widget,lockbtn));
|
||||||
|
Loading…
Reference in New Issue
Block a user