mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-24 20:57:37 +01:00
commit
b6fc795941
28 changed files with 468 additions and 58 deletions
|
@ -179,6 +179,12 @@ namespace config {
|
||||||
("trust.routers", value<std::string>()->default_value(""), "Only Connect to these routers")
|
("trust.routers", value<std::string>()->default_value(""), "Only Connect to these routers")
|
||||||
("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");
|
||||||
|
|
||||||
m_OptionsDesc
|
m_OptionsDesc
|
||||||
.add(general)
|
.add(general)
|
||||||
.add(limits)
|
.add(limits)
|
||||||
|
@ -194,6 +200,7 @@ namespace config {
|
||||||
.add(reseed)
|
.add(reseed)
|
||||||
.add(addressbook)
|
.add(addressbook)
|
||||||
.add(trust)
|
.add(trust)
|
||||||
|
.add(websocket)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
36
Daemon.cpp
36
Daemon.cpp
|
@ -25,6 +25,9 @@
|
||||||
#include "UPnP.h"
|
#include "UPnP.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Websocket.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
|
@ -38,6 +41,9 @@ namespace i2p
|
||||||
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
std::unique_ptr<i2p::http::HTTPServer> httpServer;
|
||||||
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;
|
||||||
|
#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()) {}
|
||||||
|
@ -115,6 +121,9 @@ namespace i2p
|
||||||
|
|
||||||
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
|
||||||
i2p::crypto::InitCrypto (precomputation);
|
i2p::crypto::InitCrypto (precomputation);
|
||||||
|
|
||||||
|
int netID; i2p::config::GetOption("netid", netID);
|
||||||
|
i2p::context.SetNetID (netID);
|
||||||
i2p::context.Init ();
|
i2p::context.Init ();
|
||||||
|
|
||||||
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
bool ipv6; i2p::config::GetOption("ipv6", ipv6);
|
||||||
|
@ -138,9 +147,6 @@ namespace i2p
|
||||||
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
|
||||||
SetMaxNumTransitTunnels (transitTunnels);
|
SetMaxNumTransitTunnels (transitTunnels);
|
||||||
|
|
||||||
int netID; i2p::config::GetOption("netid", netID);
|
|
||||||
i2p::context.SetNetID (netID);
|
|
||||||
|
|
||||||
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
|
||||||
if (isFloodfill) {
|
if (isFloodfill) {
|
||||||
LogPrint(eLogInfo, "Daemon: router will be floodfill");
|
LogPrint(eLogInfo, "Daemon: router will be floodfill");
|
||||||
|
@ -290,12 +296,27 @@ 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();
|
||||||
|
@ -322,9 +343,16 @@ 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 ();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
Event.cpp
Normal file
32
Event.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
namespace i2p
|
||||||
|
{
|
||||||
|
namespace event
|
||||||
|
{
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
EventCore core;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void EventCore::SetListener(EventListener * l)
|
||||||
|
{
|
||||||
|
m_listener = l;
|
||||||
|
LogPrint(eLogInfo, "Event: listener set");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventCore::QueueEvent(const EventType & ev)
|
||||||
|
{
|
||||||
|
if(m_listener)
|
||||||
|
m_listener->HandleEvent(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitEvent(const EventType & e)
|
||||||
|
{
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
i2p::event::core.QueueEvent(e);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
37
Event.h
Normal file
37
Event.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef EVENT_H__
|
||||||
|
#define EVENT_H__
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
typedef std::map<std::string, std::string> EventType;
|
||||||
|
|
||||||
|
namespace i2p
|
||||||
|
{
|
||||||
|
namespace event
|
||||||
|
{
|
||||||
|
class EventListener {
|
||||||
|
public:
|
||||||
|
virtual ~EventListener() {};
|
||||||
|
virtual void HandleEvent(const EventType & ev) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EventCore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void QueueEvent(const EventType & ev);
|
||||||
|
void SetListener(EventListener * l);
|
||||||
|
|
||||||
|
private:
|
||||||
|
EventListener * m_listener = nullptr;
|
||||||
|
};
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
extern EventCore core;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void EmitEvent(const EventType & ev);
|
||||||
|
|
||||||
|
#endif
|
|
@ -547,7 +547,6 @@ namespace i2p
|
||||||
uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET];
|
uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET];
|
||||||
uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET);
|
uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET);
|
||||||
LogPrint (eLogDebug, "I2NP: msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
|
LogPrint (eLogDebug, "I2NP: msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID);
|
||||||
|
|
||||||
uint8_t * buf = msg + I2NP_HEADER_SIZE;
|
uint8_t * buf = msg + I2NP_HEADER_SIZE;
|
||||||
int size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET);
|
int size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET);
|
||||||
switch (typeID)
|
switch (typeID)
|
||||||
|
|
|
@ -238,8 +238,8 @@ namespace client
|
||||||
if (line == "\r") endOfHeader = true;
|
if (line == "\r") endOfHeader = true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (line.find ("Host:") != std::string::npos)
|
if (m_Host.length () > 0 && line.find ("Host:") != std::string::npos)
|
||||||
m_OutHeader << "Host: " << m_Host << "\r\n";
|
m_OutHeader << "Host: " << m_Host << "\r\n"; // override host
|
||||||
else
|
else
|
||||||
m_OutHeader << line << "\n";
|
m_OutHeader << line << "\n";
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ namespace client
|
||||||
int port, std::shared_ptr<ClientDestination> localDestination,
|
int port, std::shared_ptr<ClientDestination> localDestination,
|
||||||
const std::string& host, int inport, bool gzip):
|
const std::string& host, int inport, bool gzip):
|
||||||
I2PServerTunnel (name, address, port, localDestination, inport, gzip),
|
I2PServerTunnel (name, address, port, localDestination, inport, gzip),
|
||||||
m_Host (host.length () > 0 ? host : address)
|
m_Host (host)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
Log.h
2
Log.h
|
@ -158,7 +158,7 @@ namespace log {
|
||||||
|
|
||||||
Log & Logger();
|
Log & Logger();
|
||||||
} // log
|
} // log
|
||||||
} // i2p
|
}
|
||||||
|
|
||||||
/** internal usage only -- folding args array to single string */
|
/** internal usage only -- folding args array to single string */
|
||||||
template<typename TValue>
|
template<typename TValue>
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -14,6 +14,12 @@ USE_STATIC := no
|
||||||
USE_MESHNET := no
|
USE_MESHNET := no
|
||||||
USE_UPNP := no
|
USE_UPNP := no
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(WEBSOCKETS),1)
|
||||||
|
NEEDED_CXXFLAGS += -DWITH_EVENTS
|
||||||
|
DAEMON_SRC += Websocket.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(UNAME),Darwin)
|
ifeq ($(UNAME),Darwin)
|
||||||
DAEMON_SRC += DaemonLinux.cpp
|
DAEMON_SRC += DaemonLinux.cpp
|
||||||
ifeq ($(HOMEBREW),1)
|
ifeq ($(HOMEBREW),1)
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "NTCPSession.h"
|
#include "NTCPSession.h"
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
#include "Event.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace i2p::crypto;
|
using namespace i2p::crypto;
|
||||||
|
|
||||||
|
@ -604,7 +607,12 @@ namespace transport
|
||||||
if (!memcmp (m_NextMessage->buf + m_NextMessageOffset - 4, checksum, 4))
|
if (!memcmp (m_NextMessage->buf + m_NextMessageOffset - 4, checksum, 4))
|
||||||
{
|
{
|
||||||
if (!m_NextMessage->IsExpired ())
|
if (!m_NextMessage->IsExpired ())
|
||||||
|
{
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
EmitEvent({{"type", "transport.recvmsg"} , {"ident", GetIdentHashBase64()}, {"number", "1"}});
|
||||||
|
#endif
|
||||||
m_Handler.PutNextMessage (m_NextMessage);
|
m_Handler.PutNextMessage (m_NextMessage);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogInfo, "NTCP: message expired");
|
LogPrint (eLogInfo, "NTCP: message expired");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "SSU.h"
|
#include "SSU.h"
|
||||||
#include "SSUData.h"
|
#include "SSUData.h"
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
#include "Event.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -235,7 +238,12 @@ namespace transport
|
||||||
m_ReceivedMessages.insert (msgID);
|
m_ReceivedMessages.insert (msgID);
|
||||||
m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch ();
|
m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch ();
|
||||||
if (!msg->IsExpired ())
|
if (!msg->IsExpired ())
|
||||||
|
{
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
EmitEvent({{"type", "transport.recvmsg"} , {"ident", m_Session.GetIdentHashBase64()}, {"number", "1"}});
|
||||||
|
#endif
|
||||||
m_Handler.PutNextMessage (msg);
|
m_Handler.PutNextMessage (msg);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogDebug, "SSU: message expired");
|
LogPrint (eLogDebug, "SSU: message expired");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
|
#include "Log.h"
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
|
|
||||||
|
@ -8,7 +9,7 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
std::chrono::system_clock::duration g_TimeOffset = std::chrono::system_clock::duration::zero ();
|
static int64_t g_TimeOffset = 0; // in seconds
|
||||||
|
|
||||||
void SyncTimeWithNTP (const std::string& address)
|
void SyncTimeWithNTP (const std::string& address)
|
||||||
{
|
{
|
||||||
|
@ -23,25 +24,34 @@ namespace util
|
||||||
socket.open (boost::asio::ip::udp::v4 (), ec);
|
socket.open (boost::asio::ip::udp::v4 (), ec);
|
||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
uint8_t request[48];// 48 bytes NTP request
|
uint8_t buf[48];// 48 bytes NTP request/response
|
||||||
memset (request, 0, 48);
|
memset (buf, 0, 48);
|
||||||
request[0] = 0x80; // client mode, version 0
|
htobe32buf (buf, (3 << 27) | (3 << 24)); // RFC 4330
|
||||||
uint8_t * response = new uint8_t[1500]; // MTU
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
socket.send_to (boost::asio::buffer (request, 48), ep);
|
socket.send_to (boost::asio::buffer (buf, 48), ep);
|
||||||
len = socket.receive_from (boost::asio::buffer (response, 1500), ep);
|
int i = 0;
|
||||||
|
while (!socket.available() && i < 10) // 10 seconds max
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for (std::chrono::seconds(1));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (socket.available ())
|
||||||
|
len = socket.receive_from (boost::asio::buffer (buf, 48), ep);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
LogPrint (eLogError, "NTP error: ", e.what ());
|
||||||
}
|
}
|
||||||
if (len >= 8)
|
if (len >= 8)
|
||||||
{
|
{
|
||||||
uint32_t ts = bufbe32toh (response + 4);
|
auto ourTs = GetSecondsSinceEpoch ();
|
||||||
|
uint32_t ts = bufbe32toh (buf + 32);
|
||||||
if (ts > 2208988800U) ts -= 2208988800U; // 1/1/1970 from 1/1/1900
|
if (ts > 2208988800U) ts -= 2208988800U; // 1/1/1970 from 1/1/1900
|
||||||
|
g_TimeOffset = ts - ourTs;
|
||||||
|
LogPrint (eLogInfo, address, " time offset from system time is ", g_TimeOffset, " seconds");
|
||||||
}
|
}
|
||||||
delete[] response;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,6 @@ namespace i2p
|
||||||
{
|
{
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
extern std::chrono::system_clock::duration g_TimeOffset;
|
|
||||||
|
|
||||||
inline uint64_t GetMillisecondsSinceEpoch ()
|
inline uint64_t GetMillisecondsSinceEpoch ()
|
||||||
{
|
{
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
|
|
@ -65,6 +65,8 @@ namespace transport
|
||||||
virtual ~TransportSession () {};
|
virtual ~TransportSession () {};
|
||||||
virtual void Done () = 0;
|
virtual void Done () = 0;
|
||||||
|
|
||||||
|
std::string GetIdentHashBase64() const { return m_RemoteIdentity ? m_RemoteIdentity->GetIdentHash().ToBase64() : ""; }
|
||||||
|
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> GetRemoteIdentity () { return m_RemoteIdentity; };
|
std::shared_ptr<const i2p::data::IdentityEx> GetRemoteIdentity () { return m_RemoteIdentity; };
|
||||||
void SetRemoteIdentity (std::shared_ptr<const i2p::data::IdentityEx> ident) { m_RemoteIdentity = ident; };
|
void SetRemoteIdentity (std::shared_ptr<const i2p::data::IdentityEx> ident) { m_RemoteIdentity = ident; };
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
#include "Event.h"
|
||||||
|
#include "util.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace i2p::data;
|
using namespace i2p::data;
|
||||||
|
|
||||||
|
@ -230,6 +234,9 @@ 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
|
||||||
|
EmitEvent({{"type" , "transport.sendmsg"}, {"ident", ident.ToBase64()}, {"number", std::to_string(msgs.size())}});
|
||||||
|
#endif
|
||||||
m_Service.post (std::bind (&Transports::PostMessages, this, ident, msgs));
|
m_Service.post (std::bind (&Transports::PostMessages, this, ident, msgs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +514,6 @@ namespace transport
|
||||||
bool nat; i2p::config::GetOption("nat", nat);
|
bool nat; i2p::config::GetOption("nat", nat);
|
||||||
if (nat)
|
if (nat)
|
||||||
i2p::context.SetStatus (eRouterStatusTesting);
|
i2p::context.SetStatus (eRouterStatusTesting);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
auto router = i2p::data::netdb.GetRandomPeerTestRouter ();
|
auto router = i2p::data::netdb.GetRandomPeerTestRouter ();
|
||||||
|
@ -569,6 +575,9 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -594,6 +603,9 @@ 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 (), {} }));
|
||||||
|
@ -608,6 +620,9 @@ 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 ())
|
||||||
{
|
{
|
||||||
|
|
22
Tunnel.cpp
22
Tunnel.cpp
|
@ -11,6 +11,7 @@
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "NetDb.h"
|
#include "NetDb.h"
|
||||||
#include "Tunnel.h"
|
#include "Tunnel.h"
|
||||||
|
#include "TunnelPool.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
|
@ -29,12 +30,14 @@ 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 ();
|
||||||
*msg->GetPayload () = numRecords;
|
*msg->GetPayload () = numRecords;
|
||||||
msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1;
|
msg->len += numRecords*TUNNEL_BUILD_RECORD_SIZE + 1;
|
||||||
|
|
||||||
// shuffle records
|
// shuffle records
|
||||||
std::vector<int> recordIndicies;
|
std::vector<int> recordIndicies;
|
||||||
for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i);
|
for (int i = 0; i < numRecords; i++) recordIndicies.push_back(i);
|
||||||
|
@ -55,8 +58,14 @@ namespace tunnel
|
||||||
hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID);
|
hop->CreateBuildRequestRecord (records + idx*TUNNEL_BUILD_RECORD_SIZE, msgID);
|
||||||
hop->recordIndex = idx;
|
hop->recordIndex = idx;
|
||||||
i++;
|
i++;
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
peers += ":" + hop->ident->GetIdentHash().ToBase64();
|
||||||
|
#endif
|
||||||
hop = hop->next;
|
hop = hop->next;
|
||||||
}
|
}
|
||||||
|
#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++)
|
||||||
{
|
{
|
||||||
|
@ -182,6 +191,13 @@ namespace tunnel
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tunnel::SetState(TunnelState state)
|
||||||
|
{
|
||||||
|
m_State = state;
|
||||||
|
EmitTunnelEvent("tunnel.state", this, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Tunnel::PrintHops (std::stringstream& s) const
|
void Tunnel::PrintHops (std::stringstream& s) const
|
||||||
{
|
{
|
||||||
// hops are in inverted order, we must print in direct order
|
// hops are in inverted order, we must print in direct order
|
||||||
|
@ -582,6 +598,7 @@ namespace tunnel
|
||||||
hop = hop->next;
|
hop = hop->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed);
|
||||||
// delete
|
// delete
|
||||||
it = pendingTunnels.erase (it);
|
it = pendingTunnels.erase (it);
|
||||||
m_NumFailedTunnelCreations++;
|
m_NumFailedTunnelCreations++;
|
||||||
|
@ -591,6 +608,9 @@ 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");
|
||||||
|
|
||||||
|
EmitTunnelEvent("tunnel.state", tunnel.get(), eTunnelStateBuildFailed);
|
||||||
|
|
||||||
it = pendingTunnels.erase (it);
|
it = pendingTunnels.erase (it);
|
||||||
m_NumFailedTunnelCreations++;
|
m_NumFailedTunnelCreations++;
|
||||||
break;
|
break;
|
||||||
|
|
45
Tunnel.h
45
Tunnel.h
|
@ -19,11 +19,49 @@
|
||||||
#include "TunnelGateway.h"
|
#include "TunnelGateway.h"
|
||||||
#include "TunnelBase.h"
|
#include "TunnelBase.h"
|
||||||
#include "I2NPProtocol.h"
|
#include "I2NPProtocol.h"
|
||||||
|
#include "Event.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template<typename TunnelT>
|
||||||
|
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) t;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TunnelT, typename T>
|
||||||
|
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) t;
|
||||||
|
(void) val;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TunnelT>
|
||||||
|
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) t;
|
||||||
|
(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
|
||||||
|
@ -62,11 +100,12 @@ namespace tunnel
|
||||||
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetPeers () const;
|
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetPeers () const;
|
||||||
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetInvertedPeers () const;
|
std::vector<std::shared_ptr<const i2p::data::IdentityEx> > GetInvertedPeers () const;
|
||||||
TunnelState GetState () const { return m_State; };
|
TunnelState GetState () const { return m_State; };
|
||||||
void SetState (TunnelState state) { m_State = state; };
|
void SetState (TunnelState state);
|
||||||
bool IsEstablished () const { return m_State == eTunnelStateEstablished; };
|
bool IsEstablished () const { return m_State == eTunnelStateEstablished; };
|
||||||
bool IsFailed () const { return m_State == eTunnelStateFailed; };
|
bool IsFailed () const { return m_State == eTunnelStateFailed; };
|
||||||
bool IsRecreated () const { return m_IsRecreated; };
|
bool IsRecreated () const { return m_IsRecreated; };
|
||||||
void SetIsRecreated () { m_IsRecreated = true; };
|
void SetIsRecreated () { m_IsRecreated = true; };
|
||||||
|
virtual bool IsInbound() const = 0;
|
||||||
|
|
||||||
std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
|
std::shared_ptr<TunnelPool> GetTunnelPool () const { return m_Pool; };
|
||||||
void SetTunnelPool (std::shared_ptr<TunnelPool> pool) { m_Pool = pool; };
|
void SetTunnelPool (std::shared_ptr<TunnelPool> pool) { m_Pool = pool; };
|
||||||
|
@ -108,6 +147,8 @@ namespace tunnel
|
||||||
// implements TunnelBase
|
// implements TunnelBase
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg);
|
void HandleTunnelDataMsg (std::shared_ptr<const i2p::I2NPMessage> tunnelMsg);
|
||||||
|
|
||||||
|
bool IsInbound() const { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::mutex m_SendMutex;
|
std::mutex m_SendMutex;
|
||||||
|
@ -123,7 +164,7 @@ namespace tunnel
|
||||||
void HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg);
|
void HandleTunnelDataMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); };
|
||||||
void Print (std::stringstream& s) const;
|
void Print (std::stringstream& s) const;
|
||||||
|
bool IsInbound() const { return true; }
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TunnelEndpoint m_Endpoint;
|
TunnelEndpoint m_Endpoint;
|
||||||
|
|
|
@ -7,12 +7,18 @@
|
||||||
#include "Garlic.h"
|
#include "Garlic.h"
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Tunnel.h"
|
||||||
#include "TunnelPool.h"
|
#include "TunnelPool.h"
|
||||||
|
#include "Destination.h"
|
||||||
|
#ifdef WITH_EVENTS
|
||||||
|
#include "Event.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace tunnel
|
namespace tunnel
|
||||||
{
|
{
|
||||||
|
|
||||||
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
|
TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, int numOutboundTunnels):
|
||||||
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
|
||||||
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true),
|
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_IsActive (true),
|
||||||
|
@ -67,6 +73,9 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -78,6 +87,9 @@ 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;
|
||||||
|
@ -91,6 +103,9 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -101,6 +116,9 @@ 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;
|
||||||
|
|
137
Websocket.cpp
Normal file
137
Websocket.cpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
#include "Websocket.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#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_thread(nullptr)
|
||||||
|
{
|
||||||
|
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_thread = new std::thread([&] () {
|
||||||
|
while(m_run) {
|
||||||
|
try {
|
||||||
|
m_server.run();
|
||||||
|
} catch (std::exception & e ) {
|
||||||
|
LogPrint(eLogError, "Websocket server: ", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop() {
|
||||||
|
m_run = false;
|
||||||
|
m_server.stop();
|
||||||
|
if(m_thread) {
|
||||||
|
m_thread->join();
|
||||||
|
delete m_thread;
|
||||||
|
}
|
||||||
|
m_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 HandleEvent(const EventType & ev)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_connsMutex);
|
||||||
|
LogPrint(eLogDebug, "websocket event");
|
||||||
|
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_thread;
|
||||||
|
std::mutex m_connsMutex;
|
||||||
|
ConnList m_conns;
|
||||||
|
ServerImpl m_server;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
Websocket.h
Normal file
28
Websocket.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#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
|
|
@ -58,6 +58,7 @@ LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp \
|
||||||
../../TunnelGateway.cpp \
|
../../TunnelGateway.cpp \
|
||||||
../../TunnelPool.cpp \
|
../../TunnelPool.cpp \
|
||||||
../../Timestamp.cpp \
|
../../Timestamp.cpp \
|
||||||
|
../../Event.cpp \
|
||||||
../../util.cpp \
|
../../util.cpp \
|
||||||
../../i2pd.cpp ../../UPnP.cpp
|
../../i2pd.cpp ../../UPnP.cpp
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ 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" )
|
||||||
|
@ -59,8 +60,14 @@ set (LIBI2PD_SRC
|
||||||
"${CMAKE_SOURCE_DIR}/Signature.cpp"
|
"${CMAKE_SOURCE_DIR}/Signature.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/Timestamp.cpp"
|
"${CMAKE_SOURCE_DIR}/Timestamp.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/api.cpp"
|
"${CMAKE_SOURCE_DIR}/api.cpp"
|
||||||
|
"${CMAKE_SOURCE_DIR}/Event.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (WITH_WEBSOCKETS)
|
||||||
|
add_definitions(-DWITH_EVENTS)
|
||||||
|
find_package(websocketpp REQUIRED)
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR MSYS)
|
||||||
list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp")
|
list (APPEND LIBI2PD_SRC "${CMAKE_SOURCE_DIR}/I2PEndian.cpp")
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -92,6 +99,9 @@ set (CLIENT_SRC
|
||||||
"${CMAKE_SOURCE_DIR}/I2CP.cpp"
|
"${CMAKE_SOURCE_DIR}/I2CP.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WITH_WEBSOCKETS)
|
||||||
|
list (APPEND CLIENT_SRC "${CMAKE_SOURCE_DIR}/Websocket.cpp")
|
||||||
|
endif ()
|
||||||
add_library(i2pdclient ${CLIENT_SRC})
|
add_library(i2pdclient ${CLIENT_SRC})
|
||||||
|
|
||||||
set (DAEMON_SRC
|
set (DAEMON_SRC
|
||||||
|
@ -367,6 +377,7 @@ message(STATUS " MESHNET : ${WITH_MESHNET}")
|
||||||
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
message(STATUS " ADDRSANITIZER : ${WITH_ADDRSANITIZER}")
|
||||||
message(STATUS " THEADSANITIZER : ${WITH_THREADSANITIZER}")
|
message(STATUS " THEADSANITIZER : ${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
|
||||||
|
|
|
@ -12,3 +12,4 @@ Optional tools:
|
||||||
|
|
||||||
* cmake >= 2.8 (or 3.3+ if you want to use precompiled headers on windows)
|
* cmake >= 2.8 (or 3.3+ if you want to use precompiled headers on windows)
|
||||||
* miniupnp library (for upnp support)
|
* miniupnp library (for upnp support)
|
||||||
|
* [websocketpp](https://github.com/zaphoyd/websocketpp/) (for websocket ui)
|
||||||
|
|
|
@ -46,6 +46,9 @@ Available CMake options(each option has a form of `<key>=<value>`, for more info
|
||||||
* `WITH_AESNI` build with AES-NI support (ON/OFF)
|
* `WITH_AESNI` build with AES-NI support (ON/OFF)
|
||||||
* `WITH_HARDENING` enable hardening features (ON/OFF) (gcc only)
|
* `WITH_HARDENING` enable hardening features (ON/OFF) (gcc only)
|
||||||
* `WITH_PCH` use pre-compiled header (experimental, speeds up build)
|
* `WITH_PCH` use pre-compiled header (experimental, speeds up build)
|
||||||
|
* `WITH_I2LUA` used when building i2lua
|
||||||
|
* `WITH_WEBSOCKETS` enable websocket server
|
||||||
|
|
||||||
|
|
||||||
Also there is `-L` flag for CMake that could be used to list current cached options:
|
Also there is `-L` flag for CMake that could be used to list current cached options:
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ LIB_SRC = \
|
||||||
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
SSUSession.cpp SSUData.cpp Streaming.cpp Identity.cpp TransitTunnel.cpp \
|
||||||
Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \
|
Transports.cpp Tunnel.cpp TunnelEndpoint.cpp TunnelPool.cpp TunnelGateway.cpp \
|
||||||
Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \
|
Destination.cpp Base.cpp I2PEndian.cpp FS.cpp Config.cpp Family.cpp \
|
||||||
Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp
|
Config.cpp HTTP.cpp Timestamp.cpp util.cpp api.cpp Event.cpp
|
||||||
|
|
||||||
LIB_CLIENT_SRC = \
|
LIB_CLIENT_SRC = \
|
||||||
AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \
|
AddressBook.cpp BOB.cpp ClientContext.cpp I2PTunnel.cpp I2PService.cpp \
|
||||||
|
|
|
@ -36,7 +36,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \
|
||||||
../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
|
../../SSUData.cpp ../../SSUSession.cpp ../../Streaming.cpp ../../TransitTunnel.cpp \
|
||||||
../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
|
../../Transports.cpp ../../Tunnel.cpp ../../TunnelEndpoint.cpp ../../TunnelGateway.cpp \
|
||||||
../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \
|
../../TunnelPool.cpp ../../UPnP.cpp ../../Gzip.cpp ../../Timestamp.cpp ../../util.cpp \
|
||||||
../../i2pd.cpp
|
../../Event.cpp ../../i2pd.cpp
|
||||||
|
|
||||||
HEADERS += DaemonQT.h mainwindow.h \
|
HEADERS += DaemonQT.h mainwindow.h \
|
||||||
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
|
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
|
||||||
|
@ -50,7 +50,7 @@ HEADERS += DaemonQT.h mainwindow.h \
|
||||||
../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \
|
../../Streaming.h ../../Timestamp.h ../../TransitTunnel.h ../../Transports.h \
|
||||||
../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \
|
../../TransportSession.h ../../Tunnel.h ../../TunnelBase.h ../../TunnelConfig.h \
|
||||||
../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \
|
../../TunnelEndpoint.h ../../TunnelGateway.h ../../TunnelPool.h ../../UPnP.h \
|
||||||
../../util.h ../../version.h ../../Gzip.h ../../Tag.h
|
../../util.h ../../version.h ../../Gzip.h ../../Tag.h ../../Event.h
|
||||||
|
|
||||||
FORMS += mainwindow.ui
|
FORMS += mainwindow.ui
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue