Skip to content

Commit dedad40

Browse files
committedJul 10, 2022
sockets introduces socket_set_option SO_ZEROCOPY and MSG_ZEROCOPY for the socket_send* functions. it avoids copy b/w userland and kernel for both TCP and UDP protocols.
1 parent 6cd5bd1 commit dedad40

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed
 

‎ext/sockets/sockets.c

+6
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,9 @@ static PHP_MINIT_FUNCTION(sockets)
511511
#ifdef MSG_CMSG_CLOEXEC
512512
REGISTER_LONG_CONSTANT("MSG_CMSG_CLOEXEC",MSG_CMSG_CLOEXEC,CONST_CS | CONST_PERSISTENT);
513513
#endif
514+
#ifdef MSG_ZEROCOPY
515+
REGISTER_LONG_CONSTANT("MSG_ZEROCOPY", MSG_ZEROCOPY, CONST_CS | CONST_PERSISTENT);
516+
#endif
514517

515518
REGISTER_LONG_CONSTANT("SO_DEBUG", SO_DEBUG, CONST_CS | CONST_PERSISTENT);
516519
REGISTER_LONG_CONSTANT("SO_REUSEADDR", SO_REUSEADDR, CONST_CS | CONST_PERSISTENT);
@@ -630,6 +633,9 @@ static PHP_MINIT_FUNCTION(sockets)
630633
#ifdef TCP_CONGESTION
631634
REGISTER_LONG_CONSTANT("TCP_CONGESTION", TCP_CONGESTION, CONST_CS | CONST_PERSISTENT);
632635
#endif
636+
#ifdef SO_ZEROCOPY
637+
REGISTER_LONG_CONSTANT("SO_ZEROCOPY", SO_ZEROCOPY, CONST_CS | CONST_PERSISTENT);
638+
#endif
633639
#ifdef TCP_NODELAY
634640
REGISTER_LONG_CONSTANT("TCP_NODELAY", TCP_NODELAY, CONST_CS | CONST_PERSISTENT);
635641
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
--TEST--
2+
Test socket_sendto with MSG_ZEROCOPY
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
if (!defined("SO_ZEROCOPY")) {
8+
die('skip SO_ZEROCOPY');
9+
}
10+
--FILE--
11+
<?php
12+
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
13+
if (!$socket) {
14+
die('Unable to create AF_UNIX socket');
15+
}
16+
$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
17+
if (!$s) {
18+
die('Unable to create AF_UNIX socket');
19+
}
20+
if (!socket_set_option($socket, SOL_SOCKET, SO_ZEROCOPY, 1)) {
21+
die("Unable to set the socket option to SO_ZEROCOPY");
22+
}
23+
if (!socket_set_nonblock($s)) {
24+
die('Unable to set nonblocking mode for socket');
25+
}
26+
$address = '127.0.0.1';
27+
$port = 3001;
28+
if (!socket_bind($s, $address, $port)) {
29+
die("Unable to bind to $address");
30+
}
31+
32+
$msg = str_repeat("0123456789abcdef", 1024);
33+
$len = strlen($msg);
34+
$bytes_recv = 0;
35+
$bytes_sent = socket_sendto($socket, $msg, $len, MSG_ZEROCOPY, $address, $port);
36+
if (socket_recvfrom($s, $resp, 0, MSG_ERRQUEUE, $address, $port) == -1) die ("recvfrom MSG_ERRQUEUE");
37+
$bytes_recv = socket_recvfrom($s, $resp, 16, 0, $address, $port);
38+
echo "$bytes_sent sent!\n";
39+
echo "$bytes_recv received!\n";
40+
echo "Received $resp!";
41+
socket_close($s);
42+
socket_close($socket);
43+
?>
44+
--EXPECTF--
45+
16384 sent!
46+
16 received!
47+
Received 0123456789abcdef!

0 commit comments

Comments
 (0)