diff --git a/data/web/corefork.telegram.org/api/folders.html b/data/web/corefork.telegram.org/api/folders.html
index 60310133ba..8a0a43b5e9 100644
--- a/data/web/corefork.telegram.org/api/folders.html
+++ b/data/web/corefork.telegram.org/api/folders.html
@@ -82,7 +82,7 @@ Folders can also have up to dialogs_folder_pinned_limit_*
pinned ch
Clients can receive updateDialogFilter, updateDialogFilterOrder updates with new filter information, generated by other clients when modifying folder info.
Clients can also receive updateDialogFilters, in which case folder info should be refetched manually using messages.getDialogFilters.
The API also has another method for identifying groups of peers, typically used only by archived chats.
+The API also has another method for identifying groups of peers, used by archived chats.
Schema:
inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer;
inputDialogPeerFolder#64600527 folder_id:int = InputDialogPeer;
diff --git a/data/web/corefork.telegram.org/api/updates.html b/data/web/corefork.telegram.org/api/updates.html
index 2b066be8b1..81b6a6bcc9 100644
--- a/data/web/corefork.telegram.org/api/updates.html
+++ b/data/web/corefork.telegram.org/api/updates.html
@@ -64,15 +64,15 @@
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
updatesTooLong indicates that there are too many events pending to be pushed to the client, so one needs to fetch them manually.
Events inside updateShort constructors, normally, have lower priority and are broadcast to a large number of users, i.e. one of the chat participants started entering text in a big conversation (updateChatUserTyping).
-The updateShortMessage, updateShortSentMessage and updateShortChatMessage constructors are redundant but help significantly reduce the transmitted message size for 90% of the updates. They should be transformed to updateShort upon receiving.
-Two remaining constructors updates and updatesCombined are part of the Updates sequence. Both of them have seq
attribute, which indicates the remote Updates state after the generation of the Updates, and seq_start
indicates the remote Updates state after the first of the Updates in the packet is generated. For updates, seq_start
attribute is omitted, because it is assumed that it is always equal to seq
.
The updateShortMessage, updateShortSentMessage and updateShortChatMessage constructors are redundant but help significantly reduce the transmitted message size for 90% of the updates. They should be transformed to updateShort upon receival.
+Two remaining constructors updates and updatesCombined are part of the Updates sequence. Both of them have the seq
attribute, which indicates the remote Updates state after the generation of the Updates, and seq_start
indicates the remote Updates state after the first of the Updates in the packet is generated. For updates, seq_start
attribute is omitted, because it is assumed that it is always equal to seq
.
Each event related to a message box (message created, message edited, message deleted, etc) is identified by a unique autoincremented pts, or qts in case of secret chat updates, certain bot updates, etc.
+Each event related to a message box (message created, message edited, message deleted, etc) is identified by a unique autoincremented pts
, or qts
in case of secret chat updates, certain bot updates, etc.
Each message box can be considered as some server-side DB table that stores messages and events associated with them. All boxes are completely independent, and each pts sequence is tied to just one box (see below).
-Update object may contain info about multiple events (for example, updateDeleteMessages).
-That's why all single updates might have pts_count parameter indicating the number of events contained in the received update (with some exceptions, in this case, the pts_count is considered to be 0
).
Each channel and supergroup has its message box and its event sequence as a result; private chats and basic groups of one user have another common event sequence. +
The Update object may contain info about multiple events (for example, updateDeleteMessages).
+That's why all single updates might have pts_count
parameter indicating the number of events contained in the received update (with some exceptions, in this case, the pts_count
is considered to be 0
).
Each channel and supergroup has its message box and its event sequence as a result; private chats and basic groups of one user have another common event sequence.
Secret chats, certain bot events and other kinds of updates have yet another common secondary event sequence.
To recap, the client has to take care of the integrity of the following sequences to properly handle updates:
The channel update state is represented simply by the pts of the event sequence: when first logging in, the initial channel state can be obtained from the dialog constructor when fetching dialogs, from the full channel info, or it can be received as an updateChannelTooLong update.
-The secondary update state is represented by the qts of the secret event sequence, it is contained in the updates.State of the common update state.
-The Updates sequence state is represented by the date and seq of the Updates sequence, it is contained in the updates.State of the common update state.
+The channel update state is represented simply by the pts
of the event sequence: when first logging in, the initial channel state can be obtained from the dialog constructor when fetching dialogs, from the full channel info, or it can be received as an updateChannelTooLong update.
The secondary update state is represented by the qts
of the secret event sequence, it is contained in the updates.State of the common update state.
The Updates sequence state is represented by the date
and seq
of the Updates sequence, it is contained in the updates.State of the common update state.
Update handling in Telegram clients consists of receiving events, making sure there were no gaps and no events were missed based on the locally stored state of the correspondent event sequence, and then updating the locally stored state based on the parameters received.
When the client receives payload with serialized updates, first of all, it needs to walk through all of the nested Update objects and check if they belong to any of message box sequences (have pts
or qts
parameters). Those updates need to be handled separately according to corresponding local state and new pts
/qts
values. Details below »
0xef
(abridged).
Bytes 4-8
must also not be equal to 0x00000000
, since that would indicate use of the full transport with the initial TCP sequence number (0).
The protocol identifier, if present, must be inserted in the initialization payload at byte offset 56
: if its length is less than 4, it must be padded using the protocol identifier itself, to make its length 4 (0xef
=> 0xefefefef
): the standalone protocol identifier must be not be sent aftwerwards.
This protocol is also (but not exclusively) used when connecting to MTProxies: only in this case, the DC ID in a specially encoded form must also be inserted in the initialization payload at offset 60
.
-The encoding simply consist of the DC ID in two-byte signed little-endian form; 10000
has to be added to the DC ID to connect to the test servers; it has to be made negative if the DC we're connecting to is a media (not CDN) DC.
10000
has to be added to the DC ID to connect to the test servers; it has to be made negative if the DC we're connecting to is a media (not CDN) DC.
Next, a secondary initialization payload is generated by reversing the primary initialization payload.
Two keys are extracted from both initialization payloads, using bytes at offsets 8-40
: the key extracted from the primary payload is used as encryption key, the key extracted from the secondary payload is used as decryption key.
Two IVs are extracted from both initialization payloads, using bytes at offsets 40-56
: the IV extracted from the primary payload is used as encryption IV, the IV extracted from the secondary payload is used as decryption IV.
Often, a 17-byte version of the secret can be found: this simply indicates that the client should use a specific MTProto transport (based on the first byte, usually it's 0xdd
, to indicate that the padded intermediate protocol should be used 0xdddddddd
; however, clients should default to the padded intermediate transport whenever an additional byte in the secret is encountered).
The extracted encryption and decryption keys must be concatenated with the secret (the first byte of which should be ignored if it's the 17-byte version), and the SHA256 hash of such string should be used as encryption/decryption key.
-The obtained encryption and decryption key/IV pairs must then be used with AES-256-CTR to encrypt and decrypt all outgoing and incoming payloads.
+The obtained encryption and decryption key/IV pairs must then be used with AES-256-CTR to encrypt and decrypt all outgoing and incoming payloads.
+The encryption and decryption counters must be reused for every payload, until the TCP/WS connection is closed.
+In other words, reuse the same AES-256-CTR OpenSSL instance until the connection is closed.
The first thing that must be encrypted using the encryption key is the initialization payload itself.
Then bytes 56-64
of the encrypted initialization payload are substituted in the original initialization payload: this is the part that contains the constant MTProto transport protocol identifier and the DC ID (only for MTProxies).
The final initialization payload must then be sent in the socket as first 64 bytes after the TCP handshake.
diff --git a/data/web/corefork.telegram.org/schema/mtproto.html b/data/web/corefork.telegram.org/schema/mtproto.html index c4e75b90f1..8c07b2d6a6 100644 --- a/data/web/corefork.telegram.org/schema/mtproto.html +++ b/data/web/corefork.telegram.org/schema/mtproto.html @@ -115,6 +115,8 @@ destroy_auth_key_ok#f660e1d4 = DestroyAuthKeyRes; destroy_auth_key_none#0a9f2259 = DestroyAuthKeyRes; destroy_auth_key_fail#ea109b13 = DestroyAuthKeyRes; +http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait; + ---functions--- req_pq_multi#be7e8ef1 nonce:int128 = ResPQ; @@ -129,8 +131,6 @@ ping#7abe77ec ping_id:long = Pong; ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong; destroy_session#e7512126 session_id:long = DestroySessionRes; -http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait; - destroy_auth_key#d1435160 = DestroyAuthKeyRes;