Completely rewrite auth key and connection management, proxy fixes.

This commit is contained in:
Daniil Gentili 2017-12-23 02:03:07 +01:00
parent 43adf77378
commit cca40a34ad
10 changed files with 141 additions and 95 deletions

View File

@ -92,7 +92,6 @@ class API extends APIFactory
{ {
//if (method_exists($this->API, 'wakeup')) $this->API = $this->API->wakeup(); //if (method_exists($this->API, 'wakeup')) $this->API = $this->API->wakeup();
Serialization::$instances[spl_object_hash($this)] = $this; Serialization::$instances[spl_object_hash($this)] = $this;
$this->APIFactory(); $this->APIFactory();
} }

View File

@ -42,7 +42,7 @@ class Connection
public $proxy = '\Socket'; public $proxy = '\Socket';
public $extra = []; public $extra = [];
public $obfuscated = []; public $obfuscated = [];
public $authorized = false;
public $call_queue = []; public $call_queue = [];
public $i = []; public $i = [];
@ -218,7 +218,7 @@ class Connection
public function __sleep() public function __sleep()
{ {
return ['proxy', 'extra', 'protocol', 'ip', 'port', 'timeout', 'parsed', 'time_delta', 'temp_auth_key', 'auth_key', 'session_id', 'session_out_seq_no', 'session_in_seq_no', 'ipv6', 'incoming_messages', 'outgoing_messages', 'new_incoming', 'new_outgoing', 'max_incoming_id', 'max_outgoing_id', 'obfuscated']; return ['proxy', 'extra', 'protocol', 'ip', 'port', 'timeout', 'parsed', 'time_delta', 'temp_auth_key', 'auth_key', 'session_id', 'session_out_seq_no', 'session_in_seq_no', 'ipv6', 'incoming_messages', 'outgoing_messages', 'new_incoming', 'new_outgoing', 'max_incoming_id', 'max_outgoing_id', 'obfuscated', 'authorized'];
} }
public function __wakeup() public function __wakeup()

View File

