ipv6 fixes

This commit is contained in:
Daniil Gentili 2020-02-28 14:14:02 +01:00
parent 883ace5d3c
commit 98e56ba62f
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
7 changed files with 48 additions and 38 deletions

View File

@ -29,9 +29,9 @@
"amphp/byte-stream": "^1",
"danog/dns-over-https": "^0.2",
"amphp/http-client-cookies": "^1",
"amphp/uri": "^0.1",
"danog/tg-file-decoder": "^0.1",
"danog/magicalserializer": "^1.0"
"danog/magicalserializer": "^1.0",
"league/uri": "^6"
},
"require-dev": {
"vlucas/phpdotenv": "^3",

View File

@ -120,6 +120,11 @@ class DataCenter
* @var DNSConnector
*/
private $dnsConnector;
/**
* DoH connector.
*/
private Rfc6455Connector $webSocketConnnector;
public function __sleep()
{
return ['sockets', 'curdc', 'dclist', 'settings'];
@ -228,6 +233,7 @@ class DataCenter
$this->nonProxiedDoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($nonProxiedDoHConfig);
$this->dnsConnector = new DnsConnector(new Rfc1035StubResolver());
$this->webSocketConnnector = new Rfc6455Connector($this->HTTPClient);
}
}
public function dcConnect(string $dc_number, int $id = -1): \Generator
@ -421,6 +427,9 @@ class DataCenter
continue;
}
$address = $this->dclist[$test][$ipv6][$dc_number]['ip_address'];
if ($ipv6 === 'ipv6') {
$address = "[$address]";
}
$port = $this->dclist[$test][$ipv6][$dc_number]['port'];
foreach (\array_unique([$port, 443, 80, 88, 5222]) as $port) {
$stream = \end($combo)[0];
@ -459,7 +468,7 @@ class DataCenter
$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);
$stream[1] = $this->webSocketConnnector;
}
$ctx->addStream(...$stream);
}

View File

@ -438,7 +438,7 @@ class DataCenterConnection implements JsonSerializable
*
* @return void
*/
public function disconnect()
public function disconnect(): void
{
$this->connectionsDeferred = new Deferred();
$this->connectionsPromise = $this->connectionsDeferred->promise();

View File

@ -21,10 +21,11 @@ namespace danog\MadelineProto\Stream;
use Amp\CancellationToken;
use Amp\Socket\ConnectContext;
use Amp\Uri\Uri;
use danog\MadelineProto\Exception;
use danog\MadelineProto\Stream\MTProtoTransport\ObfuscatedStream;
use danog\MadelineProto\Stream\Transport\DefaultStream;
use League\Uri\Http;
use Psr\Http\Message\UriInterface;
/**
* Connection context class.
@ -63,7 +64,7 @@ class ConnectionContext
/**
* The connection URI.
*
* @var \Amp\Uri\Uri
* @var UriInterface
*/
private $uri;
/**
@ -138,13 +139,13 @@ class ConnectionContext
/**
* Set the connection URI.
*
* @param string|\Amp\Uri\Uri $uri
* @param string|UriInterface $uri
*
* @return self
*/
public function setUri($uri): self
{
$this->uri = $uri instanceof Uri ? $uri : new Uri($uri);
$this->uri = $uri instanceof UriInterface ? $uri : Http::createFromString($uri);
return $this;
}
/**
@ -159,9 +160,9 @@ class ConnectionContext
/**
* Get the URI.
*
* @return \Amp\Uri\Uri
* @return UriInterface
*/
public function getUri(): Uri
public function getUri(): UriInterface
{
return $this->uri;
}
@ -463,7 +464,7 @@ class ConnectionContext
}
$string .= \preg_replace('/.*\\\\/', '', $stream[0]);
if ($stream[1] && $stream[0] !== DefaultStream::getName()) {
$string .= ' (' . \json_encode($stream[1]) . ')';
$string .= ' ('.\json_encode($stream[1]).')';
}
}
return $string;

