Repository navigation
Created a UnixConnection to represent UDS connections which has the ability to retrieve the local/remote PID #153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| <?php | ||
|
|
||
| namespace React\Socket; | ||
|
|
||
| /** | ||
| * A UnixConnection is a specific implementation of a Connection for Unix connections. | ||
| * | ||
| * Unix connections have the ability to retrieve the PID of the local and remote side of the socket. | ||
| * | ||
| * @see Connection | ||
| */ | ||
| class UnixConnection extends Connection | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unlike the |
||
| { | ||
| /** | ||
| * @see http://php.net/manual/en/function.get-resource-type.php | ||
| */ | ||
| const RESOURCE_TYPE_STREAM = 'stream'; | ||
|
|
||
| /** | ||
| * PHP has no built in constant for retrieving the credentials of the peer process. | ||
| * | ||
| * @see http://php.net/manual/en/sockets.constants.php | ||
| * @see http://php.net/manual/en/function.socket-get-option.php#101380 | ||
| */ | ||
| const SO_PEERCRED = 17; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be platform dependent (Linux only?). For example, FreeBSD (and Mac?) seems to use |
||
|
|
||
| /** | ||
| * @var int|null Variable to cache the remote pid. | ||
| */ | ||
| private $remote_pid; | ||
|
|
||
| /** | ||
| * @var int|null Variable to cache the local pid. | ||
| */ | ||
| private $local_pid; | ||
|
|
||
| protected function parseAddress($address) | ||
| { | ||
| if ($address === false) { | ||
| return null; | ||
| } | ||
|
|
||
| // remove trailing colon from address for HHVM < 3.19: https://3v4l.org/5C1lo | ||
| // note that technically ":" is a valid address, so keep this in place otherwise | ||
| if (substr($address, -1) === ':' && defined('HHVM_VERSION_ID') && HHVM_VERSION_ID < 31900) { | ||
| $address = (string)substr($address, 0, -1); | ||
| } | ||
|
|
||
| // work around unknown addresses should return null value: https://3v4l.org/5C1lo and https://bugs.php.net/bug.php?id=74556 | ||
| // PHP uses "\0" string and HHVM uses empty string (colon removed above) | ||
| if ($address === '' || $address[0] === "\x00") { | ||
| return null; | ||
| } | ||
|
|
||
| return 'unix://' . $address; | ||
| } | ||
|
|
||
| /** | ||
| * Retrieve the PID (process identifier) of the remote side of the Connection. The pid will be cached to avoid | ||
| * requesting the value multiple times. If the remote pid was not cached before the connection is closed, the remote | ||
| * pid cannot be retrieved anymore. | ||
| * | ||
| * Warning: Process IDs are not unique, thus they are a weak entropy source. Relying on pids in security-dependent | ||
| * contexts should be avoided. | ||
| * | ||
| * @return int|null | ||
| */ | ||
| public function getRemotePid() | ||
| { | ||
| // If the remote pid has already been cached, return that value. | ||
| if ($this->remote_pid !== null) { | ||
| return $this->remote_pid; | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the motivation for caching the PID here? |
||
|
|
||
| if (get_resource_type($this->stream) !== self::RESOURCE_TYPE_STREAM) { | ||
| return null; | ||
| } | ||
|
|
||
| $socket = socket_import_stream($this->stream); | ||
|
|
||
| if ($socket === false || $socket === null) { | ||
| return null; | ||
| } | ||
|
|
||
| // Get the PID of the remote side of the socket. | ||
| $pid = socket_get_option($socket, SOL_SOCKET, self::SO_PEERCRED); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if |
||
|
|
||
| if ($pid === false) { | ||
| return null; | ||
| } | ||
|
|
||
| $this->remote_pid = (int)$pid; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the discussion in #150:
What if PHP starts supporting |
||
|
|
||
| return $this->remote_pid; | ||
| } | ||
|
|
||
| /** | ||
| * Retrieve the PID (process identifier) of the local side of the Connection. | ||
| * | ||
| * Warning: Process IDs are not unique, thus they are a weak entropy source. Relying on pids in security-dependent | ||
| * contexts should be avoided. | ||
| * | ||
| * @return int|null | ||
| */ | ||
| public function getLocalPid() | ||
| { | ||
| if ($this->local_pid !== null) { | ||
| return $this->local_pid; | ||
| } | ||
|
|
||
| $pid = getmypid(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the motivation for this method? Looks like this should not be part of the socket API? |
||
| if ($pid === false) { | ||
| return null; | ||
| } | ||
|
|
||
| $this->local_pid = $pid; | ||
|
|
||
| return $this->local_pid; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that consumers need to depend on a concretion rather instead of an abstraction?