@ -22,8 +22,8 @@ class DataCenter
public $sockets = []; public $sockets = [];
public $curdc = 0; public $curdc = 0;
public $dclist = []; private $dclist = [];
public $settings = []; private $settings = [];
/* /*
public $i = []; public $i = [];
@ -46,9 +46,9 @@ class DataCenter
$this->settings = $settings; $this->settings = $settings;
foreach ($this->sockets as $key => $socket) { foreach ($this->sockets as $key => $socket) {
if ($socket instanceof Connection) { if ($socket instanceof Connection) {
\danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['dc_con_start'], $key)], \danog\MadelineProto\Logger::VERBOSE); \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['dc_con_stop'], $key)], \danog\MadelineProto\Logger::VERBOSE);
$socket->old = true; $socket->old = true;
$socket->close_and_reopen(); $socket->__destruct();
} else { } else {
unset($this->sockets[$key]); unset($this->sockets[$key]);
} }
@ -68,16 +68,26 @@ class DataCenter
public function dc_connect($dc_number) public function dc_connect($dc_number)
{ {
$this->curdc = $dc_number;
if (isset($this->sockets[$dc_number]) && !isset($this->sockets[$dc_number]->old)) { if (isset($this->sockets[$dc_number]) && !isset($this->sockets[$dc_number]->old)) {
return false; return false;
} }
$dc_config_number = isset($this->settings[$dc_number]) ? $dc_number : 'all'; $dc_config_number = isset($this->settings[$dc_number]) ? $dc_number : 'all';
$test = $this->settings[$dc_config_number]['test_mode'] ? 'test' : 'main'; $test = $this->settings[$dc_config_number]['test_mode'] ? 'test' : 'main';
$ipv6 = $this->settings[$dc_config_number]['ipv6'] ? 'ipv6' : 'ipv4'; $ipv6 = $this->settings[$dc_config_number]['ipv6'] ? 'ipv6' : 'ipv4';
if (!isset($this->dclist[$test][$ipv6][$dc_number]['ip_address'])) {
unset($this->sockets[$dc_number]);
return false;
}
$address = $this->dclist[$test][$ipv6][$dc_number]['ip_address']; $address = $this->dclist[$test][$ipv6][$dc_number]['ip_address'];
//$address = $this->settings[$dc_config_number]['ipv6'] ? '['.$address.']' : $address;
$port = $this->dclist[$test][$ipv6][$dc_number]['port']; $port = $this->dclist[$test][$ipv6][$dc_number]['port'];
if (isset($this->dclist[$test][$ipv6][$dc_number]['tcpo_only']) && $this->dclist[$test][$ipv6][$dc_number]['tcpo_only']) {
if ($dc_config_number === 'all') $dc_config_number = $dc_number;
if (!isset($this->settings[$dc_config_number])) $this->settings[$dc_config_number] = $this->settings['all'];
$this->settings[$dc_config_number]['protocol'] = 'obfuscated2';
}
if ($this->settings[$dc_config_number]['protocol'] === 'https') { if ($this->settings[$dc_config_number]['protocol'] === 'https') {
$subdomain = $this->dclist['ssl_subdomains'][$dc_number]; $subdomain = $this->dclist['ssl_subdomains'][$dc_number];
$path = $this->settings[$dc_config_number]['test_mode'] ? 'apiw_test1' : 'apiw1'; $path = $this->settings[$dc_config_number]['test_mode'] ? 'apiw_test1' : 'apiw1';
@ -90,14 +100,53 @@ class DataCenter
} }
\danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['dc_con_test_start'], $dc_number, $test, $ipv6, $this->settings[$dc_config_number]['protocol'])], \danog\MadelineProto\Logger::VERBOSE); \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['dc_con_test_start'], $dc_number, $test, $ipv6, $this->settings[$dc_config_number]['protocol'])], \danog\MadelineProto\Logger::VERBOSE);
if (isset($this->sockets[$dc_number]->old)) { $x = 0;
$this->sockets[$dc_number]->__construct($this->settings[$dc_config_number]['proxy'], $this->settings[$dc_config_number]['proxy_extra'], $address, $port, $this->settings[$dc_config_number]['protocol'], $this->settings[$dc_config_number]['timeout'], $this->settings[$dc_config_number]['ipv6']); do {
unset($this->sockets[$dc_number]->old); try {
} else { if (isset($this->sockets[$dc_number]->old)) {
$this->sockets[$dc_number] = new Connection($this->settings[$dc_config_number]['proxy'], $this->settings[$dc_config_number]['proxy_extra'], $address, $port, $this->settings[$dc_config_number]['protocol'], $this->settings[$dc_config_number]['timeout'], $this->settings[$dc_config_number]['ipv6']); $this->sockets[$dc_number]->__construct($this->settings[$dc_config_number]['proxy'], $this->settings[$dc_config_number]['proxy_extra'], $address, $port, $this->settings[$dc_config_number]['protocol'], $this->settings[$dc_config_number]['timeout'], $this->settings[$dc_config_number]['ipv6']);
} unset($this->sockets[$dc_number]->old);
} else {
$this->sockets[$dc_number] = new Connection($this->settings[$dc_config_number]['proxy'], $this->settings[$dc_config_number]['proxy_extra'], $address, $port, $this->settings[$dc_config_number]['protocol'], $this->settings[$dc_config_number]['timeout'], $this->settings[$dc_config_number]['ipv6']);
}
\danog\MadelineProto\Logger::log(['OK!'], \danog\MadelineProto\Logger::WARNING);
return true;
} catch (\danog\MadelineProto\Exception $e) {
} catch (\danog\MadelineProto\NothingInTheSocketException $e) { ; }
return true; switch ($x) {
case 0:
\danog\MadelineProto\Logger::log(['Connection failed, retrying connection on port 443...'], \danog\MadelineProto\Logger::WARNING);
$port = 443;
continue;
case 1:
\danog\MadelineProto\Logger::log(['Connection failed, retrying connection on port 80...'], \danog\MadelineProto\Logger::WARNING);
$port = 80;
continue;
case 2:
\danog\MadelineProto\Logger::log(['Connection failed, retrying connection on port 88...'], \danog\MadelineProto\Logger::WARNING);
$port = 88;
continue;
case 3:
\danog\MadelineProto\Logger::log(['Connection failed, retrying connection on port 443 without the proxy...'], \danog\MadelineProto\Logger::WARNING);
$port = 443;
$this->settings[$dc_config_number]['proxy'] = '\Socket';
continue;
case 4:
\danog\MadelineProto\Logger::log(['Connection failed, retrying connection on port 80 without the proxy...'], \danog\MadelineProto\Logger::WARNING);
$port = 80;
$this->settings[$dc_config_number]['proxy'] = '\Socket';
continue;
case 5:
\danog\MadelineProto\Logger::log(['Connection failed, retrying connection on port 88 without the proxy...'], \danog\MadelineProto\Logger::WARNING);
$port = 88;
$this->settings[$dc_config_number]['proxy'] = '\Socket';
continue;
default:
return false;
}
} while (++$x);
return false;
} }
public function get_dcs($all = true) public function get_dcs($all = true)

View File

@ -46,7 +46,7 @@ class MTProto
/* /*
const V = 71; const V = 71;
*/ */
const V = 82; const V = 83;
const NOT_LOGGED_IN = 0; const NOT_LOGGED_IN = 0;
const WAITING_CODE = 1; const WAITING_CODE = 1;
@ -202,13 +202,10 @@ class MTProto
$this->emojis = json_decode(self::JSON_EMOJIS); $this->emojis = json_decode(self::JSON_EMOJIS);
\danog\MadelineProto\Logger::class_exists(); \danog\MadelineProto\Logger::class_exists();
// Detect ipv6
$this->ipv6 = (bool) strlen(@file_get_contents('http://ipv6.test-ipv6.com/', false, stream_context_create(['http' => ['timeout' => 1]]))) > 0;
// Connect to servers // Connect to servers
\danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['inst_dc']], Logger::ULTRA_VERBOSE); \danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['inst_dc']], Logger::ULTRA_VERBOSE);
if (isset($this->datacenter)) { if (isset($this->datacenter)) {
$this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']); $this->connect_to_all_dcs();//datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
} else { } else {
$this->datacenter = new DataCenter($this->settings['connection'], $this->settings['connection_settings']); $this->datacenter = new DataCenter($this->settings['connection'], $this->settings['connection_settings']);
} }
@ -271,7 +268,6 @@ class MTProto
{ {
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']); set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
set_exception_handler(['\danog\MadelineProto\Serialization', 'serialize_all']); set_exception_handler(['\danog\MadelineProto\Serialization', 'serialize_all']);
$this->setup_logger(); $this->setup_logger();
if (\danog\MadelineProto\Logger::$has_thread && is_object(\Thread::getCurrentThread())) { if (\danog\MadelineProto\Logger::$has_thread && is_object(\Thread::getCurrentThread())) {
return; return;
@ -284,25 +280,8 @@ class MTProto
if (!defined('\phpseclib\Crypt\AES::MODE_IGE')) { if (!defined('\phpseclib\Crypt\AES::MODE_IGE')) {
throw new Exception(\danog\MadelineProto\Lang::$current_lang['phpseclib_fork']); throw new Exception(\danog\MadelineProto\Lang::$current_lang['phpseclib_fork']);
} }
foreach ($this->calls as $id => $controller) { $this->settings['connection_settings']['all']['ipv6'] = (bool) strlen(@file_get_contents('http://ipv6.test-ipv6.com/', false, stream_context_create(['http' => ['timeout' => 1]]))) > 0; // decides whether to use ipv6, ipv6 attribute of API attribute of API class contains autodetected boolean
if (!is_object($controller)) {
unset($this->calls[$id]);
} elseif ($controller->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_ENDED) {
$controller->setMadeline($this);
$controller->discard();
} else {
$controller->setMadeline($this);
}
}
// Detect ipv6
$oldipv6 = $this->ipv6;
$this->ipv6 = (bool) strlen(@file_get_contents('http://ipv6.test-ipv6.com/', false, stream_context_create(['http' => ['timeout' => 1]]))) > 0;
if ($oldipv6 !== $this->ipv6) {
$this->settings['connection_settings']['all']['ipv6'] = $this->ipv6;
$this->datacenter->settings = $this->settings['connection_settings'];
$this->connect_to_all_dcs();
}
preg_match('/const V = (\d+);/', @file_get_contents('https://raw.githubusercontent.com/danog/MadelineProto/master/src/danog/MadelineProto/MTProto.php'), $matches); preg_match('/const V = (\d+);/', @file_get_contents('https://raw.githubusercontent.com/danog/MadelineProto/master/src/danog/MadelineProto/MTProto.php'), $matches);
$keys = array_keys((array) get_object_vars($this)); $keys = array_keys((array) get_object_vars($this));
if (count($keys) !== count(array_unique($keys))) { if (count($keys) !== count(array_unique($keys))) {
@ -328,6 +307,7 @@ class MTProto
$this->reset_session(); $this->reset_session();
if (!isset($this->v) || $this->v !== self::V) { if (!isset($this->v) || $this->v !== self::V) {
\danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['serialization_ofd']], Logger::WARNING); \danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['serialization_ofd']], Logger::WARNING);
foreach ($this->datacenter->sockets as $dc_id => $socket) { if ($this->authorized === self::LOGGED_IN && strpos($dc_id, '_') === false) $socket->authorized = true; } //$this->authorized === self::LOGGED_IN; }
$settings = $this->settings; $settings = $this->settings;
if (isset($settings['updates']['callback'][0]) && $settings['updates']['callback'][0] === $this) { if (isset($settings['updates']['callback'][0]) && $settings['updates']['callback'][0] === $this) {
$settings['updates']['callback'] = 'get_updates_update_handler'; $settings['updates']['callback'] = 'get_updates_update_handler';
@ -378,7 +358,17 @@ class MTProto
$this->channels_state = []; $this->channels_state = [];
$this->got_state = false; $this->got_state = false;
} }
$this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']); $this->connect_to_all_dcs();//datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
foreach ($this->calls as $id => $controller) {
if (!is_object($controller)) {
unset($this->calls[$id]);
} elseif ($controller->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_ENDED) {
$controller->setMadeline($this);
$controller->discard();
} else {
$controller->setMadeline($this);
}
}
if ($this->get_self()) { if ($this->get_self()) {
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
} }
@ -490,7 +480,7 @@ class MTProto
'all' => [ // These settings will be applied on every datacenter that hasn't a custom settings subarray... 'all' => [ // These settings will be applied on every datacenter that hasn't a custom settings subarray...
'protocol' => 'tcp_full', // can be tcp_full, tcp_abridged, tcp_intermediate, http, https, obfuscated2, udp (unsupported) 'protocol' => 'tcp_full', // can be tcp_full, tcp_abridged, tcp_intermediate, http, https, obfuscated2, udp (unsupported)
'test_mode' => false, // decides whether to connect to the main telegram servers or to the testing servers (deep telegram) 'test_mode' => false, // decides whether to connect to the main telegram servers or to the testing servers (deep telegram)
'ipv6' => $this->ipv6, // decides whether to use ipv6, ipv6 attribute of API attribute of API class contains autodetected boolean 'ipv6' => (bool) strlen(@file_get_contents('http://ipv6.test-ipv6.com/', false, stream_context_create(['http' => ['timeout' => 1]]))) > 0, // decides whether to use ipv6, ipv6 attribute of API attribute of API class contains autodetected boolean
'timeout' => 2, // timeout for sockets 'timeout' => 2, // timeout for sockets
'proxy' => '\Socket', // The proxy class to use 'proxy' => '\Socket', // The proxy class to use
'proxy_extra' => [], // Extra parameters to pass to the proxy class using setExtra 'proxy_extra' => [], // Extra parameters to pass to the proxy class using setExtra
@ -636,29 +626,27 @@ class MTProto
// Connects to all datacenters and if necessary creates authorization keys, binds them and writes client info // Connects to all datacenters and if necessary creates authorization keys, binds them and writes client info
public function connect_to_all_dcs() public function connect_to_all_dcs()
{ {
foreach ($old = $this->datacenter->get_dcs() as $new_dc) { $this->datacenter->__construct($this->settings['connection'], $this->settings['connection_settings']);
foreach ($this->datacenter->get_dcs() as $new_dc) {
$this->datacenter->dc_connect($new_dc); $this->datacenter->dc_connect($new_dc);
} }
$this->init_authorization(); $this->init_authorization();
if ($old !== $this->datacenter->get_dcs()) { /*if ($old !== $this->datacenter->get_dcs()) {
$this->connect_to_all_dcs(); $this->connect_to_all_dcs();
} }*/
} }
private $initing_authorization = false; private $initing_authorization = false;
// Creates authorization keys // Creates authorization keys
public function init_authorization() public function init_authorization()
{ {
$this->initing_authorization = true; $this->initing_authorization = true;
$this->updates_state['sync_loading'] = true; $this->updates_state['sync_loading'] = true;
try { try {
foreach ($this->datacenter->sockets as $id => $socket) { foreach ($this->datacenter->sockets as $id => $socket) {
if (strpos($id, 'media')) {
continue;
}
$cdn = strpos($id, 'cdn'); $cdn = strpos($id, 'cdn');
if (strpos($id, 'media') !== false && !$cdn) continue;
if ($socket->session_id === null) { if ($socket->session_id === null) {
$socket->session_id = $this->random(8); $socket->session_id = $this->random(8);
$socket->session_in_seq_no = 0; $socket->session_in_seq_no = 0;
@ -668,54 +656,42 @@ class MTProto
if ($socket->auth_key === null && !$cdn) { if ($socket->auth_key === null && !$cdn) {
\danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_perm_auth_key'], $id)], Logger::NOTICE); \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_perm_auth_key'], $id)], Logger::NOTICE);
$socket->auth_key = $this->create_auth_key(-1, $id); $socket->auth_key = $this->create_auth_key(-1, $id);
$socket->authorized = false;
} }
\danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id)], Logger::NOTICE); \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['gen_temp_auth_key'], $id)], Logger::NOTICE);
$socket->temp_auth_key = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); $socket->temp_auth_key = $this->create_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id);
if (!$cdn) { if (!$cdn) {
$this->bind_temp_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id); $this->bind_temp_auth_key($this->settings['authorization']['default_temp_auth_key_expires_in'], $id);
$this->get_config($this->write_client_info('help.getConfig', [], ['datacenter' => $id])); $config = $this->write_client_info('help.getConfig', [], ['datacenter' => $id]);
if ($this->authorized === self::LOGGED_IN && $socket->authorized === false) {
foreach ($this->datacenter->sockets as $authorized_dc_id => $authorized_socket) {
if ($authorized_socket->authorized === true && $this->authorized === self::LOGGED_IN && $socket->authorized === false) {
try {
\danog\MadelineProto\Logger::log(['Trying to copy authorization from dc '.$authorized_dc_id.' to dc '.$id]);
$exported_authorization = $this->method_call('auth.exportAuthorization', ['dc_id' => preg_replace('|_.*|', '', $id)], ['datacenter' => $authorized_dc_id]);
$authorization = $this->method_call('auth.importAuthorization', $exported_authorization, ['datacenter' => $id]);
$socket->authorized = true;
break;
} catch (\danog\MadelineProto\RPCErrorException $e) {} // Turns out this DC isn't authorized after all
}
}
}
$this->get_config($config);
} }
if (in_array($socket->protocol, ['http', 'https'])) { if (in_array($socket->protocol, ['http', 'https'])) {
$this->method_call('http_wait', ['max_wait' => 0, 'wait_after' => 0, 'max_delay' => 0], ['datacenter' => $id]); $this->method_call('http_wait', ['max_wait' => 0, 'wait_after' => 0, 'max_delay' => 0], ['datacenter' => $id]);
} }
} }
} }
} finally { } finally {
$this->initing_authorization = false; $this->initing_authorization = false;
$this->updates_state['sync_loading'] = false; $this->updates_state['sync_loading'] = false;
} }
} }
public function sync_authorization($authorized_dc)
{
$this->updates_state['sync_loading'] = true;
$this->postpone_updates = true;
try {
foreach ($this->datacenter->sockets as $new_dc => $socket) {
if (($int_dc = preg_replace('|/D+|', '', $new_dc)) == $authorized_dc) {
continue;
}
if ($int_dc != $new_dc) {
continue;
}
\danog\MadelineProto\Logger::log([$int_dc, $new_dc]);
if (strpos($new_dc, '_') !== false) {
continue;
}
\danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['copy_auth_dcs'], $authorized_dc, $new_dc)], Logger::VERBOSE);
$exported_authorization = $this->method_call('auth.exportAuthorization', ['dc_id' => $new_dc], ['datacenter' => $authorized_dc]);
$this->method_call('auth.logOut', [], ['datacenter' => $new_dc]);
$authorization = $this->method_call('auth.importAuthorization', $exported_authorization, ['datacenter' => $new_dc]);
}
} finally {
$this->postpone_updates = false;
$this->updates_state['sync_loading'] = false;
}
return $authorization;
}
public function write_client_info($method, $arguments = [], $options = []) public function write_client_info($method, $arguments = [], $options = [])
{ {
\danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['write_client_info'], $method)], Logger::NOTICE); \danog\MadelineProto\Logger::log([sprintf(\danog\MadelineProto\Lang::$current_lang['write_client_info'], $method)], Logger::NOTICE);
@ -781,11 +757,14 @@ class MTProto
foreach ($dc_options as $dc) { foreach ($dc_options as $dc) {
$test = $this->config['test_mode'] ? 'test' : 'main'; $test = $this->config['test_mode'] ? 'test' : 'main';
$id = $dc['id']; $id = $dc['id'];
if (isset($dc['static'])) {
// $id .= $dc['static'] ? '_static' : '';
}
if (isset($dc['cdn'])) { if (isset($dc['cdn'])) {
$id .= $dc['cdn'] ? '_cdn' : ''; $id .= $dc['cdn'] ? '_cdn' : '';
} }
$id .= $dc['media_only'] ? '_media' : ''; $id .= $dc['media_only'] ? '_media' : '';
$ipv6 = ($dc['ipv6'] ? 'ipv6' : 'ipv4'); $ipv6 = $dc['ipv6'] ? 'ipv6' : 'ipv4';
$id .= (isset($this->settings['connection'][$test][$ipv6][$id]) && $this->settings['connection'][$test][$ipv6][$id]['ip_address'] != $dc['ip_address']) ? '_bk' : ''; $id .= (isset($this->settings['connection'][$test][$ipv6][$id]) && $this->settings['connection'][$test][$ipv6][$id]['ip_address'] != $dc['ip_address']) ? '_bk' : '';
if (is_numeric($id)) { if (is_numeric($id)) {
$id = (int) $id; $id = (int) $id;
@ -797,8 +776,9 @@ class MTProto
$this->settings['connection'][$test][$ipv6][$id] = $dc; $this->settings['connection'][$test][$ipv6][$id] = $dc;
} }
$curdc = $this->datacenter->curdc; $curdc = $this->datacenter->curdc;
$this->datacenter->dclist = $this->settings['connection']; //$this->datacenter->dclist = $this->settings['connection'];
$this->datacenter->settings = $this->settings['connection_settings']; //$this->datacenter->settings = $this->settings['connection_settings'];
\danog\MadelineProto\Logger::log(['Got new DC options, reconnecting']);
$this->connect_to_all_dcs(); $this->connect_to_all_dcs();
$this->datacenter->curdc = $curdc; $this->datacenter->curdc = $curdc;
} }

