Skip to content

Commit 107cc9c

Browse files
committed
ext/sockets: rfc 3542 support of destination and hop options
carry optional informations for the router (multicast) and for the destination node to see.
1 parent dfff6ac commit 107cc9c

File tree

5 files changed

+154
-19
lines changed

5 files changed

+154
-19
lines changed

ext/sockets/conversions.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
# include <sys/socket.h>
1818
# include <arpa/inet.h>
1919
# include <netinet/in.h>
20+
# ifdef HAVE_IPV6
21+
# include <netinet/ip6.h>
22+
# endif
2023
# include <sys/un.h>
2124
# include <sys/ioctl.h>
2225
# include <net/if.h>
@@ -404,6 +407,25 @@ static void from_zval_write_uint32(const zval *arr_value, char *field, ser_conte
404407
ival = (uint32_t)lval;
405408
memcpy(field, &ival, sizeof(ival));
406409
}
410+
static void from_zval_write_uint8(const zval *arr_value, char *field, ser_context *ctx)
411+
{
412+
zend_long lval;
413+
uint8_t ival;
414+
415+
lval = from_zval_integer_common(arr_value, ctx);
416+
if (ctx->err.has_error) {
417+
return;
418+
}
419+
420+
if (lval < 0 || lval > 0xFF) {
421+
do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
422+
"for an unsigned 8-bit integer");
423+
return;
424+
}
425+
426+
ival = (uint8_t)lval;
427+
memcpy(field, &ival, sizeof(ival));
428+
}
407429
static void from_zval_write_net_uint16(const zval *arr_value, char *field, ser_context *ctx)
408430
{
409431
zend_long lval;
@@ -529,6 +551,13 @@ static void to_zval_read_uint32(const char *data, zval *zv, res_context *ctx)
529551

530552
ZVAL_LONG(zv, (zend_long)ival);
531553
}
554+
static void to_zval_read_uint8(const char *data, zval *zv, res_context *ctx)
555+
{
556+
uint8_t ival;
557+
memcpy(&ival, data, sizeof(ival));
558+
559+
ZVAL_LONG(zv, (zend_long)ival);
560+
}
532561
#endif
533562
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT) || defined(LOCAL_CREDS)
534563
static void to_zval_read_pid_t(const char *data, zval *zv, res_context *ctx)
@@ -1307,6 +1336,18 @@ static const field_descriptor descriptors_in6_pktinfo[] = {
13071336
{"ifindex", sizeof("ifindex"), true, offsetof(struct in6_pktinfo, ipi6_ifindex), from_zval_write_ifindex, to_zval_read_unsigned},
13081337
{0}
13091338
};
1339+
1340+
static const field_descriptor descriptors_in6_hbh[] = {
1341+
{"nxt", sizeof("nxt"), true, offsetof(struct ip6_hbh, ip6h_nxt), from_zval_write_uint8, to_zval_read_uint8},
1342+
{"len", sizeof("len"), true, offsetof(struct ip6_hbh, ip6h_len), from_zval_write_uint8, to_zval_read_uint8},
1343+
{0}
1344+
};
1345+
static const field_descriptor descriptors_in6_dest[] = {
1346+
{"nxt", sizeof("nxt"), true, offsetof(struct ip6_dest, ip6d_nxt), from_zval_write_uint8, to_zval_read_uint8},
1347+
{"len", sizeof("len"), true, offsetof(struct ip6_dest, ip6d_len), from_zval_write_uint8, to_zval_read_uint8},
1348+
{0}
1349+
};
1350+
13101351
void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser_context *ctx)
13111352
{
13121353
from_zval_write_aggregation(container, in6_pktinfo_c, descriptors_in6_pktinfo, ctx);
@@ -1317,6 +1358,30 @@ void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx)
13171358

