diff --git a/.travis.yml b/.travis.yml index 04544ff4..75ea350c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,8 @@ php: - '7.0' - '5.6' +git: + submodules: false jobs: allow_failures: diff --git a/docs b/docs index e8cd2a7b..7a8bc742 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit e8cd2a7bb534007357d2c07e886ea37bb223e91e +Subproject commit 7a8bc742393a50f32acec02b8b0f8db31ada2028 diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php index a7a2627c..ca75cb78 100644 --- a/src/danog/MadelineProto/API.php +++ b/src/danog/MadelineProto/API.php @@ -161,17 +161,6 @@ class API extends InternalDoc $this->logger->logger(Lang::$current_lang['madelineproto_ready'], Logger::NOTICE); } - /** - * Enable or disable async. - * - * @param bool $async Whether to enable or disable async - * - * @return void - */ - public function async(bool $async): void - { - parent::async($async); - } /** * Destruct function. * @@ -201,17 +190,6 @@ class API extends InternalDoc { $this->oldInstance = true; } - /** - * Sleep function. - * - * @internal - * - * @return array - */ - public function __sleep(): array - { - return APIWrapper::__sleep(); - } /** * Init API wrapper. * diff --git a/src/danog/MadelineProto/DataCenter.php b/src/danog/MadelineProto/DataCenter.php index 4e599657..fea7849f 100644 --- a/src/danog/MadelineProto/DataCenter.php +++ b/src/danog/MadelineProto/DataCenter.php @@ -33,6 +33,7 @@ use Amp\Http\Client\DelegateHttpClient; use Amp\Http\Client\HttpClientBuilder; use Amp\Http\Client\Request; use Amp\Socket\ConnectContext; +use Amp\Socket\DnsConnector; use Amp\Websocket\Client\Rfc6455Connector; use danog\MadelineProto\MTProto\PermAuthKey; use danog\MadelineProto\MTProto\TempAuthKey; @@ -113,6 +114,12 @@ class DataCenter * @var \Amp\Http\Client\Cookie\CookieJar */ private $CookieJar; + /** + * DNS connector + * + * @var DNSConnector + */ + private $dnsConnector; public function __sleep() { return ['sockets', 'curdc', 'dclist', 'settings']; @@ -200,7 +207,7 @@ class DataCenter $this->settings = $settings; foreach ($this->sockets as $key => $socket) { if ($socket instanceof DataCenterConnection && !\strpos($key, '_bk')) { - //$this->API->logger->logger(\sprintf(\danog\MadelineProto\Lang::$current_lang['dc_con_stop'], $key), \danog\MadelineProto\Logger::VERBOSE); + //$this->API->logger->logger(\sprintf(Lang::$current_lang['dc_con_stop'], $key), \danog\MadelineProto\Logger::VERBOSE); if ($reconnectAll || isset($changed[$id])) { $this->API->logger->logger("Disconnecting all before reconnect!"); $socket->needReconnect(true); @@ -219,6 +226,8 @@ class DataCenter $nonProxiedDoHConfig = new DoHConfig([new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'), new Nameserver('https://dns.google/resolve')]); $this->DoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($DoHConfig); $this->nonProxiedDoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($nonProxiedDoHConfig); + + $this->dnsConnector = new DnsConnector(new Rfc1035StubResolver()); } } public function dcConnect(string $dc_number, int $id = -1): \Generator @@ -253,7 +262,7 @@ class DataCenter $this->API->logger->logger("Connection failed ({$dc_number}): " . $e->getMessage(), \danog\MadelineProto\Logger::ERROR); } } - throw new \danog\MadelineProto\Exception("Could not connect to DC {$dc_number}"); + throw new Exception("Could not connect to DC {$dc_number}"); } public function generateContexts($dc_number = 0, string $uri = '', ConnectContext $context = null) { @@ -348,7 +357,7 @@ class DataCenter } $extra = $proxy_extras[$key]; if (!isset(\class_implements($proxy)[StreamInterface::class])) { - throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['proxy_class_invalid']); + throw new Exception(Lang::$current_lang['proxy_class_invalid']); } if ($proxy === ObfuscatedStream::getName() && \in_array(\strlen($extra['secret']), [17, 34])) { $combos[] = [[DefaultStream::getName(), []], [BufferedRawStream::getName(), []], [$proxy, $extra], [IntermediatePaddedStream::getName(), []]]; @@ -390,67 +399,72 @@ class DataCenter foreach ($combos as $combo) { $ipv6 = [$this->settings[$dc_config_number]['ipv6'] ? 'ipv6' : 'ipv4', $this->settings[$dc_config_number]['ipv6'] ? 'ipv4' : 'ipv6']; foreach ($ipv6 as $ipv6) { - // This is only for non-MTProto connections - if (!$dc_number) { - /* @var $ctx \danog\MadelineProto\Stream\ConnectionContext */ - $ctx = (new ConnectionContext())->setSocketContext($context)->setUri($uri)->setIpv6($ipv6 === 'ipv6'); - foreach ($combo as $stream) { - if ($stream[0] === DefaultStream::getName() && $stream[1] === []) { - $stream[1] = new DoHConnector($this, $ctx); + foreach ([true, false] as $useDoH) { + // This is only for non-MTProto connections + if (!$dc_number) { + /* @var $ctx \danog\MadelineProto\Stream\ConnectionContext */ + $ctx = (new ConnectionContext())->setSocketContext($context)->setUri($uri)->setIpv6($ipv6 === 'ipv6'); + foreach ($combo as $stream) { + if ($stream[0] === DefaultStream::getName() && $stream[1] === []) { + $stream[1] = $useDoH ? new DoHConnector($this, $ctx) : $this->dnsConnector; + } + $ctx->addStream(...$stream); } - $ctx->addStream(...$stream); + $ctxs[] = $ctx; + continue; } - $ctxs[] = $ctx; - continue; - } - // This is only for MTProto connections - if (!isset($this->dclist[$test][$ipv6][$dc_number]['ip_address'])) { - continue; - } - $address = $this->dclist[$test][$ipv6][$dc_number]['ip_address']; - $port = $this->dclist[$test][$ipv6][$dc_number]['port']; - foreach (\array_unique([$port, 443, 80, 88, 5222]) as $port) { - $stream = \end($combo)[0]; - if ($stream === HttpsStream::getName()) { - $subdomain = $this->dclist['ssl_subdomains'][\preg_replace('/\\D+/', '', $dc_number)]; - if (\strpos($dc_number, '_media') !== false) { - $subdomain .= '-1'; - } - $path = $this->settings[$dc_config_number]['test_mode'] ? 'apiw_test1' : 'apiw1'; - $uri = 'tcp://' . $subdomain . '.web.telegram.org:' . $port . '/' . $path; - } elseif ($stream === HttpStream::getName()) { - $uri = 'tcp://' . $address . ':' . $port . '/api'; - } else { - $uri = 'tcp://' . $address . ':' . $port; + + + + // This is only for MTProto connections + if (!isset($this->dclist[$test][$ipv6][$dc_number]['ip_address'])) { + continue; } - if ($combo[1][0] === WssStream::getName()) { - $subdomain = $this->dclist['ssl_subdomains'][\preg_replace('/\\D+/', '', $dc_number)]; - if (\strpos($dc_number, '_media') !== false) { - $subdomain .= '-1'; + $address = $this->dclist[$test][$ipv6][$dc_number]['ip_address']; + $port = $this->dclist[$test][$ipv6][$dc_number]['port']; + foreach (\array_unique([$port, 443, 80, 88, 5222]) as $port) { + $stream = \end($combo)[0]; + if ($stream === HttpsStream::getName()) { + $subdomain = $this->dclist['ssl_subdomains'][\preg_replace('/\\D+/', '', $dc_number)]; + if (\strpos($dc_number, '_media') !== false) { + $subdomain .= '-1'; + } + $path = $this->settings[$dc_config_number]['test_mode'] ? 'apiw_test1' : 'apiw1'; + $uri = 'tcp://'.$subdomain.'.web.telegram.org:'.$port.'/'.$path; + } elseif ($stream === HttpStream::getName()) { + $uri = 'tcp://'.$address.':'.$port.'/api'; + } else { + $uri = 'tcp://'.$address.':'.$port; } - $path = $this->settings[$dc_config_number]['test_mode'] ? 'apiws_test' : 'apiws'; - $uri = 'tcp://' . $subdomain . '.web.telegram.org:' . $port . '/' . $path; - } elseif ($combo[1][0] === WsStream::getName()) { - $subdomain = $this->dclist['ssl_subdomains'][\preg_replace('/\\D+/', '', $dc_number)]; - if (\strpos($dc_number, '_media') !== false) { - $subdomain .= '-1'; + if ($combo[1][0] === WssStream::getName()) { + $subdomain = $this->dclist['ssl_subdomains'][\preg_replace('/\\D+/', '', $dc_number)]; + if (\strpos($dc_number, '_media') !== false) { + $subdomain .= '-1'; + } + $path = $this->settings[$dc_config_number]['test_mode'] ? 'apiws_test' : 'apiws'; + $uri = 'tcp://'.$subdomain.'.web.telegram.org:'.$port.'/'.$path; + } elseif ($combo[1][0] === WsStream::getName()) { + $subdomain = $this->dclist['ssl_subdomains'][\preg_replace('/\\D+/', '', $dc_number)]; + if (\strpos($dc_number, '_media') !== false) { + $subdomain .= '-1'; + } + $path = $this->settings[$dc_config_number]['test_mode'] ? 'apiws_test' : 'apiws'; + //$uri = 'tcp://' . $subdomain . '.web.telegram.org:' . $port . '/' . $path; + $uri = 'tcp://'.$address.':'.$port.'/'.$path; } - $path = $this->settings[$dc_config_number]['test_mode'] ? 'apiws_test' : 'apiws'; - //$uri = 'tcp://' . $subdomain . '.web.telegram.org:' . $port . '/' . $path; - $uri = 'tcp://' . $address . ':' . $port . '/' . $path; + /* @var $ctx \danog\MadelineProto\Stream\ConnectionContext */ + $ctx = (new ConnectionContext())->setDc($dc_number)->setTest($this->settings[$dc_config_number]['test_mode'])->setSocketContext($context)->setUri($uri)->setIpv6($ipv6 === 'ipv6'); + foreach ($combo as $stream) { + if ($stream[0] === DefaultStream::getName() && $stream[1] === []) { + $stream[1] = $useDoH ? new DoHConnector($this, $ctx) : $this->dnsConnector; + } + if (\in_array($stream[0], [WsStream::class, WssStream::class]) && $stream[1] === []) { + $stream[1] = new Rfc6455Connector($this->HTTPClient); + } + $ctx->addStream(...$stream); + } + $ctxs[] = $ctx; } - /* @var $ctx \danog\MadelineProto\Stream\ConnectionContext */ - $ctx = (new ConnectionContext())->setDc($dc_number)->setTest($this->settings[$dc_config_number]['test_mode'])->setSocketContext($context)->setUri($uri)->setIpv6($ipv6 === 'ipv6'); - foreach ($combo as $stream) { - if ($stream[0] === DefaultStream::getName() && $stream[1] === []) { - $stream[1] = new DoHConnector($this, $ctx); - } - if (\in_array($stream[0], [WsStream::class, WssStream::class]) && $stream[1] === []) { - $stream[1] = new Rfc6455Connector($this->HTTPClient); - } - $ctx->addStream(...$stream); - } - $ctxs[] = $ctx; } } } diff --git a/tests/danog/MadelineProto/DataCenterTest.php b/tests/danog/MadelineProto/DataCenterTest.php index a6f63686..17925738 100644 --- a/tests/danog/MadelineProto/DataCenterTest.php +++ b/tests/danog/MadelineProto/DataCenterTest.php @@ -20,12 +20,13 @@ final class DataCenterTest extends TestCase * @param string $protocol Protocol name * @param boolean $test_mode Test mode * @param boolean $ipv6 IPv6 + * @param boolean $doh DNS over HTTPS? * * @dataProvider protocolProvider * * @return void */ - public function testCanUseProtocol(string $transport, bool $obfuscated, string $protocol, bool $test_mode, bool $ipv6): void + public function testCanUseProtocol(string $transport, bool $obfuscated, string $protocol, bool $test_mode, bool $ipv6, bool $doh): void { $settings = MTProto::getSettings( [ @@ -72,7 +73,7 @@ final class DataCenterTest extends TestCase ); $API->datacenter = $datacenter; - $API->getLogger()->logger("Testing protocol $protocol using transport $transport, ".($obfuscated ? 'obfuscated ' : 'not obfuscated ').($test_mode ? 'test DC ' : 'main DC ').($ipv6 ? 'IPv6' : 'IPv4')); + $API->getLogger()->logger("Testing protocol $protocol using transport $transport, ".($obfuscated ? 'obfuscated ' : 'not obfuscated ').($test_mode ? 'test DC ' : 'main DC ').($ipv6 ? 'IPv6 ' : 'IPv4 ').($doh ? "DNS over HTTPS" : "DNS"); \sleep(1); try { @@ -91,22 +92,26 @@ final class DataCenterTest extends TestCase $ipv6Pair []= true; } foreach ([false, true] as $test_mode) { - foreach ($ipv6Pair as $ipv6) { - foreach (['tcp', 'ws', 'wss'] as $transport) { - foreach ([true, false] as $obfuscated) { - if ($transport !== 'tcp' && !$obfuscated) { - continue; - } - foreach (['abridged', 'intermediate', 'intermediate_padded', 'full'] as $protocol) { - if ($protocol === 'full' && $obfuscated) { + foreach ([false, true] as $doh) { + foreach ($ipv6Pair as $ipv6) { + foreach (['tcp', 'ws', 'wss'] as $transport) { + foreach ([true, false] as $obfuscated) { + if ($transport !== 'tcp' && !$obfuscated) { continue; } - yield [$transport, $obfuscated, $protocol, $test_mode, $ipv6]; + foreach (['abridged', 'intermediate', 'intermediate_padded', 'full'] as $protocol) { + if ($protocol === 'full' && $obfuscated) { + continue; + } + yield [$transport, $obfuscated, $protocol, $test_mode, $ipv6, $doh]; + } } } + yield ['tcp', false, 'http', $test_mode, $ipv6, true]; + yield ['tcp', false, 'https', $test_mode, $ipv6, true]; + yield ['tcp', false, 'http', $test_mode, $ipv6, false]; + yield ['tcp', false, 'https', $test_mode, $ipv6, false]; } - yield ['tcp', false, 'http', $test_mode, $ipv6]; - yield ['tcp', false, 'https', $test_mode, $ipv6]; } } }