]> granicus.if.org Git - php/commitdiff
- Fixed ext/sockets build on Mac OS X (hopefully).
authorGustavo André dos Santos Lopes <cataphract@php.net>
Sat, 11 Jun 2011 20:20:50 +0000 (20:20 +0000)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Sat, 11 Jun 2011 20:20:50 +0000 (20:20 +0000)
- Improvements in the multicast tests.
- Very light refactoring in sockets.c.

ext/sockets/multicast.c
ext/sockets/multicast.h
ext/sockets/sockets.c
ext/sockets/tests/mcast_helpers.php.inc [new file with mode: 0644]
ext/sockets/tests/mcast_ipv4_recv.phpt
ext/sockets/tests/mcast_ipv6_recv.phpt
ext/sockets/tests/mcast_ipv6_recv_limited.phpt

index 9a1ecd5371f4694af07f65924a64f8d110a23aa6..49e9c5cf730e96bbbd9a78218adc0dbaa7af0110 100644 (file)
 #include "multicast.h"
 #include "main/php_network.h"
 
-#if defined(MCAST_JOIN_GROUP) && 1 &&\
-       (!defined(PHP_WIN32) || (_WIN32_WINNT >= 0x600 && SOCKETS_ENABLE_VISTA_API))
-#define RFC3678_API 1
-#endif
-
 
 enum source_op {
        JOIN_SOURCE,
@@ -67,10 +62,13 @@ enum source_op {
 };
 
 static int _php_mcast_join_leave(php_socket *sock, int level, struct sockaddr *group, socklen_t group_len, unsigned int if_index, int join TSRMLS_DC);
+#ifdef HAS_MCAST_EXT
 static int _php_mcast_source_op(php_socket *sock, int level, struct sockaddr *group, socklen_t group_len, struct sockaddr *source, socklen_t source_len, unsigned int if_index, enum source_op sop TSRMLS_DC);
-#if RFC3678_API
+#endif
+
+#ifdef RFC3678_API
 static int _php_source_op_to_rfc3678_op(enum source_op sop);
-#else
+#elif HAS_MCAST_EXT
 static const char *_php_source_op_to_string(enum source_op sop);
 static int _php_source_op_to_ipv4_op(enum source_op sop);
 #endif
@@ -95,6 +93,7 @@ int php_mcast_leave(
        return _php_mcast_join_leave(sock, level, group, group_len, if_index, 0 TSRMLS_CC);
 }
 
+#ifdef HAS_MCAST_EXT
 int php_mcast_join_source(
        php_socket *sock,
        int level,
@@ -142,6 +141,8 @@ int php_mcast_unblock_source(
 {
        return _php_mcast_source_op(sock, level, group, group_len, source, source_len, if_index, UNBLOCK_SOURCE TSRMLS_CC);
 }
+#endif /* HAS_MCAST_EXT */
+
 
 static int _php_mcast_join_leave(
        php_socket *sock,
@@ -204,6 +205,7 @@ static int _php_mcast_join_leave(
 #endif
 }
 
+#ifdef HAS_MCAST_EXT
 static int _php_mcast_source_op(
        php_socket *sock,
        int level,
@@ -318,6 +320,8 @@ static int _php_source_op_to_ipv4_op(enum source_op sop)
 }
 #endif
 
+#endif /* HAS_MCAST_EXT */
+
 #if PHP_WIN32
 int php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struct in_addr *out_addr TSRMLS_DC)
 {
index 5b63cf03815cb69d7d01e282dc7ff9ab39d82957..0b1a1422e78421dbff320c5830e7687b1d63d0b0 100644 (file)
 
 /* $Id$ */
 
+#if defined(MCAST_JOIN_GROUP) && \
+       (!defined(PHP_WIN32) || (_WIN32_WINNT >= 0x600 && SOCKETS_ENABLE_VISTA_API))
+#define RFC3678_API 1
+/* has block/unblock and source membership, in this case for both IPv4 and IPv6 */
+#define HAS_MCAST_EXT 1
+#elif defined(IP_ADD_SOURCE_MEMBERSHIP)
+/* has block/unblock and source membership, but only for IPv4 */
+#define HAS_MCAST_EXT 1
+#endif
+
 int php_if_index_to_addr4(
         unsigned if_index,
         php_socket *php_sock,
@@ -42,6 +52,7 @@ int php_mcast_leave(
        socklen_t group_len,
        unsigned int if_index TSRMLS_DC);
 
+#ifdef HAS_MCAST_EXT
 int php_mcast_join_source(
        php_socket *sock,
        int level,
@@ -77,3 +88,4 @@ int php_mcast_unblock_source(
        struct sockaddr *source,
        socklen_t source_len,
        unsigned int if_index TSRMLS_DC);
+#endif
index 2af92005b827063b79ab41049cb144bdb7ccf971..456e89d087545f8eb327aa0f3e1098e336704e23 100644 (file)
@@ -806,21 +806,25 @@ PHP_MINIT_FUNCTION(sockets)
        REGISTER_LONG_CONSTANT("PHP_NORMAL_READ", PHP_NORMAL_READ, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("PHP_BINARY_READ", PHP_BINARY_READ, CONST_CS | CONST_PERSISTENT);
 
-#ifndef MCAST_JOIN_GROUP
+#ifndef RFC3678_API
 #define MCAST_JOIN_GROUP                       IP_ADD_MEMBERSHIP
 #define MCAST_LEAVE_GROUP                      IP_DROP_MEMBERSHIP
+#ifdef HAS_MCAST_EXT
 #define MCAST_BLOCK_SOURCE                     IP_BLOCK_SOURCE
 #define MCAST_UNBLOCK_SOURCE           IP_UNBLOCK_SOURCE
 #define MCAST_JOIN_SOURCE_GROUP                IP_ADD_SOURCE_MEMBERSHIP
 #define MCAST_LEAVE_SOURCE_GROUP       IP_DROP_SOURCE_MEMBERSHIP
+#endif
 #endif
        
        REGISTER_LONG_CONSTANT("MCAST_JOIN_GROUP",                      MCAST_JOIN_GROUP,                       CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("MCAST_LEAVE_GROUP",                     MCAST_LEAVE_GROUP,                      CONST_CS | CONST_PERSISTENT);
+#ifdef HAS_MCAST_EXT
        REGISTER_LONG_CONSTANT("MCAST_BLOCK_SOURCE",            MCAST_BLOCK_SOURCE,                     CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("MCAST_UNBLOCK_SOURCE",          MCAST_UNBLOCK_SOURCE,           CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("MCAST_JOIN_SOURCE_GROUP",       MCAST_JOIN_SOURCE_GROUP,        CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("MCAST_LEAVE_SOURCE_GROUP",      MCAST_LEAVE_SOURCE_GROUP,       CONST_CS | CONST_PERSISTENT);
+#endif
 
        REGISTER_LONG_CONSTANT("IP_MULTICAST_IF",                       IP_MULTICAST_IF,                CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("IP_MULTICAST_TTL",                      IP_MULTICAST_TTL,               CONST_CS | CONST_PERSISTENT);
@@ -1485,11 +1489,6 @@ PHP_FUNCTION(socket_connect)
 {
        zval                            *arg1;
        php_socket                      *php_sock;
-       struct sockaddr_in      sin;
-#if HAVE_IPV6
-       struct sockaddr_in6     sin6;
-#endif
-       struct sockaddr_un      s_un;
        char                            *addr;
        int                                     retval, addr_len;
        long                            port = 0;
@@ -1503,7 +1502,9 @@ PHP_FUNCTION(socket_connect)
 
        switch(php_sock->type) {
 #if HAVE_IPV6
-               case AF_INET6:
+               case AF_INET6: {
+                       struct sockaddr_in6 sin6 = {0};
+                       
                        if (argc != 3) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Socket of type AF_INET6 requires 3 arguments");
                                RETURN_FALSE;
@@ -1520,15 +1521,16 @@ PHP_FUNCTION(socket_connect)
 
                        retval = connect(php_sock->bsd_socket, (struct sockaddr *)&sin6, sizeof(struct sockaddr_in6));
                        break;
+               }
 #endif
-               case AF_INET:
+               case AF_INET: {
+                       struct sockaddr_in sin = {0};
+                       
                        if (argc != 3) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Socket of type AF_INET requires 3 arguments");
                                RETURN_FALSE;
                        }
 
-                       memset(&sin, 0, sizeof(struct sockaddr_in));
-
                        sin.sin_family = AF_INET;
                        sin.sin_port   = htons((unsigned short int)port);
 
@@ -1538,19 +1540,22 @@ PHP_FUNCTION(socket_connect)
 
                        retval = connect(php_sock->bsd_socket, (struct sockaddr *)&sin, sizeof(struct sockaddr_in));
                        break;
+               }
 
-               case AF_UNIX:
+               case AF_UNIX: {
+                       struct sockaddr_un s_un = {0};
+                       
                        if (addr_len >= sizeof(s_un.sun_path)) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Path too long");
                                RETURN_FALSE;
                        }
-                               
-                       memset(&s_un, 0, sizeof(struct sockaddr_un));
 
                        s_un.sun_family = AF_UNIX;
                        memcpy(&s_un.sun_path, addr, addr_len);
-                       retval = connect(php_sock->bsd_socket, (struct sockaddr *) &s_un, (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + addr_len);
+                       retval = connect(php_sock->bsd_socket, (struct sockaddr *) &s_un,
+                               (socklen_t)(XtOffsetOf(struct sockaddr_un, sun_path) + addr_len));
                        break;
+               }
 
                default:
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported socket type %d", php_sock->type);
@@ -2034,8 +2039,10 @@ static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval *
        int                                             retval;
        int (*mcast_req_fun)(php_socket *, int, struct sockaddr *, socklen_t,
                unsigned TSRMLS_DC);
+#ifdef HAS_MCAST_EXT
        int (*mcast_sreq_fun)(php_socket *, int, struct sockaddr *, socklen_t,
                struct sockaddr *, socklen_t, unsigned TSRMLS_DC);
+#endif
 
        switch (optname) {
        case MCAST_JOIN_GROUP:
@@ -2065,6 +2072,7 @@ mcast_req_fun:
                        break;
                }
 
+#ifdef HAS_MCAST_EXT
        case MCAST_BLOCK_SOURCE:
                mcast_sreq_fun = &php_mcast_block_source;
                goto mcast_sreq_fun;
@@ -2103,6 +2111,7 @@ mcast_req_fun:
                                        glen, (struct sockaddr*)&source, slen, if_index TSRMLS_CC);
                        break;
                }
+#endif
        default:
                php_error_docref(NULL TSRMLS_CC, E_WARNING,
                        "unexpected option in php_do_mcast_opt (level %d, option %d). "
@@ -2154,11 +2163,13 @@ PHP_FUNCTION(socket_set_option)
        if (level == IPPROTO_IP) {
                switch (optname) {
                case MCAST_JOIN_GROUP:
-               case MCAST_LEAVE_GROUP:         
+               case MCAST_LEAVE_GROUP:
+#ifdef HAS_MCAST_EXT
                case MCAST_BLOCK_SOURCE:
                case MCAST_UNBLOCK_SOURCE:
                case MCAST_JOIN_SOURCE_GROUP:
                case MCAST_LEAVE_SOURCE_GROUP:
+#endif
                        if (php_do_mcast_opt(php_sock, level, optname, arg4 TSRMLS_CC) == FAILURE) {
                                RETURN_FALSE;
                        } else {
diff --git a/ext/sockets/tests/mcast_helpers.php.inc b/ext/sockets/tests/mcast_helpers.php.inc
new file mode 100644 (file)
index 0000000..ad65a3f
--- /dev/null
@@ -0,0 +1,8 @@
+<?php
+function checktimeout($sock, $limit) {
+       $readfs = array($sock);
+       $writefs = $exceptfs = array();
+       if (socket_select($readfs, $writefs, $exceptfs, 0, $limit*1000) != 1) {
+               die("Socket read timeout hit. Can be a bug, a test bug, or a firewall issue.");
+       }
+}
index a7aab86ff93c9e95aff6bbed70885b5fe51bfa35..8c90ae0b17621638070ab673ea812af0de5ea7ad 100644 (file)
@@ -14,8 +14,12 @@ $so = socket_set_option($s, IPPROTO_IP, MCAST_JOIN_GROUP, array(
 if ($so === false) {\r
     die('skip interface \'lo\' is unavailable.');\r
 }\r
+if (!defined("MCAST_BLOCK_SOURCE")) {\r
+    die('skip source operations are unavailable');\r
+}\r
 --FILE--\r
 <?php\r
+include __DIR__."/mcast_helpers.php.inc";\r
 $domain = AF_INET;\r
 $level = IPPROTO_IP;\r
 $interface = "lo";\r
@@ -47,6 +51,7 @@ $r = socket_sendto($sends1, $m = "initial packet", strlen($m), 0, $mcastaddr, 30
 var_dump($r);\r
 \r
 $i = 0;\r
+checktimeout($s, 500);\r
 while (($str = socket_read($s, 3000)) !== FALSE) {\r
        $i++;\r
        echo "$i> ", $str, "\n";\r
@@ -146,13 +151,13 @@ if ($i == 8) {
 }\r
 \r
 }\r
---EXPECT--\r
+--EXPECTF--\r
 creating send socket bound to 127.0.0.1\r
 bool(true)\r
 creating unbound socket and hoping the routing table causes an interface other than lo to be used for sending messages to 224.0.0.23\r
 bool(true)\r
 creating receive socket\r
-resource(6) of type (Socket)\r
+resource(%d) of type (Socket)\r
 bool(true)\r
 bool(true)\r
 int(14)\r
index b33306da1d223adf9d9997ba6b287df6fd06166a..38390c025cecc39a90f5117f407087ee1992797a 100644 (file)
@@ -24,6 +24,10 @@ $r = socket_sendto($s, $m = "testing packet", strlen($m), 0, 'ff01::114', 3000);
 if ($r === false) {\r
        die('skip unable to send multicast packet.');\r
 }\r
+\r
+if (!defined("MCAST_JOIN_SOURCE_GROUP"))\r
+    die('skip source operations are unavailable');\r
+\r
 $so = socket_set_option($s, IPPROTO_IPV6, MCAST_LEAVE_GROUP, array(\r
        "group" => 'ff01::114',\r
        "interface" => 0,\r
@@ -39,6 +43,7 @@ if ($so === false) {
 \r
 --FILE--\r
 <?php\r
+include __DIR__."/mcast_helpers.php.inc";\r
 $domain = AF_INET6;\r
 $level = IPPROTO_IPV6;\r
 $interface = 0;\r
@@ -63,6 +68,7 @@ var_dump($so);
 \r
 $r = socket_sendto($sends1, $m = "testing packet", strlen($m), 0, $mcastaddr, 3000);\r
 var_dump($r);\r
+checktimeout($s, 500);\r
 $r = socket_recvfrom($s, $str, 2000, 0, $from, $fromPort);\r
 var_dump($r, $str, $from);\r
 $sblock = $from;\r
@@ -71,6 +77,7 @@ $r = socket_sendto($sends1, $m = "initial packet", strlen($m), 0, $mcastaddr, 30
 var_dump($r);\r
 \r
 $i = 0;\r
+checktimeout($s, 500);\r
 while (($str = socket_read($s, 3000)) !== FALSE) {\r
        $i++;\r
        echo "$i> ", $str, "\n";\r
@@ -171,9 +178,9 @@ if ($i == 8) {
 }\r
 --EXPECTF--\r
 creating send socket\r
-resource(4) of type (Socket)\r
+resource(%d) of type (Socket)\r
 creating receive socket\r
-resource(5) of type (Socket)\r
+resource(%d) of type (Socket)\r
 bool(true)\r
 bool(true)\r
 int(14)\r
index 2afea569bc7cad9a08d224015a18f71c68ead974..fda099877d6a98f6586fa68f9ae74d225d7a1c5b 100644 (file)
@@ -28,17 +28,20 @@ $so = socket_set_option($s, IPPROTO_IPV6, MCAST_LEAVE_GROUP, array(
        "group" => 'ff01::114',\r
        "interface" => 0,\r
 ));\r
-$so = socket_set_option($s, IPPROTO_IPV6, MCAST_JOIN_SOURCE_GROUP, array(\r
-       "group" => 'ff01::114',\r
-       "interface" => 0,\r
-       "source" => '2001::dead:beef',\r
-));\r
-if ($so !== false) {\r
-    die('skip protocol independent multicast API is available.');\r
+if (defined("MCAST_JOIN_SOURCE_GROUP")) {\r
+       $so = socket_set_option($s, IPPROTO_IPV6, MCAST_JOIN_SOURCE_GROUP, array(\r
+               "group" => 'ff01::114',\r
+               "interface" => 0,\r
+               "source" => '2001::dead:beef',\r
+       ));\r
+       if ($so !== false) {\r
+           die('skip protocol independent multicast API is available.');\r
+       }\r
 }\r
 \r
 --FILE--\r
 <?php\r
+include __DIR__."/mcast_helpers.php.inc";\r
 $domain = AF_INET6;\r
 $level = IPPROTO_IPV6;\r
 $interface = 0;\r
@@ -63,6 +66,7 @@ var_dump($so);
 \r
 $r = socket_sendto($sends1, $m = "testing packet", strlen($m), 0, $mcastaddr, 3000);\r
 var_dump($r);\r
+checktimeout($s, 500);\r
 $r = socket_recvfrom($s, $str, 2000, 0, $from, $fromPort);\r
 var_dump($r, $str, $from);\r
 $sblock = $from;\r
@@ -71,7 +75,8 @@ $r = socket_sendto($sends1, $m = "initial packet", strlen($m), 0, $mcastaddr, 30
 var_dump($r);\r
 \r
 $i = 0;\r
-while (($str = socket_read($s, 3000)) !== FALSE) {\r
+checktimeout($s, 500);\r
+while (($str = socket_read($s, 3000, 500)) !== FALSE) {\r
        $i++;\r
        echo "$i> ", $str, "\n";\r
 \r
@@ -104,9 +109,9 @@ if ($i == 3) {
 }\r
 --EXPECTF--\r
 creating send socket\r
-resource(4) of type (Socket)\r
+resource(%d) of type (Socket)\r
 creating receive socket\r
-resource(5) of type (Socket)\r
+resource(%d) of type (Socket)\r
 bool(true)\r
 bool(true)\r
 int(14)\r