diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp index de4b5674..2f3d5eef 100644 --- a/libi2pd/Datagram.cpp +++ b/libi2pd/Datagram.cpp @@ -58,25 +58,35 @@ namespace datagram { if (session) { - if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + if (session->GetVersion () == eDatagramV3) { - uint8_t hash[32]; - SHA256(payload, len, hash); - m_Owner->Sign (hash, 32, m_Signature.data ()); + constexpr uint8_t flags[] = { 0x00, 0x03 }; // datagram3, no options + auto msg = CreateDataMessage ({{m_Owner->GetIdentity ()->GetIdentHash (), 32}, + {flags, 2}, {payload, len}}, fromPort, toPort, i2p::client::PROTOCOL_TYPE_DATAGRAM3, false); // datagram3 + session->SendMsg(msg); } else - m_Owner->Sign (payload, len, m_Signature.data ()); + { + if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) + { + uint8_t hash[32]; + SHA256(payload, len, hash); + m_Owner->Sign (hash, 32, m_Signature.data ()); + } + else + m_Owner->Sign (payload, len, m_Signature.data ()); - auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, - fromPort, toPort, false, !session->IsRatchets ()); // datagram - session->SendMsg(msg); + auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}}, + fromPort, toPort, i2p::client::PROTOCOL_TYPE_DATAGRAM, !session->IsRatchets ()); // datagram1 + session->SendMsg(msg); + } } } void DatagramDestination::SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort) { if (session) - session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw + session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, i2p::client::PROTOCOL_TYPE_RAW, !session->IsRatchets ())); // raw } void DatagramDestination::FlushSendQueue (std::shared_ptr session) @@ -145,6 +155,7 @@ namespace datagram if (!memcmp (from->GetRemoteStaticKey (), staticKey, 32)) { auto session = ObtainSession (ident); + session->SetVersion (eDatagramV3); session->SetRemoteLeaseSet (ls); session->Ack (); auto r = FindReceiver(toPort); @@ -274,7 +285,7 @@ namespace datagram std::shared_ptr DatagramDestination::CreateDataMessage ( const std::vector >& payloads, - uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum) + uint16_t fromPort, uint16_t toPort, uint8_t protocolType, bool checksum) { size_t size; auto msg = m_I2NPMsgsPool.AcquireShared (); @@ -290,8 +301,8 @@ namespace datagram { htobe32buf (msg->GetPayload (), size); // length htobe16buf (buf + 4, fromPort); // source port - htobe16buf (buf + 6, toPort); // destination port - buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_RAW : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol + htobe16buf (buf + 6, toPort); // destination port + buf[9] = protocolType; // raw or datagram protocol msg->len += size + 4; msg->FillI2NPMessageHeader (eI2NPData, 0, checksum); } @@ -350,8 +361,7 @@ namespace datagram DatagramSession::DatagramSession(std::shared_ptr localDestination, const i2p::data::IdentHash & remoteIdent) : m_LocalDestination(localDestination), m_RemoteIdent(remoteIdent), - m_LastUse (0), m_LastFlush (0), - m_RequestingLS(false) + m_LastUse (0), m_LastFlush (0), m_RequestingLS (false), m_Version (eDatagramV1) { } diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h index a293c84b..a6fc130d 100644 --- a/libi2pd/Datagram.h +++ b/libi2pd/Datagram.h @@ -45,6 +45,13 @@ namespace datagram const uint64_t DATAGRAM_MAX_FLUSH_INTERVAL = 5; // in milliseconds const int DATAGRAM_SESSION_ACK_REQUEST_INTERVAL = 5500; // in milliseconds + enum DatagramVersion + { + eDatagramV1 = 1, + eDatagramV2 = 2, + eDatagramV3 = 3, + }; + constexpr uint16_t DATAGRAM3_FLAG_OPTIONS = 0x10; class DatagramSession : public std::enable_shared_from_this @@ -69,6 +76,9 @@ namespace datagram bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); } void SetRemoteLeaseSet (std::shared_ptr ls) { m_RemoteLeaseSet = ls; } + + DatagramVersion GetVersion () const { return m_Version; } + void SetVersion (DatagramVersion version) { m_Version = version; } struct Info { @@ -104,6 +114,7 @@ namespace datagram std::vector > m_SendQueue; uint64_t m_LastUse, m_LastFlush; // milliseconds bool m_RequestingLS; + DatagramVersion m_Version; }; typedef std::shared_ptr DatagramSession_ptr; @@ -147,7 +158,7 @@ namespace datagram std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident); std::shared_ptr CreateDataMessage (const std::vector >& payloads, - uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true); + uint16_t fromPort, uint16_t toPort, uint8_t protocolType, bool checksum = true); void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len); void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);