Skip to content

Commit 4671f85

Browse files
committed
ext/sockets: UDP_SEGMENT support.
UDP segmentation offload is an optimisation attempt by sending multiple large enough datagrams over UDP which reduces syscalls as by default, they have to be broke down in small UDP packets, it is better if the hardware supports it, other handed down to the software implementation. close GH-18213
1 parent ea26562 commit 4671f85

File tree

7 files changed

+61
-2
lines changed

7 files changed

+61
-2
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ PHP NEWS
208208
(David Carlier)
209209
. Added IP_BINDANY for a socket to bind to any address. (David Carlier)
210210
. Added SO_BUSY_POOL to reduce packets poll latency. (David Carlier)
211+
- Added UDP_SEGMENT support to optimise multiple large datagrams over UDP
212+
if the kernel and hardware supports it. (David Carlier)
211213

212214
- Sodium:
213215
. Fix overall theorical overflows on zend_string buffer allocations.

UPGRADING

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ PHP 8.5 UPGRADE NOTES
440440
. AF_PACKET (Linux only).
441441
. IP_BINDANY (FreeBSD/NetBSD/OpenBSD only).
442442
. SO_BUSY_POLL (Linux only).
443+
. UDP_SEGMENT (Linux only).
443444

444445
========================================
445446
11. Changes to INI File Handling

ext/sockets/config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ PHP_ARG_ENABLE([sockets],
55

66
if test "$PHP_SOCKETS" != "no"; then
77
AC_CHECK_FUNCS([hstrerror if_nametoindex if_indextoname sockatmark])
8-
AC_CHECK_HEADERS([sys/sockio.h linux/filter.h linux/if_packet.h linux/if_ether.h])
8+
AC_CHECK_HEADERS([sys/sockio.h linux/filter.h linux/if_packet.h linux/if_ether.h linux/udp.h])
99
AC_DEFINE([HAVE_SOCKETS], [1],
1010
[Define to 1 if the PHP extension 'sockets' is available.])
1111

ext/sockets/sockets.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@
7070
# if defined(HAVE_LINUX_IF_ETHER_H)
7171
# include <linux/if_ether.h>
7272
# endif
73+
# if defined(HAVE_LINUX_UDP_H)
74+
# include <linux/udp.h>
75+
# endif
7376
#endif
7477

7578
#include <stddef.h>
@@ -2301,6 +2304,22 @@ PHP_FUNCTION(socket_set_option)
23012304
}
23022305
#endif
23032306

2307+
#if defined(UDP_SEGMENT)
2308+
case UDP_SEGMENT: {
2309+
ov = zval_get_long(arg4);
2310+
2311+
// UDP segmentation offload maximum size or 0 to disable it
2312+
if (ov < 0 || ov > USHRT_MAX) {
2313+
zend_argument_value_error(4, "must be of between 0 and %u", USHRT_MAX);
2314+
RETURN_FALSE;
2315+
}
2316+
2317+
optlen = sizeof(ov);
2318+
opt_ptr = &ov;
2319+
break;
2320+
}
2321+
#endif
2322+
23042323
default:
23052324
default_case:
23062325
ov = zval_get_long(arg4);

ext/sockets/sockets.stub.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,14 @@
20222022
const ETH_P_ALL = UNKNOWN;
20232023
#endif
20242024

2025+
#ifdef UDP_SEGMENT
2026+
/**
2027+
* @var int
2028+
* @cvalue UDP_SEGMENT
2029+
*/
2030+
const UDP_SEGMENT = UNKNOWN;
2031+
#endif
2032+
20252033
/**
20262034
* @strict-properties
20272035
* @not-serializable

ext/sockets/sockets_arginfo.h

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
UDP_SEGMENT setsockopt(), can't really test is as the kernel support might not be enabled.
3+
--EXTENSIONS--
4+
sockets
5+
--SKIPIF--
6+
<?php
7+
if (!defined('UDP_SEGMENT')) { die('skip UDP_SEGMENT is not defined'); }
8+
?>
9+
--FILE--
10+
<?php
11+
$src = socket_create(AF_UNIX, SOCK_DGRAM, 0);
12+
13+
try {
14+
socket_setopt($src, SOL_UDP, UDP_SEGMENT, -1);
15+
} catch (\ValueError $e) {
16+
echo $e->getMessage(), PHP_EOL;
17+
}
18+
try {
19+
socket_setopt($src, SOL_UDP, UDP_SEGMENT, 65536);
20+
} catch (\ValueError $e) {
21+
echo $e->getMessage(), PHP_EOL;
22+
}
23+
?>
24+
--EXPECT--
25+
socket_setopt(): Argument #4 ($value) must be of between 0 and 65535
26+
socket_setopt(): Argument #4 ($value) must be of between 0 and 65535

0 commit comments

Comments
 (0)