/** * @param NetworkAddressInterface $remotePeer * @return \React\Promise\PromiseInterface */ public function rawConnect(NetworkAddressInterface $remotePeer) { return $this->socketConnector->create($remotePeer->getIp()->getHost(), $remotePeer->getPort())->then(function (Stream $stream) { $peer = new Peer($this->msgs, $this->eventLoop); $peer->setupStream($stream); return $peer; }); }
/** * @param string $host * @param int $port * @return string */ public function connect($host, $port) { return $this->connector->create($host, $port)->then(function (Stream $stream) { return new Connection($stream, $this->requestFactory); }, function (\Exception $e) { throw $e; }); }
public function getConnection($host, $port) { if (strlen($host) > 255 || $port > 65535 || $port < 0) { return When::reject(new InvalidArgumentException('Invalid target specified')); } $deferred = new Deferred(); $timestampTimeout = microtime(true) + $this->timeout; $timerTimeout = $this->loop->addTimer($this->timeout, function () use($deferred) { $deferred->reject(new Exception('Timeout while connecting to socks server')); // TODO: stop initiating connection and DNS query }); // create local references as these settings may change later due to its async nature $auth = $this->auth; $protocolVersion = $this->protocolVersion; // protocol version not explicitly set? if ($protocolVersion === null) { // authentication requires SOCKS5, otherwise use SOCKS4a $protocolVersion = $auth === null ? '4a' : '5'; } $loop = $this->loop; $that = $this; When::all(array($this->connector->create($this->socksHost, $this->socksPort)->then(null, function ($error) { throw new Exception('Unable to connect to socks server', 0, $error); }), $this->resolve($host)->then(null, function ($error) { throw new Exception('Unable to resolve remote hostname', 0, $error); })), function ($fulfilled) use($deferred, $port, $timestampTimeout, $that, $loop, $timerTimeout, $protocolVersion, $auth) { $loop->cancelTimer($timerTimeout); $timeout = max($timestampTimeout - microtime(true), 0.1); $deferred->resolve($that->handleConnectedSocks($fulfilled[0], $fulfilled[1], $port, $timeout, $protocolVersion, $auth)); }, function ($error) use($deferred, $loop, $timerTimeout) { $loop->cancelTimer($timerTimeout); $deferred->reject(new Exception('Unable to connect to socks server', 0, $error)); }); return $deferred->promise(); }
/** * Establishes a network connection to a server. * * @param string $host * @param int $port * @param int $timeout * * @return ExtendedPromiseInterface */ private function establishConnection($host, $port, $timeout) { $deferred = new Deferred(); $timer = $this->loop->addTimer($timeout, function () use($deferred, $timeout) { $exception = new \RuntimeException(sprintf('Connection timed out after %d seconds.', $timeout)); $deferred->reject($exception); }); $this->connector->create($host, $port)->always(function () use($timer) { $this->loop->cancelTimer($timer); })->then(function (Stream $stream) use($deferred, $timeout) { $stream->on('data', function ($data) { $this->handleReceive($data); }); $stream->getBuffer()->on('full-drain', function () { $this->handleSend(); }); $stream->on('close', function () { $this->handleClose(); }); $stream->on('error', function (\Exception $e) { $this->handleError($e); }); $deferred->resolve($stream); })->otherwise(function (\Exception $e) use($deferred) { $deferred->reject($e); }); return $deferred->promise(); }
public function ping(ConnectorInterface $via, $host, $port) { $start = microtime(true); return $via->create($host, $port)->then(function ($stream) use($start) { $stop = microtime(true); $stream->close(); return $stop - $start; }); }
/** * @param ConnectorInterface $connector * @param string $host * @param int $port * * @return Promise */ private function attachErrorHandler(ConnectorInterface $connector, $host, $port) { return $connector->create($host, $port)->then(function (Stream $stream) use($host, $port, &$capturedStream) { $stream->on('error', function ($error) use($host, $port) { throw new \ErrorException('Connection to host ' . $host . ':' . $port . ' failed: ' . $error); }); return $stream; }, function ($error) { echo 'Connection failed: ' . $error->getMessage() . PHP_EOL; echo '(Tip: If using secure connections, make sure you use an SSL-only port)' . PHP_EOL; }); }
/** * Create client. * * @param array $options * * @return \React\Promise\Promise */ public function create(array $options = []) { foreach (['host', 'port', 'username', 'secret'] as $key) { $options[$key] = Arr::get($options, $key, null); } $promise = $this->connector->create($options['host'], $options['port'])->then(function (Stream $stream) { return new Client($stream, new Parser()); }); if (!is_null($options['username'])) { $promise = $promise->then(function (Client $client) use($options) { $sender = new ActionSender($client); return $sender->login($options['username'], $options['secret'])->then(function () use($client) { return $client; }, function ($error) use($client) { $client->close(); throw $error; }); }, function ($error) { throw $error; }); } return $promise; }
private function connect($host, $port) { $promise = $this->connector->create($host, $port); return new Promise\Promise(function ($resolve, $reject) use($promise) { // resolve/reject with result of TCP/IP connection return $promise->then($resolve, function (Exception $reason) use($reject) { $reject(new \RuntimeException('Unable to connect to SOCKS server', 0, $reason)); }); }, function ($_, $reject) use($promise) { // cancellation should reject connection attempt $reject(new RuntimeException('Connection attempt cancelled while connecting to SOCKS server')); // forefully close TCP/IP connection if it completes despite cancellation $promise->then(function (Stream $stream) { $stream->close(); }); // (try to) cancel pending TCP/IP connection if ($promise instanceof CancellablePromiseInterface) { $promise->cancel(); } }); }
/** * @param string $host * @param int $port * * @return PromiseInterface */ public function createClient($host, $port) { return $this->connector->create($host, $port)->then(function (DuplexStreamInterface $stream) { return new Client($stream); }); }