diff options
author | Shawn Landden <shawn@git.icu> | 2018-07-25 21:16:29 -0700 |
---|---|---|
committer | Shawn Landden <shawn@git.icu> | 2018-07-25 21:19:07 -0700 |
commit | 08c24d2d71bffed9c224a722f2958757a35545f2 (patch) | |
tree | 174d303f2da5857f57d9bd99198bf29c852e5302 | |
parent | bd137d0cfb7b0517efe998a7b79d3318b471ccd6 (diff) | |
download | distcc-git-08c24d2d71bffed9c224a722f2958757a35545f2.tar.gz |
test for sockets
-rw-r--r-- | src/io.c | 6 | ||||
-rw-r--r-- | src/util.c | 103 | ||||
-rw-r--r-- | src/util.h | 2 |
3 files changed, 107 insertions, 4 deletions
@@ -252,7 +252,6 @@ int dcc_writex(int fd, const void *buf, size_t len) return 0; } - /** * Stick a TCP cork in the socket. It's not clear that this will help * performance, but it might. @@ -262,7 +261,8 @@ int dcc_writex(int fd, const void *buf, size_t len) int tcp_cork_sock(int POSSIBLY_UNUSED(fd), int POSSIBLY_UNUSED(corked)) { #if defined(TCP_CORK) && defined(SOL_TCP) - if (!dcc_getenv_bool("DISTCC_TCP_CORK", 1)) + if (!dcc_getenv_bool("DISTCC_TCP_CORK", 1) || !(sd_is_socket(fd, AF_INET, SOCK_STREAM, 1) || + sd_is_socket(fd, AF_INET6, SOCK_STREAM, 1))) return 0; if (setsockopt(fd, SOL_TCP, TCP_CORK, &corked, sizeof corked) == -1) { @@ -280,8 +280,6 @@ int tcp_cork_sock(int POSSIBLY_UNUSED(fd), int POSSIBLY_UNUSED(corked)) return 0; } - - int dcc_close(int fd) { if (close(fd) != 0) { @@ -36,6 +36,8 @@ #include <sys/stat.h> #include <sys/time.h> +#include <sys/un.h> +#include <sys/socket.h> #ifdef HAVE_SYS_RESOURCE_H #include <sys/resource.h> @@ -902,3 +904,104 @@ ssize_t getline(char **lineptr, size_t *n, FILE *stream) { return bytes_read == 0 ? -1 : (ssize_t) bytes_read; } #endif + +/* from old systemd + + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ +static int sd_is_socket_internal(int fd, int type, int listening) { + struct stat st_fd; + + if (fd < 0 || type < 0) + return -EINVAL; + + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISSOCK(st_fd.st_mode)) + return 0; + + if (type != 0) { + int other_type = 0; + socklen_t l = sizeof(other_type); + + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0) + return -errno; + + if (l != sizeof(other_type)) + return -EINVAL; + + if (other_type != type) + return 0; + } + + if (listening >= 0) { + int accepting = 0; + socklen_t l = sizeof(accepting); + + if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0) + return -errno; + + if (l != sizeof(accepting)) + return -EINVAL; + + if (!accepting != !listening) + return 0; + } + + return 1; +} + +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; +}; + +int sd_is_socket(int fd, int family, int type, int listening) { + int r; + + if (family < 0) + return -EINVAL; + + r = sd_is_socket_internal(fd, type, listening); + if (r <= 0) + return r; + + if (family > 0) { + union sockaddr_union sockaddr = {}; + socklen_t l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + return sockaddr.sa.sa_family == family; + } + + return 1; +} @@ -62,3 +62,5 @@ int dcc_tokenize_string(const char *in, char ***argv_ptr); #ifndef HAVE_GETLINE ssize_t getline(char **lineptr, size_t *n, FILE *stream); #endif + +int sd_is_socket(int fd, int family, int type, int listening); |