View File

@ -551,7 +551,7 @@ trait AuthKeyHandler
$encrypted_message = $this->datacenter->sockets[$datacenter]->auth_key['id'].$message_key.$this->ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv); $encrypted_message = $this->datacenter->sockets[$datacenter]->auth_key['id'].$message_key.$this->ige_encrypt($encrypted_data.$padding, $aes_key, $aes_iv);
$res = $this->method_call('auth.bindTempAuthKey', ['perm_auth_key_id' => $perm_auth_key_id, 'nonce' => $nonce, 'expires_at' => $expires_at, 'encrypted_message' => $encrypted_message], ['message_id' => $message_id, 'datacenter' => $datacenter]); $res = $this->method_call('auth.bindTempAuthKey', ['perm_auth_key_id' => $perm_auth_key_id, 'nonce' => $nonce, 'expires_at' => $expires_at, 'encrypted_message' => $encrypted_message], ['message_id' => $message_id, 'datacenter' => $datacenter]);
if ($res === true) { if ($res === true) {
\danog\MadelineProto\Logger::log(['Successfully binded temporary and permanent authorization keys.'], \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log(['Successfully binded temporary and permanent authorization keys, DC '.$datacenter], \danog\MadelineProto\Logger::NOTICE);
return true; return true;
} }

View File

@ -67,7 +67,7 @@ trait CallHandler
unset($aargs['queue']); unset($aargs['queue']);
} }
if (isset($aargs['serialized'])) { if (isset($aargs['serialized'])) {
$serialized = $args; $serialized = $args['serialized'];
} else { } else {
$serialized = $this->serialize_method($method, $args); $serialized = $this->serialize_method($method, $args);
} }
@ -135,6 +135,7 @@ trait CallHandler
if ($this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key !== null) { if ($this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key !== null) {
\danog\MadelineProto\Logger::log(['WARNING: Resetting auth key...'], \danog\MadelineProto\Logger::WARNING); \danog\MadelineProto\Logger::log(['WARNING: Resetting auth key...'], \danog\MadelineProto\Logger::WARNING);
$this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key = null; $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key = null;
$this->datacenter->sockets[$aargs['datacenter']]->auth_key = null;
$this->init_authorization(); $this->init_authorization();
throw new \danog\MadelineProto\Exception('I had to recreate the temporary authorization key'); throw new \danog\MadelineProto\Exception('I had to recreate the temporary authorization key');

View File

@ -326,17 +326,23 @@ trait ResponseHandler
case 'USER_DEACTIVATED': case 'USER_DEACTIVATED':
case 'SESSION_REVOKED': case 'SESSION_REVOKED':
case 'SESSION_EXPIRED': case 'SESSION_EXPIRED':
$this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key = null; foreach ($this->datacenter->sockets as $socket) {
$this->datacenter->sockets[$aargs['datacenter']]->auth_key = null; $socket->temp_auth_key = null;
$socket->auth_key = null;
$socket->authorized = false;
}
$this->authorized = self::NOT_LOGGED_IN; $this->authorized = self::NOT_LOGGED_IN;
$this->authorization = null; $this->authorization = null;
$this->init_authorization(); // idk $this->init_authorization(); // idk
throw new \danog\MadelineProto\RPCErrorException($server_answer['error_message'], $server_answer['error_code']); throw new \danog\MadelineProto\RPCErrorException($server_answer['error_message'], $server_answer['error_code']);
case 'AUTH_KEY_UNREGISTERED': case 'AUTH_KEY_UNREGISTERED':
case 'AUTH_KEY_INVALID': case 'AUTH_KEY_INVALID':
if ($this->authorized !== self::LOGGED_IN) throw new \danog\MadelineProto\RPCErrorException($server_answer['error_message'], $server_answer['error_code']);
$this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key = null; $this->datacenter->sockets[$aargs['datacenter']]->temp_auth_key = null;
$this->datacenter->sockets[$aargs['datacenter']]->auth_key = null;
$this->datacenter->sockets[$aargs['datacenter']]->authorized = false;
$this->init_authorization(); // idk $this->init_authorization(); // idk
throw new \danog\MadelineProto\RPCErrorException($server_answer['error_message'], $server_answer['error_code']); throw new \danog\MadelineProto\Exception('I had to recreate the temporary authorization key');
} }
case 420: case 420:
$seconds = preg_replace('/[^0-9]+/', '', $server_answer['error_message']); $seconds = preg_replace('/[^0-9]+/', '', $server_answer['error_message']);