13181359
to_zval_read_aggregation(data, zv, descriptors_in6_pktinfo, ctx);
13191360
}
1361+
1362+
void from_zval_write_ip6_hbh(const zval *container, char *in6_hbh_c, ser_context *ctx)
1363+
{
1364+
from_zval_write_aggregation(container, in6_hbh_c, descriptors_in6_hbh, ctx);
1365+
}
1366+
1367+
void to_zval_read_ip6_hbh(const char *data, zval *zv, res_context *ctx)
1368+
{
1369+
array_init_size(zv, 2);
1370+
1371+
to_zval_read_aggregation(data, zv, descriptors_in6_hbh, ctx);
1372+
}
1373+
1374+
void from_zval_write_ip6_dest(const zval *container, char *in6_dest_c, ser_context *ctx)
1375+
{
1376+
from_zval_write_aggregation(container, in6_dest_c, descriptors_in6_dest, ctx);
1377+
}
1378+
1379+
void to_zval_read_ip6_dest(const char *data, zval *zv, res_context *ctx)
1380+
{
1381+
array_init_size(zv, 2);
1382+
1383+
to_zval_read_aggregation(data, zv, descriptors_in6_dest, ctx);
1384+
}
13201385
#endif
13211386

13221387
/* CONVERSIONS for struct ucred */

ext/sockets/conversions.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser
6161
void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx);
6262
#endif
6363

64+
#ifdef IPV6_HOPOPTS
65+
void from_zval_write_ip6_hbh(const zval *container, char *in6_hbh_c, ser_context *ctx);
66+
void to_zval_read_ip6_hbh(const char *data, zval *zv, res_context *ctx);
67+
#endif
68+
69+
#ifdef IPV6_DSTOPTS
70+
void from_zval_write_ip6_dest(const zval *container, char *in6_dest_c, ser_context *ctx);
71+
void to_zval_read_ip6_dest(const char *data, zval *zv, res_context *ctx);
72+
#endif
73+
6474
#if defined(SO_PASSCRED) || defined(LOCAL_CREDS_PERSISTENT) || defined(LOCAL_CREDS)
6575
void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx);
6676
void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx);

ext/sockets/sendrecvmsg.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include "sendrecvmsg.h"
2424
#include "conversions.h"
2525
#include <limits.h>
26+
#ifdef HAVE_IPV6
27+
# include <netinet/ip6.h>
28+
#endif
2629
#include <Zend/zend_llist.h>
2730
#ifdef ZTS
2831
#include <TSRM/TSRM.h>
@@ -107,21 +110,33 @@ static void init_ancillary_registry(void)
107110
key.cmsg_type = type; \
108111
zend_hash_str_update_mem(&ancillary_registry.ht, (char*)&key, sizeof(key), (void*)&entry, sizeof(entry))
109112

110-
#if defined(IPV6_PKTINFO) && defined(HAVE_IPV6)
113+
#if defined(HAVE_IPV6)
114+
#if defined(IPV6_PKTINFO)
111115
PUT_ENTRY(sizeof(struct in6_pktinfo), 0, 0, from_zval_write_in6_pktinfo,
112116
to_zval_read_in6_pktinfo, IPPROTO_IPV6, IPV6_PKTINFO);
113117
#endif
114118

115-
#if defined(IPV6_HOPLIMIT) && defined(HAVE_IPV6)
119+
#if defined(IPV6_HOPLIMIT)
116120
PUT_ENTRY(sizeof(int), 0, 0, from_zval_write_int,
117121
to_zval_read_int, IPPROTO_IPV6, IPV6_HOPLIMIT);
118122
#endif
119123

120-
#if defined(IPV6_TCLASS) && defined(HAVE_IPV6)
124+
#if defined(IPV6_TCLASS)
121125
PUT_ENTRY(sizeof(int), 0, 0, from_zval_write_int,
122126
to_zval_read_int, IPPROTO_IPV6, IPV6_TCLASS);
123127
#endif
124128

