diff --git a/LeaseSet.cpp b/LeaseSet.cpp index 7d429057..7cdbcb5e 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -1,6 +1,5 @@ #include #include "Log.h" -#include "RouterInfo.h" #include "LeaseSet.h" namespace i2p @@ -12,7 +11,7 @@ namespace data #pragma pack(1) struct H { - RouterIdentity destination; + Identity destination; uint8_t encryptionKey[256]; uint8_t signingKey[128]; uint8_t num; @@ -20,7 +19,7 @@ namespace data #pragma pack () const H * header = (const H *)buf; - CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&header->destination, sizeof (RouterIdentity)); + CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&header->destination, sizeof (Identity)); memcpy (m_EncryptionKey, header->encryptionKey, 256); LogPrint ("LeaseSet num=", (int)header->num); diff --git a/LeaseSet.h b/LeaseSet.h index d03aa61f..6906c23e 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -11,12 +11,21 @@ namespace data { #pragma pack(1) + + struct Identity + { + uint8_t publicKey[256]; + uint8_t signingKey[128]; + uint8_t certificate[3]; + }; + struct Lease { uint8_t tunnelGateway[32]; uint32_t tunnelID; uint64_t endDate; }; + #pragma pack() class IdentHash diff --git a/NTCPSession.h b/NTCPSession.h index 1fa9fd6d..4ef0e3dd 100644 --- a/NTCPSession.h +++ b/NTCPSession.h @@ -37,7 +37,7 @@ namespace ntcp struct NTCPPhase3 { uint16_t size; - i2p::data::RouterIdentity ident; + i2p::data::Identity ident; uint32_t timestamp; uint8_t padding[15]; uint8_t signature[40]; diff --git a/RouterContext.cpp b/RouterContext.cpp index 6adc0154..43f2c387 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -26,7 +26,7 @@ namespace i2p void RouterContext::CreateNewRouter () { - i2p::data::RouterIdentity ident; + i2p::data::Identity ident; CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); dh.GenerateKeyPair(m_Rnd, m_PrivateKey, ident.publicKey); diff --git a/RouterContext.h b/RouterContext.h index 75e913a2..f3780b4b 100644 --- a/RouterContext.h +++ b/RouterContext.h @@ -22,7 +22,7 @@ namespace i2p const uint8_t * GetSigningPrivateKey () const; const uint8_t * GetLeaseSetPrivateKey () const { return m_LeaseSetPrivateKey; }; const uint8_t * GetLeaseSetPublicKey () const { return m_LeaseSetPublicKey; }; - const i2p::data::RouterIdentity& GetRouterIdentity () const { return m_RouterInfo.GetRouterIdentity (); }; + const i2p::data::Identity& GetRouterIdentity () const { return m_RouterInfo.GetRouterIdentity (); }; CryptoPP::RandomNumberGenerator& GetRandomNumberGenerator () { return m_Rnd; }; void Sign (uint8_t * buf, int len, uint8_t * signature); diff --git a/RouterInfo.cpp b/RouterInfo.cpp index 4c85626f..95dfcc25 100644 --- a/RouterInfo.cpp +++ b/RouterInfo.cpp @@ -30,7 +30,7 @@ namespace data ReadFromBuffer (); } - void RouterInfo::SetRouterIdentity (const RouterIdentity& identity) + void RouterInfo::SetRouterIdentity (const Identity& identity) { m_RouterIdentity = identity; CryptoPP::SHA256().CalculateDigest(m_IdentHash, (uint8_t *)&m_RouterIdentity, sizeof (m_RouterIdentity)); diff --git a/RouterInfo.h b/RouterInfo.h index 8787ca32..780eb8c7 100644 --- a/RouterInfo.h +++ b/RouterInfo.h @@ -12,18 +12,7 @@ namespace i2p { namespace data -{ -#pragma pack (1) - - struct RouterIdentity - { - uint8_t publicKey[256]; - uint8_t signingKey[128]; - uint8_t certificate[3]; - }; -#pragma pack () - - +{ class RouterInfo: public RoutingDestination { public: @@ -49,8 +38,8 @@ namespace data RouterInfo (const RouterInfo& ) = default; RouterInfo (const uint8_t * buf, int len); - const RouterIdentity& GetRouterIdentity () const { return m_RouterIdentity; }; - void SetRouterIdentity (const RouterIdentity& identity); + const Identity& GetRouterIdentity () const { return m_RouterIdentity; }; + void SetRouterIdentity (const Identity& identity); const char * GetIdentHashBase64 () const { return m_IdentHashBase64; }; const char * GetIdentHashAbbreviation () const { return m_IdentHashAbbreviation; }; uint64_t GetTimestamp () const { return m_Timestamp; }; @@ -88,7 +77,7 @@ namespace data private: - RouterIdentity m_RouterIdentity; + Identity m_RouterIdentity; IdentHash m_IdentHash; char m_IdentHashBase64[48], m_IdentHashAbbreviation[5]; char m_Buffer[2048]; diff --git a/Streaming.cpp b/Streaming.cpp index f9d253ac..7a8c18ef 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -3,13 +3,20 @@ #include #include "Log.h" #include "RouterInfo.h" +#include "RouterContext.h" #include "Streaming.h" namespace i2p { namespace stream { - void StreamingDestination::HandleNextPacket (const uint8_t * buf, size_t len) + Stream::Stream (const i2p::data::IdentHash& destination): + m_SendStreamID (0) + { + m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); + } + + void Stream::HandleNextPacket (const uint8_t * buf, size_t len) { const uint8_t * end = buf + len; buf += 4; // sendStreamID @@ -42,15 +49,45 @@ namespace stream if (flags & PACKET_FLAG_FROM_INCLUDED) { LogPrint ("From identity"); - optionalData += sizeof (i2p::data::RouterIdentity); + optionalData += sizeof (i2p::data::Identity); } // we have reached payload section std::string str((const char *)buf, end-buf); LogPrint ("Payload: ", str); } + + StreamingDestination m_SharedLocalDestination; + + void StreamingDestination::HandleNextPacket (const uint8_t * buf, size_t len) + { + uint32_t sendStreamID = *(uint32_t *)(buf); + auto it = m_Streams.find (sendStreamID); + if (it != m_Streams.end ()) + it->second->HandleNextPacket (buf, len); + else + LogPrint ("Unknown stream ", sendStreamID); + } - + Stream * StreamingDestination::CreateNewStream (const i2p::data::IdentHash& destination) + { + /*i2p::data::LeaseSet * leaseSet = i2p::data::netdb.FindLeaseSet (destination); + if (!leaseSet) + { + i2p::data::netdb.RequestDestination (destination); + sleep (5); // wait for 5 seconds + leaseSet = i2p::data::netdb.FindLeaseSet (destination); + if (!leaseSet) + { + LogPrint ("Couldn't find LeaseSet"); + return nullptr; + } + } */ + Stream * s = new Stream (destination); + m_Streams[s->GetRecvStreamID ()] = s; + return s; + } + void HandleDataMessage (i2p::data::IdentHash * destination, const uint8_t * buf, size_t len) { uint32_t length = be32toh (*(uint32_t *)buf); @@ -63,12 +100,32 @@ namespace stream decompressor.Put (buf, length); decompressor.MessageEnd(); uint8_t uncompressed[2048]; - int uncomressedSize = decompressor.MaxRetrievable (); - decompressor.Get (uncompressed, uncomressedSize); + int uncompressedSize = decompressor.MaxRetrievable (); + decompressor.Get (uncompressed, uncompressedSize); // then forward to streaming engine + // TODO: we have onle one destination, might be more + m_SharedLocalDestination.HandleNextPacket (uncompressed, uncompressedSize); } else LogPrint ("Data: protocol ", buf[9], " is not supported"); } + + I2NPMessage * CreateDataMessage (Stream * s, uint8_t * payload, size_t len) + { + I2NPMessage * msg = NewI2NPMessage (); + CryptoPP::Gzip compressor; + compressor.Put (payload, len); + compressor.MessageEnd(); + int size = compressor.MaxRetrievable (); + uint8_t * buf = msg->GetPayload (); + *(uint16_t *)buf = htobe32 (size); // length + buf += 4; + compressor.Get (buf, size); + buf[9] = 6; // streaming protocol + msg->len += size + 4; + FillI2NPMessageHeader (msg, eI2NPData); + + return msg; + } } } diff --git a/Streaming.h b/Streaming.h index a52c440e..c75f0b13 100644 --- a/Streaming.h +++ b/Streaming.h @@ -2,7 +2,9 @@ #define STREAMING_H__ #include +#include #include "LeaseSet.h" +#include "I2NPProtocol.h" namespace i2p { @@ -20,15 +22,36 @@ namespace stream const uint16_t PACKET_FLAG_ECHO = 0x0200; const uint16_t PACKET_FLAG_NO_ACK = 0x0400; + class Stream + { + public: + + Stream (const i2p::data::IdentHash& destination); + uint32_t GetSendStreamID () const { return m_SendStreamID; }; + uint32_t GetRecvStreamID () const { return m_RecvStreamID; }; + + void HandleNextPacket (const uint8_t * buf, size_t len); + + private: + + uint32_t m_SendStreamID, m_RecvStreamID; + }; + class StreamingDestination { public: + Stream * CreateNewStream (const i2p::data::IdentHash& destination); void HandleNextPacket (const uint8_t * buf, size_t len); - }; + private: + + std::map m_Streams; + }; + // assuming data is I2CP message void HandleDataMessage (i2p::data::IdentHash * destination, const uint8_t * buf, size_t len); + I2NPMessage * CreateDataMessage (Stream * s, uint8_t * payload, size_t len); } }