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
42--FILE--
43<?php
44include __DIR__."/mcast_helpers.php.inc";
45$domain = AF_INET6;
46$level = IPPROTO_IPV6;
47$interface = 0;
48$mcastaddr = 'ff01::114';
49$sblock = "?";
50
51echo "creating send socket\n";
52$sends1 = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err");
53var_dump($sends1);
54
55echo "creating receive socket\n";
56$s = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("err");
57var_dump($s);
58$br = socket_bind($s, '::0', 3000) or die("err");
59var_dump($br);
60
61$so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array(
62	"group"	=> $mcastaddr,
63	"interface" => $interface,
64)) or die("err");
65var_dump($so);
66
67$r = socket_sendto($sends1, $m = "testing packet", strlen($m), 0, $mcastaddr, 3000);
68var_dump($r);
69checktimeout($s, 500);
70$r = socket_recvfrom($s, $str, 2000, 0, $from, $fromPort);
71var_dump($r, $str, $from);
72$sblock = $from;
73
74$r = socket_sendto($sends1, $m = "initial packet", strlen($m), 0, $mcastaddr, 3000);
75var_dump($r);
76
77$i = 0;
78checktimeout($s, 500);
79while (($str = socket_read($s, 3000, 500)) !== FALSE) {
80	$i++;
81	echo "$i> ", $str, "\n";
82
83if ($i == 1) {
84	echo "leaving group\n";
85	$so = socket_set_option($s, $level, MCAST_LEAVE_GROUP, array(
86		"group"	=> $mcastaddr,
87		"interface" => $interface,
88	));
89	var_dump($so);
90	$r = socket_sendto($sends1, $m = "ignored mcast packet", strlen($m), 0, $mcastaddr, 3000);
91	var_dump($r);
92	$r = socket_sendto($sends1, $m = "unicast packet", strlen($m), 0, "::1", 3000);
93	var_dump($r);
94}
95if ($i == 2) {
96	echo "re-joining group\n";
97	$so = socket_set_option($s, $level, MCAST_JOIN_GROUP, array(
98		"group"	=> $mcastaddr,
99		"interface" => $interface,
100	));
101	var_dump($so);
102	$r = socket_sendto($sends1, $m = "mcast packet", strlen($m), 0, $mcastaddr, 3000);
103	var_dump($r);
104}
105if ($i == 3) {
106	break;
107}
108
109}
110--EXPECTF--
111creating send socket
112resource(%d) of type (Socket)
113creating receive socket
114resource(%d) of type (Socket)
115bool(true)
116bool(true)
117int(14)
118int(14)
119string(14) "testing packet"
120string(%d) "%s"
121int(14)
1221> initial packet
123leaving group
124bool(true)
125int(20)
126int(14)
1272> unicast packet
128re-joining group
129bool(true)
130int(12)
1313> mcast packet
132