diff options
author | Simon Rettberg | 2015-11-24 12:30:46 +0100 |
---|---|---|
committer | Simon Rettberg | 2015-11-24 12:30:46 +0100 |
commit | 7b51c287a60d2f202fb131eeed9d1bf19b65a7a3 (patch) | |
tree | 031573c708b50aeafe9a6fe6f0992b3ae6456e7c /src/server/sockhelper.c | |
parent | [SERVER] Fix race condition potentially leading to use after release (diff) | |
download | dnbd3-7b51c287a60d2f202fb131eeed9d1bf19b65a7a3.tar.gz dnbd3-7b51c287a60d2f202fb131eeed9d1bf19b65a7a3.tar.xz dnbd3-7b51c287a60d2f202fb131eeed9d1bf19b65a7a3.zip |
[FUSE] Mid-refactoring, does not compile
Diffstat (limited to 'src/server/sockhelper.c')
-rw-r--r-- | src/server/sockhelper.c | 214 |
1 files changed, 0 insertions, 214 deletions
diff --git a/src/server/sockhelper.c b/src/server/sockhelper.c deleted file mode 100644 index fb09ec2..0000000 --- a/src/server/sockhelper.c +++ /dev/null @@ -1,214 +0,0 @@ -#include "sockhelper.h" -#include "log.h" -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> // inet_ntop -#include <netdb.h> -#include <string.h> -#include <stdio.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <poll.h> -#include <stdlib.h> - -#define MAXLISTEN 20 - -struct _poll_list { - int count; - struct pollfd entry[MAXLISTEN]; -}; - -int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const int rw_ms) -{ - // TODO: Move out of here, this unit should contain general socket functions - // TODO: Rework the dnbd3_host_t to not use AF_* as these could theoretically change - // TODO: Abstract away from sockaddr_in* like the rest of the functions here do, - // so WITH_IPV6 can finally be removed as everything is transparent. - struct sockaddr_storage ss; - int proto, addrlen; - memset( &ss, 0, sizeof ss ); - if ( addr->type == AF_INET ) { - // Set host (IPv4) - struct sockaddr_in *addr4 = (struct sockaddr_in*)&ss; - addr4->sin_family = AF_INET; - memcpy( &addr4->sin_addr, addr->addr, 4 ); - addr4->sin_port = addr->port; - proto = PF_INET; - addrlen = sizeof *addr4; - } -#ifdef WITH_IPV6 - else if ( addr->type == AF_INET6 ) { - // Set host (IPv6) - struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)&ss; - addr6->sin6_family = AF_INET6; - memcpy( &addr6->sin6_addr, addr->addr, 16 ); - addr6->sin6_port = addr->port; - proto = PF_INET6; - addrlen = sizeof *addr6; - } -#endif - else { - logadd( LOG_DEBUG1, "Unsupported address type: %d\n", (int)addr->type ); - return -1; - } - int client_sock = socket( proto, SOCK_STREAM, IPPROTO_TCP ); - if ( client_sock == -1 ) return -1; - // Apply connect timeout - sock_setTimeout( client_sock, connect_ms ); - if ( connect( client_sock, (struct sockaddr *)&ss, addrlen ) == -1 ) { - close( client_sock ); - return -1; - } - // Apply read/write timeout - sock_setTimeout( client_sock, rw_ms ); - return client_sock; -} - -void sock_setTimeout(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) ); -} - -poll_list_t* sock_newPollList() -{ - poll_list_t *list = (poll_list_t*)malloc( sizeof( poll_list_t ) ); - list->count = 0; - return list; -} - -void sock_destroyPollList(poll_list_t *list) -{ - for ( int i = 0; i < list->count; ++i ) { - if ( list->entry[i].fd >= 0 ) close( list->entry[i].fd ); - } - free( list ); -} - -bool sock_printable(struct sockaddr *addr, socklen_t addrLen, char *output, int len) -{ - char host[100], port[10]; - int ret = getnameinfo( addr, addrLen, host, 100, port, 10, NI_NUMERICHOST | NI_NUMERICSERV ); - if ( ret == 0 ) snprintf( output, len, "[%s]:%s", host, port ); - return ret == 0; -} - -bool sock_listen(poll_list_t* list, char* bind_addr, uint16_t port) -{ - if ( list->count >= MAXLISTEN ) return false; - struct addrinfo hints, *res, *ptr; - char portStr[6]; - const int on = 1; - int openCount = 0; - // Set hints for local addresses. - memset( &hints, 0, sizeof(hints) ); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - snprintf( portStr, sizeof portStr, "%d", (int)port ); - if ( getaddrinfo( bind_addr, portStr, &hints, &res ) != 0 || res == NULL ) return false; - // Attempt to bind to all of the addresses as long as there's room in the poll list - for( ptr = res; ptr != NULL; ptr = ptr->ai_next ) { - char bla[100]; - if ( !sock_printable( (struct sockaddr*)ptr->ai_addr, ptr->ai_addrlen, bla, 100 ) ) snprintf( bla, 100, "[invalid]" ); - logadd( LOG_DEBUG1, "Binding to %s...", bla ); - int sock = socket( ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol ); - if ( sock < 0 ) { - logadd( LOG_WARNING, "(Bind to %s): cannot socket(), errno=%d", bla, errno ); - continue; - } - setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ); - if ( ptr->ai_family == PF_INET6 ) setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on) ); - if ( bind( sock, ptr->ai_addr, ptr->ai_addrlen ) == -1 ) { - logadd( LOG_WARNING, "(Bind to %s): cannot bind(), errno=%d", bla, errno ); - close( sock ); - continue; - } - if ( listen( sock, 20 ) == -1 ) { - logadd( LOG_WARNING, "(Bind to %s): cannot listen(), errno=%d", errno ); - close( sock ); - continue; - } - list->entry[list->count].fd = sock; - list->entry[list->count].events = POLLIN | POLLRDHUP; - list->count++; - openCount++; - if ( list->count >= MAXLISTEN ) break; - } - freeaddrinfo( res ); - return openCount > 0; -} - -int sock_listenAny(poll_list_t* list, uint16_t port) -{ - return sock_listen( list, NULL, port ); -} - -int sock_accept(poll_list_t *list, struct sockaddr_storage *addr, socklen_t *length_ptr) -{ - int ret = poll( list->entry, list->count, -1 ); - if ( ret < 0 ) { - return -1; - } - for ( int i = list->count - 1; i >= 0; --i ) { - if ( list->entry[i].revents == 0 ) continue; - if ( list->entry[i].revents == POLLIN ) return accept( list->entry[i].fd, (struct sockaddr *)addr, length_ptr ); - if ( list->entry[i].revents & ( POLLNVAL | POLLHUP | POLLERR | POLLRDHUP ) ) { - logadd( LOG_DEBUG1, "poll fd revents=%d for index=%d and fd=%d", (int)list->entry[i].revents, i, list->entry[i].fd ); - if ( ( list->entry[i].revents & POLLNVAL ) == 0 ) close( list->entry[i].fd ); - if ( i != list->count ) list->entry[i] = list->entry[list->count]; - list->count--; - } - } - 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 ); -} - -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 ); -} - -bool sock_append(poll_list_t *list, const int sock, bool wantRead, bool wantWrite) -{ - if ( sock == -1 || list->count >= MAXLISTEN ) return false; - list->entry[list->count++].fd = sock; - list->entry[list->count++].events = ( wantRead ? POLLIN : 0 ) | ( wantWrite ? POLLOUT : 0 ) | POLLRDHUP; - list->count++; - return true; -} - -ssize_t sock_sendAll(int sock, void *buffer, size_t len, int maxtries) -{ - size_t done = 0; - ssize_t ret = 0; - while ( done < len ) { - if ( maxtries >= 0 && --maxtries == -1 ) break; - ret = write( sock, (char*)buffer + done, len - done ); - if ( ret < 0 ) { - if ( errno == EINTR ) continue; - if ( errno == EAGAIN || errno == EWOULDBLOCK ) { - usleep( 1000 ); - continue; - } - break; - } - if ( ret == 0 ) break; - done += ret; - } - if ( done == 0 ) return ret; - return done; -} - |