From b4e9ed7d18f076ed090ffb8912f6346e29c04285 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 20 Oct 2016 09:12:15 -0400 Subject: [PATCH 1/8] add web socket ui --- ClientContext.cpp | 2 +- ClientContext.h | 2 +- Config.cpp | 15 ++++- Daemon.cpp | 25 +++++++- Event.cpp | 28 +++++++++ Event.h | 37 ++++++++++++ I2NPProtocol.cpp | 1 - Log.h | 4 +- NTCPSession.cpp | 4 ++ SSUData.cpp | 8 +++ TransportSession.h | 4 +- Transports.cpp | 15 ++++- Websocket.cpp | 136 +++++++++++++++++++++++++++++++++++++++++++ Websocket.h | 30 ++++++++++ build/CMakeLists.txt | 20 +++++++ 15 files changed, 322 insertions(+), 9 deletions(-) create mode 100644 Event.cpp create mode 100644 Event.h create mode 100644 Websocket.cpp create mode 100644 Websocket.h diff --git a/ClientContext.cpp b/ClientContext.cpp index b7300ad2..215768c2 100644 --- a/ClientContext.cpp +++ b/ClientContext.cpp @@ -290,7 +290,7 @@ namespace client } return infos; } - + std::shared_ptr ClientContext::CreateNewLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType, const std::map * params) { diff --git a/ClientContext.h b/ClientContext.h index d82058c6..356f28c4 100644 --- a/ClientContext.h +++ b/ClientContext.h @@ -68,7 +68,7 @@ namespace client const SAMBridge * GetSAMBridge () const { return m_SamBridge; }; std::vector > GetForwardInfosFor(const i2p::data::IdentHash & destination); - + private: void ReadTunnels (); diff --git a/Config.cpp b/Config.cpp index 4750a9e3..99f4b0bb 100644 --- a/Config.cpp +++ b/Config.cpp @@ -176,9 +176,21 @@ namespace config { trust.add_options() ("trust.enabled", value()->default_value(false), "Enable explicit trust options") ("trust.family", value()->default_value(""), "Router Familiy to trust for first hops") +<<<<<<< HEAD ("trust.routers", value()->default_value(""), "Only Connect to these routers") ("trust.hidden", value()->default_value(false), "Should we hide our router from other routers?"); +======= + ("trust.routerInfo", value()->default_value(""), "Path to routerInfo of floodfill to use with floodfill friend mode") + ("trust.hidden", value()->default_value(true), "should we hide our router from other routers?"); + + options_description websocket("Websocket Options"); + websocket.add_options() + ("websockets.enabled", value()->default_value(false), "enable websocket server") + ("websockets.address", value()->default_value("127.0.0.1"), "address to bind websocket server on") + ("websockets.port", value()->default_value(7666), "port to bind websocket server on"); + +>>>>>>> bda4170... add web socket ui m_OptionsDesc .add(general) .add(limits) @@ -193,7 +205,8 @@ namespace config { .add(precomputation) .add(reseed) .add(addressbook) - .add(trust) + .add(trust) + .add(websocket) ; } diff --git a/Daemon.cpp b/Daemon.cpp index ce2f4173..d8b501a3 100644 --- a/Daemon.cpp +++ b/Daemon.cpp @@ -25,6 +25,9 @@ #include "UPnP.h" #include "util.h" +#include "Event.h" +#include "Websocket.h" + namespace i2p { namespace util @@ -38,6 +41,7 @@ namespace i2p std::unique_ptr httpServer; std::unique_ptr m_I2PControlService; std::unique_ptr UPnP; + std::unique_ptr m_WebsocketServer; }; Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {} @@ -291,11 +295,23 @@ namespace i2p d.m_I2PControlService->Start (); } + 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(new i2p::event::WebsocketServer (websocketAddr, websocketPort)); + d.m_WebsocketServer->Start(); + i2p::event::core.SetListener(d.m_WebsocketServer->ToListener()); + } + + return true; } bool Daemon_Singleton::stop() { + i2p::event::core.SetListener(nullptr); LogPrint(eLogInfo, "Daemon: shutting down"); LogPrint(eLogInfo, "Daemon: stopping Client"); i2p::client::context.Stop(); @@ -321,7 +337,14 @@ namespace i2p LogPrint(eLogInfo, "Daemon: stopping I2PControl"); d.m_I2PControlService->Stop (); d.m_I2PControlService = nullptr; - } + } + + if (d.m_WebsocketServer) { + LogPrint(eLogInfo, "Daemon: stopping Websocket server"); + d.m_WebsocketServer->Stop(); + d.m_WebsocketServer = nullptr; + } + i2p::crypto::TerminateCrypto (); return true; diff --git a/Event.cpp b/Event.cpp new file mode 100644 index 00000000..45e4e09c --- /dev/null +++ b/Event.cpp @@ -0,0 +1,28 @@ +#include "Event.h" +#include "Log.h" + +namespace i2p +{ + namespace event + { + EventCore core; + + 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) +{ + i2p::event::core.QueueEvent(e); +} + diff --git a/Event.h b/Event.h new file mode 100644 index 00000000..e9830289 --- /dev/null +++ b/Event.h @@ -0,0 +1,37 @@ +#ifndef EVENT_H__ +#define EVENT_H__ +#include +#include +#include + +#include + +typedef std::map 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; + }; + + extern EventCore core; + } +} + +void EmitEvent(const EventType & ev); + +#endif diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index cdc4fb9b..96b30cb6 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -547,7 +547,6 @@ namespace i2p uint8_t typeID = msg[I2NP_HEADER_TYPEID_OFFSET]; uint32_t msgID = bufbe32toh (msg + I2NP_HEADER_MSGID_OFFSET); LogPrint (eLogDebug, "I2NP: msg received len=", len,", type=", (int)typeID, ", msgID=", (unsigned int)msgID); - uint8_t * buf = msg + I2NP_HEADER_SIZE; int size = bufbe16toh (msg + I2NP_HEADER_SIZE_OFFSET); switch (typeID) diff --git a/Log.h b/Log.h index 79bbeb3f..b4eb70cd 100644 --- a/Log.h +++ b/Log.h @@ -152,13 +152,13 @@ namespace log { std::string text; /**< message text as single string */ LogLevel level; /**< message level */ std::thread::id tid; /**< id of thread that generated message */ - + LogMsg (LogLevel lvl, std::time_t ts, const std::string & txt): timestamp(ts), text(txt), level(lvl) {}; }; Log & Logger(); } // log -} // i2p +} /** internal usage only -- folding args array to single string */ template diff --git a/NTCPSession.cpp b/NTCPSession.cpp index 20dc9ab0..876b8a4c 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -11,6 +11,7 @@ #include "Transports.h" #include "NetDb.h" #include "NTCPSession.h" +#include "Event.h" using namespace i2p::crypto; @@ -604,7 +605,10 @@ namespace transport if (!memcmp (m_NextMessage->buf + m_NextMessageOffset - 4, checksum, 4)) { if (!m_NextMessage->IsExpired ()) + { + EmitEvent({{"type", "transport.recvmsg"} , {"ident", GetIdentHashBase64()}, {"number", "1"}}); m_Handler.PutNextMessage (m_NextMessage); + } else LogPrint (eLogInfo, "NTCP: message expired"); } diff --git a/SSUData.cpp b/SSUData.cpp index e5abfd54..a1e18c0b 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -5,6 +5,7 @@ #include "NetDb.h" #include "SSU.h" #include "SSUData.h" +#include "Event.h" namespace i2p { @@ -233,9 +234,16 @@ namespace transport if (!m_ReceivedMessages.count (msgID)) { m_ReceivedMessages.insert (msgID); +<<<<<<< HEAD m_LastMessageReceivedTime = i2p::util::GetSecondsSinceEpoch (); if (!msg->IsExpired ()) +======= + m_LastMessageReceivedTime = i2p::util::GetSinceEpoch