129+
#if defined(IPV6_HOPOPTS)
130+
PUT_ENTRY(sizeof(struct ip6_hbh), 0, 0, from_zval_write_ip6_hbh,
131+
to_zval_read_ip6_hbh, IPPROTO_IPV6, IPV6_HOPOPTS);
132+
#endif
133+
134+
#if defined(IPV6_DSTPOPTS)
135+
PUT_ENTRY(sizeof(struct ip6_dest), 0, 0, from_zval_write_ip6_dest,
136+
to_zval_read_ip6_dest, IPPROTO_IPV6, IPV6_DSTOPTS);
137+
#endif
138+
#endif
139+
125140
#ifdef SO_PASSCRED
126141
#ifdef HAVE_STRUCT_UCRED
127142
PUT_ENTRY(sizeof(struct ucred), 0, 0, from_zval_write_ucred,
@@ -156,7 +171,6 @@ static void destroy_ancillary_registry(void)
156171
ancillary_reg_entry *get_ancillary_reg_entry(int cmsg_level, int msg_type)
157172
{
158173
anc_reg_key key = { cmsg_level, msg_type };
159-
ancillary_reg_entry *entry;
160174

161175
#ifdef ZTS
162176
tsrm_mutex_lock(ancillary_mutex);
@@ -168,11 +182,7 @@ ancillary_reg_entry *get_ancillary_reg_entry(int cmsg_level, int msg_type)
168182
tsrm_mutex_unlock(ancillary_mutex);
169183
#endif
170184

171-
if ((entry = zend_hash_str_find_ptr(&ancillary_registry.ht, (char*)&key, sizeof(key))) != NULL) {
172-
return entry;
173-
} else {
174-
return NULL;
175-
}
185+
return zend_hash_str_find_ptr(&ancillary_registry.ht, (char*)&key, sizeof(key));
176186
}
177187

178188
PHP_FUNCTION(socket_sendmsg)
@@ -394,6 +404,18 @@ int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname,
394404
size = sizeof(struct in6_pktinfo);
395405
reader = &to_zval_read_in6_pktinfo;
396406
break;
407+
#endif
408+
#ifdef IPV6_HOPOPTS
409+
case IPV6_HOPOPTS:
410+
size = sizeof(struct ip6_hbh);
411+
reader = &to_zval_read_ip6_hbh;
412+
break;
413+
#endif
414+
#ifdef IPV6_DSTOPTS
415+
case IPV6_DSTOPTS:
416+
size = sizeof(struct ip6_dest);
417+
reader = &to_zval_read_ip6_dest;
418+
break;
397419
#endif
398420
default:
399421
return 1;

ext/sockets/sockets.stub.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,8 @@
17831783
const SOL_LOCAL = UNKNOWN;
17841784
#endif
17851785

1786-
#if (defined(IPV6_RECVPKTINFO) && defined(HAVE_IPV6))
1786+
#if defined(HAVE_IPV6)
1787+
#if defined(IPV6_RECVPKTINFO)
17871788
/**
17881789
* IPv6 ancillary data
17891790
* @var int
@@ -1796,7 +1797,7 @@
17961797
*/
17971798
const IPV6_PKTINFO = UNKNOWN;
17981799
#endif
1799-
#if (defined(IPV6_RECVHOPLIMIT) && defined(HAVE_IPV6))
1800+
#if defined(IPV6_RECVHOPLIMIT)
18001801
/**
18011802
* @var int
18021803
* @cvalue IPV6_RECVHOPLIMIT
@@ -1809,7 +1810,7 @@
18091810
const IPV6_HOPLIMIT = UNKNOWN;
18101811
#endif
18111812

1812-
#if (defined(IPV6_RECVTCLASS) && defined(HAVE_IPV6))
1813+
#if defined(IPV6_RECVTCLASS)
18131814
/**
18141815
* @var int
18151816
* @cvalue IPV6_RECVTCLASS
@@ -1821,6 +1822,31 @@
18211822
*/
18221823
const IPV6_TCLASS = UNKNOWN;
18231824
#endif
1825+
#if defined(IPV6_RECVHOPOPTS)
1826+
/**
1827+
* @var int
1828+
* @cvalue IPV6_RECVHOPOPTS
1829+
*/
1830+
const IPV6_RECVHOPOPTS = UNKNOWN;
1831+
/**
1832+
* @var int
1833+
* @cvalue IPV6_HOPOPTS
1834+
*/
1835+
const IPV6_HOPOPTS = UNKNOWN;
1836+
#endif
1837+
#if defined(IPV6_RECVDSTOPTS)
1838+
/**
1839+
* @var int
1840+
* @cvalue IPV6_RECVDSTOPTS
1841+
*/
1842+
const IPV6_RECVDSTOPTS = UNKNOWN;
1843+
/**
1844+
* @var int
1845+
* @cvalue IPV6_DSTOPTS
1846+
*/
1847+
const IPV6_DSTOPTS = UNKNOWN;
1848+
#endif
1849+
#endif
18241850

18251851
#ifdef SCM_RIGHTS
18261852
/**

ext/sockets/sockets_arginfo.h

Lines changed: 19 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)