0xdd transport

GitOrigin-RevId: 241c2fcea3ebaac20fc68531692cbd299a9de95a
This commit is contained in:
Arseny Smirnov 2018-06-15 21:54:22 +03:00
parent fdd898124b
commit c02d4505e4
7 changed files with 45 additions and 9 deletions

View File

@ -74,6 +74,10 @@ size_t Transport::max_prepend_size() const {
return MAX_PREPEND_SIZE;
}
size_t Transport::max_append_size() const {
return 0;
}
} // namespace http
} // namespace mtproto
} // namespace td

View File

@ -33,6 +33,7 @@ class Transport : public IStreamTransport {
}
size_t max_prepend_size() const override;
size_t max_append_size() const override;
TransportType get_type() const override {
return {TransportType::Http, 0, ""};
}

View File

@ -30,6 +30,7 @@ class IStreamTransport {
virtual bool can_write() const = 0;
virtual void init(ChainBufferReader *input, ChainBufferWriter *output) = 0;
virtual size_t max_prepend_size() const = 0;
virtual size_t max_append_size() const = 0;
virtual TransportType get_type() const = 0;
};

View File

@ -27,7 +27,8 @@ void RawConnection::send_crypto(const Storer &storer, int64 session_id, int64 sa
info.salt = salt;
info.session_id = session_id;
auto packet = BufferWriter{mtproto::Transport::write(storer, auth_key, &info), transport_->max_prepend_size(), 0};
auto packet = BufferWriter{mtproto::Transport::write(storer, auth_key, &info), transport_->max_prepend_size(),
transport_->max_append_size()};
mtproto::Transport::write(storer, auth_key, &info, packet.as_slice());
bool use_quick_ack = false;
@ -47,8 +48,8 @@ uint64 RawConnection::send_no_crypto(const Storer &storer) {
mtproto::PacketInfo info;
info.no_crypto_flag = true;
auto packet =
BufferWriter{mtproto::Transport::write(storer, mtproto::AuthKey(), &info), transport_->max_prepend_size(), 0};
auto packet = BufferWriter{mtproto::Transport::write(storer, mtproto::AuthKey(), &info),
transport_->max_prepend_size(), transport_->max_append_size()};
mtproto::Transport::write(storer, mtproto::AuthKey(), &info, packet.as_slice());
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
transport_->write(std::move(packet), false);

View File

@ -58,11 +58,20 @@ void IntermediateTransport::write_prepare_inplace(BufferWriter *message, bool qu
CHECK(prepend.size() >= prepend_size);
message->confirm_prepend(prepend_size);
as<uint32>(message->as_slice().begin()) = static_cast<uint32>(size);
size_t append_size = 0;
if (with_padding()) {
append_size = static_cast<uint32>(Random::secure_int32()) % 16;
MutableSlice append = message->prepare_append().truncate(append_size);
CHECK(append.size() == append_size);
Random::secure_bytes(append);
message->confirm_append(append.size());
}
as<uint32>(message->as_slice().begin()) = static_cast<uint32>(size + append_size);
}
void IntermediateTransport::init_output_stream(ChainBufferWriter *stream) {
const uint32 magic = 0xeeeeeeee;
const uint32 magic = with_padding() ? 0xdddddddd : 0xeeeeeeee;
stream->append(Slice(reinterpret_cast<const char *>(&magic), 4));
}
@ -153,7 +162,7 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp
}
// TODO: It is actually IntermediateTransport::init_output_stream, so it will work only with
// TransportImpl==IntermediateTransport
as<uint32>(header_slice.begin() + 56) = 0xeeeeeeee;
as<uint32>(header_slice.begin() + 56) = impl_.with_padding() ? 0xdddddddd : 0xeeeeeeee;
if (dc_id_ != 0) {
as<int16>(header_slice.begin() + 60) = dc_id_;
}
@ -161,6 +170,9 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp
string rheader = header;
std::reverse(rheader.begin(), rheader.end());
auto key = as<UInt256>(rheader.data() + 8);
if (secret_.size() == 17) {
secret_ = secret_.substr(1);
}
auto fix_key = [&](UInt256 &key) {
if (secret_.size() == 16) {
Sha256State state;

View File

@ -56,12 +56,20 @@ class AbridgedTransport : public ITransport {
class IntermediateTransport : ITransport {
public:
explicit IntermediateTransport(bool with_padding) : with_padding_(with_padding) {
}
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) override;
void write_prepare_inplace(BufferWriter *message, bool quick_ack) override;
void init_output_stream(ChainBufferWriter *stream) override;
bool support_quick_ack() const override {
return true;
}
bool with_padding() const {
return with_padding_;
}
private:
bool with_padding_;
};
using TransportImpl = IntermediateTransport;
@ -94,12 +102,17 @@ class OldTransport : public IStreamTransport {
size_t max_prepend_size() const override {
return 4;
}
size_t max_append_size() const override {
return 15;
}
TransportType get_type() const override {
return TransportType{TransportType::Tcp, 0, ""};
}
private:
TransportImpl impl_;
TransportImpl impl_{false};
ChainBufferReader *input_;
ChainBufferWriter *output_;
};
@ -138,14 +151,18 @@ class ObfuscatedTransport : public IStreamTransport {
return 4;
}
size_t max_append_size() const override {
return 15;
}
TransportType get_type() const override {
return TransportType{TransportType::ObfuscatedTcp, dc_id_, secret_};
}
private:
TransportImpl impl_;
int16 dc_id_;
std::string secret_;
TransportImpl impl_{secret_.size() >= 17};
AesCtrByteFlow aes_ctr_byte_flow_;
ByteFlowSink byte_flow_sink_;
ChainBufferReader *input_;

View File

@ -288,7 +288,7 @@ void ConnectionCreator::add_proxy(string server, int32 port, bool enable,
}
case td_api::proxyTypeMtproto::ID: {
auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type);
if (type->secret_.size() != 32 || hex_decode(type->secret_).is_error()) {
if ((type->secret_.size() != 32 && type->secret_.size() != 34) || hex_decode(type->secret_).is_error()) {
return promise.set_error(Status::Error(400, "Wrong server secret"));
}
new_proxy = Proxy::mtproto(server, port, type->secret_);