View File

@ -27,6 +27,7 @@ use danog\MadelineProto\Stream\BufferedProxyStreamInterface;
use danog\MadelineProto\Stream\ConnectionContext;
use danog\MadelineProto\Stream\MTProtoBufferInterface;
use danog\MadelineProto\Stream\RawStreamInterface;
use Psr\Http\Message\UriInterface;
/**
* HTTP stream wrapper.
@ -42,10 +43,8 @@ class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
private $header = '';
/**
* URI of the HTTP API.
*
* @var \Amp\Uri\Uri
*/
private $uri;
private UriInterface $uri;
/**
* Connect to stream.
*

View File

@ -68,8 +68,10 @@ class WsStream implements RawStreamInterface, ProxyStreamInterface
throw new \danog\MadelineProto\Exception('Please install amphp/websocket-client by running "composer require amphp/websocket-client:dev-master"');
}
$this->dc = $ctx->getIntDc();
$handshake = new Handshake(\str_replace('tcp://', $ctx->isSecure() ? 'wss://' : 'ws://', $ctx->getStringUri()));
$this->stream = (yield ($this->connector ?? connector())->connect($handshake, $ctx->getCancellationToken()));
$uri = $ctx->getStringUri();
$uri = \str_replace('tcp://', $ctx->isSecure() ? 'wss://' : 'ws://', $uri);
$handshake = new Handshake($uri);
$this->stream = yield ($this->connector ?? connector())->connect($handshake, $ctx->getCancellationToken());
if (\strlen($header)) {
yield $this->write($header);
}

View File

@ -20,15 +20,14 @@ 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, bool $doh): void
public function testCanUseProtocol(string $transport, bool $obfuscated, string $protocol, bool $test_mode, bool $ipv6): void
{
$settings = MTProto::getSettings(
$settings = MTProto::parseSettings(
[
'connection_settings' => [
'all' => [
@ -36,7 +35,8 @@ final class DataCenterTest extends TestCase
'test_mode' => $test_mode,
'protocol' => $protocol,
'obfuscated' => $obfuscated,
'transport' => $transport
'transport' => $transport,
'do_not_retry' => true
],
],
'logger' => [
@ -73,45 +73,44 @@ 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 ').($doh ? "DNS over HTTPS" : "DNS"));
$API->getLogger()->logger("Testing protocol $protocol using transport $transport, ".($obfuscated ? 'obfuscated ' : 'not obfuscated ').($test_mode ? 'test DC ' : 'main DC ').($ipv6 ? 'IPv6 ' : 'IPv4 '));
\sleep(1);
try {
Tools::wait($datacenter->dcConnect(2));
} catch (\Throwable $e) {
if (!$test_mode) {
throw $e;
}
} finally {
Tools::wait($datacenter->getDataCenterConnection(2)->disconnect());
$datacenter->getDataCenterConnection(2)->disconnect();
}
$this->assertTrue(true);
}
public function protocolProvider(): \Generator
{
return yield;
$ipv6Pair = [false];
if (@\file_get_contents('https://ipv6.google.com')) {
$ipv6Pair []= true;
}
foreach ([false, true] as $test_mode) {
foreach ([false, true] as $doh) {
foreach ($ipv6Pair as $ipv6) {
foreach (['tcp', 'ws', 'wss'] as $transport) {
foreach ([true, false] as $obfuscated) {
if ($transport !== 'tcp' && !$obfuscated) {
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) {
continue;
}
foreach (['abridged', 'intermediate', 'intermediate_padded', 'full'] as $protocol) {
if ($protocol === 'full' && $obfuscated) {
continue;
}
yield [$transport, $obfuscated, $protocol, $test_mode, $ipv6, $doh];
}
yield [$transport, $obfuscated, $protocol, $test_mode, $ipv6];
}
}
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];
}
}
}