From ea8190feece234693b3a3bd4ffb61756a8ee00ae Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 3 Apr 2017 16:12:52 -0400 Subject: [PATCH] built-in I2P --- src/net.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/net.h | 19 ++++++++++++++++-- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 158c7cd..0cc6a9c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -10,6 +10,7 @@ #include "ui_interface.h" #include "script.h" #include "irc.h" +#include "Log.h" #include "i2p.h" #ifdef WIN32 @@ -689,6 +690,36 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) return true; } +void CNode::I2PStreamReceive () +{ + if (i2pStream) + { + auto buf = std::make_shared(); + i2pStream->AsyncReceive (boost::asio::buffer (*buf), + std::bind (&CNode::HandleI2PStreamReceive, this, + std::placeholders::_1, std::placeholders::_2, buf), 600); // idle time is 10 minutes + } +} + +void CNode::HandleI2PStreamReceive (const boost::system::error_code& ecode, size_t bytes_transferred, std::shared_ptr buf) +{ + LOCK(cs_vRecvMsg); + if (ecode) + { + LogPrint (eLogInfo, "I2P stream receive error: ", ecode.message ()); + CloseSocketDisconnect(); + } + else + { + if (!ReceiveMsgBytes((const char *)buf->data (), bytes_transferred)) + CloseSocketDisconnect(); + nLastRecv = GetTime(); + nRecvBytes += bytes_transferred; + } + if (!fDisconnect) + I2PStreamReceive (); +} + void AddIncomingConnection(SOCKET hSocket, const CAddress& addr) { int nInbound = 0; @@ -732,6 +763,30 @@ void AddIncomingConnection(SOCKET hSocket, const CAddress& addr) } } +void AddIncomingI2PStream (std::shared_ptr stream) +{ + if (!stream) return; + CAddress addr; + addr.SetSpecial (stream->GetRemoteIdentity ()->ToBase64 ()); + int nInbound = 0; + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->fInbound) + nInbound++; + } + printf("accepted connection %s\n", addr.ToString().c_str()); + CNode* pnode = new CNode(INVALID_SOCKET, addr, "", true); + pnode->SetI2PStream (stream); + pnode->I2PStreamReceive (); + pnode->AddRef(); + { + LOCK(cs_vNodes); + vNodes.push_back(pnode); + } +} + + int CNetMessage::readHeader(const char *pch, unsigned int nBytes) { // copy data to temporary parsing buffer diff --git a/src/net.h b/src/net.h index 8966c3c..d8fd273 100644 --- a/src/net.h +++ b/src/net.h @@ -21,6 +21,7 @@ #include "addrman.h" #include "hash.h" #include "bloom.h" +#include "api.h" // i2pd class CNode; class CBlockIndex; @@ -50,6 +51,7 @@ bool BindListenNativeI2P(SOCKET& hSocket); bool IsI2POnly(); bool IsI2PEnabled(); +void AddIncomingI2PStream (std::shared_ptr stream); enum { @@ -155,8 +157,8 @@ public: }; - - +const size_t I2P_CNODE_BUFFER_SIZE = 0x10000; // 64k +typedef std::array I2PCNodeBuffer; /** Information about a peer */ class CNode @@ -165,6 +167,8 @@ public: // socket uint64 nServices; SOCKET hSocket; + std::shared_ptr i2pStream; // non-null means built-in I2P + CDataStream ssSend; size_t nSendSize; // total size of all vSendMsg entries size_t nSendOffset; // offset inside the first vSendMsg already sent @@ -291,6 +295,14 @@ private: int nSendStreamType; int nRecvStreamType; public: + + void SetI2PStream (std::shared_ptr s) + { + i2pStream = s; + if (i2pStream && !fInbound) + PushVersion(); + } + void SetSendStreamType(int nType) { nSendStreamType = nType; @@ -668,6 +680,9 @@ public: static bool IsBanned(CNetAddr ip); bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot void copyStats(CNodeStats &stats); + + void I2PStreamReceive (); + void HandleI2PStreamReceive (const boost::system::error_code& ecode, size_t bytes_transferred, std::shared_ptr buf); };