1--TEST--
2Multicast support: IPv6 receive options (limited)
3--SKIPIF--
4<?php
5if (!extension_loaded('sockets')) {
6    die('skip sockets extension not available.');
7}
8if (!defined('IPPROTO_IPV6')) {
9    die('skip IPv6 not available.');
10}
11$s = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP);
12$br = socket_bind($s, '::', 3000);
13/* On Linux, there is no route ff00::/8 by default on lo, which makes it
14 * troublesome to send multicast traffic from lo, which we must since
15 * we're dealing with interface-local traffic... */
16$so = @socket_set_option($s, IPPROTO_IPV6, MCAST_JOIN_GROUP, array(
17    "group"	=> 'ff01::114',
18    "interface" => 0,
19));
20if ($so === false) {
21    die('skip unable to join multicast group on any interface.');
22}
23$r = socket_sendto($s, $m = "testing packet", strlen($m), 0, 'ff01::114', 3000);
24if ($r === false) {
25    die('skip unable to send multicast packet.');
26}
27$so = @socket_set_option($s, IPPROTO_IPV6, MCAST_LEAVE_GROUP, array(
28    "group"	=> 'ff01::114',
29    "interface" => 0,
30));
31if (defined("MCAST_JOIN_SOURCE_GROUP")) {
32    $so = @socket_set_option($s, IPPROTO_IPV6, MCAST_JOIN_SOURCE_GROUP, array(
33        "group"	=> 'ff01::114',
34        "interface" => 0,
35        "source" => '2001::dead:beef',
36    ));
37    if ($so !== false) {
38        die('skip protocol independent multicast API is available.');
39    }
40}
41--FILE--
42<?php
43include __DIR__."/mcast_helpers.php.inc";
44$domain = AF_INET6;
45$level = IPPROTO_IPV6;
46$interface = 0;
47$mcastaddr = 'ff01::114';
48$sblock = "?";
49
50echo "creating send socket\n";
51$sends1 = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err");
52var_dump($sends1);
53
54echo "creating receive socket\n";
55$s = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err");
56var_dump($s);
57$br = socket_bind($s, '::0', 3000) or die("err");
58var_dump($br);
59
60$so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array(
61    "group"	=> $mcastaddr,
62    "interface" => $interface,
63)) or die("err");
64var_dump($so);
65
66$r = socket_sendto($sends1, $m = "testing packet", strlen($m), 0, $mcastaddr, 3000);
67var_dump($r);
68checktimeout($s, 500);
69$r = socket_recvfrom($s, $str, 2000, 0, $from, $fromPort);
70var_dump($r, $str, $from);
71$sblock = $from;
72
73$r = socket_sendto($sends1, $m = "initial packet", strlen($m), 0, $mcastaddr, 3000);
74var_dump($r);
75
76$i = 0;
77checktimeout($s, 500);
78while (($str = socket_read($s, 3000, 500)) !== FALSE) {
79    $i++;
80    echo "$i> ", $str, "\n";
81
82if ($i == 1) {
83    echo "leaving group\n";
84    $so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array(
85        "group"	=> $mcastaddr,
86        "interface" => $interface,
87    ));
88    var_dump($so);
89    $r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000);
90    var_dump($r);
91    $r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000);
92    var_dump($r);
93}
94if ($i == 2) {
95    echo "re-joining group\n";
96    $so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array(
97        "group"	=> $mcastaddr,
98        "interface" => $interface,
99    ));
100    var_dump($so);
101    $r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000);
102    var_dump($r);
103}
104if ($i == 3) {
105    break;
106}
107
108}
109?>
110--EXPECTF--
111creating send socket
112object(Socket)#%d (0) {
113}
114creating receive socket
115object(Socket)#%d (0) {
116}
117bool(true)
118bool(true)
119int(14)
120int(14)
121string(14) "testing packet"
122string(%d) "%s"
123int(14)
1241> initial packet
125leaving group
126bool(true)
127int(20)
128int(14)
1292> unicast packet
130re-joining group
131bool(true)
132int(12)
1333> mcast packet
134