diff options
author | Martin Schwenke <martin@meltin.net> | 2017-09-04 16:41:30 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-09-19 13:30:26 +0200 |
commit | ef676d5acf8042c02a2b50e18f4ae07a4f96f7c4 (patch) | |
tree | e7944bca5ab332c6313f6affd9d35a4c088aece9 /ctdb | |
parent | 285020360a4142fb982ad94bb21a0e87275cfed7 (diff) | |
download | samba-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.c | 95 | ||||
-rw-r--r-- | ctdb/protocol/protocol_util.h | 8 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_util_test.c | 84 |
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; } |