]> granicus.if.org Git - php/commitdiff
improve server sock creation and support ipv6
authorAnatol Belski <ab@php.net>
Sun, 19 Oct 2014 11:40:45 +0000 (13:40 +0200)
committerAnatol Belski <ab@php.net>
Sun, 19 Oct 2014 11:40:45 +0000 (13:40 +0200)
phpdbg.c
phpdbg_io.c
phpdbg_io.h

index 136662275904a8ffc1dd5e01d4f7e6ed653982a2..2893aa300e4a953f2559dc1049985fcf5c157e2f 100644 (file)
--- a/phpdbg.c
+++ b/phpdbg.c
@@ -781,52 +781,10 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */
        }
 } /* }}} */
 
-int phpdbg_open_socket(const char *interface, short port) /* {{{ */
-{
-       int reuse = 1;
-       struct sockaddr_in address;
-       int fd = socket(AF_INET, SOCK_STREAM, 0);
-
-       if (fd == -1) {
-               return -1;
-       }
-
-       if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) == -1) {
-               close(fd);
-               return -2;
-       }
-
-
-       memset(&address, 0, sizeof(address));
-
-       address.sin_port = htons(port);
-       address.sin_family = AF_INET;
-
-       if ((*interface == '*')) {
-               address.sin_addr.s_addr = htonl(INADDR_ANY);
-       } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) {
-               close(fd);
-               return -3;
-       }
-
-       if (bind(fd, (struct sockaddr *)&address, sizeof(address)) == -1) {
-               close(fd);
-               return -4;
-       }
-
-       listen(fd, 5);
-
-       return fd;
-} /* }}} */
 
 static void phpdbg_remote_close(int socket, FILE *stream) {
        if (socket >= 0) {
-#ifdef _WIN32
-               closesocket(socket);
-#else
-               shutdown(socket, SHUT_RDWR);
-               close(socket);
-#endif
+               phpdbg_close_socket(socket);
        }
 
        if (stream) {
@@ -846,13 +804,13 @@ static int phpdbg_remote_init(const char* address, unsigned short port, int serv
 
        phpdbg_rlog(fileno(stderr), "accepting connections on %s:%u", address, port);
        {
-               struct sockaddr_in address;
+               struct sockaddr_storage address;
                socklen_t size = sizeof(address);
                char buffer[20] = {0};
                /* XXX error checks */
                memset(&address, 0, size);
                *socket = accept(server, (struct sockaddr *) &address, &size);
-               inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer));
+               inet_ntop(AF_INET, &(((struct sockaddr_in *)&address)->sin_addr), buffer, sizeof(buffer));
 
                phpdbg_rlog(fileno(stderr), "connection established from %s", buffer);
        }
@@ -1298,7 +1256,7 @@ phpdbg_main:
        /* setup remote server if necessary */
        if (!cleaning && listen > 0) {
                server = phpdbg_open_socket(address, listen);
-               if (phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) {
+               if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) {
                        exit(0);
                }
 
index ec0ac681258d629e33e4b5da1497295bfb6a90a5..2dc6884f4e43fde216833b6389beddd99e08ab6d 100644 (file)
@@ -58,6 +58,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo)
        char *p = ptr;
 #ifndef PHP_WIN32
        struct pollfd pfd;
+       TSRMLS_FETCH();
 
        pfd.fd = sock;
        pfd.events = POLLIN;
@@ -68,6 +69,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo)
 #else
        struct fd_set readfds;
        struct timeval ttmo;
+       TSRMLS_FETCH();
 
        FD_ZERO(&readfds);
        FD_SET(sock, &readfds);
@@ -90,6 +92,7 @@ phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo)
 
                got_now = recv(sock, p, i, 0);
                if (got_now == -1) {
+                       write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Read operation timed out!\n"));
                        return -1;
                }
                i -= got_now;
@@ -138,3 +141,135 @@ phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC)
 
        return write(sock, ptr, len);
 }/*}}}*/
