MtProtoKit: dont drop the salt from bad_server_salt on normal requests (fixes infinite "Connecting" after backgrounding on iOS)#2197
Open
sleep3r wants to merge 1 commit into
Conversation
…only the time-fix ping fixes the infinite Connecting/Updating on iOS after backgrounding (telemt/telemt#582)
|
No findings. Great job! 🎉 🔍 Reviewed by nitpicker |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
looked into the thing from telemt/telemt#582 (ios gets stuck on "Connecting"/"Updating" basically forever after the app has been in background for a while, force-killing the app fixes it, android on the same network and same server is totally fine). turns out it's a salt handling bug in MtProtoKit and has nothing to do with the proxy
what's going on
after a longer background the cached server salt is stale. on the new connection the dc answers
bad_server_saltalmost immediately and that message already carries a fresh valid salt. but in-[MTProto _processIncomingMessage:]the bad_server_salt branch only applies the salt when the rejected message is the in-flight time fix ping:on resume what you actually send is normal requests, so it goes into the else, drops the salt and calls
initiateTimeSync, which setsMTProtoStateAwaitingTimeFixAndSalts. while that bit is setcanAskForTransactionsis false, so none of the queued requests ever leave. from there recovery depends entirely on the time fix ping coming back, and nothing rescues it if it doesnt:_timeFixContexthas no timeout (timeFixAbsoluteStartTimeis stored but never read anywhere)MTTcpTransportis behind#if falseso the session just sits there silent until the dc closes the socket from its side (~90-120s), and only the reconnect after that actually works. that's the stuck "Connecting"/"Updating" people are seeing. android (tgnet) doesnt hit it because it drops idle connections a few seconds into background, so it always comes back on a fresh session
the fix
the salt in
bad_server_saltcomes inside the aes-ige envelope under the auth key, so it's exactly as trustworthy when it rejects a normal request as when it rejects the time fix ping. so just apply it in both cases and keep the_timeFixContextcheck only for clearing the context:completeTimeSyncis a no-op when the awaiting flag isnt set, andtimeSyncInfoChanged:already merges the salt and callsrequestTransportTransaction, so the queued requests go straight out with the right salt. the matched (time fix) path behaves exactly like before. left the bad_msg codes 16/17/32/33/48 as is since those are about msg id / time, not the saltwith this the whole resume batch (getDifference included) goes through in well under a second on the first bad_server_salt, instead of hanging until the server gives up on the connection