From 0461822151d42ffc72d1c5dc2d73fb558d235f93 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 15 Aug 2013 20:29:40 +0200 Subject: [SERVER] Fix embarrassing descriptor leak --- src/server/sockhelper.c | 131 ++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 76 deletions(-) diff --git a/src/server/sockhelper.c b/src/server/sockhelper.c index e202d78..b72cf05 100644 --- a/src/server/sockhelper.c +++ b/src/server/sockhelper.c @@ -12,27 +12,25 @@ static inline int connect_shared(const int client_sock, void* addr, const int ad // Connect to server tv.tv_sec = connect_ms / 1000; tv.tv_usec = connect_ms * 1000; - setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - setsockopt(client_sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); - if (connect(client_sock, (struct sockaddr *)addr, addrlen) == -1) - { - //int e = errno; - //printf("connect -1 (%d)\n", e); + setsockopt( client_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) ); + setsockopt( client_sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) ); + if ( connect( client_sock, (struct sockaddr *)addr, addrlen ) == -1 ) { + close( client_sock ); return -1; } // Apply read/write timeout tv.tv_sec = rw_ms / 1000; tv.tv_usec = rw_ms * 1000; - setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - setsockopt(client_sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + setsockopt( client_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) ); + setsockopt( client_sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) ); return client_sock; } int sock_connect4(struct sockaddr_in *addr, const int connect_ms, const int rw_ms) { - int client_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (client_sock == -1) return -1; - return connect_shared(client_sock, addr, sizeof(struct sockaddr_in), connect_ms, rw_ms); + int client_sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); + if ( client_sock == -1 ) return -1; + return connect_shared( client_sock, addr, sizeof(struct sockaddr_in), connect_ms, rw_ms ); } int sock_connect6(struct sockaddr_in6 *addr, const int connect_ms, const int rw_ms) @@ -42,22 +40,21 @@ int sock_connect6(struct sockaddr_in6 *addr, const int connect_ms, const int rw_ if (client_sock == -1) return -1; return connect_shared(client_sock, addr, sizeof(struct sockaddr_in6), connect_ms, rw_ms); #else - printf("[DEBUG] Not compiled with IPv6 support.\n"); + printf( "[DEBUG] Not compiled with IPv6 support.\n" ); return -1; #endif } int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const int rw_ms) { - if (addr->type == AF_INET) - { + if ( addr->type == AF_INET ) { // Set host (IPv4) struct sockaddr_in addr4; - memset(&addr4, 0, sizeof(addr4)); + memset( &addr4, 0, sizeof(addr4) ); addr4.sin_family = AF_INET; - memcpy(&addr4.sin_addr, addr->addr, 4); + memcpy( &addr4.sin_addr, addr->addr, 4 ); addr4.sin_port = addr->port; - return sock_connect4(&addr4, connect_ms, rw_ms); + return sock_connect4( &addr4, connect_ms, rw_ms ); } #ifdef WITH_IPV6 else if (addr->type == AF_INET6) @@ -71,7 +68,7 @@ int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const in return sock_connect6(&addr6, connect_ms, rw_ms); } #endif - printf("[DEBUG] Unsupported address type: %d\n", (int)addr->type); + printf( "[DEBUG] Unsupported address type: %d\n", (int)addr->type ); return -1; } @@ -80,19 +77,18 @@ void sock_set_timeout(const int sockfd, const int milliseconds) struct timeval tv; tv.tv_sec = milliseconds / 1000; tv.tv_usec = (milliseconds * 1000) % 1000000; - setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) ); + setsockopt( sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv) ); } int sock_listen_any(int protocol_family, uint16_t port) { struct sockaddr_storage addr; - memset(&addr, 0, sizeof(addr)); - if (protocol_family == PF_INET) - { + memset( &addr, 0, sizeof(addr) ); + if ( protocol_family == PF_INET ) { struct sockaddr_in *v4 = (struct sockaddr_in *)&addr; v4->sin_addr.s_addr = INADDR_ANY; - v4->sin_port = htons(port); + v4->sin_port = htons( port ); v4->sin_family = AF_INET; } #ifdef WITH_IPV6 @@ -104,56 +100,49 @@ int sock_listen_any(int protocol_family, uint16_t port) v6->sin6_family = AF_INET6; } #endif - else - { - printf("[DEBUG] sock_listen: Unsupported protocol: %d\n", protocol_family); + else { + printf( "[DEBUG] sock_listen: Unsupported protocol: %d\n", protocol_family ); return -1; } - return sock_listen(&addr, sizeof(addr)); + return sock_listen( &addr, sizeof(addr) ); } int sock_listen(struct sockaddr_storage *addr, int addrlen) { int pf; // On Linux AF_* == PF_*, but this is not guaranteed on all platforms, so let's be safe here: - if (addr->ss_family == AF_INET) - pf = PF_INET; + if ( addr->ss_family == AF_INET ) pf = PF_INET; #ifdef WITH_IPV6 else if (addr->ss_family == AF_INET6) - pf = PF_INET6; + pf = PF_INET6; #endif - else - { - printf("[DEBUG] sock_listen: unsupported address type: %d\n", (int)addr->ss_family); + else { + printf( "[DEBUG] sock_listen: unsupported address type: %d\n", (int)addr->ss_family ); return -1; } int sock; // Create socket - sock = socket(pf, SOCK_STREAM, IPPROTO_TCP); - if (sock < 0) - { - memlogf("[ERROR] sock_listen: Socket setup failure"); // TODO: print port number to help troubleshooting + sock = socket( pf, SOCK_STREAM, IPPROTO_TCP ); + if ( sock < 0 ) { + memlogf( "[ERROR] sock_listen: Socket setup failure" ); // TODO: print port number to help troubleshooting return -1; } const int on = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - if (pf == PF_INET6) - setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); + setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ); + if ( pf == PF_INET6 ) setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on) ); // Bind to socket - if (bind(sock, (struct sockaddr *) addr, addrlen) < 0) - { + if ( bind( sock, (struct sockaddr *)addr, addrlen ) < 0 ) { int e = errno; - close(sock); - memlogf("[ERROR] Bind failure (%d)", e); // TODO: print port number to help troubleshooting + close( sock ); + memlogf( "[ERROR] Bind failure (%d)", e ); // TODO: print port number to help troubleshooting return -1; } // Listen on socket - if (listen(sock, 20) == -1) - { - close(sock); - memlogf("[ERROR] Listen failure"); // TODO ... + if ( listen( sock, 20 ) == -1 ) { + close( sock ); + memlogf( "[ERROR] Listen failure" ); // TODO ... return -1; } @@ -163,53 +152,43 @@ int sock_listen(struct sockaddr_storage *addr, int addrlen) int accept_any(const int * const sockets, const int socket_count, struct sockaddr_storage *addr, socklen_t *length_ptr) { fd_set set; - FD_ZERO(&set); + FD_ZERO( &set ); int max = 0; - for (int i = 0; i < socket_count; ++i) - { - FD_SET(sockets[i], &set); - if (sockets[i] > max) - max = sockets[i]; + for (int i = 0; i < socket_count; ++i) { + FD_SET( sockets[i], &set ); + if ( sockets[i] > max ) max = sockets[i]; } - if (select(max + 1, &set, NULL, NULL, NULL) <= 0) return -1; - for (int i = 0; i < socket_count; ++i) - { - if (FD_ISSET(sockets[i], &set)) - return accept(sockets[i], (struct sockaddr *)addr, length_ptr); + if ( select( max + 1, &set, NULL, NULL, NULL ) <= 0 ) return -1; + for (int i = 0; i < socket_count; ++i) { + if ( FD_ISSET(sockets[i], &set)) return accept( sockets[i], (struct sockaddr *)addr, length_ptr ); } return -1; } void sock_set_nonblock(int sock) { - int flags = fcntl(sock, F_GETFL, 0); - if (flags == -1) - flags = 0; - fcntl(sock, F_SETFL, flags | O_NONBLOCK); + int flags = fcntl( sock, F_GETFL, 0 ); + if ( flags == -1 ) flags = 0; + fcntl( sock, F_SETFL, flags | O_NONBLOCK ); } void sock_set_block(int sock) { - int flags = fcntl(sock, F_GETFL, 0); - if (flags == -1) - flags = 0; - fcntl(sock, F_SETFL, flags & ~(int)O_NONBLOCK); + int flags = fcntl( sock, F_GETFL, 0 ); + if ( flags == -1 ) flags = 0; + fcntl( sock, F_SETFL, flags & ~(int)O_NONBLOCK ); } int sock_add_array(const int sock, int *array, int *array_fill, const int array_length) { - if (sock == -1) - return TRUE; - for (int i = 0; i < *array_fill; ++i) - { - if (array[i] == -1) - { + if ( sock == -1 ) return TRUE; + for (int i = 0; i < *array_fill; ++i) { + if ( array[i] == -1 ) { array[i] = sock; return TRUE; } } - if (*array_fill >= array_length) - return FALSE; + if ( *array_fill >= array_length ) return FALSE; array[*array_fill] = sock; (*array_fill) += 1; return TRUE; -- cgit v1.2.3-55-g7522