+
+
+PHPDBG_API int
+phpdbg_open_socket(const char *interface, short port) /* {{{ */
+{
+       struct addrinfo res;
+       int fd = phpdbg_create_listenable_socket(interface, port, &res);
+
+       if (fd == -1) {
+               return -1;
+       }
+
+       if (bind(fd, res.ai_addr, res.ai_addrlen) == -1) {
+               phpdbg_close_socket(fd);
+               return -4;
+       }
+
+       listen(fd, 5);
+
+       return fd;
+} /* }}} */
+
+
+PHPDBG_API int
+phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *addr_res)
+{/*{{{*/
+       int sock = -1, rc;
+       int reuse = 1;
+       struct in6_addr serveraddr;
+       struct addrinfo hints, *res = NULL;
+       char port_buf[8];
+       int8_t any_addr = *addr == '*';
+       TSRMLS_FETCH();
+
+       do {
+               memset(&hints, 0, sizeof hints);
+               if (any_addr) {
+                       hints.ai_flags = AI_PASSIVE;
+               } else {
+                       hints.ai_flags = AI_NUMERICSERV;
+               }
+               hints.ai_family = AF_UNSPEC;
+               hints.ai_socktype = SOCK_STREAM;
+
+               rc = inet_pton(AF_INET, addr, &serveraddr);
+               if (1 == rc) {
+                       hints.ai_family = AF_INET;
+                       if (!any_addr) {
+                               hints.ai_flags |= AI_NUMERICHOST;
+                       }
+               } else {
+                       rc = inet_pton(AF_INET6, addr, &serveraddr);
+                       if (1 == rc) {
+                               hints.ai_family = AF_INET6;
+                               if (!any_addr) {
+                                       hints.ai_flags |= AI_NUMERICHOST;
+                               }
+                       } else {
+                               /* XXX get host by name ??? */
+                       }
+               }
+
+               snprintf(port_buf, 7, "%d", port);
+               if (!any_addr) {
+                       rc = getaddrinfo(addr, port_buf, &hints, &res);
+               } else {
+                       rc = getaddrinfo(NULL, port_buf, &hints, &res);
+               }
+               if (0 != rc) {
+#ifndef PHP_WIN32
+                       if (rc == EAI_SYSTEM) {
+                               char buf[128];
+                               int wrote;
+
+                               wrote = snprintf(buf, 128, "Could not translate address '%s'", addr);
+                               buf[wrote] = '\0';
+                               write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf));
+
+                               return sock;
+                       } else {
+#endif
+                               char buf[256];
+                               int wrote;
+
+                               wrote = snprintf(buf, 256, "Host '%s' not found. %s", addr, estrdup(gai_strerror(rc)));
+                               buf[wrote] = '\0';
+                               write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf));
+
+                               return sock;
+#ifndef PHP_WIN32
+                       }
+#endif
+                       return sock;
+               }
+
+               if((sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
+                       char buf[128];
+                       int wrote;
+
+                       wrote = sprintf(buf, "Unable to create socket");
+                       buf[wrote] = '\0';
+                       write(PHPDBG_G(io)[PHPDBG_STDERR].fd, buf, strlen(buf));
+
+                       return sock;
+               } 
+
+               if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)) == -1) {
+                       phpdbg_close_socket(sock);
+                       return sock;
+               }
+
+
+       } while (0);
+
+       *addr_res = *res;
+
+       return sock;
+}/*}}}*/
+
+PHPDBG_API void
+phpdbg_close_socket(int sock)
+{
+       if (socket >= 0) {
+#ifdef _WIN32
+               closesocket(sock);
+#else
+               shutdown(sock, SHUT_RDWR);
+               close(sock);
+#endif
+       }
+}
+
index 3c4684698ae637185cd1a4d9b010dd5ef9e91c97..1edfe73662b8e22516a6600b78377a139f11aad3 100644 (file)
@@ -33,5 +33,14 @@ phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_CC);
 PHPDBG_API int
 phpdbg_mixed_write(int sock, char *ptr, int len TSRMLS_CC);
 
+PHPDBG_API int
+phpdbg_create_listenable_socket(const char *addr, int port, struct addrinfo *res);
+
+PHPDBG_API int
+phpdbg_open_socket(const char *interface, short port); 
+
+PHPDBG_API void
+phpdbg_close_socket(int sock);
+
 #endif /* PHPDBG_IO_H */