When a relay does not recognise a ClientHello it proxies the connection on to the domain it fronts for, so the ServerHello we then verify was written by a real TLS server. Its first application data record carries a certificate chain, which is kilobytes; a relay's is about sixty bytes, for a batch of roughly two hundred in total. The size tells the two apart with no ambiguity, and the reports in hand sat at 1448, 2856 and 4099 bytes against 202 for the connection that worked. Both were reported as "bad Server Hello digest", which points at the relay and hides that the hello never reached it. They are separate reasons now, and the log carries server_hello_foreign_tls for the one that means the relay looked straight past us. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
84 lines
2 KiB
C++
84 lines
2 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 "mtproto/runtime/proxy_data.h"
|
|
|
|
namespace MTP::details::MtProxy {
|
|
|
|
enum class RouteAddressFamily {
|
|
Unknown,
|
|
Host,
|
|
IPv4,
|
|
IPv6,
|
|
};
|
|
|
|
enum class FailureReason {
|
|
None,
|
|
DnsFailed,
|
|
TcpConnectTimeout,
|
|
TcpConnectedNoClientHelloWrite,
|
|
ClientHelloSentNoServerHello,
|
|
TlsAlertAfterClientHello,
|
|
ServerHelloHmacMismatch,
|
|
ServerHelloForeignTls,
|
|
ServerHelloOkNoAppData,
|
|
ServerHelloOkNoMtprotoData,
|
|
AppDataRemoteClosed,
|
|
ConnectedNoMtprotoData,
|
|
MtpReceiveTimeoutAfterData,
|
|
Network,
|
|
ProxyProtocolBadResponse,
|
|
};
|
|
|
|
struct CanonicalProxyEndpoint {
|
|
ProxyData::Type type = ProxyData::Type::None;
|
|
QString originalHost;
|
|
int port = 0;
|
|
QString secretHash;
|
|
QString domainFromSecret;
|
|
ProxyData::Type proxyKind = ProxyData::Type::None;
|
|
|
|
bool operator==(const CanonicalProxyEndpoint &other) const {
|
|
return (type == other.type)
|
|
&& (originalHost == other.originalHost)
|
|
&& (port == other.port)
|
|
&& (secretHash == other.secretHash)
|
|
&& (domainFromSecret == other.domainFromSecret)
|
|
&& (proxyKind == other.proxyKind);
|
|
}
|
|
};
|
|
|
|
struct RouteEndpoint {
|
|
QString address;
|
|
int port = 0;
|
|
RouteAddressFamily addressFamily = RouteAddressFamily::Unknown;
|
|
ProxyTransport transport = ProxyTransport::Tcp;
|
|
QString resolvedFromHost;
|
|
|
|
bool operator==(const RouteEndpoint &other) const {
|
|
return (address == other.address)
|
|
&& (port == other.port)
|
|
&& (addressFamily == other.addressFamily)
|
|
&& (transport == other.transport)
|
|
&& (resolvedFromHost == other.resolvedFromHost);
|
|
}
|
|
};
|
|
|
|
struct EndpointId {
|
|
CanonicalProxyEndpoint canonical;
|
|
RouteEndpoint route;
|
|
|
|
bool operator==(const EndpointId &other) const {
|
|
return (canonical == other.canonical)
|
|
&& (route == other.route);
|
|
}
|
|
};
|
|
|
|
} // namespace MTP::details::MtProxy
|