|
@@ -166,22 +166,54 @@ class PhpiredisSocketConnection extends AbstractConnection
|
|
$this->onConnectionError(trim($errstr), $errno);
|
|
$this->onConnectionError(trim($errstr), $errno);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Gets the address of an host from connection parameters.
|
|
|
|
+ *
|
|
|
|
+ * @param ParametersInterface $parameters Parameters used to initialize the connection.
|
|
|
|
+ *
|
|
|
|
+ * @return string
|
|
|
|
+ */
|
|
|
|
+ protected static function getAddress(ParametersInterface $parameters)
|
|
|
|
+ {
|
|
|
|
+ if (filter_var($host = $parameters->host, FILTER_VALIDATE_IP)) {
|
|
|
|
+ return $host;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ($host === $address = gethostbyname($host)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return $address;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* {@inheritdoc}
|
|
* {@inheritdoc}
|
|
*/
|
|
*/
|
|
protected function createResource()
|
|
protected function createResource()
|
|
{
|
|
{
|
|
- $isUnix = $this->parameters->scheme === 'unix';
|
|
|
|
- $domain = $isUnix ? AF_UNIX : AF_INET;
|
|
|
|
- $protocol = $isUnix ? 0 : SOL_TCP;
|
|
|
|
|
|
+ $parameters = $this->parameters;
|
|
|
|
|
|
- $socket = @call_user_func('socket_create', $domain, SOCK_STREAM, $protocol);
|
|
|
|
|
|
+ if ($parameters->scheme === 'unix') {
|
|
|
|
+ $address = $parameters->path;
|
|
|
|
+ $domain = AF_UNIX;
|
|
|
|
+ $protocol = 0;
|
|
|
|
+ } else {
|
|
|
|
+ if (false === $address = self::getAddress($parameters)) {
|
|
|
|
+ $this->onConnectionError("Cannot resolve the address of '$parameters->host'.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $domain = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? AF_INET6 : AF_INET;
|
|
|
|
+ $protocol = SOL_TCP;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $socket = @socket_create($domain, SOCK_STREAM, $protocol);
|
|
|
|
|
|
if (!is_resource($socket)) {
|
|
if (!is_resource($socket)) {
|
|
$this->emitSocketError();
|
|
$this->emitSocketError();
|
|
}
|
|
}
|
|
|
|
|
|
- $this->setSocketOptions($socket, $this->parameters);
|
|
|
|
|
|
+ $this->setSocketOptions($socket, $parameters);
|
|
|
|
+ $this->connectWithTimeout($socket, $address, $parameters);
|
|
|
|
|
|
return $socket;
|
|
return $socket;
|
|
}
|
|
}
|
|
@@ -194,12 +226,14 @@ class PhpiredisSocketConnection extends AbstractConnection
|
|
*/
|
|
*/
|
|
private function setSocketOptions($socket, ParametersInterface $parameters)
|
|
private function setSocketOptions($socket, ParametersInterface $parameters)
|
|
{
|
|
{
|
|
- if (!socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1)) {
|
|
|
|
- $this->emitSocketError();
|
|
|
|
- }
|
|
|
|
|
|
+ if ($parameters->scheme !== 'unix') {
|
|
|
|
+ if (!socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1)) {
|
|
|
|
+ $this->emitSocketError();
|
|
|
|
+ }
|
|
|
|
|
|
- if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
|
|
|
|
- $this->emitSocketError();
|
|
|
|
|
|
+ if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
|
|
|
|
+ $this->emitSocketError();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (isset($parameters->read_write_timeout)) {
|
|
if (isset($parameters->read_write_timeout)) {
|
|
@@ -222,50 +256,20 @@ class PhpiredisSocketConnection extends AbstractConnection
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * Gets the address from the connection parameters.
|
|
|
|
- *
|
|
|
|
- * @param ParametersInterface $parameters Parameters used to initialize the connection.
|
|
|
|
- *
|
|
|
|
- * @return string
|
|
|
|
- */
|
|
|
|
- protected static function getAddress(ParametersInterface $parameters)
|
|
|
|
- {
|
|
|
|
- if ($parameters->scheme === 'unix') {
|
|
|
|
- return $parameters->path;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- $host = $parameters->host;
|
|
|
|
-
|
|
|
|
- if (ip2long($host) === false) {
|
|
|
|
- if (false === $addresses = gethostbynamel($host)) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return $addresses[array_rand($addresses)];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return $host;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Opens the actual connection to the server with a timeout.
|
|
* Opens the actual connection to the server with a timeout.
|
|
*
|
|
*
|
|
|
|
+ * @param resource $socket Socket resource.
|
|
|
|
+ * @param string $address IP address (DNS-resolved from hostname)
|
|
* @param ParametersInterface $parameters Parameters used to initialize the connection.
|
|
* @param ParametersInterface $parameters Parameters used to initialize the connection.
|
|
*
|
|
*
|
|
* @return string
|
|
* @return string
|
|
*/
|
|
*/
|
|
- private function connectWithTimeout(ParametersInterface $parameters)
|
|
|
|
|
|
+ private function connectWithTimeout($socket, $address, ParametersInterface $parameters)
|
|
{
|
|
{
|
|
- if (false === $host = self::getAddress($parameters)) {
|
|
|
|
- $this->onConnectionError("Cannot resolve the address of '$parameters->host'.");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- $socket = $this->getResource();
|
|
|
|
-
|
|
|
|
socket_set_nonblock($socket);
|
|
socket_set_nonblock($socket);
|
|
|
|
|
|
- if (@socket_connect($socket, $host, (int) $parameters->port) === false) {
|
|
|
|
|
|
+ if (@socket_connect($socket, $address, (int) $parameters->port) === false) {
|
|
$error = socket_last_error();
|
|
$error = socket_last_error();
|
|
|
|
|
|
if ($error != SOCKET_EINPROGRESS && $error != SOCKET_EALREADY) {
|
|
if ($error != SOCKET_EINPROGRESS && $error != SOCKET_EALREADY) {
|
|
@@ -287,9 +291,11 @@ class PhpiredisSocketConnection extends AbstractConnection
|
|
if ($selected === 2) {
|
|
if ($selected === 2) {
|
|
$this->onConnectionError('Connection refused.', SOCKET_ECONNREFUSED);
|
|
$this->onConnectionError('Connection refused.', SOCKET_ECONNREFUSED);
|
|
}
|
|
}
|
|
|
|
+
|
|
if ($selected === 0) {
|
|
if ($selected === 0) {
|
|
$this->onConnectionError('Connection timed out.', SOCKET_ETIMEDOUT);
|
|
$this->onConnectionError('Connection timed out.', SOCKET_ETIMEDOUT);
|
|
}
|
|
}
|
|
|
|
+
|
|
if ($selected === false) {
|
|
if ($selected === false) {
|
|
$this->emitSocketError();
|
|
$this->emitSocketError();
|
|
}
|
|
}
|
|
@@ -300,13 +306,9 @@ class PhpiredisSocketConnection extends AbstractConnection
|
|
*/
|
|
*/
|
|
public function connect()
|
|
public function connect()
|
|
{
|
|
{
|
|
- if (parent::connect()) {
|
|
|
|
- $this->connectWithTimeout($this->parameters);
|
|
|
|
-
|
|
|
|
- if ($this->initCommands) {
|
|
|
|
- foreach ($this->initCommands as $command) {
|
|
|
|
- $this->executeCommand($command);
|
|
|
|
- }
|
|
|
|
|
|
+ if (parent::connect() && $this->initCommands) {
|
|
|
|
+ foreach ($this->initCommands as $command) {
|
|
|
|
+ $this->executeCommand($command);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|