diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-04-05 16:25:42 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-10-10 11:45:19 +0200 |
commit | c700464d2330f3cede96349c0cdcc55bbb88a5a0 (patch) | |
tree | 79f5ce79b1a9cffc28f87967c902210458fb42c6 | |
parent | 24e4197195a4a23d1b901ce1d5d9ab5fca22696a (diff) | |
download | samba-c700464d2330f3cede96349c0cdcc55bbb88a5a0.tar.gz |
ctdb-protocol: Add protocol marshalling for CTDB_REQ_TUNNEL
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
-rw-r--r-- | ctdb/protocol/protocol_api.h | 14 | ||||
-rw-r--r-- | ctdb/protocol/protocol_debug.c | 47 | ||||
-rw-r--r-- | ctdb/protocol/protocol_tunnel.c | 114 | ||||
-rwxr-xr-x | ctdb/tests/cunit/protocol_test_101.sh | 1 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_common_ctdb.c | 15 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_common_ctdb.h | 4 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_ctdb_compat_test.c | 87 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_ctdb_test.c | 3 | ||||
-rw-r--r-- | ctdb/wscript | 1 |
9 files changed, 286 insertions, 0 deletions
diff --git a/ctdb/protocol/protocol_api.h b/ctdb/protocol/protocol_api.h index 0e5d57fdece..8b40d1d8c0e 100644 --- a/ctdb/protocol/protocol_api.h +++ b/ctdb/protocol/protocol_api.h @@ -653,6 +653,20 @@ int ctdb_req_keepalive_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, struct ctdb_req_keepalive *c); +/* From protocol/protocol_tunnel.c */ + +size_t ctdb_req_tunnel_len(struct ctdb_req_header *h, + struct ctdb_req_tunnel *c); + +int ctdb_req_tunnel_push(struct ctdb_req_header *h, + struct ctdb_req_tunnel *c, + uint8_t *buf, size_t *buflen); + +int ctdb_req_tunnel_pull(uint8_t *buf, size_t buflen, + struct ctdb_req_header *h, + TALLOC_CTX *mem_ctx, + struct ctdb_req_tunnel *c); + /* From protocol/protocol_event.c */ size_t ctdb_event_request_len(struct ctdb_event_request *in); diff --git a/ctdb/protocol/protocol_debug.c b/ctdb/protocol/protocol_debug.c index 1a87ade3419..3dd5c32ab11 100644 --- a/ctdb/protocol/protocol_debug.c +++ b/ctdb/protocol/protocol_debug.c @@ -354,6 +354,24 @@ static void ctdb_srvid_print(uint64_t srvid, FILE *fp) } } +static void ctdb_tunnel_id_print(uint64_t tunnel_id, FILE *fp) +{ + fprintf(fp, "0x%"PRIx64, tunnel_id); +} + +static void ctdb_tunnel_flags_print(uint32_t flags, FILE *fp) +{ + if (flags & CTDB_TUNNEL_FLAG_REQUEST) { + fprintf(fp, "REQUEST "); + } + if (flags & CTDB_TUNNEL_FLAG_REPLY) { + fprintf(fp, "REPLY "); + } + if (flags & CTDB_TUNNEL_FLAG_NOREPLY) { + fprintf(fp, "NOREPLY "); + } +} + /* * Print routines */ @@ -472,6 +490,16 @@ static void ctdb_req_keepalive_print(struct ctdb_req_keepalive *c, FILE *fp) fprintf(fp, "\n"); } +static void ctdb_req_tunnel_print(struct ctdb_req_tunnel *c, FILE *fp) +{ + fprintf(fp, "Data\n"); + fprintf(fp, " tunnel_id:"); + ctdb_tunnel_id_print(c->tunnel_id, fp); + ctdb_tunnel_flags_print(c->flags, fp); + tdb_data_print(c->data, fp); + fprintf(fp, "\n"); +} + /* * Parse routines */ @@ -611,6 +639,21 @@ static void ctdb_req_keepalive_parse(uint8_t *buf, size_t buflen, FILE *fp, ctdb_req_keepalive_print(&c, fp); } +static void ctdb_req_tunnel_parse(uint8_t *buf, size_t buflen, FILE *fp, + TALLOC_CTX *mem_ctx) +{ + struct ctdb_req_tunnel c; + int ret; + + ret = ctdb_req_tunnel_pull(buf, buflen, NULL, mem_ctx, &c); + if (ret != 0) { + fprintf(fp, "Failed to parse CTDB_REQ_TUNNEL\n"); + return; + } + + ctdb_req_tunnel_print(&c, fp); +} + /* * Packet print */ @@ -679,6 +722,10 @@ void ctdb_packet_print(uint8_t *buf, size_t buflen, FILE *fp) ctdb_req_keepalive_parse(buf, buflen, fp, mem_ctx); break; + case CTDB_REQ_TUNNEL: + ctdb_req_tunnel_parse(buf, buflen, fp, mem_ctx); + break; + default: fprintf(fp, "Invalid ctdb operation\n"); break; diff --git a/ctdb/protocol/protocol_tunnel.c b/ctdb/protocol/protocol_tunnel.c new file mode 100644 index 00000000000..d31d9d50f01 --- /dev/null +++ b/ctdb/protocol/protocol_tunnel.c @@ -0,0 +1,114 @@ +/* + CTDB protocol marshalling + + Copyright (C) Amitay Isaacs 2017 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "replace.h" +#include "system/network.h" + +#include <talloc.h> +#include <tdb.h> + +#include "protocol.h" +#include "protocol_api.h" +#include "protocol_private.h" + +size_t ctdb_req_tunnel_len(struct ctdb_req_header *h, + struct ctdb_req_tunnel *c) +{ + return ctdb_req_header_len(h) + + ctdb_uint64_len(&c->tunnel_id) + + ctdb_uint32_len(&c->flags) + + ctdb_tdb_datan_len(&c->data); +} + +int ctdb_req_tunnel_push(struct ctdb_req_header *h, + struct ctdb_req_tunnel *c, + uint8_t *buf, size_t *buflen) +{ + size_t length, offset = 0, np; + + length = ctdb_req_tunnel_len(h, c); + if (*buflen < length) { + *buflen = length; + return EMSGSIZE; + } + + h->length = *buflen; + ctdb_req_header_push(h, buf, &np); + offset += np; + + ctdb_uint64_push(&c->tunnel_id, buf+offset, &np); + offset += np; + + ctdb_uint32_push(&c->flags, buf+offset, &np); + offset += np; + + ctdb_tdb_datan_push(&c->data, buf+offset, &np); + offset += np; + + if (offset > *buflen) { + return EMSGSIZE; + } + + return 0; +} + +int ctdb_req_tunnel_pull(uint8_t *buf, size_t buflen, + struct ctdb_req_header *h, + TALLOC_CTX *mem_ctx, + struct ctdb_req_tunnel *c) +{ + struct ctdb_req_header header; + size_t offset = 0, np; + int ret; + + ret = ctdb_req_header_pull(buf, buflen, &header, &np); + if (ret != 0) { + return ret; + } + offset += np; + + if (h != NULL) { + *h = header; + } + + ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->tunnel_id, &np); + if (ret != 0) { + return ret; + } + offset += np; + + ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->flags, &np); + if (ret != 0) { + return ret; + } + offset += np; + + ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, mem_ctx, + &c->data, &np); + if (ret != 0) { + return ret; + } + offset += np; + + if (offset > buflen) { + return EMSGSIZE; + } + + return 0; +} diff --git a/ctdb/tests/cunit/protocol_test_101.sh b/ctdb/tests/cunit/protocol_test_101.sh index 8b3645a8b67..36751d4fbe7 100755 --- a/ctdb/tests/cunit/protocol_test_101.sh +++ b/ctdb/tests/cunit/protocol_test_101.sh @@ -55,6 +55,7 @@ output=$( generate_message_output "ctdb_req_message" echo "ctdb_req_message_data" echo "ctdb_req_keepalive" + echo "ctdb_req_tunnel" ) ok "$output" diff --git a/ctdb/tests/src/protocol_common_ctdb.c b/ctdb/tests/src/protocol_common_ctdb.c index 928b7d127cd..03888f44e62 100644 --- a/ctdb/tests/src/protocol_common_ctdb.c +++ b/ctdb/tests/src/protocol_common_ctdb.c @@ -2001,3 +2001,18 @@ void verify_ctdb_req_keepalive(struct ctdb_req_keepalive *c, assert(c->version == c2->version); assert(c->uptime == c2->uptime); } + +void fill_ctdb_req_tunnel(TALLOC_CTX *mem_ctx, struct ctdb_req_tunnel *c) +{ + c->tunnel_id = rand64(); + c->flags = rand32(); + fill_tdb_data(mem_ctx, &c->data); +} + +void verify_ctdb_req_tunnel(struct ctdb_req_tunnel *c, + struct ctdb_req_tunnel *c2) +{ + assert(c->tunnel_id == c2->tunnel_id); + assert(c->flags == c2->flags); + verify_tdb_data(&c->data, &c2->data); +} diff --git a/ctdb/tests/src/protocol_common_ctdb.h b/ctdb/tests/src/protocol_common_ctdb.h index cf22418b623..06810895a9f 100644 --- a/ctdb/tests/src/protocol_common_ctdb.h +++ b/ctdb/tests/src/protocol_common_ctdb.h @@ -94,4 +94,8 @@ void fill_ctdb_req_keepalive(TALLOC_CTX *mem_ctx, void verify_ctdb_req_keepalive(struct ctdb_req_keepalive *c, struct ctdb_req_keepalive *c2); +void fill_ctdb_req_tunnel(TALLOC_CTX *mem_ctx, struct ctdb_req_tunnel *c); +void verify_ctdb_req_tunnel(struct ctdb_req_tunnel *c, + struct ctdb_req_tunnel *c2); + #endif /* __CTDB_PROTOCOL_COMMON_CTDB_H__ */ diff --git a/ctdb/tests/src/protocol_ctdb_compat_test.c b/ctdb/tests/src/protocol_ctdb_compat_test.c index 8357283d372..f0235ddc9fa 100644 --- a/ctdb/tests/src/protocol_ctdb_compat_test.c +++ b/ctdb/tests/src/protocol_ctdb_compat_test.c @@ -29,6 +29,7 @@ #include "protocol/protocol_control.c" #include "protocol/protocol_message.c" #include "protocol/protocol_keepalive.c" +#include "protocol/protocol_tunnel.c" #include "tests/src/protocol_common.h" #include "tests/src/protocol_common_ctdb.h" @@ -1107,6 +1108,90 @@ static int ctdb_req_keepalive_pull_old(uint8_t *buf, size_t buflen, return 0; } +struct ctdb_req_tunnel_wire { + struct ctdb_req_header hdr; + uint64_t tunnel_id; + uint32_t flags; + uint32_t datalen; + uint8_t data[1]; +}; + +static size_t ctdb_req_tunnel_len_old(struct ctdb_req_header *h, + struct ctdb_req_tunnel *c) +{ + return offsetof(struct ctdb_req_tunnel_wire, data) + + ctdb_tdb_data_len(&c->data); +} + +static int ctdb_req_tunnel_push_old(struct ctdb_req_header *h, + struct ctdb_req_tunnel *c, + uint8_t *buf, size_t *buflen) +{ + struct ctdb_req_tunnel_wire *wire = + (struct ctdb_req_tunnel_wire *)buf; + size_t length, np; + + length = ctdb_req_tunnel_len_old(h, c); + if (*buflen < length) { + *buflen = length; + return EMSGSIZE; + } + + h->length = *buflen; + ctdb_req_header_push_old(h, (uint8_t *)&wire->hdr); + + wire->tunnel_id = c->tunnel_id; + wire->flags = c->flags; + wire->datalen = ctdb_tdb_data_len(&c->data); + ctdb_tdb_data_push(&c->data, wire->data, &np); + + return 0; +} + +static int ctdb_req_tunnel_pull_old(uint8_t *buf, size_t buflen, + struct ctdb_req_header *h, + TALLOC_CTX *mem_ctx, + struct ctdb_req_tunnel *c) +{ + struct ctdb_req_tunnel_wire *wire = + (struct ctdb_req_tunnel_wire *)buf; + size_t length, np; + int ret; + + length = offsetof(struct ctdb_req_tunnel_wire, data); + if (buflen < length) { + return EMSGSIZE; + } + if (wire->datalen > buflen) { + return EMSGSIZE; + } + if (length + wire->datalen < length) { + return EMSGSIZE; + } + if (buflen < length + wire->datalen) { + return EMSGSIZE; + } + + if (h != NULL) { + ret = ctdb_req_header_pull_old((uint8_t *)&wire->hdr, buflen, + h); + if (ret != 0) { + return ret; + } + } + + c->tunnel_id = wire->tunnel_id; + c->flags = wire->flags; + + ret = ctdb_tdb_data_pull(wire->data, wire->datalen, mem_ctx, &c->data, + &np); + if (ret != 0) { + return ret; + } + + return 0; +} + COMPAT_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header); @@ -1123,6 +1208,7 @@ COMPAT_CTDB7_TEST(struct ctdb_req_message, ctdb_req_message, CTDB_REQ_MESSAGE); COMPAT_CTDB4_TEST(struct ctdb_req_message_data, ctdb_req_message_data, CTDB_REQ_MESSAGE); COMPAT_CTDB4_TEST(struct ctdb_req_keepalive, ctdb_req_keepalive, CTDB_REQ_KEEPALIVE); +COMPAT_CTDB4_TEST(struct ctdb_req_tunnel, ctdb_req_tunnel, CTDB_REQ_TUNNEL); #define NUM_CONTROLS 151 @@ -1178,6 +1264,7 @@ int main(int argc, char *argv[]) COMPAT_TEST_FUNC(ctdb_req_message_data)(); COMPAT_TEST_FUNC(ctdb_req_keepalive)(); + COMPAT_TEST_FUNC(ctdb_req_tunnel)(); return 0; } diff --git a/ctdb/tests/src/protocol_ctdb_test.c b/ctdb/tests/src/protocol_ctdb_test.c index 64f67f1e5da..cb268679c41 100644 --- a/ctdb/tests/src/protocol_ctdb_test.c +++ b/ctdb/tests/src/protocol_ctdb_test.c @@ -26,6 +26,7 @@ #include "protocol/protocol_control.c" #include "protocol/protocol_message.c" #include "protocol/protocol_keepalive.c" +#include "protocol/protocol_tunnel.c" #include "protocol/protocol_packet.c" #include "tests/src/protocol_common.h" @@ -301,6 +302,7 @@ PROTOCOL_CTDB4_TEST(struct ctdb_req_message_data, ctdb_req_message_data, PROTOCOL_CTDB4_TEST(struct ctdb_req_keepalive, ctdb_req_keepalive, CTDB_REQ_KEEPALIVE); +PROTOCOL_CTDB4_TEST(struct ctdb_req_tunnel, ctdb_req_tunnel, CTDB_REQ_TUNNEL); int main(int argc, char *argv[]) { @@ -364,6 +366,7 @@ int main(int argc, char *argv[]) TEST_FUNC(ctdb_req_message_data)(); TEST_FUNC(ctdb_req_keepalive)(); + TEST_FUNC(ctdb_req_tunnel)(); return 0; } diff --git a/ctdb/wscript b/ctdb/wscript index 1da1b2dade8..196cd2048c7 100644 --- a/ctdb/wscript +++ b/ctdb/wscript @@ -399,6 +399,7 @@ def build(bld): protocol_message.c protocol_control.c protocol_keepalive.c + protocol_tunnel.c protocol_client.c protocol_debug.c protocol_event.c |