ZaStoGram_desktop/Telegram/SourceFiles/mtproto/proxy/mtproxy/client_hello_builder.h
loop-uh 96d0c00950 Report the clock a hello carried, with its reference
A relay reads the time out of the digest and refuses a hello whose time it
does not like, and the windows are narrow: MTProxy takes nothing more than
three seconds ahead of itself, mtg compares the absolute difference against
three seconds in either direction. So a clock a few seconds off is enough to
make every relay look broken, and the client had no way to say so.

The skew alone would have been worse than nothing. The time we send is the
system clock plus two corrections, and both arrive over channels that go
around the proxy - the MTProto session and a Date header fetched with the
proxy explicitly disabled. On the network where a proxy is needed they may
never arrive at all, and then the skew computed against our own estimate is
zero however wrong the machine is. Zero reads as "clock is fine". So the
number never goes out alone: clock_ref says which corrections stood behind
it, and the warning fires on clock_ref=none rather than on any threshold.

The timestamp itself comes back from the generator instead of being read
again at report time, because the clock moves between the two and the value
worth reporting is the one that went into the digest. The snapshot of the
references is taken at that same moment, since an MTProto time update clears
the HTTP correction as a side effect.

A verified ServerHello is also a measurement - it proves the time we sent sat
inside the relay's window - so it says so in the log and closes the question
for that attempt.

The guard test pins the shape that matters: that the warning keys on the
absence of a reference and not on the size of the skew. That is the line a
later simplification would quietly cross.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 02:20:17 +03:00

66 lines
1.6 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/basic_types.h"
#include "base/bytes.h"
#include "base/timer.h"
#include "mtproto/proxy/data.h"
#include "scheme.h"
#include <QtCore/QByteArray>
#include <optional>
namespace MTP::details {
struct SyntheticPskOffer {
bytes::vector identity;
uint32 obfuscatedTicketAge = 0;
int binderLength = 0;
};
struct ClientHello {
QByteArray data;
QByteArray digest;
// The time actually mixed into the digest. Relays check it and refuse
// anything more than three seconds ahead of their own clock, so this is
// the one value worth reporting - re-reading the clock anywhere else
// gives a number that has already drifted from the one on the wire.
TimeId timestamp = 0;
};
struct ClientHelloFragmentationPlan {
int firstSize = 0;
crl::time secondDelay = 0;
[[nodiscard]] explicit operator bool() const {
return firstSize > 0;
}
};
struct ClientHelloGenerationOptions {
bool deterministic = false;
};
[[nodiscard]] MTPTlsClientHello PrepareClientHelloRules(
ProxyTlsProfile profile);
[[nodiscard]] ClientHello PrepareClientHello(
const MTPTlsClientHello &rules,
bytes::const_span domain,
bytes::const_span key,
ProxyTlsProfile profile,
std::optional<SyntheticPskOffer> pskOffer,
ClientHelloGenerationOptions options = {});
[[nodiscard]] ClientHelloFragmentationPlan PrepareClientHelloFragmentation(
const QByteArray &data,
ProxyClientHelloFragmentation mode);
} // namespace MTP::details