@@ -891,8 +891,11 @@ void ConnectionsManager::onConnectionDataReceived(Connection *connection, Native
891891 TLObject *request;
892892 if (datacenter->isHandshaking (connection->isMediaConnection )) {
893893 request = datacenter->getCurrentHandshakeRequest (connection->isMediaConnection );
894+ if (request == nullptr ) {
895+ return ;
896+ }
894897 } else {
895- request = getRequestWithMessageId (messageId) ;
898+ return ;
896899 }
897900
898901 deserializingDatacenter = datacenter;
@@ -1287,6 +1290,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
12871290 static std::string authRestart = " AUTH_RESTART" ;
12881291 static std::string authKeyPermEmpty = " AUTH_KEY_PERM_EMPTY" ;
12891292 static std::string workerBusy = " WORKER_BUSY_TOO_LONG_RETRY" ;
1293+ static std::string integrityCheckClassic = " INTEGRITY_CHECK_CLASSIC_" ;
12901294 bool processEvenFailed = error->error_code == 500 && error->error_message .find (authRestart) != std::string::npos;
12911295 bool isWorkerBusy = error->error_code == 500 && error->error_message .find (workerBusy) != std::string::npos;
12921296 if (LOGS_ENABLED) DEBUG_E (" request %p rpc error %d: %s" , request, error->error_code , error->error_message .c_str ());
@@ -1301,8 +1305,19 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
13011305 saveConfig ();
13021306 datacenter->beginHandshake (connection->isMediaConnection ? HandshakeTypeMediaTemp : HandshakeTypeTemp, false );
13031307 }
1304- } else if ((request->requestFlags & RequestFlagFailOnServerErrors) == 0 || processEvenFailed) {
1305- if (error->error_code == 500 || error->error_code < 0 ) {
1308+ } else if (error->error_code == 403 && error->error_message .find (integrityCheckClassic) != std::string::npos) {
1309+ discardResponse = true ;
1310+ std::string nonce = error->error_message .substr (integrityCheckClassic.size (), error->error_message .size () - integrityCheckClassic.size ());
1311+ request->awaitingIntegrityCheck = true ;
1312+ request->startTime = 0 ;
1313+ request->startTimeMillis = 0 ;
1314+ if (delegate != nullptr ) {
1315+ delegate->onIntegrityCheckClassic (instanceNum, request->requestToken , nonce);
1316+ }
1317+ } else {
1318+ bool failServerErrors = (request->requestFlags & RequestFlagFailOnServerErrors) == 0 || processEvenFailed;
1319+ bool exceptFloodWait = (request->requestFlags & RequestFlagFailOnServerErrorsExceptFloodWait) != 0 ;
1320+ if (failServerErrors && (error->error_code == 500 || error->error_code < 0 )) {
13061321 static std::string waitFailed = " MSG_WAIT_FAILED" ;
13071322 static std::string waitTimeout = " MSG_WAIT_TIMEOUT" ;
13081323 if (error->error_message .find (waitFailed) != std::string::npos) {
@@ -1318,13 +1333,14 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
13181333 request->serverFailureCount ++;
13191334 }
13201335 discardResponse = true ;
1321- } else if (error->error_code == -504 ) {
1336+ } else if (failServerErrors && error->error_code == -504 ) {
13221337 discardResponse = (request->requestFlags & RequestFlagIgnoreFloodWait) == 0 ;
13231338 request->failedByFloodWait = 2 ;
13241339 request->startTime = 0 ;
13251340 request->startTimeMillis = 0 ;
13261341 request->minStartTime = (int32_t ) (getCurrentTimeMonotonicMillis () / 1000 + 2 );
13271342 } else if (
1343+ (failServerErrors || exceptFloodWait) &&
13281344 error->error_code == 420 && (request->requestFlags & RequestFlagIgnoreFloodWait) == 0 &&
13291345 error->error_message .find (" STORY_SEND_FLOOD" ) == std::string::npos
13301346 ) {
@@ -1363,7 +1379,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
13631379 if (isPremiumFloodWait && delegate != nullptr ) {
13641380 delegate->onPremiumFloodWait (instanceNum, request->requestToken , (request->connectionType & ConnectionTypeUpload) != 0 );
13651381 }
1366- } else if (error->error_code == 400 ) {
1382+ } else if (failServerErrors && error->error_code == 400 ) {
13671383 static std::string waitFailed = " MSG_WAIT_FAILED" ;
13681384 static std::string bindFailed = " ENCRYPTED_MESSAGE_INVALID" ;
13691385 static std::string waitTimeout = " MSG_WAIT_TIMEOUT" ;
@@ -2154,6 +2170,32 @@ void ConnectionsManager::failNotRunningRequest(int32_t token) {
21542170 });
21552171}
21562172
2173+ void ConnectionsManager::receivedIntegrityCheckClassic (int32_t requestToken, std::string nonce, std::string token) {
2174+ scheduleTask ([&, requestToken, nonce, token] {
2175+ for (auto iter = runningRequests.begin (); iter != runningRequests.end (); iter++) {
2176+ Request *request = iter->get ();
2177+ if (requestToken != 0 && request->requestToken == requestToken) {
2178+ auto invokeIntegrity = new invokeWithGooglePlayIntegrity ();
2179+ invokeIntegrity->nonce = nonce;
2180+ invokeIntegrity->token = token;
2181+ invokeIntegrity->query = std::move (request->rpcRequest );
2182+ request->rpcRequest = std::unique_ptr<invokeWithGooglePlayIntegrity>(invokeIntegrity);
2183+
2184+ request->awaitingIntegrityCheck = false ;
2185+ request->requestFlags &=~ RequestFlagFailOnServerErrors;
2186+
2187+ if (LOGS_ENABLED) DEBUG_D (" account%d: received integrity token, wrapping %s" , instanceNum, token.c_str ());
2188+
2189+ processRequestQueue (request->connectionType , request->datacenterId );
2190+
2191+ return ;
2192+ }
2193+ }
2194+
2195+ if (LOGS_ENABLED) DEBUG_E (" account%d: received integrity token but no request %d found" , instanceNum, requestToken);
2196+ });
2197+ }
2198+
21572199void ConnectionsManager::onDatacenterHandshakeComplete (Datacenter *datacenter, HandshakeType type, int32_t timeDiff) {
21582200 saveConfig ();
21592201 uint32_t datacenterId = datacenter->getDatacenterId ();
@@ -2474,13 +2516,13 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
24742516 forceThisRequest = false ;
24752517 }
24762518
2477- if (forceThisRequest || (
2519+ if (( forceThisRequest || (
24782520 abs (currentTime - request->startTime ) > maxTimeout && (
24792521 currentTime >= request->minStartTime ||
24802522 (request->failedByFloodWait != 0 && (request->minStartTime - currentTime) > request->failedByFloodWait ) ||
24812523 (request->failedByFloodWait == 0 && abs (currentTime - request->minStartTime ) >= 60 )
24822524 )
2483- )) {
2525+ )) && !request-> awaitingIntegrityCheck ) {
24842526 if (!forceThisRequest && request->connectionToken > 0 ) {
24852527 if ((request->connectionType & ConnectionTypeGeneric || request->connectionType & ConnectionTypeTemp) && request->connectionToken == connection->getConnectionToken ()) {
24862528 if (LOGS_ENABLED) DEBUG_D (" request token is valid, not retrying %s (%p)" , typeInfo.name (), request->rawRequest );
@@ -3519,12 +3561,9 @@ void ConnectionsManager::applyDnsConfig(NativeByteBuffer *buffer, std::string ph
35193561 if (LOGS_ENABLED) DEBUG_D (" can't decrypt dns config" );
35203562 } else {
35213563 delete config;
3522- if (LOGS_ENABLED) DEBUG_D (" dns config not valid due to date or expire" );
3564+ if (LOGS_ENABLED) DEBUG_D (" dns config not valid due to date or expire, current date = %d, config date = %d, config expired = %d " , currentDate, config-> date , config-> expires );
35233565 }
3524- if (requestingSecondAddress == 2 ) {
3525- requestingSecondAddress = 3 ;
3526- delegate->onRequestNewServerIpAndPort (requestingSecondAddress, instanceNum);
3527- } else if (requestingSecondAddress == 1 ) {
3566+ if (requestingSecondAddress == 1 ) {
35283567 requestingSecondAddress = 2 ;
35293568 delegate->onRequestNewServerIpAndPort (requestingSecondAddress, instanceNum);
35303569 } else if (requestingSecondAddress == 0 ) {
0 commit comments