TCP is the only active MTProto transport on Telegram-iOS as I explained in the previous post. Let’s continue with the implementation details of connection management for MTProto.

The major parts of network code reside in modules [TelegramCore](https://github.com/TelegramMessenger/Telegram-iOS/tree/release-6.1.2/submodules/TelegramCore) and [MTProtoKit](https://github.com/TelegramMessenger/Telegram-iOS/tree/release-6.1.2/submodules/MtProtoKit). I started my reading to answer a simple question:

How many connections are used by MTProtoKit during the first login process?

The result surprised me: **20** TCP connections to Telegram data centers and **8** HTTPS requests to external services. The common best practice should be using as few connections as possible.

Before diving into the code to reveal the reason, please let me introduce some important concepts.

1. Basic Concepts of Connections

Data Center

Telegram divides its backend servers into 5 data centers. Each has an id and an alias. Alias is useful to compose URIs for HTTP transport, which is not used in the iOS app. Telegram backend associates a registered account to a master DC id. It requires the client to use the correct master data center to access the user data and might use other DC ids to download images, files, etc.

DC 1, pluto

DC 2, venus

DC 3, aurora

DC 4, vesta

DC 5, flora

Each data center can be connected via multiple IP addresses. It’s common to NOT use domain names directly due to several reasons:

  • The system DNS service might be unstable, or even untrustful.
  • IP addresses and ports need to change frequently to react to network issues. Static IPs could be inaccessible in some regions. Then elastic IPs could be deployed to proxy traffic to data centers. The app should be able to update its endpoint configuration in time.
  • Solutions like Geo DNS is good for very coarse-grained IP selection. It’s better for the backend to control it directly.

Telegram-iOS includes several seed addresses for a cold start:

let seedAddressList: [Int: [String]]

	seedAddressList = [
	    1: ["149.154.175.50", "2001:b28:f23d:f001::a"],   //AS59930
	    2: ["149.154.167.50", "2001:67c:4e8:f002::a"],    //AS62041
	    3: ["149.154.175.100", "2001:b28:f23d:f003::a"],  //AS59930
	    4: ["149.154.167.91", "2001:67c:4e8:f004::a"],    //AS62041
	    5: ["149.154.171.5", "2001:b28:f23f:f005::a"]     //AS62014
	]

Telegram owns four AS numbers to announce the IPs: AS62014AS62041AS59930, and AS44907. More static IPs can be found by searching with the AS numbers if you’re interested in it.

Endpoint Discovery

Telegram-iOS can update endpoints from internal and external services. The approaches work as complementary to others to maximize the success rate of updating. The result is persisted in Keychain with key [datacenterAddressSetById](https://github.com/TelegramMessenger/Telegram-iOS/blob/release-6.1.2/submodules/MtProtoKit/Sources/MTContext.m#L340).

  • DNS-over-HTTPS via the JSON API from Google Public DNStapv3.stel.com is the hostname to resolve, and the parameter random_padding is set to prevent possible side-channel attacks. An example of request and response is below:
// https://dns.google.com/resolve?name=apv3.stel.com&type=16&random_padding=Fw8ZQonqP0qOqoa
	{
	  "Status": 0,
	  "Question": [
	    {
	      "name": "apv3.stel.com.",
	      "type": 16
	    }
	  ],
	  "Answer": [
	    {
	      "name": "apv3.stel.com.",
	      "type": 16,
	      "data": "\"vEB1g6iW/a5RtZI/Rx33SEzLmRhz+vNenoY7iqAHW35plgToLfkNRVfvlaBsztOTeYSRqFko73rr2lumKmGax2biMcSQ==\""
	    },
	    {
	      "name": "apv3.stel.com.",
	      "type": 16,
	      "data": "\"pEI+NHncHJCj9S0XzxhhTd3bkPteVxE5UQ8T06KCz0nP591un4Un82id0FyCEDF0BVmxMp+t673l3HAGD+fzR/qaJ1XpQ6KWxNpRLqA74m2UFTI1REP7ZczU2hmbURzSQvWQTxfp9tnGc1EnyqpUYphFb/Vi+sV83iaw6dTGOcKW1Kp/PW2xV99mmSFLBsspQRdUbKWvbrSpmXHbPbkSRZV61NvtaEiODG1We29nG58DUBqdW7m68ae11w\""
	    }
	  ]
	}

Google service responds with several DNS TXT records, that can be merged and transformed into a valid base64 string. The client has the RSA public key to decode the data and deserialize it into a list of [MTBackupDatacenterAddress](https://github.com/TelegramMessenger/Telegram-iOS/blob/release-6.1.2/submodules/MtProtoKit/Sources/MTEncryption.m#L834).

#ios #telegram #ios-app-development

Source Code Walkthrough of Telegram-iOS Part 4: MTProto Connections
4.45 GEEK