summaryrefslogtreecommitdiff
path: root/ctdb
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2017-09-04 16:41:30 +1000
committerMartin Schwenke <martins@samba.org>2017-09-19 13:30:26 +0200
commitef676d5acf8042c02a2b50e18f4ae07a4f96f7c4 (patch)
treee7944bca5ab332c6313f6affd9d35a4c088aece9 /ctdb
parent285020360a4142fb982ad94bb21a0e87275cfed7 (diff)
downloadsamba-ef676d5acf8042c02a2b50e18f4ae07a4f96f7c4.tar.gz
ctdb-protocol: Add ctdb_connection utilities
Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/protocol/protocol_util.c95
-rw-r--r--ctdb/protocol/protocol_util.h8
-rw-r--r--ctdb/tests/src/protocol_util_test.c84
3 files changed, 187 insertions, 0 deletions
diff --git a/ctdb/protocol/protocol_util.c b/ctdb/protocol/protocol_util.c
index b42cf47fbc3..2b6585b1958 100644
--- a/ctdb/protocol/protocol_util.c
+++ b/ctdb/protocol/protocol_util.c
@@ -417,3 +417,98 @@ bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
{
return (ctdb_sock_addr_cmp(addr1, addr2) == 0);
}
+
+int ctdb_connection_to_buf(char *buf, size_t buflen,
+ struct ctdb_connection *conn, bool client_first)
+{
+ char server[64], client[64];
+ int ret;
+
+ ret = ctdb_sock_addr_to_buf(server, sizeof(server),
+ &conn->server, true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = ctdb_sock_addr_to_buf(client, sizeof(client),
+ &conn->client, true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (! client_first) {
+ ret = snprintf(buf, buflen, "%s %s", server, client);
+ } else {
+ ret = snprintf(buf, buflen, "%s %s", client, server);
+ }
+ if (ret >= buflen) {
+ return ENOSPC;
+ }
+
+ return 0;
+}
+
+const char *ctdb_connection_to_string(TALLOC_CTX *mem_ctx,
+ struct ctdb_connection *conn,
+ bool client_first)
+{
+ const size_t len = 128;
+ char *out;
+ int ret;
+
+ out = talloc_size(mem_ctx, len);
+ if (out == NULL) {
+ return NULL;
+ }
+
+ ret = ctdb_connection_to_buf(out, len, conn, client_first);
+ if (ret != 0) {
+ talloc_free(out);
+ return NULL;
+ }
+
+ return out;
+}
+
+int ctdb_connection_from_string(const char *str, bool client_first,
+ struct ctdb_connection *conn)
+{
+ char s[128];
+ char *t1 = NULL, *t2 = NULL;
+ size_t len;
+ ctdb_sock_addr *first = (client_first ? &conn->client : &conn->server);
+ ctdb_sock_addr *second = (client_first ? &conn->server : &conn->client);
+ int ret;
+
+ len = strlcpy(s, str, sizeof(s));
+ if (len >= sizeof(s)) {
+ return EINVAL;
+ }
+
+ t1 = strtok(s, " \t\n");
+ if (t1 == NULL) {
+ return EINVAL;
+ }
+
+ t2 = strtok(NULL, " \t\n\0");
+ if (t2 == NULL) {
+ return EINVAL;
+ }
+
+ ret = ctdb_sock_addr_from_string(t1, first, true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = ctdb_sock_addr_from_string(t2, second, true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = ctdb_sock_addr_cmp_family(first, second);
+ if (ret != 0) {
+ return EINVAL;
+ }
+
+ return 0;
+}
diff --git a/ctdb/protocol/protocol_util.h b/ctdb/protocol/protocol_util.h
index 88819366e5d..ab2a20b4631 100644
--- a/ctdb/protocol/protocol_util.h
+++ b/ctdb/protocol/protocol_util.h
@@ -52,4 +52,12 @@ bool ctdb_sock_addr_same_ip(const ctdb_sock_addr *addr1,
bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2);
+int ctdb_connection_to_buf(char *buf, size_t buflen,
+ struct ctdb_connection * conn, bool client_first);
+const char *ctdb_connection_to_string(TALLOC_CTX *mem_ctx,
+ struct ctdb_connection * conn,
+ bool client_first);
+int ctdb_connection_from_string(const char *str, bool client_first,
+ struct ctdb_connection *conn);
+
#endif /* __CTDB_PROTOCOL_UTIL_H__ */
diff --git a/ctdb/tests/src/protocol_util_test.c b/ctdb/tests/src/protocol_util_test.c
index 8926de0197b..4ca70aef108 100644
--- a/ctdb/tests/src/protocol_util_test.c
+++ b/ctdb/tests/src/protocol_util_test.c
@@ -72,6 +72,78 @@ static void test_sock_addr_cmp(const char *ip1, const char *ip2,
assert(ret == res);
}
+/*
+ * Test parsing of connection, conversion to string
+ */
+
+static void test_connection_to_string(const char *conn_str)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ctdb_connection conn;
+ const char *s, *r;
+ int ret;
+
+ tmp_ctx = talloc_new(NULL);
+ assert(tmp_ctx != NULL);
+
+ /*
+ * Test non-reversed parse and render
+ */
+
+ ret = ctdb_connection_from_string(conn_str, false, &conn);
+ assert(ret == 0);
+
+ s = ctdb_connection_to_string(tmp_ctx, &conn, false);
+ assert(s != NULL);
+ ret = strcmp(conn_str, s);
+ assert(ret == 0);
+
+ talloc_free(discard_const(s));
+
+ /*
+ * Reversed render
+ */
+ r = ctdb_connection_to_string(tmp_ctx, &conn, true);
+ assert(r != NULL);
+ ret = strcmp(conn_str, r);
+ assert(ret != 0);
+
+ /*
+ * Reversed parse with forward render
+ */
+ ret = ctdb_connection_from_string(conn_str, true, &conn);
+ assert(ret == 0);
+
+ s = ctdb_connection_to_string(tmp_ctx, &conn, false);
+ assert(s != NULL);
+ ret = strcmp(r, s);
+ assert(ret == 0);
+
+ talloc_free(discard_const(s));
+
+ /*
+ * Reversed parse and render
+ */
+ ret = ctdb_connection_from_string(conn_str, true, &conn);
+ assert(ret == 0);
+
+ s = ctdb_connection_to_string(tmp_ctx, &conn, true);
+ assert(s != NULL);
+ ret = strcmp(conn_str, s);
+ assert(ret == 0);
+
+ talloc_free(tmp_ctx);
+}
+
+static void test_connection_from_string_bad(const char *conn_str)
+{
+ struct ctdb_connection conn;
+ int ret;
+
+ ret = ctdb_connection_from_string(conn_str, false, &conn);
+ assert(ret != 0);
+}
+
int main(int argc, char *argv[])
{
test_sock_addr_to_string("0.0.0.0", false);
@@ -110,5 +182,17 @@ int main(int argc, char *argv[])
test_sock_addr_cmp("127.0.0.1:123", "127.0.0.1:124" , true, -1);
test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136:123",
"fe80::6af7:28ff:fefa:d136:122" , true, 1);
+
+ test_connection_to_string("127.0.0.1:12345 127.0.0.2:54321");
+ test_connection_to_string("fe80::6af7:28ff:fefa:d137:12345 "
+ "fe80::6af7:28ff:fefa:d138:54321");
+
+ test_connection_from_string_bad("127.0.0.1:12345 127.0.0.2:");
+ test_connection_from_string_bad("127.0.0.1:12345");
+ test_connection_from_string_bad("127.0.0.1:12345 "
+ "fe80::6af7:28ff:fefa:d136:122");
+ test_connection_from_string_bad("Junk!");
+ test_connection_from_string_bad("More junk");
+
return 0;
}