diff --git a/td/mtproto/TcpTransport.cpp b/td/mtproto/TcpTransport.cpp index b2270a376..d4da59a5b 100644 --- a/td/mtproto/TcpTransport.cpp +++ b/td/mtproto/TcpTransport.cpp @@ -77,64 +77,6 @@ void IntermediateTransport::init_output_stream(ChainBufferWriter *stream) { stream->append(Slice(reinterpret_cast(&magic), 4)); } -size_t AbridgedTransport::read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) { - if (stream->empty()) { - return 1; - } - uint8 byte = 0; - stream->clone().advance(1, MutableSlice(&byte, 1)); - size_t header_size; - uint32 data_size; - if (byte < 0x7f) { - header_size = 1; - data_size = byte * 4u; - } else { - if (stream->size() < 4) { - return 4; - } - header_size = 4; - stream->clone().advance(4, MutableSlice(reinterpret_cast(&data_size), sizeof(data_size))); - data_size >>= 8; - data_size = data_size * 4; - } - - size_t total_size = header_size + data_size; - if (stream->size() < total_size) { - // optimization - // stream->make_solid(total_size); - return total_size; - } - - stream->advance(header_size); - *message = stream->cut_head(data_size).move_as_buffer_slice(); - return 0; -} - -void AbridgedTransport::write_prepare_inplace(BufferWriter *message, bool quick_ack) { - CHECK(!quick_ack); - size_t size = message->size() / 4; - CHECK(size % 4 == 0); - CHECK(size < 1 << 24); - - size_t prepend_size = size >= 0x7f ? 4 : 1; - - MutableSlice prepend = message->prepare_prepend(); - CHECK(prepend.size() >= prepend_size); - message->confirm_prepend(prepend_size); - - MutableSlice data = message->as_slice(); - if (size >= 0x7f) { - uint32 size_encoded = 0x7f + (static_cast(size) << 8); - as(data.begin()) = size_encoded; - } else { - as(data.begin()) = static_cast(size); - } -} - -void AbridgedTransport::init_output_stream(ChainBufferWriter *stream) { - stream->append("\xef"); -} - void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *output) { input_ = input; output_ = output; @@ -164,8 +106,6 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp } break; } - // TODO: It is actually IntermediateTransport::init_output_stream, so it will work only with - // TransportImpl==IntermediateTransport as(header_slice.begin() + 56) = impl_.with_padding() ? 0xdddddddd : 0xeeeeeeee; if (dc_id_ != 0) { as(header_slice.begin() + 60) = dc_id_; diff --git a/td/mtproto/TcpTransport.h b/td/mtproto/TcpTransport.h index a4f0c9ac5..8d9d5664b 100644 --- a/td/mtproto/TcpTransport.h +++ b/td/mtproto/TcpTransport.h @@ -24,51 +24,24 @@ namespace td { namespace mtproto { namespace tcp { -class ITransport { - // Writes packet into message. - // Returns 0 if everything is ok, and [expected_size] otherwise. - // There is no sense to call this function when [stream->size > expected_size] - // - // (tpc is stream-base protocol. So the input message is a stream, not a slice) - virtual size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) = 0; - - // Writes header inplace. - virtual void write_prepare_inplace(BufferWriter *message, bool quick_ack) = 0; - - // Writes first several bytes into output stream. - virtual void init_output_stream(ChainBufferWriter *stream) = 0; - - virtual bool support_quick_ack() const = 0; - - public: - ITransport() = default; - ITransport(const ITransport &) = delete; - ITransport &operator=(const ITransport &) = delete; - ITransport(ITransport &&) = delete; - ITransport &operator=(ITransport &&) = delete; - virtual ~ITransport() = default; -}; - -class AbridgedTransport final : public ITransport { - public: - size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) final; - void write_prepare_inplace(BufferWriter *message, bool quick_ack) final; - void init_output_stream(ChainBufferWriter *stream) final; - bool support_quick_ack() const final { - return false; - } -}; - -class IntermediateTransport final : public ITransport { +class IntermediateTransport { public: explicit IntermediateTransport(bool with_padding) : with_padding_(with_padding) { } - size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) final; - void write_prepare_inplace(BufferWriter *message, bool quick_ack) final; - void init_output_stream(ChainBufferWriter *stream) final; - bool support_quick_ack() const final { - return true; - } + + // Writes a packet into message. + // Returns 0 if everything is ok, and [expected_size] otherwise. + // There is no sense to call this function when [stream->size > expected_size] + // + // (TCP is a stream-oriented protocol, so the input message is a stream, not a slice) + size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack); + + // Writes header inplace. + void write_prepare_inplace(BufferWriter *message, bool quick_ack); + + // Writes first several bytes into output stream. + void init_output_stream(ChainBufferWriter *stream); + bool with_padding() const { return with_padding_; } @@ -77,8 +50,6 @@ class IntermediateTransport final : public ITransport { bool with_padding_; }; -using TransportImpl = IntermediateTransport; - class OldTransport final : public IStreamTransport { public: OldTransport() = default; @@ -86,7 +57,7 @@ class OldTransport final : public IStreamTransport { return impl_.read_from_stream(input_, message, quick_ack); } bool support_quick_ack() const final { - return impl_.support_quick_ack(); + return true; } void write(BufferWriter &&message, bool quick_ack) final { impl_.write_prepare_inplace(&message, quick_ack); @@ -121,7 +92,7 @@ class OldTransport final : public IStreamTransport { } private: - TransportImpl impl_{false}; + IntermediateTransport impl_{false}; ChainBufferReader *input_{nullptr}; ChainBufferWriter *output_{nullptr}; }; @@ -135,7 +106,7 @@ class ObfuscatedTransport final : public IStreamTransport { Result read_next(BufferSlice *message, uint32 *quick_ack) final TD_WARN_UNUSED_RESULT; bool support_quick_ack() const final { - return impl_.support_quick_ack(); + return true; } void write(BufferWriter &&message, bool quick_ack) final; @@ -182,7 +153,7 @@ class ObfuscatedTransport final : public IStreamTransport { bool is_first_tls_packet_{true}; ProxySecret secret_; std::string header_; - TransportImpl impl_; + IntermediateTransport impl_; TlsReaderByteFlow tls_reader_byte_flow_; AesCtrByteFlow aes_ctr_byte_flow_; ByteFlowSink byte_flow_sink_;