diff options
Diffstat (limited to 'src/shared/sockhelper.c')
-rw-r--r-- | src/shared/sockhelper.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/src/shared/sockhelper.c b/src/shared/sockhelper.c index ab34aa1..5096320 100644 --- a/src/shared/sockhelper.c +++ b/src/shared/sockhelper.c @@ -1,6 +1,8 @@ -#include "sockhelper.h" -#include "log.h" +#include <dnbd3/shared/sockhelper.h> +#include <dnbd3/shared/log.h> +#include <dnbd3/types.h> #include <arpa/inet.h> // inet_ntop +#include <netinet/tcp.h> #include <netdb.h> #include <stdio.h> #include <unistd.h> @@ -19,8 +21,7 @@ struct _poll_list { 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: Abstract away from sockaddr_in* like the rest of the functions here do, - // so WITH_IPV6 can finally be removed as everything is transparent. b- but how? + // TODO: Abstract away from sockaddr_in* like the rest of the functions here struct sockaddr_storage ss; int proto, addrlen; memset( &ss, 0, sizeof ss ); @@ -32,9 +33,7 @@ int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const in addr4->sin_port = addr->port; proto = PF_INET; addrlen = sizeof *addr4; - } -#ifdef WITH_IPV6 - else if ( addr->type == HOST_IP6 ) { + } else if ( addr->type == HOST_IP6 ) { // Set host (IPv6) struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)&ss; addr6->sin6_family = AF_INET6; @@ -42,10 +41,9 @@ int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const in addr6->sin6_port = addr->port; proto = PF_INET6; addrlen = sizeof *addr6; - } -#endif - else { + } else { logadd( LOG_DEBUG1, "Unsupported address type: %d\n", (int)addr->type ); + errno = EAFNOSUPPORT; return -1; } int client_sock = socket( proto, SOCK_STREAM, IPPROTO_TCP ); @@ -56,9 +54,13 @@ int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const in } else { sock_setTimeout( client_sock, connect_ms ); } + // NODELAY makes sense for the client side, which should be all users in this code base + int e2 = 1; + setsockopt( client_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&e2, sizeof(e2) ); for ( int i = 0; i < 5; ++i ) { int ret = connect( client_sock, (struct sockaddr *)&ss, addrlen ); - if ( ret != -1 || errno == EINPROGRESS || errno == EISCONN ) break; + e2 = errno; + if ( ret != -1 || ( connect_ms == -1 && errno == EINPROGRESS ) || errno == EISCONN ) break; if ( errno == EINTR ) { // http://www.madore.org/~david/computers/connect-intr.html #ifdef __linux__ @@ -67,21 +69,26 @@ int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const in struct pollfd unix_really_sucks = { .fd = client_sock, .events = POLLOUT | POLLIN }; while ( i-- > 0 ) { int pr = poll( &unix_really_sucks, 1, connect_ms == 0 ? -1 : connect_ms ); + e2 = errno; if ( pr == 1 && ( unix_really_sucks.revents & POLLOUT ) ) break; if ( pr == -1 && errno == EINTR ) continue; close( client_sock ); + errno = e2; return -1; } - sockaddr_storage junk; + struct sockaddr_storage junk; socklen_t more_junk = sizeof(junk); if ( getpeername( client_sock, (struct sockaddr*)&junk, &more_junk ) == -1 ) { + e2 = errno; close( client_sock ); + errno = e2; return -1; } break; #endif } // EINTR close( client_sock ); + errno = e2; return -1; } if ( connect_ms != -1 && connect_ms != rw_ms ) { @@ -157,7 +164,7 @@ bool sock_sockaddrToDnbd3(struct sockaddr* sa, dnbd3_host_t *host) memcpy( host->addr, &addr4->sin_addr, 4 ); return true; } -#ifdef WITH_IPV6 + if ( sa->sa_family == AF_INET6 ) { // Set host (IPv6) struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)sa; @@ -166,7 +173,7 @@ bool sock_sockaddrToDnbd3(struct sockaddr* sa, dnbd3_host_t *host) memcpy( host->addr, &addr6->sin6_addr, 16 ); return true; } -#endif + return false; } @@ -234,7 +241,10 @@ size_t sock_printable(const struct sockaddr * const addr, const socklen_t addrLe outlen = snprintf( output, len, "[%s]:%s", host, port ); } } - if ( outlen <= 0 ) return 0; + if ( outlen <= 0 ) { + output[0] = '\0'; + return 0; + } return MIN( (size_t)outlen, len-1 ); } @@ -338,7 +348,7 @@ int sock_multiConnect(poll_list_t* list, const dnbd3_host_t* host, int connect_m if ( i != list->count ) list->entry[i] = list->entry[list->count]; if ( fd != -1 ) { sock_set_block( fd ); - if ( rw_ms != -1 && rw_ms != connect_ms ) { + if ( rw_ms != -1 ) { sock_setTimeout( fd, rw_ms ); } return fd; |