Skip to content

fix(telegram): use permanent key only for CDN connections#1772

Merged
ernado merged 1 commit into
gotd:mainfrom
pylakey:fix/cdn-skip-pfs-bind
Jun 12, 2026
Merged

fix(telegram): use permanent key only for CDN connections#1772
ernado merged 1 commit into
gotd:mainfrom
pylakey:fix/cdn-skip-pfs-bind

Conversation

@pylakey

@pylakey pylakey commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Problem

With PFS enabled (telegram.WithPFS / Options.EnablePFS), connecting to a CDN datacenter fails. After generating the permanent and temporary auth keys, the connection sends auth.bindTempAuthKey, which a CDN DC rejects:

rpc error code 400: CDN_METHOD_INVALID

The connection is then torn down, so any request routed to that CDN DC — in particular file downloads that follow an upload.fileCdnRedirect — can never acquire a usable connection. It fails on the first chunk and on every retry.

Root cause: the temporary-key bind is gated solely by the per-connection PFS flag (mtproto.Options.EnablePFS). CDN pools are created from a copy of the client options and inherit that flag. The CDN connection mode (manager.ConnModeCDN) is already threaded through the rest of the connection setup (CDN public keys, skipping help.getConfig, separate sessions, no auth transfer), but it is not consulted at the bind decision — so a CDN connection still attempts auth.bindTempAuthKey.

Official client behavior

CDN datacenters are authenticated with a permanent key only; PFS / temp-key binding is intentionally disabled for them:

  • TDLib forces PFS off for CDN: SessionMultiProxy::get_pfs_flag() returns use_pfs_ && !is_cdn_, so need_send_bind_key() is always false and auth.bindTempAuthKey is never sent on a CDN connection.
  • Telegram for Android (tgnet) selects the auth key with usePermKey = isCdnDatacenter || perm || !PFS_ENABLED and never starts a temp-key handshake for a CDN datacenter, so it never calls bindTempAuthKey there.

Fix

Disable PFS for CDN connections in (*Client).dc. The CDN branch operates on a local copy of the options, so PFS stays enabled for the primary and data DCs — only CDN connections become permanent-key-only, matching the official clients.

Test

TestClientCDNDisablesPFS: with PFS enabled globally, asserts that the options passed to a CDN connection have EnablePFS == false.

CDN datacenters reject auth.bindTempAuthKey with CDN_METHOD_INVALID, so a
CDN connection must authenticate with a permanent key only. With PFS enabled
globally, CDN pools inherited EnablePFS and attempted the temp-key bind,
tearing down the connection and breaking requests routed to a CDN DC
(notably downloads following upload.fileCdnRedirect). Disable PFS for the
CDN pool only; the primary and data connections keep PFS. Mirrors the
official clients (tdlib get_pfs_flag = use_pfs && !is_cdn; android
usePermKey = isCdnDatacenter || ...).
@ernado ernado self-assigned this Jun 12, 2026
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 71.06%. Comparing base (5bd59ff) to head (f259e1a).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1772      +/-   ##
==========================================
- Coverage   71.10%   71.06%   -0.05%     
==========================================
  Files         501      501              
  Lines       23501    23502       +1     
==========================================
- Hits        16711    16702       -9     
- Misses       5569     5574       +5     
- Partials     1221     1226       +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ernado ernado merged commit 6138c4a into gotd:main Jun 12, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants