#ifndef TGCALLS_ENCRYPTED_CONNECTION_H #define TGCALLS_ENCRYPTED_CONNECTION_H #include "Instance.h" #include "Message.h" namespace rtc { class ByteBufferReader; } // namespace rtc namespace tgcalls { class EncryptedConnection final { public: enum class Type : uint8_t { Signaling, Transport, }; EncryptedConnection( Type type, const EncryptionKey &key, std::function requestSendService); struct EncryptedPacket { std::vector bytes; uint32_t counter = 0; }; absl::optional prepareForSending(const Message &message); absl::optional prepareForSendingRawMessage(rtc::CopyOnWriteBuffer &serialized, bool messageRequiresAck); absl::optional prepareForSendingService(int cause); struct DecryptedPacket { DecryptedMessage main; std::vector additional; }; struct DecryptedRawPacket { DecryptedRawMessage main; std::vector additional; }; absl::optional handleIncomingPacket(const char *bytes, size_t size); absl::optional handleIncomingRawPacket(const char *bytes, size_t size); absl::optional encryptRawPacket(rtc::CopyOnWriteBuffer const &buffer); absl::optional decryptRawPacket(rtc::CopyOnWriteBuffer const &buffer); private: struct DelayIntervals { // In milliseconds. int minDelayBeforeMessageResend = 0; int maxDelayBeforeMessageResend = 0; int maxDelayBeforeAckResend = 0; }; struct MessageForResend { rtc::CopyOnWriteBuffer data; int64_t lastSent = 0; }; bool enoughSpaceInPacket(const rtc::CopyOnWriteBuffer &buffer, size_t amount) const; size_t packetLimit() const; size_t fullNotAckedLength() const; void appendAcksToSend(rtc::CopyOnWriteBuffer &buffer); void appendAdditionalMessages(rtc::CopyOnWriteBuffer &buffer); EncryptedPacket encryptPrepared(const rtc::CopyOnWriteBuffer &buffer); bool registerIncomingCounter(uint32_t incomingCounter); absl::optional processPacket(const rtc::Buffer &fullBuffer, uint32_t packetSeq); absl::optional processRawPacket(const rtc::Buffer &fullBuffer, uint32_t packetSeq); bool registerSentAck(uint32_t counter, bool firstInPacket); void ackMyMessage(uint32_t counter); void sendAckPostponed(uint32_t incomingSeq); bool haveAdditionalMessages() const; absl::optional computeNextSeq(bool messageRequiresAck, bool singleMessagePacket); void appendReceivedMessage( absl::optional &to, Message &&message, uint32_t incomingSeq); void appendReceivedRawMessage( absl::optional &to, rtc::CopyOnWriteBuffer &&message, uint32_t incomingSeq); absl::optional prepareForSendingMessageInternal(rtc::CopyOnWriteBuffer &serialized, uint32_t seq, bool messageRequiresAck); const char *logHeader() const; static DelayIntervals DelayIntervalsByType(Type type); static rtc::CopyOnWriteBuffer SerializeEmptyMessageWithSeq(uint32_t seq); Type _type = Type(); EncryptionKey _key; uint32_t _counter = 0; DelayIntervals _delayIntervals; std::vector _largestIncomingCounters; std::vector _ackedIncomingCounters; std::vector _acksToSendSeqs; std::vector _acksSentCounters; std::vector _myNotYetAckedMessages; std::function _requestSendService; bool _resendTimerActive = false; bool _sendAcksTimerActive = false; }; } // namespace tgcalls #endif