ctdb-protocol: Add ctdb_connection utilities
authorMartin Schwenke <martin@meltin.net>
Mon, 4 Sep 2017 06:41:30 +0000 (16:41 +1000)
committerMartin Schwenke <martins@samba.org>
Tue, 19 Sep 2017 11:30:26 +0000 (13:30 +0200)
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/protocol/protocol_util.c
ctdb/protocol/protocol_util.h
ctdb/tests/src/protocol_util_test.c

index b42cf47fbc33e96c2801f662d9955f2256ac3105..2b6585b1958b6ef0d166588a8cafee78386e3531 100644 (file)
@@ -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;
+}
index 88819366e5d09420d9bcee97d3a44fc854010583..ab2a20b4631e6352cdf443db364689a0e6eb4c5a 100644 (file)
@@ -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__ */
index 8926de0197b7e68d0a9d0b7e28045e62d59731b4..4ca70aef108956b959f9ac4ecca1505e600051d7 100644 (file)
@@ -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;
 }