0xdd transport
GitOrigin-RevId: 241c2fcea3ebaac20fc68531692cbd299a9de95a
This commit is contained in:
parent
fdd898124b
commit
c02d4505e4
@ -74,6 +74,10 @@ size_t Transport::max_prepend_size() const {
|
|||||||
return MAX_PREPEND_SIZE;
|
return MAX_PREPEND_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Transport::max_append_size() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
||||||
} // namespace mtproto
|
} // namespace mtproto
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -33,6 +33,7 @@ class Transport : public IStreamTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t max_prepend_size() const override;
|
size_t max_prepend_size() const override;
|
||||||
|
size_t max_append_size() const override;
|
||||||
TransportType get_type() const override {
|
TransportType get_type() const override {
|
||||||
return {TransportType::Http, 0, ""};
|
return {TransportType::Http, 0, ""};
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ class IStreamTransport {
|
|||||||
virtual bool can_write() const = 0;
|
virtual bool can_write() const = 0;
|
||||||
virtual void init(ChainBufferReader *input, ChainBufferWriter *output) = 0;
|
virtual void init(ChainBufferReader *input, ChainBufferWriter *output) = 0;
|
||||||
virtual size_t max_prepend_size() const = 0;
|
virtual size_t max_prepend_size() const = 0;
|
||||||
|
virtual size_t max_append_size() const = 0;
|
||||||
virtual TransportType get_type() const = 0;
|
virtual TransportType get_type() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ void RawConnection::send_crypto(const Storer &storer, int64 session_id, int64 sa
|
|||||||
info.salt = salt;
|
info.salt = salt;
|
||||||
info.session_id = session_id;
|
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());
|
mtproto::Transport::write(storer, auth_key, &info, packet.as_slice());
|
||||||
|
|
||||||
bool use_quick_ack = false;
|
bool use_quick_ack = false;
|
||||||
@ -47,8 +48,8 @@ uint64 RawConnection::send_no_crypto(const Storer &storer) {
|
|||||||
mtproto::PacketInfo info;
|
mtproto::PacketInfo info;
|
||||||
|
|
||||||
info.no_crypto_flag = true;
|
info.no_crypto_flag = true;
|
||||||
auto packet =
|
auto packet = BufferWriter{mtproto::Transport::write(storer, mtproto::AuthKey(), &info),
|
||||||
BufferWriter{mtproto::Transport::write(storer, mtproto::AuthKey(), &info), transport_->max_prepend_size(), 0};
|
transport_->max_prepend_size(), transport_->max_append_size()};
|
||||||
mtproto::Transport::write(storer, mtproto::AuthKey(), &info, packet.as_slice());
|
mtproto::Transport::write(storer, mtproto::AuthKey(), &info, packet.as_slice());
|
||||||
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
|
LOG(INFO) << "Send handshake packet: " << format::as_hex_dump<4>(packet.as_slice());
|
||||||
transport_->write(std::move(packet), false);
|
transport_->write(std::move(packet), false);
|
||||||
|
@ -58,11 +58,20 @@ void IntermediateTransport::write_prepare_inplace(BufferWriter *message, bool qu
|
|||||||
CHECK(prepend.size() >= prepend_size);
|
CHECK(prepend.size() >= prepend_size);
|
||||||
message->confirm_prepend(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) {
|
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));
|
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
|
// TODO: It is actually IntermediateTransport::init_output_stream, so it will work only with
|
||||||
// TransportImpl==IntermediateTransport
|
// TransportImpl==IntermediateTransport
|
||||||
as<uint32>(header_slice.begin() + 56) = 0xeeeeeeee;
|
as<uint32>(header_slice.begin() + 56) = impl_.with_padding() ? 0xdddddddd : 0xeeeeeeee;
|
||||||
if (dc_id_ != 0) {
|
if (dc_id_ != 0) {
|
||||||
as<int16>(header_slice.begin() + 60) = dc_id_;
|
as<int16>(header_slice.begin() + 60) = dc_id_;
|
||||||
}
|
}
|
||||||
@ -161,6 +170,9 @@ void ObfuscatedTransport::init(ChainBufferReader *input, ChainBufferWriter *outp
|
|||||||
string rheader = header;
|
string rheader = header;
|
||||||
std::reverse(rheader.begin(), rheader.end());
|
std::reverse(rheader.begin(), rheader.end());
|
||||||
auto key = as<UInt256>(rheader.data() + 8);
|
auto key = as<UInt256>(rheader.data() + 8);
|
||||||
|
if (secret_.size() == 17) {
|
||||||
|
secret_ = secret_.substr(1);
|
||||||
|
}
|
||||||
auto fix_key = [&](UInt256 &key) {
|
auto fix_key = [&](UInt256 &key) {
|
||||||
if (secret_.size() == 16) {
|
if (secret_.size() == 16) {
|
||||||
Sha256State state;
|
Sha256State state;
|
||||||
|
@ -56,12 +56,20 @@ class AbridgedTransport : public ITransport {
|
|||||||
|
|
||||||
class IntermediateTransport : ITransport {
|
class IntermediateTransport : ITransport {
|
||||||
public:
|
public:
|
||||||
|
explicit IntermediateTransport(bool with_padding) : with_padding_(with_padding) {
|
||||||
|
}
|
||||||
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) override;
|
size_t read_from_stream(ChainBufferReader *stream, BufferSlice *message, uint32 *quick_ack) override;
|
||||||
void write_prepare_inplace(BufferWriter *message, bool quick_ack) override;
|
void write_prepare_inplace(BufferWriter *message, bool quick_ack) override;
|
||||||
void init_output_stream(ChainBufferWriter *stream) override;
|
void init_output_stream(ChainBufferWriter *stream) override;
|
||||||
bool support_quick_ack() const override {
|
bool support_quick_ack() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
bool with_padding() const {
|
||||||
|
return with_padding_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool with_padding_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using TransportImpl = IntermediateTransport;
|
using TransportImpl = IntermediateTransport;
|
||||||
@ -94,12 +102,17 @@ class OldTransport : public IStreamTransport {
|
|||||||
size_t max_prepend_size() const override {
|
size_t max_prepend_size() const override {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t max_append_size() const override {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
TransportType get_type() const override {
|
TransportType get_type() const override {
|
||||||
return TransportType{TransportType::Tcp, 0, ""};
|
return TransportType{TransportType::Tcp, 0, ""};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TransportImpl impl_;
|
TransportImpl impl_{false};
|
||||||
ChainBufferReader *input_;
|
ChainBufferReader *input_;
|
||||||
ChainBufferWriter *output_;
|
ChainBufferWriter *output_;
|
||||||
};
|
};
|
||||||
@ -138,14 +151,18 @@ class ObfuscatedTransport : public IStreamTransport {
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t max_append_size() const override {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
TransportType get_type() const override {
|
TransportType get_type() const override {
|
||||||
return TransportType{TransportType::ObfuscatedTcp, dc_id_, secret_};
|
return TransportType{TransportType::ObfuscatedTcp, dc_id_, secret_};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TransportImpl impl_;
|
|
||||||
int16 dc_id_;
|
int16 dc_id_;
|
||||||
std::string secret_;
|
std::string secret_;
|
||||||
|
TransportImpl impl_{secret_.size() >= 17};
|
||||||
AesCtrByteFlow aes_ctr_byte_flow_;
|
AesCtrByteFlow aes_ctr_byte_flow_;
|
||||||
ByteFlowSink byte_flow_sink_;
|
ByteFlowSink byte_flow_sink_;
|
||||||
ChainBufferReader *input_;
|
ChainBufferReader *input_;
|
||||||
|
@ -288,7 +288,7 @@ void ConnectionCreator::add_proxy(string server, int32 port, bool enable,
|
|||||||
}
|
}
|
||||||
case td_api::proxyTypeMtproto::ID: {
|
case td_api::proxyTypeMtproto::ID: {
|
||||||
auto type = td_api::move_object_as<td_api::proxyTypeMtproto>(proxy_type);
|
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"));
|
return promise.set_error(Status::Error(400, "Wrong server secret"));
|
||||||
}
|
}
|
||||||
new_proxy = Proxy::mtproto(server, port, type->secret_);
|
new_proxy = Proxy::mtproto(server, port, type->secret_);
|
||||||
|
Reference in New Issue
Block a user