[tarantool-patches] [PATCH 3/5] sio: return 'no host' flag from sio_uri_to_addr()

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Wed May 1 01:31:25 MSK 2019


Results of sio_uri_to_addr("0.0.0.0:port") and
sio_uri_to_addr("port") are indistinguishable - both fill
sockaddr_in.sin_addr as INADDR_ANY. But SWIM wants to forbid the
former, and allow the latter. In case if only port is specified,
host will be 'localhost'.

This commit returns a flag from sio_uri_to_addr() signaling if a
host was specified.
---
 src/lib/core/sio.c   |  3 ++-
 src/lib/core/sio.h   |  2 +-
 src/lib/swim/swim.c  |  4 +++-
 test/unit/sio.c      | 29 ++++++++++++++++++++---------
 test/unit/sio.result | 32 ++++++++++++++++++--------------
 5 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/src/lib/core/sio.c b/src/lib/core/sio.c
index 28aef1d6c..97a512eee 100644
--- a/src/lib/core/sio.c
+++ b/src/lib/core/sio.c
@@ -344,11 +344,12 @@ sio_strfaddr(const struct sockaddr *addr, socklen_t addrlen)
 }
 
 int
-sio_uri_to_addr(const char *uri, struct sockaddr *addr)
+sio_uri_to_addr(const char *uri, struct sockaddr *addr, bool *is_host_empty)
 {
 	struct uri u;
 	if (uri_parse(&u, uri) != 0 || u.service == NULL)
 		goto invalid_uri;
+	*is_host_empty = u.host_len == 0;
 	if (u.host_len == strlen(URI_HOST_UNIX) &&
 	    memcmp(u.host, URI_HOST_UNIX, u.host_len) == 0) {
 		struct sockaddr_un *un = (struct sockaddr_un *) addr;
diff --git a/src/lib/core/sio.h b/src/lib/core/sio.h
index 093b5f5ba..db2e3281f 100644
--- a/src/lib/core/sio.h
+++ b/src/lib/core/sio.h
@@ -223,7 +223,7 @@ ssize_t sio_recvfrom(int fd, void *buf, size_t len, int flags,
  * sockaddr_in/un structure.
  */
 int
-sio_uri_to_addr(const char *uri, struct sockaddr *addr);
+sio_uri_to_addr(const char *uri, struct sockaddr *addr, bool *is_host_empty);
 
 #if defined(__cplusplus)
 } /* extern "C" */
diff --git a/src/lib/swim/swim.c b/src/lib/swim/swim.c
index 941214289..22dfc3d2a 100644
--- a/src/lib/swim/swim.c
+++ b/src/lib/swim/swim.c
@@ -1686,7 +1686,9 @@ swim_uri_to_addr(const char *uri, struct sockaddr_in *addr,
 		 const char *prefix)
 {
 	struct sockaddr_storage storage;
-	if (sio_uri_to_addr(uri, (struct sockaddr *) &storage) != 0)
+	bool is_host_empty;
+	if (sio_uri_to_addr(uri, (struct sockaddr *) &storage,
+			    &is_host_empty) != 0)
 		return -1;
 	if (storage.ss_family != AF_INET) {
 		diag_set(IllegalParams, "%s only IP sockets are supported",
diff --git a/test/unit/sio.c b/test/unit/sio.c
index dffdd5592..4ded96f4a 100644
--- a/test/unit/sio.c
+++ b/test/unit/sio.c
@@ -39,40 +39,49 @@ static void
 check_uri_to_addr(void)
 {
 	header();
-	plan(18);
+	plan(22);
+	bool is_host_empty;
 	struct sockaddr_storage storage;
 	struct sockaddr *addr = (struct sockaddr *) &storage;
 	struct sockaddr_un *un = (struct sockaddr_un *) addr;
 	struct sockaddr_in *in = (struct sockaddr_in *) addr;
-	isnt(0, sio_uri_to_addr("invalid uri", addr),
+	isnt(0, sio_uri_to_addr("invalid uri", addr, &is_host_empty),
 	     "invalid uri is detected");
 
 	char long_path[1000];
 	char *pos = long_path + sprintf(long_path, "unix/:/");
 	memset(pos, 'a', 900);
 	pos[900] = 0;
-	isnt(0, sio_uri_to_addr(long_path, addr), "too long UNIX path");
+	isnt(0, sio_uri_to_addr(long_path, addr, &is_host_empty),
+	     "too long UNIX path");
 
-	is(0, sio_uri_to_addr("unix/:/normal_path", addr), "UNIX");
+	is(0, sio_uri_to_addr("unix/:/normal_path", addr, &is_host_empty),
+	   "UNIX");
 	is(0, strcmp(un->sun_path, "/normal_path"), "UNIX path");
 	is(AF_UNIX, un->sun_family, "UNIX family");
+	ok(! is_host_empty, "unix host is not empty");
 
-	is(0, sio_uri_to_addr("localhost:1234", addr), "localhost");
+	is(0, sio_uri_to_addr("localhost:1234", addr, &is_host_empty),
+	   "localhost");
 	is(AF_INET, in->sin_family, "localhost family");
 	is(htonl(INADDR_LOOPBACK), in->sin_addr.s_addr, "localhost address");
 	is(htons(1234), in->sin_port, "localhost port");
+	ok(! is_host_empty, "'localhost' host is not empty");
 
-	is(0, sio_uri_to_addr("5678", addr), "'any'");
+	is(0, sio_uri_to_addr("5678", addr, &is_host_empty), "'any'");
 	is(AF_INET, in->sin_family, "'any' family");
 	is(htonl(INADDR_ANY), in->sin_addr.s_addr, "'any' address");
 	is(htons(5678), in->sin_port, "'any' port");
+	ok(is_host_empty, "only port specified - host is empty");
 
-	is(0, sio_uri_to_addr("192.168.0.1:9101", addr), "IP");
+	is(0, sio_uri_to_addr("192.168.0.1:9101", addr, &is_host_empty), "IP");
 	is(AF_INET, in->sin_family, "IP family");
 	is(inet_addr("192.168.0.1"), in->sin_addr.s_addr, "IP address");
 	is(htons(9101), in->sin_port, "IP port");
+	ok(! is_host_empty, "IPv4 host is not empty");
 
-	isnt(0, sio_uri_to_addr("192.168.0.300:1112", addr), "invalid IP");
+	isnt(0, sio_uri_to_addr("192.168.0.300:1112", addr, &is_host_empty),
+	     "invalid IP");
 
 	check_plan();
 	footer();
@@ -84,9 +93,11 @@ check_auto_bind(void)
 	header();
 	plan(3);
 
+	bool is_host_empty;
 	struct sockaddr_in addr;
 	socklen_t addrlen = sizeof(addr);
-	sio_uri_to_addr("127.0.0.1:0", (struct sockaddr *) &addr);
+	sio_uri_to_addr("127.0.0.1:0", (struct sockaddr *) &addr,
+			&is_host_empty);
 	int fd = sio_socket(AF_INET, SOCK_STREAM, 0);
 	is(sio_bind(fd, (struct sockaddr *) &addr, sizeof(addr)), 0,
 	   "bind to 0 works");
diff --git a/test/unit/sio.result b/test/unit/sio.result
index e5712ad3c..896736bf9 100644
--- a/test/unit/sio.result
+++ b/test/unit/sio.result
@@ -1,25 +1,29 @@
 	*** main ***
 1..2
 	*** check_uri_to_addr ***
-    1..18
+    1..22
     ok 1 - invalid uri is detected
     ok 2 - too long UNIX path
     ok 3 - UNIX
     ok 4 - UNIX path
     ok 5 - UNIX family
-    ok 6 - localhost
-    ok 7 - localhost family
-    ok 8 - localhost address
-    ok 9 - localhost port
-    ok 10 - 'any'
-    ok 11 - 'any' family
-    ok 12 - 'any' address
-    ok 13 - 'any' port
-    ok 14 - IP
-    ok 15 - IP family
-    ok 16 - IP address
-    ok 17 - IP port
-    ok 18 - invalid IP
+    ok 6 - unix host is not empty
+    ok 7 - localhost
+    ok 8 - localhost family
+    ok 9 - localhost address
+    ok 10 - localhost port
+    ok 11 - 'localhost' host is not empty
+    ok 12 - 'any'
+    ok 13 - 'any' family
+    ok 14 - 'any' address
+    ok 15 - 'any' port
+    ok 16 - only port specified - host is empty
+    ok 17 - IP
+    ok 18 - IP family
+    ok 19 - IP address
+    ok 20 - IP port
+    ok 21 - IPv4 host is not empty
+    ok 22 - invalid IP
 ok 1 - subtests
 	*** check_uri_to_addr: done ***
 	*** check_auto_bind ***
-- 
2.20.1 (Apple Git-117)





More information about the Tarantool-patches mailing list