1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Implements socket ancillary data on FreeBSD. (#7708)

using LOCAL_CREDS_PERSISTENT/SCM_CREDS2 instead so we also get the send process id.
This commit is contained in:
David CARLIER
2022-06-02 14:08:03 +01:00
committed by GitHub
parent 171ebb15c2
commit f813520b50
7 changed files with 125 additions and 10 deletions

1
NEWS
View File

@@ -67,6 +67,7 @@ PHP NEWS
(David Carlier)
. Added TCP_KEEPALIVE, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT socket
options. (David Carlier)
. Added ancillary data support for FreeBSD. (David Carlier)
- Sodium:
. Added sodium_crypto_stream_xchacha20_xor_ic(). (Scott)

View File

@@ -246,6 +246,8 @@ PHP 8.2 UPGRADE NOTES
. TCP_KEEPIDLE (Linux, others)
. TCP_KEEPINTVL (Linux, others)
. TCP_NOTSENT_LOWAT
. LOCAL_CREDS_PERSISTENT (FreeBSD)
. SCM_CREDS2 (FreeBSD)
========================================
11. Changes to INI File Handling

View File

@@ -435,7 +435,7 @@ static void from_zval_write_sa_family(const zval *arr_value, char *field, ser_co
memcpy(field, &ival, sizeof(ival));
}
#ifdef SO_PASSCRED
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
static void from_zval_write_pid_t(const zval *arr_value, char *field, ser_context *ctx)
{
zend_long lval;
@@ -522,7 +522,7 @@ static void to_zval_read_uint32(const char *data, zval *zv, res_context *ctx)
ZVAL_LONG(zv, (zend_long)ival);
}
#endif
#ifdef SO_PASSCRED
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
static void to_zval_read_pid_t(const char *data, zval *zv, res_context *ctx)
{
pid_t ival;
@@ -1301,19 +1301,24 @@ void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx)
}
#endif
/* CONVERSIONS for struct ucred/cmsgcred */
#ifdef SO_PASSCRED
/* CONVERSIONS for struct ucred */
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
static const field_descriptor descriptors_ucred[] = {
#if defined(ANC_CREDS_UCRED)
{"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t},
{"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t},
/* assume the type gid_t is the same as uid_t: */
{"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t},
#if defined(LOCAL_CREDS_PERSISTENT)
{"pid", sizeof("pid"), 1, offsetof(struct sockcred2, sc_pid), from_zval_write_pid_t, to_zval_read_pid_t},
{"uid", sizeof("uid"), 1, offsetof(struct sockcred2, sc_euid), from_zval_write_uid_t, to_zval_read_uid_t},
/* the type gid_t is the same as uid_t: */
{"gid", sizeof("gid"), 1, offsetof(struct sockcred2, sc_egid), from_zval_write_uid_t, to_zval_read_uid_t},
#elif defined(ANC_CREDS_CMSGCRED)
{"pid", sizeof("pid"), 1, offsetof(struct cmsgcred, cmcred_pid), from_zval_write_pid_t, to_zval_read_pid_t},
{"uid", sizeof("uid"), 1, offsetof(struct cmsgcred, cmcred_uid), from_zval_write_uid_t, to_zval_read_uid_t},
/* assume the type gid_t is the same as uid_t: */
{"gid", sizeof("gid"), 1, offsetof(struct cmsgcred, cmcred_gid), from_zval_write_uid_t, to_zval_read_uid_t},
#elif defined(SO_PASSCRED)
{"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t},
{"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t},
/* assume the type gid_t is the same as uid_t: */
{"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t},
#endif
{0}
};

View File

@@ -6,6 +6,9 @@
#ifndef PHP_WIN32
# include <netinet/in.h>
# include <sys/socket.h>
# ifdef __FreeBSD__
# include <sys/un.h>
# endif
#else
# include <Ws2tcpip.h>
#endif
@@ -51,7 +54,7 @@ void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser
void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx);
#endif
#ifdef SO_PASSCRED
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT)
void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx);
void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx);
#endif

View File

@@ -134,6 +134,11 @@ static void init_ancillary_registry(void)
#endif
#endif
#ifdef LOCAL_CREDS_PERSISTENT
PUT_ENTRY(SOCKCRED2SIZE(1), 1, 0, from_zval_write_ucred,
to_zval_read_ucred, SOL_SOCKET, SCM_CREDS2);
#endif
#ifdef SCM_RIGHTS
PUT_ENTRY(0, sizeof(int), calculate_scm_rights_space, from_zval_write_fd_array,
to_zval_read_fd_array, SOL_SOCKET, SCM_RIGHTS);
@@ -452,6 +457,10 @@ void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS)
#endif
REGISTER_LONG_CONSTANT("SO_PASSCRED", SO_PASSCRED, CONST_CS | CONST_PERSISTENT);
#endif
#ifdef LOCAL_CREDS_PERSISTENT
REGISTER_LONG_CONSTANT("SCM_CREDS2", SCM_CREDS2, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("LOCAL_CREDS_PERSISTENT", LOCAL_CREDS_PERSISTENT, CONST_CS | CONST_PERSISTENT);
#endif
#ifdef ZTS
ancillary_mutex = tsrm_mutex_alloc();

View File

@@ -638,6 +638,9 @@ static PHP_MINIT_FUNCTION(sockets)
#ifdef AI_NUMERICSERV
REGISTER_LONG_CONSTANT("AI_NUMERICSERV", AI_NUMERICSERV, CONST_CS | CONST_PERSISTENT);
#endif
#ifdef SOL_LOCAL
REGISTER_LONG_CONSTANT("SOL_LOCAL", SOL_LOCAL, CONST_CS | CONST_PERSISTENT);
#endif
php_socket_sendrecvmsg_init(INIT_FUNC_ARGS_PASSTHRU);

View File

@@ -0,0 +1,92 @@
--TEST--
recvmsg(): receive SCM_CREDS messages
--EXTENSIONS--
sockets
--SKIPIF--
<?php
if (!str_contains(PHP_OS, 'FreeBSD')) {
die('skipped supported only on FreeBSD');
}
--FILE--
<?php
include __DIR__."/mcast_helpers.php.inc";
$path = __DIR__ . "/socket_cmsg_credentials_fbsd.sock";
@unlink($path);
echo "creating send socket\n";
$sends1 = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
var_dump($sends1);
socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
echo "creating receive socket\n";
$s = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
var_dump($s);
$br = socket_bind($s, $path) or die("err");
var_dump($br);
socket_set_nonblock($s) or die("Could not put in non-blocking mode");
socket_set_option($s, SOL_LOCAL, LOCAL_CREDS_PERSISTENT, 1) or die("could not set LOCAL_CREDS");
$r = socket_sendto($sends1, $msg = "dread", strlen($msg), 0, $path);
var_dump($r);
checktimeout($s, 500);
$data = [
"name" => [],
"buffer_size" => 2000,
"controllen" => socket_cmsg_space(SOL_SOCKET, SCM_CREDS2, 1)
];
if (!socket_recvmsg($s, $data, 0)) die("recvmsg");
print_r($data);
$pid = getmypid();
var_dump($data['control'][0]['data']['pid'] === $pid);
?>
--CLEAN--
<?php
$path = __DIR__ . "/socket_cmsg_credentials_fbsd.sock";
@unlink($path);
--EXPECTF--
creating send socket
object(Socket)#%d (0) {
}
creating receive socket
object(Socket)#%d (0) {
}
bool(true)
int(5)
Array
(
[name] => Array
(
[family] => %d
[path] =>
)
[control] => Array
(
[0] => Array
(
[level] => %d
[type] => %d
[data] => Array
(
[pid] => %d
[uid] => %d
[gid] => %d
)
)
)
[iov] => Array
(
[0] => dread
)
[flags] => 0
)
bool(true)