View File

@ -22,6 +22,7 @@ class Serialization
public static function serialize_all($exception) public static function serialize_all($exception)
{ {
echo $exception.PHP_EOL; echo $exception.PHP_EOL;
return;
foreach (self::$instances as $instance) { foreach (self::$instances as $instance) {
if (isset($instance->session)) { if (isset($instance->session)) {
$instance->serialize(); $instance->serialize();

View File

@ -19,6 +19,7 @@ trait Login
{ {
public function logout() public function logout()
{ {
foreach ($this->datacenter->sockets as $socket) { $socket->authorized = false; }
$this->authorized = self::NOT_LOGGED_IN; $this->authorized = self::NOT_LOGGED_IN;
$this->authorization = null; $this->authorization = null;
$this->updates = []; $this->updates = [];
@ -51,12 +52,14 @@ trait Login
], ['datacenter' => $this->datacenter->curdc] ], ['datacenter' => $this->datacenter->curdc]
); );
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->sync_authorization($this->datacenter->curdc); $this->datacenter->sockets[$this->datacenter->curdc]->authorized = true;
$this->updates = []; $this->updates = [];
$this->updates_key = 0; $this->updates_key = 0;
if (!isset($this->settings['pwr']['pwr']) || !$this->settings['pwr']['pwr']) { if (!isset($this->settings['pwr']['pwr']) || !$this->settings['pwr']['pwr']) {
@file_get_contents('https://api.pwrtelegram.xyz/bot'.$token.'/getme'); @file_get_contents('https://api.pwrtelegram.xyz/bot'.$token.'/getme');
} }
$this->init_authorization();
\danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['login_ok']], \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['login_ok']], \danog\MadelineProto\Logger::NOTICE);
return $this->authorization; return $this->authorization;
@ -128,7 +131,9 @@ trait Login
} }
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->authorization = $authorization; $this->authorization = $authorization;
$this->sync_authorization($this->datacenter->curdc); $this->datacenter->sockets[$this->datacenter->curdc]->authorized = true;
$this->init_authorization();
\danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['login_ok']], \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['login_ok']], \danog\MadelineProto\Logger::NOTICE);
@ -152,11 +157,13 @@ trait Login
$this->datacenter->sockets[$dc_id]->outgoing_messages = []; $this->datacenter->sockets[$dc_id]->outgoing_messages = [];
$this->datacenter->sockets[$dc_id]->new_outgoing = []; $this->datacenter->sockets[$dc_id]->new_outgoing = [];
$this->datacenter->sockets[$dc_id]->new_incoming = []; $this->datacenter->sockets[$dc_id]->new_incoming = [];
$this->datacenter->sockets[$dc_id]->authorized = true;
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->init_authorization(); $this->init_authorization();
return $this->authorization = $this->sync_authorization($dc_id);
return $this->get_self();
} }
public function export_authorization() public function export_authorization()
@ -186,7 +193,8 @@ trait Login
], ['datacenter' => $this->datacenter->curdc] ], ['datacenter' => $this->datacenter->curdc]
); );
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->sync_authorization($this->datacenter->curdc); $this->datacenter->sockets[$this->datacenter->curdc]->authorized = true;
$this->init_authorization();
\danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['signup_ok']], \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['signup_ok']], \danog\MadelineProto\Logger::NOTICE);
@ -207,7 +215,9 @@ trait Login
], ['datacenter' => $this->datacenter->curdc] ], ['datacenter' => $this->datacenter->curdc]
); );
$this->authorized = self::LOGGED_IN; $this->authorized = self::LOGGED_IN;
$this->sync_authorization($this->datacenter->curdc); $this->datacenter->sockets[$this->datacenter->curdc]->authorized = true;
$this->init_authorization();
\danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['login_ok']], \danog\MadelineProto\Logger::NOTICE); \danog\MadelineProto\Logger::log([\danog\MadelineProto\Lang::$current_lang['login_ok']], \danog\MadelineProto\Logger::NOTICE);
return $this->authorization; return $this->authorization;

View File

@ -54,7 +54,7 @@ echo 'Loading settings...'.PHP_EOL;
var_dump(getenv('MTPROTO_SETTINGS')); var_dump(getenv('MTPROTO_SETTINGS'));
$settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: []; $settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: [];
//$settings['connection_settings']['all']['proxy'] = '\SocksProxy'; //$settings['connection_settings']['all']['proxy'] = '\SocksProxy';
//$settings['connection_settings']['all']['proxy_extra'] = ['address' => '209.195.74.200', 'port' => 43545]; //$settings['connection_settings']['all']['proxy_extra'] = ['address' => '127.0.0.1', 'port' => 1080];
var_dump($settings); var_dump($settings);
if ($MadelineProto === false) { if ($MadelineProto === false) {