Documentation
¶
Overview ¶
Package middleproxy implements the client side of Telegram's MTProto middle proxy (RPC) protocol. It is used to carry a client's traffic through a Telegram middle proxy while advertising a 16-byte ad_tag, which makes a sponsored channel appear in the client. The wire protocol constants and layouts are ported byte-for-byte from 9seconds/mtg v1 (the last mtg version that shipped middle-proxy support) and cross-checked against Telegram's official mtproto-proxy.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DialParams ¶
type DialParams struct {
DC int
ClientAddr *net.TCPAddr
PublicIPv4 net.IP
PublicIPv6 net.IP
// PaddedIntermediate says the client's transport is 0xdddddddd, the only
// one whose frames carry 0-15 bytes of trailing padding. It drives RPC_F_PAD
// and the alignment trim, both of which are a lie for plain intermediate.
PaddedIntermediate bool
AdvertisedPort int
AdTag [adTagLength]byte
}
DialParams carries the addressing the proxy contributes to a middle-proxy dial. ClientAddr is the real client's address (put in RPC_PROXY_REQ). PublicIPv4 and PublicIPv6 optionally override the address the middle proxy sees as our source (needed on multi-homed hosts); the family matching the dialed socket is used. AdvertisedPort is the port reported as ours in RPC_PROXY_REQ.
type Dialer ¶
type Dialer interface {
Dial(network, address string) (essentials.Conn, error)
}
Dialer is the subset of mtglib.Network the manager needs to reach a middle proxy. It is declared here to keep this internal package free of an import cycle back to mtglib.
type Logger ¶
Logger is the minimal logging surface used by the background refresh loop. mtglib.Logger satisfies it.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager fetches and caches Telegram's proxy secret and middle-proxy address lists, and dials RPC proxy streams that carry an ad_tag. It fetches lazily on first use (so a proxy without advertising never touches the network) and then refreshes hourly. It is safe for concurrent use.
func NewManager ¶
func NewManager(ctx context.Context, httpClient *http.Client, logger Logger, preferIP string) *Manager
NewManager builds a Manager. httpClient should be built with the proxy's network settings (e.g. mtglib.Network.MakeHTTPClient) so DNS and upstream proxying apply. preferIP is the proxy's IP connectivity preference. The hourly refresh loop and any in-flight fetches stop when ctx is cancelled.
func (*Manager) DialProxyStream ¶
func (m *Manager) DialProxyStream(dialer Dialer, params DialParams) (essentials.Conn, net.IP, error)
DialProxyStream connects to a middle proxy for params.DC, performs the RPC handshake, and returns an essentials.Conn that transparently carries the client's traffic wrapped in RPC_PROXY_REQ with the ad_tag. It also returns the middle-proxy IP for the connected-to-DC event.