summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2017-10-28 14:56:58 +0200
committerSimon Rettberg2017-10-28 14:56:58 +0200
commitc8c62246f84b5d9d4a496097f043696e2d9ba0bb (patch)
tree27a896f6677791ef8087fa44b1aab7cb2071d774
parent[SERVER] Add function to parse x-www-form-urlencoded strings (diff)
downloaddnbd3-c8c62246f84b5d9d4a496097f043696e2d9ba0bb.tar.gz
dnbd3-c8c62246f84b5d9d4a496097f043696e2d9ba0bb.tar.xz
dnbd3-c8c62246f84b5d9d4a496097f043696e2d9ba0bb.zip
[*] 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.
-rw-r--r--src/client/client.c17
-rw-r--r--src/fuse/helper.h4
-rw-r--r--src/kernel/net.c24
-rw-r--r--src/kernel/sysfs.c8
-rw-r--r--src/server/altservers.c2
-rw-r--r--src/server/helper.c14
-rw-r--r--src/server/helper.h4
-rw-r--r--src/server/rpc.c4
-rw-r--r--src/shared/sockhelper.c13
-rw-r--r--src/types.h8
10 files changed, 52 insertions, 46 deletions
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)