MCPcopy Create free account
hub / github.com/PurpleI2P/i2pd / SendFragmentedMessage

Method SendFragmentedMessage

libi2pd/SSU2Session.cpp:547–599  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

545 }
546
547 bool SSU2Session::SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg)
548 {
549 if (!msg) return false;
550 size_t lastFragmentSize = (msg->GetNTCP2Length () + 3 - m_MaxPayloadSize) % (m_MaxPayloadSize - 8);
551 size_t extraSize = m_MaxPayloadSize - lastFragmentSize;
552 bool ackBlockSent = false;
553 uint32_t msgID;
554 memcpy (&msgID, msg->GetHeader () + I2NP_HEADER_MSGID_OFFSET, 4);
555 auto ts = i2p::util::GetMillisecondsSinceEpoch ();
556 auto packet = m_Server.GetSentPacketsPool ().AcquireShared ();
557 if (extraSize >= 8)
558 {
559 packet->payloadSize = CreateAckBlock (packet->payload, extraSize);
560 ackBlockSent = true;
561 if (packet->payloadSize + 12 < m_MaxPayloadSize)
562 {
563 uint32_t packetNum = SendData (packet->payload, packet->payloadSize);
564 packet->sendTime = ts;
565 m_SentPackets.emplace (packetNum, packet);
566 packet = m_Server.GetSentPacketsPool ().AcquireShared ();
567 }
568 else
569 extraSize -= packet->payloadSize;
570 }
571 size_t offset = extraSize > 0 ? (m_Server.GetRng ()() % extraSize) : 0;
572 if (offset + packet->payloadSize >= m_MaxPayloadSize) offset = 0;
573 auto size = CreateFirstFragmentBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - offset - packet->payloadSize, msg);
574 if (!size) return false;
575 extraSize -= offset;
576 packet->payloadSize += size;
577 uint32_t firstPacketNum = SendData (packet->payload, packet->payloadSize);
578 packet->sendTime = ts;
579 m_SentPackets.emplace (firstPacketNum, packet);
580 uint8_t fragmentNum = 0;
581 while (msg->offset < msg->len)
582 {
583 offset = extraSize > 0 ? (m_Server.GetRng ()() % extraSize) : 0;
584 packet = m_Server.GetSentPacketsPool ().AcquireShared ();
585 packet->payloadSize = CreateFollowOnFragmentBlock (packet->payload, m_MaxPayloadSize - offset, msg, fragmentNum, msgID);
586 extraSize -= offset;
587 uint8_t flags = 0;
588 if (msg->offset >= msg->len && packet->payloadSize + 16 < m_MaxPayloadSize) // last fragment
589 {
590 packet->payloadSize += CreatePaddingBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize);
591 if (fragmentNum > 2) // 3 or more fragments
592 flags |= SSU2_FLAG_IMMEDIATE_ACK_REQUESTED;
593 }
594 uint32_t followonPacketNum = SendData (packet->payload, packet->payloadSize, flags);
595 packet->sendTime = ts;
596 m_SentPackets.emplace (followonPacketNum, packet);
597 }
598 return ackBlockSent;
599 }
600
601 size_t SSU2Session::Resend (uint64_t ts)
602 {

Callers 3

SendLocalRouterInfoMethod · 0.80
HandleRelayRequestMethod · 0.80
HandlePeerTestMethod · 0.80

Calls 4

GetNTCP2LengthMethod · 0.80
AcquireSharedMethod · 0.80
GetHeaderMethod · 0.45

Tested by

no test coverage detected