From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: kostja@tarantool.org, vdavydov.dev@gmail.com
Subject: [PATCH v4 01/12] sio: introduce sio_uri_to_addr
Date: Thu, 31 Jan 2019 00:28:27 +0300 [thread overview]
Message-ID: <696bb7ee520bd568e5a3d32d2e2aaaecc0a94898.1548883137.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1548883137.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1548883137.git.v.shpilevoy@tarantool.org>
The function parses string URI consisting of either IP and port,
or UNIX socket address, and stores the result into struct
sockaddr.
---
src/CMakeLists.txt | 2 +-
src/sio.c | 41 +++++++++++++++++
src/sio.h | 7 +++
test/unit/CMakeLists.txt | 3 ++
test/unit/sio.c | 96 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 test/unit/sio.c
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 04de5ad04..38bd576e6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -120,7 +120,7 @@ endif ()
add_library(core STATIC ${core_sources})
target_link_libraries(core
- salad small
+ salad small uri
${LIBEV_LIBRARIES}
${LIBEIO_LIBRARIES}
${LIBCORO_LIBRARIES}
diff --git a/src/sio.c b/src/sio.c
index 613cd9412..419f4e0f4 100644
--- a/src/sio.c
+++ b/src/sio.c
@@ -36,9 +36,11 @@
#include <limits.h>
#include <netinet/in.h> /* TCP_NODELAY */
#include <netinet/tcp.h> /* TCP_NODELAY */
+#include <arpa/inet.h>
#include "say.h"
#include "trivia/util.h"
#include "exception.h"
+#include "uri.h"
const char *
sio_socketname(int fd)
@@ -321,3 +323,42 @@ sio_strfaddr(struct sockaddr *addr, socklen_t addrlen)
}
return name;
}
+
+int
+sio_uri_to_addr(const char *uri, struct sockaddr *addr)
+{
+ struct uri u;
+ if (uri_parse(&u, uri) != 0 || u.service == NULL)
+ goto invalid_uri;
+ 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;
+ if (u.service_len + 1 > sizeof(un->sun_path))
+ goto invalid_uri;
+ memcpy(un->sun_path, u.service, u.service_len);
+ un->sun_path[u.service_len] = 0;
+ un->sun_family = AF_UNIX;
+ return 0;
+ }
+ in_addr_t iaddr;
+ if (u.host_len == 0) {
+ iaddr = htonl(INADDR_ANY);
+ } else if (u.host_len == 9 && memcmp("localhost", u.host, 9) == 0) {
+ iaddr = htonl(INADDR_LOOPBACK);
+ } else {
+ iaddr = inet_addr(tt_cstr(u.host, u.host_len));
+ if (iaddr == (in_addr_t) -1)
+ goto invalid_uri;
+ }
+ struct sockaddr_in *in = (struct sockaddr_in *) addr;
+ int port = htons(atoi(u.service));
+ memset(in, 0, sizeof(*in));
+ in->sin_family = AF_INET;
+ in->sin_addr.s_addr = iaddr;
+ in->sin_port = port;
+ return 0;
+
+invalid_uri:
+ diag_set(SocketError, sio_socketname(-1), "invalid uri \"%s\"", uri);
+ return -1;
+}
diff --git a/src/sio.h b/src/sio.h
index 3067dc111..27988a232 100644
--- a/src/sio.h
+++ b/src/sio.h
@@ -203,6 +203,13 @@ ssize_t sio_sendto(int fd, const void *buf, size_t len, int flags,
ssize_t sio_recvfrom(int fd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
+/**
+ * Convert a string URI like "ip:port" or "unix/:path" to
+ * sockaddr_in/un structure.
+ */
+int
+sio_uri_to_addr(const char *uri, struct sockaddr *addr);
+
#if defined(__cplusplus)
} /* extern "C" */
#endif /* defined(__cplusplus) */
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index 0025d3611..16739f75d 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -203,3 +203,6 @@ add_executable(checkpoint_schedule.test
${PROJECT_SOURCE_DIR}/src/box/checkpoint_schedule.c
)
target_link_libraries(checkpoint_schedule.test m unit)
+
+add_executable(sio.test sio.c)
+target_link_libraries(sio.test unit core)
diff --git a/test/unit/sio.c b/test/unit/sio.c
new file mode 100644
index 000000000..84a86aac3
--- /dev/null
+++ b/test/unit/sio.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "unit.h"
+#include "memory.h"
+#include "fiber.h"
+#include <sys/un.h>
+#include <arpa/inet.h>
+#include "sio.h"
+
+static void
+check_uri_to_addr(void)
+{
+ header();
+ plan(18);
+ 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),
+ "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");
+
+ is(0, sio_uri_to_addr("unix/:/normal_path", addr), "UNIX");
+ is(0, strcmp(un->sun_path, "/normal_path"), "UNIX path");
+ is(AF_UNIX, un->sun_family, "UNIX family");
+
+ is(0, sio_uri_to_addr("localhost:1234", addr), "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");
+
+ is(0, sio_uri_to_addr("5678", addr), "'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");
+
+ is(0, sio_uri_to_addr("192.168.0.1:9101", addr), "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");
+
+ isnt(0, sio_uri_to_addr("192.168.0.300:1112", addr), "invalid IP");
+
+ check_plan();
+ footer();
+}
+
+int
+main(void)
+{
+ memory_init();
+ fiber_init(fiber_c_invoke);
+
+ header();
+ plan(1);
+ check_uri_to_addr();
+ int rc = check_plan();
+ footer();
+
+ fiber_free();
+ memory_free();
+ return rc;
+}
--
2.17.2 (Apple Git-113)
next prev parent reply other threads:[~2019-01-30 21:28 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-30 21:28 [PATCH v4 00/12] SWIM draft Vladislav Shpilevoy
2019-01-30 21:28 ` Vladislav Shpilevoy [this message]
2019-02-15 13:21 ` [tarantool-patches] [PATCH v4 01/12] sio: introduce sio_uri_to_addr Konstantin Osipov
2019-02-15 21:22 ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 10/12] [RAW] swim: introduce 'quit' message Vladislav Shpilevoy
2019-02-21 12:13 ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 11/12] [RAW] swim: introduce broadcast tasks Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 12/12] [RAW] swim: allow to use broadcast tasks to send pings Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 02/12] evio: expose evio_setsockopt_server function Vladislav Shpilevoy
2019-02-15 13:21 ` [tarantool-patches] " Konstantin Osipov
2019-02-15 21:22 ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 03/12] rlist: introduce rlist_add_tail_entry_sorted Vladislav Shpilevoy
2019-02-15 13:26 ` [tarantool-patches] " Konstantin Osipov
2019-02-15 13:34 ` [tarantool-patches] " Vladislav Shpilevoy
2019-02-15 18:07 ` Konstantin Osipov
2019-01-30 21:28 ` [PATCH v4 04/12] [RAW] swim: introduce SWIM's anti-entropy component Vladislav Shpilevoy
2019-02-21 18:35 ` [tarantool-patches] " Konstantin Osipov
2019-02-26 18:28 ` [tarantool-patches] " Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 05/12] [RAW] swim: introduce failure detection component Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 06/12] [RAW] swim: introduce dissemination component Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 07/12] [RAW] swim: keep encoded round message cached Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 08/12] [RAW] swim: introduce payload Vladislav Shpilevoy
2019-01-30 21:28 ` [PATCH v4 09/12] [RAW] swim: introduce routing Vladislav Shpilevoy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=696bb7ee520bd568e5a3d32d2e2aaaecc0a94898.1548883137.git.v.shpilevoy@tarantool.org \
--to=v.shpilevoy@tarantool.org \
--cc=kostja@tarantool.org \
--cc=tarantool-patches@freelists.org \
--cc=vdavydov.dev@gmail.com \
--subject='Re: [PATCH v4 01/12] sio: introduce sio_uri_to_addr' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox