From c8c62246f84b5d9d4a496097f043696e2d9ba0bb Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Sat, 28 Oct 2017 14:56:58 +0200 Subject: [*] Introduce constants for IPv4/6 in dnbd3_host_t AF_INET luckily was "2" on all platforms checked, so no problems there with interoperation, but AF_INET6 is different between Linux, BSD, Windows and possibly others, so map back and forth between AF_INET/AF_INET6 and HOST_IP4/HOST_IP6 to fix this. --- src/client/client.c | 17 +++++++++-------- src/fuse/helper.h | 4 ++-- src/kernel/net.c | 24 ++++++++++++------------ src/kernel/sysfs.c | 8 ++++---- src/server/altservers.c | 2 +- src/server/helper.c | 14 +++++++------- src/server/helper.h | 4 ++-- src/server/rpc.c | 4 ++-- src/shared/sockhelper.c | 13 ++++++------- src/types.h | 8 +++++++- 10 files changed, 52 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/client/client.c b/src/client/client.c index 685dbfd..37f0558 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -82,12 +82,12 @@ static char host_to_string(const dnbd3_host_t *host, char *target, size_t target { // Worst case: Port 5 chars, ':' to separate ip and port 1 char, terminating null 1 char = 7, [] for IPv6 if ( targetlen < 10 ) return false; - if ( host->type == AF_INET6 ) { + if ( host->type == HOST_IP6 ) { *target++ = '['; inet_ntop( AF_INET6, host->addr, target, targetlen - 10 ); target += strlen( target ); *target++ = ']'; - } else if ( host->type == AF_INET ) { + } else if ( host->type == HOST_IP4 ) { inet_ntop( AF_INET, host->addr, target, targetlen - 8 ); target += strlen( target ); } else { @@ -106,7 +106,7 @@ static char host_to_string(const dnbd3_host_t *host, char *target, size_t target /** * Parse IPv4 or IPv6 address in string representation to a suitable format usable by the BSD socket library * @string eg. "1.2.3.4" or "2a01::10:5", optially with port appended, eg "1.2.3.4:6666" or "[2a01::10:5]:6666" - * @af will contain either AF_INET or AF_INET6 + * @af will contain either HOST_IP4 or HOST_IP6 * @addr will contain the address in network representation * @port will contain the port in network representation, defaulting to #define PORT if none was given * returns 1 on success, 0 in failure. contents of af, addr and port are undefined in the latter case @@ -119,14 +119,14 @@ static char parse_address(char *string, dnbd3_host_t *host) // Try IPv4 without port if ( 1 == inet_pton( AF_INET, string, &v4 ) ) { - host->type = AF_INET; + host->type = HOST_IP4; memcpy( host->addr, &v4, 4 ); host->port = htons( PORT ); return 1; } // Try IPv6 without port if ( 1 == inet_pton( AF_INET6, string, &v6 ) ) { - host->type = AF_INET6; + host->type = HOST_IP6; memcpy( host->addr, &v6, 16 ); host->port = htons( PORT ); return 1; @@ -153,13 +153,13 @@ static char parse_address(char *string, dnbd3_host_t *host) // Try IPv4 with port if ( 1 == inet_pton( AF_INET, string, &v4 ) ) { - host->type = AF_INET; + host->type = HOST_IP4; memcpy( host->addr, &v4, 4 ); return 1; } // Try IPv6 with port if ( 1 == inet_pton( AF_INET6, string, &v6 ) ) { - host->type = AF_INET6; + host->type = HOST_IP6; memcpy( host->addr, &v6, 16 ); return 1; } @@ -178,10 +178,11 @@ static int dnbd3_get_ip(char *hostname, dnbd3_host_t *host) return false; } - host->type = (uint8_t)hent->h_addrtype; if ( hent->h_addrtype == AF_INET ) { + host->type = HOST_IP4; memcpy( host->addr, hent->h_addr, 4); } else if (hent->h_addrtype == AF_INET6) { + host->type = HOST_IP6; memcpy(host->addr, hent->h_addr, 16); } else { printf("FATAL: Unknown address type: %d\n", hent->h_addrtype); diff --git a/src/fuse/helper.h b/src/fuse/helper.h index 8c290cc..9e5d127 100644 --- a/src/fuse/helper.h +++ b/src/fuse/helper.h @@ -24,12 +24,12 @@ int connect_to_server(char *server_adress, int port); static inline bool isSameAddressPort(const dnbd3_host_t * const a, const dnbd3_host_t * const b) { - return (a->type == b->type) && (a->port == b->port) && (0 == memcmp( a->addr, b->addr, (a->type == AF_INET ? 4 : 16) )); + return (a->type == b->type) && (a->port == b->port) && (0 == memcmp( a->addr, b->addr, (a->type == HOST_IP4 ? 4 : 16) )); } static inline bool isSameAddress(const dnbd3_host_t * const a, const dnbd3_host_t * const b) { - return (a->type == b->type) && (0 == memcmp( a->addr, b->addr, (a->type == AF_INET ? 4 : 16) )); + return (a->type == b->type) && (0 == memcmp( a->addr, b->addr, (a->type == HOST_IP4 ? 4 : 16) )); } #endif diff --git a/src/kernel/net.c b/src/kernel/net.c index b4c2331..f6de404 100644 --- a/src/kernel/net.c +++ b/src/kernel/net.c @@ -32,9 +32,9 @@ #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -#define dnbd3_sock_create(af,type,proto,sock) sock_create_kern(&init_net, af, type, proto, sock) +#define dnbd3_sock_create(af,type,proto,sock) sock_create_kern(&init_net, (af) == HOST_IP4 ? AF_INET : AF_INET6, type, proto, sock) #else -#define dnbd3_sock_create(af,type,proto,sock) sock_create_kern(af, type, proto, sock) +#define dnbd3_sock_create(af,type,proto,sock) sock_create_kern((af) == HOST_IP4 ? AF_INET : AF_INET6, type, proto, sock) #endif /** @@ -44,7 +44,7 @@ */ #if 1 // Change to 0 to disable debug messages #define debug_print_va_host(_host, _fmt, ...) do { \ - if ((_host).type == AF_INET) \ + if ((_host).type == HOST_IP4) \ printk("%s:%d " _fmt " (%s, %pI4:%d)\n", __FILE__, __LINE__, __VA_ARGS__, dev->disk->disk_name, (_host).addr, (int)ntohs((_host).port)); \ else \ printk("%s:%d " _fmt " (%s, [%pI6]:%d)\n", __FILE__, __LINE__, __VA_ARGS__, dev->disk->disk_name, (_host).addr, (int)ntohs((_host).port)); \ @@ -59,7 +59,7 @@ #define error_alt_va(_fmt, ...) debug_error_va_host(dev->alt_servers[i].host, _fmt, __VA_ARGS__) #define debug_print_host(_host, txt) do { \ - if ((_host).type == AF_INET) \ + if ((_host).type == HOST_IP4) \ printk("%s:%d " txt " (%s, %pI4:%d)\n", __FILE__, __LINE__, dev->disk->disk_name, (_host).addr, (int)ntohs((_host).port)); \ else \ printk("%s:%d " txt " (%s, [%pI6]:%d)\n", __FILE__, __LINE__, dev->disk->disk_name, (_host).addr, (int)ntohs((_host).port)); \ @@ -87,7 +87,7 @@ static inline int is_same_server(const dnbd3_server_t * const a, const dnbd3_server_t * const b) { return (a->host.type == b->host.type) && (a->host.port == b->host.port) - && (0 == memcmp(a->host.addr, b->host.addr, (a->host.type == AF_INET ? 4 : 16))); + && (0 == memcmp(a->host.addr, b->host.addr, (a->host.type == HOST_IP4 ? 4 : 16))); } static inline dnbd3_server_t *get_existing_server(const dnbd3_server_entry_t * const newserver, @@ -99,7 +99,7 @@ static inline dnbd3_server_t *get_existing_server(const dnbd3_server_entry_t * c if ((newserver->host.type == dev->alt_servers[i].host.type) && (newserver->host.port == dev->alt_servers[i].host.port) && (0 - == memcmp(newserver->host.addr, dev->alt_servers[i].host.addr, (newserver->host.type == AF_INET ? 4 : 16)))) + == memcmp(newserver->host.addr, dev->alt_servers[i].host.addr, (newserver->host.type == HOST_IP4 ? 4 : 16)))) { return &dev->alt_servers[i]; break; @@ -159,7 +159,7 @@ int dnbd3_net_connect(dnbd3_device_t *dev) if (dev->sock) error_dev("ERROR: Already connected."); - if (dev->cur_server.host.type != AF_INET && dev->cur_server.host.type != AF_INET6) + if (dev->cur_server.host.type != HOST_IP4 && dev->cur_server.host.type != HOST_IP6) error_dev_va("ERROR: Unknown address type %d", (int)dev->cur_server.host.type); debug_dev("INFO: Connecting..."); @@ -182,7 +182,7 @@ int dnbd3_net_connect(dnbd3_device_t *dev) kernel_setsockopt(dev->sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)); kernel_setsockopt(dev->sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); dev->sock->sk->sk_allocation = GFP_NOIO; - if (dev->cur_server.host.type == AF_INET) + if (dev->cur_server.host.type == HOST_IP4) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); @@ -479,7 +479,7 @@ int dnbd3_net_discover(void *data) spin_lock_irqsave(&dev->blk_lock, irqflags); for (i = 0; i < dev->new_servers_num; ++i) { - if (dev->new_servers[i].host.type != AF_INET && dev->new_servers[i].host.type != AF_INET6) // Invalid entry? + if (dev->new_servers[i].host.type != HOST_IP4 && dev->new_servers[i].host.type != HOST_IP6) // Invalid entry? continue; alt_server = get_existing_server(&dev->new_servers[i], dev); if (alt_server != NULL ) // Server already known @@ -487,7 +487,7 @@ int dnbd3_net_discover(void *data) if (dev->new_servers[i].failures == 1) { // REMOVE request - if (alt_server->host.type == AF_INET) + if (alt_server->host.type == HOST_IP4) debug_dev_va("Removing alt server %pI4", alt_server->host.addr); else debug_dev_va("Removing alt server %pI6", alt_server->host.addr); @@ -505,7 +505,7 @@ int dnbd3_net_discover(void *data) continue; // Add new server entry alt_server->host = dev->new_servers[i].host; - if (alt_server->host.type == AF_INET) + if (alt_server->host.type == HOST_IP4) debug_dev_va("Adding alt server %pI4", alt_server->host.addr); else debug_dev_va("Adding alt server %pI6", alt_server->host.addr); @@ -559,7 +559,7 @@ int dnbd3_net_discover(void *data) kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)); kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); sock->sk->sk_allocation = GFP_NOIO; - if (dev->alt_servers[i].host.type == AF_INET) + if (dev->alt_servers[i].host.type == HOST_IP4) { sin4.sin_family = AF_INET; memcpy(&sin4.sin_addr, dev->alt_servers[i].host.addr, 4); diff --git a/src/kernel/sysfs.c b/src/kernel/sysfs.c index efe1cad..4406072 100644 --- a/src/kernel/sysfs.c +++ b/src/kernel/sysfs.c @@ -29,9 +29,9 @@ ssize_t show_cur_server_addr(char *buf, dnbd3_device_t *dev) { - if (dev->cur_server.host.type == AF_INET) + if (dev->cur_server.host.type == HOST_IP4) return MIN(snprintf(buf, PAGE_SIZE, "%pI4,%d\n", dev->cur_server.host.addr, (int)ntohs(dev->cur_server.host.port)), PAGE_SIZE); - else if (dev->cur_server.host.type == AF_INET6) + else if (dev->cur_server.host.type == HOST_IP6) return MIN(snprintf(buf, PAGE_SIZE, "%pI6,%d\n", dev->cur_server.host.addr, (int)ntohs(dev->cur_server.host.port)), PAGE_SIZE); *buf = '\0'; return 0; @@ -57,14 +57,14 @@ ssize_t show_alt_servers(char *buf, dnbd3_device_t *dev) int i, size = PAGE_SIZE, ret; for (i = 0; i < NUMBER_SERVERS; ++i) { - if (dev->alt_servers[i].host.type == AF_INET) + if (dev->alt_servers[i].host.type == HOST_IP4) ret = MIN(snprintf(buf, size, "%pI4,%d,%llu,%d\n", dev->alt_servers[i].host.addr, (int)ntohs(dev->alt_servers[i].host.port), (unsigned long long)((dev->alt_servers[i].rtts[0] + dev->alt_servers[i].rtts[1] + dev->alt_servers[i].rtts[2] + dev->alt_servers[i].rtts[3]) / 4), (int)dev->alt_servers[i].failures) , size); - else if (dev->alt_servers[i].host.type == AF_INET6) + else if (dev->alt_servers[i].host.type == HOST_IP6) ret = MIN(snprintf(buf, size, "%pI6,%d,%llu,%d\n", dev->alt_servers[i].host.addr, (int)ntohs(dev->alt_servers[i].host.port), diff --git a/src/server/altservers.c b/src/server/altservers.c index 18e2548..b9394cf 100644 --- a/src/server/altservers.c +++ b/src/server/altservers.c @@ -296,7 +296,7 @@ int altservers_netCloseness(dnbd3_host_t *host1, dnbd3_host_t *host2) { if ( host1 == NULL || host2 == NULL || host1->type != host2->type ) return -1; int retval = 0; - const int max = host1->type == AF_INET ? 4 : 16; + const int max = host1->type == HOST_IP4 ? 4 : 16; for (int i = 0; i < max; ++i) { if ( (host1->addr[i] & 0xf0) != (host2->addr[i] & 0xf0) ) return retval; ++retval; diff --git a/src/server/helper.c b/src/server/helper.c index 1a67a95..2dbc3ea 100644 --- a/src/server/helper.c +++ b/src/server/helper.c @@ -16,7 +16,7 @@ * * @param string eg. "1.2.3.4" or "2a01::10:5", optially with port appended, eg "1.2.3.4:6666" or "[2a01::10:5]:6666" * @param host pointer to dnbd3_host_t that will be filled with the following data: - * .type will contain either AF_INET or AF_INET6 + * .type will contain either HOST_IP4 or HOST_IP6 * .addr will contain the address in network representation * .port will contain the port in network representation, defaulting to #define PORT if none was given * @return true on success, false in failure. contents of af, addr and port are undefined in the latter case @@ -29,14 +29,14 @@ bool parse_address(char *string, dnbd3_host_t *host) memset( host, 0, sizeof(*host) ); // Try IPv4 without port if ( 1 == inet_pton( AF_INET, string, &v4 ) ) { - host->type = AF_INET; + host->type = HOST_IP4; memcpy( host->addr, &v4, 4 ); host->port = htons( PORT ); return true; } // Try IPv6 without port if ( 1 == inet_pton( AF_INET6, string, &v6 ) ) { - host->type = AF_INET6; + host->type = HOST_IP6; memcpy( host->addr, &v6, 16 ); host->port = htons( PORT ); return true; @@ -61,13 +61,13 @@ bool parse_address(char *string, dnbd3_host_t *host) // Try IPv4 with port if ( 1 == inet_pton( AF_INET, string, &v4 ) ) { - host->type = AF_INET; + host->type = HOST_IP4; memcpy( host->addr, &v4, 4 ); return true; } // Try IPv6 with port if ( 1 == inet_pton( AF_INET6, string, &v6 ) ) { - host->type = AF_INET6; + host->type = HOST_IP6; memcpy( host->addr, &v6, 16 ); return true; } @@ -85,12 +85,12 @@ bool host_to_string(const dnbd3_host_t *host, char *target, size_t targetlen) { // Worst case: Port 5 chars, ':' to separate ip and port 1 char, terminating null 1 char = 7, [] for IPv6 if ( targetlen < 10 ) return false; - if ( host->type == AF_INET6 ) { + if ( host->type == HOST_IP6 ) { *target++ = '['; inet_ntop( AF_INET6, host->addr, target, (socklen_t)targetlen - 10 ); target += strlen( target ); *target++ = ']'; - } else if ( host->type == AF_INET ) { + } else if ( host->type == HOST_IP4 ) { inet_ntop( AF_INET, host->addr, target, (socklen_t)targetlen - 8 ); target += strlen( target ); } else { diff --git a/src/server/helper.h b/src/server/helper.h index 2fa67a5..78a1c41 100644 --- a/src/server/helper.h +++ b/src/server/helper.h @@ -19,12 +19,12 @@ void blockNoncriticalSignals(); static inline bool isSameAddress(const dnbd3_host_t * const a, const dnbd3_host_t * const b) { - return (a->type == b->type) && (0 == memcmp( a->addr, b->addr, (a->type == AF_INET ? 4 : 16) )); + return (a->type == b->type) && (0 == memcmp( a->addr, b->addr, (a->type == HOST_IP4 ? 4 : 16) )); } static inline bool isSameAddressPort(const dnbd3_host_t * const a, const dnbd3_host_t * const b) { - return (a->type == b->type) && (a->port == b->port) && (0 == memcmp( a->addr, b->addr, (a->type == AF_INET ? 4 : 16) )); + return (a->type == b->type) && (a->port == b->port) && (0 == memcmp( a->addr, b->addr, (a->type == HOST_IP4 ? 4 : 16) )); } /** diff --git a/src/server/rpc.c b/src/server/rpc.c index 6b958be..255d893 100644 --- a/src/server/rpc.c +++ b/src/server/rpc.c @@ -267,11 +267,11 @@ static void addacl(int argc, char **argv, void *data UNUSED) char *last; bits = strtol( slash, &last, 10 ); if ( last == slash ) slash = NULL; - if ( host.type == AF_INET && bits > 32 ) bits = 32; + if ( host.type == HOST_IP4 && bits > 32 ) bits = 32; if ( bits > 128 ) bits = 128; } if ( slash == NULL ) { - if ( host.type == AF_INET ) { + if ( host.type == HOST_IP4 ) { bits = 32; } else { bits = 128; diff --git a/src/shared/sockhelper.c b/src/shared/sockhelper.c index 118fbec..6fc7f46 100644 --- a/src/shared/sockhelper.c +++ b/src/shared/sockhelper.c @@ -25,7 +25,7 @@ int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const in struct sockaddr_storage ss; int proto, addrlen; memset( &ss, 0, sizeof ss ); - if ( addr->type == AF_INET ) { + if ( addr->type == HOST_IP4 ) { // Set host (IPv4) struct sockaddr_in *addr4 = (struct sockaddr_in*)&ss; addr4->sin_family = AF_INET; @@ -35,7 +35,7 @@ int sock_connect(const dnbd3_host_t * const addr, const int connect_ms, const in addrlen = sizeof *addr4; } #ifdef WITH_IPV6 - else if ( addr->type == AF_INET6 ) { + else if ( addr->type == HOST_IP6 ) { // Set host (IPv6) struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)&ss; addr6->sin6_family = AF_INET6; @@ -112,11 +112,10 @@ int sock_resolveToDnbd3Host(const char * const address, dnbd3_host_t * const des return 0; } for ( ptr = res; ptr != NULL && count > 0; ptr = ptr->ai_next ) { - // TODO: AF->DNBD3 if ( ptr->ai_addr->sa_family == AF_INET ) { // Set host (IPv4) struct sockaddr_in *addr4 = (struct sockaddr_in*)ptr->ai_addr; - dest[addCount].type = AF_INET; + dest[addCount].type = HOST_IP4; dest[addCount].port = addr4->sin_port; memcpy( dest[addCount].addr, &addr4->sin_addr, 4 ); addCount += 1; @@ -124,7 +123,7 @@ int sock_resolveToDnbd3Host(const char * const address, dnbd3_host_t * const des } else if ( ptr->ai_addr->sa_family == AF_INET6 ) { // Set host (IPv6) struct sockaddr_in6 *addr6 = (struct sockaddr_in6*)ptr->ai_addr; - dest[addCount].type = AF_INET6; + dest[addCount].type = HOST_IP6; dest[addCount].port = addr6->sin6_port; memcpy( dest[addCount].addr, &addr6->sin6_addr, 16 ); addCount += 1; @@ -165,12 +164,12 @@ size_t sock_printHost(const dnbd3_host_t * const host, char * const buffer, cons // Worst case: Port 5 chars, ':' to separate ip and port 1 char, terminating null 1 char = 7, [] for IPv6 if ( len < 10 ) return 0; char *output = buffer; - if ( host->type == AF_INET6 ) { + if ( host->type == HOST_IP6 ) { *output++ = '['; inet_ntop( AF_INET6, host->addr, output, (socklen_t)( len - 10 ) ); output += strlen( output ); *output++ = ']'; - } else if ( host->type == AF_INET ) { + } else if ( host->type == HOST_IP4 ) { inet_ntop( AF_INET, host->addr, output, (socklen_t)( len - 8 ) ); output += strlen( output ); } else { diff --git a/src/types.h b/src/types.h index 9f9e744..313e907 100644 --- a/src/types.h +++ b/src/types.h @@ -98,12 +98,18 @@ static const uint16_t dnbd3_packet_magic = (0x73) | (0x72 << 8); #error "Unknown Endianness" #endif +typedef uint8_t dnbd3_af; + +static const dnbd3_af HOST_NONE = (dnbd3_af)0; +static const dnbd3_af HOST_IP4 = (dnbd3_af)2; +static const dnbd3_af HOST_IP6 = (dnbd3_af)10; + #pragma pack(1) typedef struct dnbd3_host_t { uint8_t addr[16]; // 16byte (network representation, so it can be directly passed to socket functions) uint16_t port; // 2byte (network representation, so it can be directly passed to socket functions) - uint8_t type; // 1byte (ip version. AF_INET or AF_INET6. 0 means this struct is empty and should be ignored) + dnbd3_af type; // 1byte (ip version. HOST_IP4 or HOST_IP6. 0 means this struct is empty and should be ignored) } dnbd3_host_t; #pragma pack(0) -- cgit v1.2.3-55-g7522