Fix proxied DNS over HTTPS
This commit is contained in:
parent
d82914187c
commit
b9e8c5a06f
@ -24,10 +24,21 @@ use Amp\Artax\Cookie\ArrayCookieJar;
|
|||||||
use Amp\Artax\DefaultClient;
|
use Amp\Artax\DefaultClient;
|
||||||
use Amp\Artax\HttpSocketPool;
|
use Amp\Artax\HttpSocketPool;
|
||||||
use Amp\CancellationToken;
|
use Amp\CancellationToken;
|
||||||
|
use Amp\Deferred;
|
||||||
|
use Amp\Dns\Record;
|
||||||
use Amp\Dns\Resolver;
|
use Amp\Dns\Resolver;
|
||||||
|
use Amp\Dns\Rfc1035StubResolver;
|
||||||
use Amp\DoH\DoHConfig;
|
use Amp\DoH\DoHConfig;
|
||||||
|
use Amp\DoH\Nameserver;
|
||||||
use Amp\DoH\Rfc8484StubResolver;
|
use Amp\DoH\Rfc8484StubResolver;
|
||||||
|
use Amp\Loop;
|
||||||
|
use Amp\NullCancellationToken;
|
||||||
|
use Amp\Promise;
|
||||||
use Amp\Socket\ClientConnectContext;
|
use Amp\Socket\ClientConnectContext;
|
||||||
|
use Amp\Socket\ClientSocket;
|
||||||
|
use Amp\Socket\ClientTlsContext;
|
||||||
|
use Amp\Socket\ConnectException;
|
||||||
|
use Amp\TimeoutException;
|
||||||
use danog\MadelineProto\Stream\Common\BufferedRawStream;
|
use danog\MadelineProto\Stream\Common\BufferedRawStream;
|
||||||
use danog\MadelineProto\Stream\ConnectionContext;
|
use danog\MadelineProto\Stream\ConnectionContext;
|
||||||
use danog\MadelineProto\Stream\MTProtoTransport\AbridgedStream;
|
use danog\MadelineProto\Stream\MTProtoTransport\AbridgedStream;
|
||||||
@ -42,19 +53,8 @@ use danog\MadelineProto\Stream\Proxy\SocksProxy;
|
|||||||
use danog\MadelineProto\Stream\Transport\DefaultStream;
|
use danog\MadelineProto\Stream\Transport\DefaultStream;
|
||||||
use danog\MadelineProto\Stream\Transport\WssStream;
|
use danog\MadelineProto\Stream\Transport\WssStream;
|
||||||
use danog\MadelineProto\Stream\Transport\WsStream;
|
use danog\MadelineProto\Stream\Transport\WsStream;
|
||||||
use Amp\DoH\Nameserver;
|
|
||||||
use function Amp\call;
|
use function Amp\call;
|
||||||
use Amp\Promise;
|
|
||||||
use Amp\Socket\ClientTlsContext;
|
|
||||||
use Amp\Deferred;
|
|
||||||
use Amp\NullCancellationToken;
|
|
||||||
use function Amp\Socket\Internal\parseUri;
|
use function Amp\Socket\Internal\parseUri;
|
||||||
use Amp\Dns\Record;
|
|
||||||
use Amp\Socket\ConnectException;
|
|
||||||
use Amp\Loop;
|
|
||||||
use Amp\TimeoutException;
|
|
||||||
use Amp\Socket\ClientSocket;
|
|
||||||
use Amp\Dns\Rfc1035StubResolver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages datacenters.
|
* Manages datacenters.
|
||||||
@ -70,6 +70,7 @@ class DataCenter
|
|||||||
private $settings = [];
|
private $settings = [];
|
||||||
private $HTTPClient;
|
private $HTTPClient;
|
||||||
private $DoHClient;
|
private $DoHClient;
|
||||||
|
private $NonProxiedDoHClient;
|
||||||
|
|
||||||
public function __sleep()
|
public function __sleep()
|
||||||
{
|
{
|
||||||
@ -91,16 +92,33 @@ class DataCenter
|
|||||||
unset($this->sockets[$key]);
|
unset($this->sockets[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->HTTPClient = new DefaultClient(new ArrayCookieJar(), new HttpSocketPool(new ProxySocketPool($this)));
|
$this->HTTPClient = new DefaultClient(new ArrayCookieJar(), new HttpSocketPool(new ProxySocketPool([$this, 'rawConnectAsync'])));
|
||||||
|
|
||||||
|
$DoHHTTPClient = new DefaultClient(
|
||||||
|
new ArrayCookieJar(),
|
||||||
|
new HttpSocketPool(
|
||||||
|
new ProxySocketPool(
|
||||||
|
function (string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null) {
|
||||||
|
return $this->rawConnectAsync($uri, $token, $ctx, true);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
$DoHConfig = new DoHConfig(
|
$DoHConfig = new DoHConfig(
|
||||||
[
|
[
|
||||||
new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'),
|
new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'),
|
||||||
new Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]),
|
new Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]),
|
||||||
],
|
],
|
||||||
$this->HTTPClient
|
$DoHHTTPClient
|
||||||
|
);
|
||||||
|
$NonProxiedDoHConfig = new DoHConfig(
|
||||||
|
[
|
||||||
|
new Nameserver('https://mozilla.cloudflare-dns.com/dns-query'),
|
||||||
|
new Nameserver('https://google.com/resolve', Nameserver::GOOGLE_JSON, ["Host" => "dns.google.com"]),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
$this->DoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($DoHConfig);
|
$this->DoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($DoHConfig);
|
||||||
|
$this->NonProxiedDoHClient = Magic::$altervista || Magic::$zerowebhost ? new Rfc1035StubResolver() : new Rfc8484StubResolver($NonProxiedDoHConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,7 +126,7 @@ class DataCenter
|
|||||||
*
|
*
|
||||||
* Note: Once resolved the socket stream will already be set to non-blocking mode.
|
* Note: Once resolved the socket stream will already be set to non-blocking mode.
|
||||||
*
|
*
|
||||||
* @param bool $ipv6
|
* @param ConnectionContext $ctx
|
||||||
* @param string $uricall
|
* @param string $uricall
|
||||||
* @param ClientConnectContext $socketContext
|
* @param ClientConnectContext $socketContext
|
||||||
* @param ClientTlsContext $tlsContext
|
* @param ClientTlsContext $tlsContext
|
||||||
@ -117,13 +135,13 @@ class DataCenter
|
|||||||
* @return Promise<ClientSocket>
|
* @return Promise<ClientSocket>
|
||||||
*/
|
*/
|
||||||
public function cryptoConnect(
|
public function cryptoConnect(
|
||||||
bool $ipv6,
|
ConnectionContext $ctx,
|
||||||
string $uri,
|
string $uri,
|
||||||
ClientConnectContext $socketContext = null,
|
ClientConnectContext $socketContext = null,
|
||||||
ClientTlsContext $tlsContext = null,
|
ClientTlsContext $tlsContext = null,
|
||||||
CancellationToken $token = null
|
CancellationToken $token = null
|
||||||
): Promise {
|
): Promise {
|
||||||
return call(function () use ($ipv6, $uri, $socketContext, $tlsContext, $token) {
|
return call(function () use ($ctx, $uri, $socketContext, $tlsContext, $token) {
|
||||||
$tlsContext = $tlsContext ?? new ClientTlsContext;
|
$tlsContext = $tlsContext ?? new ClientTlsContext;
|
||||||
|
|
||||||
if ($tlsContext->getPeerName() === null) {
|
if ($tlsContext->getPeerName() === null) {
|
||||||
@ -131,7 +149,7 @@ class DataCenter
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @var ClientSocket $socket */
|
/** @var ClientSocket $socket */
|
||||||
$socket = yield $this->socketConnect($ipv6, $uri, $socketContext, $token);
|
$socket = yield $this->socketConnect($ctx, $uri, $socketContext, $token);
|
||||||
|
|
||||||
$promise = $socket->enableCrypto($tlsContext);
|
$promise = $socket->enableCrypto($tlsContext);
|
||||||
|
|
||||||
@ -170,16 +188,16 @@ class DataCenter
|
|||||||
/**
|
/**
|
||||||
* Asynchronously establish a socket connection to the specified URI.
|
* Asynchronously establish a socket connection to the specified URI.
|
||||||
*
|
*
|
||||||
* @param bool $ipv6 Whether to use IPv6
|
* @param ConnectionContext $ctx Connection context
|
||||||
* @param string $uri URI in scheme://host:port format. TCP is assumed if no scheme is present.
|
* @param string $uri URI in scheme://host:port format. TCP is assumed if no scheme is present.
|
||||||
* @param ClientConnectContext $socketContext Socket connect context to use when connecting.
|
* @param ClientConnectContext $socketContext Socket connect context to use when connecting.
|
||||||
* @param CancellationToken|null $token
|
* @param CancellationToken|null $token
|
||||||
*
|
*
|
||||||
* @return Promise<\Amp\Socket\ClientSocket>
|
* @return Promise<\Amp\Socket\ClientSocket>
|
||||||
*/
|
*/
|
||||||
public function socketConnect(bool $ipv6, string $uri, ClientConnectContext $socketContext = null, CancellationToken $token = null): Promise
|
public function socketConnect(ConnectionContext $ctx, string $uri, ClientConnectContext $socketContext = null, CancellationToken $token = null): Promise
|
||||||
{
|
{
|
||||||
return call(function () use ($ipv6, $uri, $socketContext, $token) {
|
return call(function () use ($ctx, $uri, $socketContext, $token) {
|
||||||
$socketContext = $socketContext ?? new ClientConnectContext;
|
$socketContext = $socketContext ?? new ClientConnectContext;
|
||||||
$token = $token ?? new NullCancellationToken;
|
$token = $token ?? new NullCancellationToken;
|
||||||
$attempt = 0;
|
$attempt = 0;
|
||||||
@ -197,12 +215,37 @@ class DataCenter
|
|||||||
$uris = [$uri];
|
$uris = [$uri];
|
||||||
} else {
|
} else {
|
||||||
// Host is not an IP address, so resolve the domain name.
|
// Host is not an IP address, so resolve the domain name.
|
||||||
$records = yield $this->DoHClient->resolve($host, $socketContext->getDnsTypeRestriction());
|
// When we're connecting to a host, we may need to resolve the domain name, first.
|
||||||
|
// The resolution is usually done using DNS over HTTPS.
|
||||||
|
//
|
||||||
|
// The DNS over HTTPS resolver needs to resolve the domain name of the DOH server:
|
||||||
|
// this is handled internally by the DNS over HTTPS client,
|
||||||
|
// by redirecting the resolution request to the plain DNS client.
|
||||||
|
//
|
||||||
|
// However, if the DoH connection is proxied with a proxy that has a domain name itself,
|
||||||
|
// we cannot resolve it with the DoH resolver, since this will cause an infinite loop
|
||||||
|
//
|
||||||
|
// resolve host.com => (DoH resolver) => resolve dohserver.com => (simple resolver) => OK
|
||||||
|
//
|
||||||
|
// |> resolve dohserver.com => (simple resolver) => OK
|
||||||
|
// resolve host.com => (DoH resolver) =|
|
||||||
|
// |> resolve proxy.com => (non-proxied resolver) => OK
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// This means that we must detect if the domain name we're trying to resolve is a proxy domain name.
|
||||||
|
//
|
||||||
|
// Here, we simply check if the connection URI has changed since we first set it:
|
||||||
|
// this would indicate that a proxy class has changed the connection URI to the proxy URI.
|
||||||
|
//
|
||||||
|
if ($ctx->isDns()) {
|
||||||
|
$records = yield $this->NonProxiedDoHClient->resolve($host, $socketContext->getDnsTypeRestriction());
|
||||||
|
} else {
|
||||||
|
$records = yield $this->DoHClient->resolve($host, $socketContext->getDnsTypeRestriction());
|
||||||
|
}
|
||||||
\usort($records, function (Record $a, Record $b) {
|
\usort($records, function (Record $a, Record $b) {
|
||||||
return $a->getType() - $b->getType();
|
return $a->getType() - $b->getType();
|
||||||
});
|
});
|
||||||
if ($ipv6) {
|
if ($ctx->getIpv6()) {
|
||||||
$records = array_reverse($records);
|
$records = array_reverse($records);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +333,7 @@ class DataCenter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rawConnectAsync(string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null): \Generator
|
public function rawConnectAsync(string $uri, CancellationToken $token = null, ClientConnectContext $ctx = null, $fromDns = false): \Generator
|
||||||
{
|
{
|
||||||
$ctxs = $this->generateContexts(0, $uri, $ctx);
|
$ctxs = $this->generateContexts(0, $uri, $ctx);
|
||||||
if (empty($ctxs)) {
|
if (empty($ctxs)) {
|
||||||
@ -299,6 +342,7 @@ class DataCenter
|
|||||||
foreach ($ctxs as $ctx) {
|
foreach ($ctxs as $ctx) {
|
||||||
/* @var $ctx \danog\MadelineProto\Stream\ConnectionContext */
|
/* @var $ctx \danog\MadelineProto\Stream\ConnectionContext */
|
||||||
try {
|
try {
|
||||||
|
$ctx->setIsDns($fromDns);
|
||||||
$ctx->setCancellationToken($token);
|
$ctx->setCancellationToken($token);
|
||||||
$result = yield $ctx->getStream();
|
$result = yield $ctx->getStream();
|
||||||
$this->API->logger->logger('OK!', \danog\MadelineProto\Logger::WARNING);
|
$this->API->logger->logger('OK!', \danog\MadelineProto\Logger::WARNING);
|
||||||
@ -308,9 +352,9 @@ class DataCenter
|
|||||||
if (defined('MADELINEPROTO_TEST') && MADELINEPROTO_TEST === 'pony') {
|
if (defined('MADELINEPROTO_TEST') && MADELINEPROTO_TEST === 'pony') {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
$this->API->logger->logger('Connection failed: '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR);
|
$this->API->logger->logger('Connection failed: '.$e, \danog\MadelineProto\Logger::ERROR);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->API->logger->logger('Connection failed: '.$e->getMessage(), \danog\MadelineProto\Logger::ERROR);
|
$this->API->logger->logger('Connection failed: '.$e, \danog\MadelineProto\Logger::ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +542,7 @@ class DataCenter
|
|||||||
$ipv6 = [$this->settings[$dc_config_number]['ipv6'] ? 'ipv6' : 'ipv4', $this->settings[$dc_config_number]['ipv6'] ? 'ipv4' : 'ipv6'];
|
$ipv6 = [$this->settings[$dc_config_number]['ipv6'] ? 'ipv6' : 'ipv4', $this->settings[$dc_config_number]['ipv6'] ? 'ipv4' : 'ipv6'];
|
||||||
|
|
||||||
foreach ($ipv6 as $ipv6) {
|
foreach ($ipv6 as $ipv6) {
|
||||||
|
// This is only for non-MTProto connections
|
||||||
if (!$dc_number) {
|
if (!$dc_number) {
|
||||||
/** @var $ctx \danog\MadelineProto\Stream\ConnectionContext */
|
/** @var $ctx \danog\MadelineProto\Stream\ConnectionContext */
|
||||||
$ctx = (new ConnectionContext())
|
$ctx = (new ConnectionContext())
|
||||||
@ -507,23 +552,22 @@ class DataCenter
|
|||||||
|
|
||||||
foreach ($combo as $stream) {
|
foreach ($combo as $stream) {
|
||||||
if ($stream[0] === DefaultStream::getName() && $stream[1] === []) {
|
if ($stream[0] === DefaultStream::getName() && $stream[1] === []) {
|
||||||
$isIpv6 = $ipv6 === 'ipv6';
|
|
||||||
$stream[1] = [
|
$stream[1] = [
|
||||||
function (
|
function (
|
||||||
string $uri,
|
string $uri,
|
||||||
ClientConnectContext $socketContext = null,
|
ClientConnectContext $socketContext = null,
|
||||||
CancellationToken $token = null
|
CancellationToken $token = null
|
||||||
) use ($isIpv6): Promise {
|
) use ($ctx): Promise {
|
||||||
return $this->socketConnect($isIpv6, $uri, $socketContext, $token);
|
return $this->socketConnect($ctx, $uri, $socketContext, $token);
|
||||||
},
|
},
|
||||||
function (
|
function (
|
||||||
string $uri,
|
string $uri,
|
||||||
ClientConnectContext $socketContext = null,
|
ClientConnectContext $socketContext = null,
|
||||||
ClientTlsContext $tlsContext = null,
|
ClientTlsContext $tlsContext = null,
|
||||||
CancellationToken $token = null
|
CancellationToken $token = null
|
||||||
) use ($isIpv6): Promise {
|
) use ($ctx): Promise {
|
||||||
return $this->cryptoConnect($isIpv6, $uri, $socketContext, $tlsContext, $token);
|
return $this->cryptoConnect($ctx, $uri, $socketContext, $tlsContext, $token);
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$ctx->addStream(...$stream);
|
$ctx->addStream(...$stream);
|
||||||
@ -531,6 +575,8 @@ class DataCenter
|
|||||||
$ctxs[] = $ctx;
|
$ctxs[] = $ctx;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is only for MTProto connections
|
||||||
if (!isset($this->dclist[$test][$ipv6][$dc_number]['ip_address'])) {
|
if (!isset($this->dclist[$test][$ipv6][$dc_number]['ip_address'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -584,23 +630,22 @@ class DataCenter
|
|||||||
|
|
||||||
foreach ($combo as $stream) {
|
foreach ($combo as $stream) {
|
||||||
if ($stream[0] === DefaultStream::getName() && $stream[1] === []) {
|
if ($stream[0] === DefaultStream::getName() && $stream[1] === []) {
|
||||||
$isIpv6 = $ipv6 === 'ipv6';
|
|
||||||
$stream[1] = [
|
$stream[1] = [
|
||||||
function (
|
function (
|
||||||
string $uri,
|
string $uri,
|
||||||
ClientConnectContext $socketContext = null,
|
ClientConnectContext $socketContext = null,
|
||||||
CancellationToken $token = null
|
CancellationToken $token = null
|
||||||
) use ($isIpv6): Promise {
|
) use ($ctx): Promise {
|
||||||
return $this->socketConnect($isIpv6, $uri, $socketContext, $token);
|
return $this->socketConnect($ctx, $uri, $socketContext, $token);
|
||||||
},
|
},
|
||||||
function (
|
function (
|
||||||
string $uri,
|
string $uri,
|
||||||
ClientConnectContext $socketContext = null,
|
ClientConnectContext $socketContext = null,
|
||||||
ClientTlsContext $tlsContext = null,
|
ClientTlsContext $tlsContext = null,
|
||||||
CancellationToken $token = null
|
CancellationToken $token = null
|
||||||
) use ($isIpv6): Promise {
|
) use ($ctx): Promise {
|
||||||
return $this->cryptoConnect($isIpv6, $uri, $socketContext, $tlsContext, $token);
|
return $this->cryptoConnect($ctx, $uri, $socketContext, $tlsContext, $token);
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$ctx->addStream(...$stream);
|
$ctx->addStream(...$stream);
|
||||||
|
@ -826,7 +826,7 @@ class MTProto extends AsyncConstruct implements TLCallback
|
|||||||
public function parse_settings($settings)
|
public function parse_settings($settings)
|
||||||
{
|
{
|
||||||
$settings = self::getSettings($settings, $this->settings);
|
$settings = self::getSettings($settings, $this->settings);
|
||||||
if ($this->settings['app_info'] === null) {
|
if ($settings['app_info'] === null) {
|
||||||
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['api_not_set'], 0, null, 'MadelineProto', 1);
|
throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['api_not_set'], 0, null, 'MadelineProto', 1);
|
||||||
}
|
}
|
||||||
$this->settings = $settings;
|
$this->settings = $settings;
|
||||||
|
@ -31,13 +31,13 @@ class ProxySocketPool implements SocketPool
|
|||||||
private $pendingCount = [];
|
private $pendingCount = [];
|
||||||
private $idleTimeout;
|
private $idleTimeout;
|
||||||
private $socketContext;
|
private $socketContext;
|
||||||
private $dataCenter;
|
private $connectCallback;
|
||||||
|
|
||||||
public function __construct(DataCenter $dataCenter, int $idleTimeout = 10000, ClientConnectContext $socketContext = null)
|
public function __construct(callable $connectCallback, int $idleTimeout = 10000, ClientConnectContext $socketContext = null)
|
||||||
{
|
{
|
||||||
$this->idleTimeout = $idleTimeout;
|
$this->idleTimeout = $idleTimeout;
|
||||||
$this->socketContext = $socketContext ?? new ClientConnectContext();
|
$this->socketContext = $socketContext ?? new ClientConnectContext();
|
||||||
$this->dataCenter = $dataCenter;
|
$this->connectCallback = $connectCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,7 +129,7 @@ class ProxySocketPool implements SocketPool
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
/** @var ClientSocket $rawSocket */
|
/** @var ClientSocket $rawSocket */
|
||||||
$rawSocket = yield $this->call($this->dataCenter->rawConnectAsync($uri, $token, $this->socketContext));
|
$rawSocket = yield $this->call(($this->connectCallback)($uri, $token, $this->socketContext));
|
||||||
} finally {
|
} finally {
|
||||||
if (--$this->pendingCount[$uri] === 0) {
|
if (--$this->pendingCount[$uri] === 0) {
|
||||||
unset($this->pendingCount[$uri]);
|
unset($this->pendingCount[$uri]);
|
||||||
|
@ -51,6 +51,12 @@ class ConnectionContext
|
|||||||
* @var \Amp\Uri\Uri
|
* @var \Amp\Uri\Uri
|
||||||
*/
|
*/
|
||||||
private $uri;
|
private $uri;
|
||||||
|
/**
|
||||||
|
* Whether this connection context will be used by the DNS client
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $isDns = false;
|
||||||
/**
|
/**
|
||||||
* Socket context.
|
* Socket context.
|
||||||
*
|
*
|
||||||
@ -122,7 +128,7 @@ class ConnectionContext
|
|||||||
public function setUri($uri): self
|
public function setUri($uri): self
|
||||||
{
|
{
|
||||||
$this->uri = $uri instanceof Uri ? $uri : new Uri($uri);
|
$this->uri = $uri instanceof Uri ? $uri : new Uri($uri);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +175,15 @@ class ConnectionContext
|
|||||||
{
|
{
|
||||||
return $this->cancellationToken;
|
return $this->cancellationToken;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Return a clone of the current connection context
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function getCtx(): self
|
||||||
|
{
|
||||||
|
return clone $this;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Set the secure boolean.
|
* Set the secure boolean.
|
||||||
*
|
*
|
||||||
@ -194,6 +208,26 @@ class ConnectionContext
|
|||||||
return $this->test;
|
return $this->test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this connection context will only be used by the DNS client
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isDns(): bool
|
||||||
|
{
|
||||||
|
return $this->isDns;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Whether this connection context will only be used by the DNS client
|
||||||
|
*
|
||||||
|
* @param boolean $isDns
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setIsDns(bool $isDns): self
|
||||||
|
{
|
||||||
|
$this->isDns = $isDns;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Set the secure boolean.
|
* Set the secure boolean.
|
||||||
*
|
*
|
||||||
@ -284,16 +318,6 @@ class ConnectionContext
|
|||||||
return $this->ipv6;
|
return $this->ipv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the ipv6 boolean.
|
|
||||||
*
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public function getCtx(): self
|
|
||||||
{
|
|
||||||
return clone $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a stream to the stream chain.
|
* Add a stream to the stream chain.
|
||||||
*
|
*
|
||||||
|
@ -34,7 +34,6 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
|
|||||||
use BufferedStream;
|
use BufferedStream;
|
||||||
|
|
||||||
private $stream;
|
private $stream;
|
||||||
private $ctx;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to stream.
|
* Connect to stream.
|
||||||
@ -45,7 +44,6 @@ class AbridgedStream implements BufferedStreamInterface, MTProtoBufferInterface
|
|||||||
*/
|
*/
|
||||||
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator
|
public function connectAsync(ConnectionContext $ctx, string $header = ''): \Generator
|
||||||
{
|
{
|
||||||
$this->ctx = $ctx->getCtx();
|
|
||||||
$this->stream = yield $ctx->getStream(chr(239).$header);
|
$this->stream = yield $ctx->getStream(chr(239).$header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user