Fixed handling of bad_server_salt notifications, improved switching of DCs when user is authorized, session ids and sequence numbers will now be resetted on deserialization
This commit is contained in:
parent
dae2375bf3
commit
496d6790bc
@ -8,6 +8,8 @@ PHP implementation of MTProto, based on [telepy](https://github.com/griganton/te
|
||||
|
||||
This project can run on PHP 7, PHP 5.6 and HHVM.
|
||||
|
||||
Also note that MadelineProto will perform better if a big math extension like gmp o bcmath is installed.
|
||||
|
||||
This project is in beta state.
|
||||
|
||||
|
||||
|
@ -178,6 +178,7 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
||||
{
|
||||
$this->setup_logger();
|
||||
$this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
|
||||
$this->reset_session();
|
||||
}
|
||||
|
||||
public function setup_logger()
|
||||
@ -188,23 +189,39 @@ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB
|
||||
}
|
||||
}
|
||||
|
||||
public function reset_session() {
|
||||
foreach ($this->datacenter->sockets as $id => &$socket) {
|
||||
\danog\MadelineProto\Logger::log('Resetting session id and seq_no in DC '.$id.'...');
|
||||
$socket->session_id = \phpseclib\Crypt\Random::string(8);
|
||||
$socket->seq_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Switches to a new datacenter and if necessary creates authorization keys, binds them and writes client info
|
||||
public function switch_dc($new_dc, $allow_nearest_dc_switch = false)
|
||||
{
|
||||
\danog\MadelineProto\Logger::log('Switching to DC '.$new_dc.'...');
|
||||
if ($this->datacenter->curdc !== 0 && $this->datacenter->authorized) {
|
||||
$exported_authorization = $this->method_call('auth.exportAuthorization', ['dc_id' => $new_dc]);
|
||||
}
|
||||
if ($this->datacenter->dc_connect($new_dc)) {
|
||||
$old_dc = $this->datacenter->curdc;
|
||||
if (!isset($this->datacenter->sockets[$new_dc])) {
|
||||
$this->datacenter->dc_connect($new_dc);
|
||||
$this->init_authorization();
|
||||
$this->config = $this->write_client_info('help.getConfig');
|
||||
$this->parse_config();
|
||||
if (isset($exported_authorization)) {
|
||||
$this->datacenter->authorization = $this->method_call('auth.importAuthorization', $exported_authorization);
|
||||
$this->datacenter->authorized = true;
|
||||
}
|
||||
$this->get_nearest_dc($allow_nearest_dc_switch);
|
||||
}
|
||||
if (
|
||||
(isset($this->datacenter->sockets[$old_dc]->authorized) && $this->datacenter->sockets[$old_dc]->authorized) &&
|
||||
!(isset($this->datacenter->sockets[$new_dc]->authorized) && $this->datacenter->sockets[$new_dc]->authorized && $this->datacenter->sockets[$new_dc]->authorization['user']['id'] === $this->datacenter->sockets[$old_dc]->authorization['user']['id'])
|
||||
) {
|
||||
$this->datacenter->curdc = $old_dc;
|
||||
$exported_authorization = $this->method_call('auth.exportAuthorization', ['dc_id' => $new_dc]);
|
||||
$this->datacenter->curdc = $new_dc;
|
||||
if (isset($this->datacenter->sockets[$new_dc]->authorized) && $this->datacenter->sockets[$new_dc]->authorized && $this->datacenter->sockets[$new_dc]->authorization['user']['id'] !== $this->datacenter->sockets[$old_dc]->authorization['user']['id']) {
|
||||
$this->method_call('auth.logOut');
|
||||
}
|
||||
$this->datacenter->authorization = $this->method_call('auth.importAuthorization', $exported_authorization);
|
||||
$this->datacenter->authorized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates authorization keys
|
||||
|
@ -69,7 +69,7 @@ class MessageHandler extends Crypt
|
||||
|
||||
$server_salt = \danog\PHP\Struct::unpack('<q', substr($decrypted_data, 0, 8))[0];
|
||||
if ($server_salt != $this->datacenter->temp_auth_key['server_salt']) {
|
||||
throw new \danog\MadelineProto\Exception('Server salt mismatch (my server salt '.$this->datacenter->temp_auth_key['server_salt'].' is not equal to server server salt '.$server_salt.').');
|
||||
\danog\MadelineProto\Logger::log('WARNING: Server salt mismatch (my server salt '.$this->datacenter->temp_auth_key['server_salt'].' is not equal to server server salt '.$server_salt.').');
|
||||
}
|
||||
|
||||
$session_id = substr($decrypted_data, 8, 8);
|
||||
|
@ -43,6 +43,7 @@ class ResponseHandler extends MsgIdHandler
|
||||
$this->datacenter->incoming_messages[$last_received]['content'] = $response;
|
||||
break;
|
||||
|
||||
case 'bad_server_salt':
|
||||
case 'bad_msg_notification':
|
||||
$error_codes = [
|
||||
16 => 'msg_id too low (most likely, client time is wrong; it would be worthwhile to synchronize it using msg_id notifications and re-send the original message with the “correct” msg_id or wrap it in a container with a new msg_id if the original message had waited too long on the client to be transmitted)',
|
||||
@ -57,13 +58,15 @@ class ResponseHandler extends MsgIdHandler
|
||||
48 => 'incorrect server salt (in this case, the bad_server_salt response is received with the correct salt, and the message is to be re-sent with it)',
|
||||
64 => 'invalid container.',
|
||||
];
|
||||
switch ($response['error_code']) {
|
||||
case 48:
|
||||
$this->datacenter->temp_auth_key['server_salt'] = $response['new_server_salt'];
|
||||
$this->ack_outgoing_message_id($response['bad_msg_id']); // Acknowledge that the server received my request
|
||||
throw new \danog\MadelineProto\Exception('New server salt stored, re-executing query');
|
||||
break;
|
||||
}
|
||||
throw new \danog\MadelineProto\RPCErrorException('Received bad_msg_notification for '.$response['bad_msg_id'].': '.$error_codes[$response['error_code']]);
|
||||
break;
|
||||
case 'bad_server_salt':
|
||||
$this->datacenter->temp_auth_key['server_salt'] = $response['new_server_salt'];
|
||||
$this->ack_outgoing_message_id($response['bad_msg_id']); // Acknowledge that the server received my request
|
||||
$this->datacenter->outgoing_messages[$response['bad_msg_id']]['response'] = $last_received;
|
||||
$this->datacenter->incoming_messages[$last_received]['content'] = $response;
|
||||
break;
|
||||
|
||||
case 'pong':
|
||||
|
Loading…
Reference in New Issue
Block a user