ctdb-protocol: Add protocol marshalling for CTDB_REQ_TUNNEL
authorAmitay Isaacs <amitay@gmail.com>
Wed, 5 Apr 2017 06:25:42 +0000 (16:25 +1000)
committerMartin Schwenke <martins@samba.org>
Tue, 10 Oct 2017 09:45:19 +0000 (11:45 +0200)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/protocol/protocol_api.h
ctdb/protocol/protocol_debug.c
ctdb/protocol/protocol_tunnel.c [new file with mode: 0644]
ctdb/tests/cunit/protocol_test_101.sh
ctdb/tests/src/protocol_common_ctdb.c
ctdb/tests/src/protocol_common_ctdb.h
ctdb/tests/src/protocol_ctdb_compat_test.c
ctdb/tests/src/protocol_ctdb_test.c
ctdb/wscript

index 0e5d57fdece977d9c2e893f53053e8281c5c44d8..8b40d1d8c0e9c959a2078d8a364036c0a56dd624 100644 (file)
@@ -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);
index 1a87ade3419f5b403f5b60bf537ae76172e5c942..3dd5c32ab1148c8e2ba53df98caac2ca9bb6b933 100644 (file)
@@ -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 (file)
index 0000000..d31d9d5
--- /dev/null
@@ -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;
+}
index 8b3645a8b6787f95b27e57c57f5fb3a40ea9d97b..36751d4fbe7c76aa4d505252ef123add82911444 100755 (executable)
@@ -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"
index 928b7d127cdc6b887bac5e6a6ece1954c564e8ff..03888f44e628ba9a07c7bbbc32f0b7ebd838baec 100644 (file)
@@ -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);
+}
index cf22418b623e1369d24df22b9611a87b8cdcf104..06810895a9f1cfae1a21965ecc41b881ba7bcaa6 100644 (file)
@@ -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__ */
index 8357283d3729316067cdd30c26558b7718bb6745..f0235ddc9fa0cc1cddcfd5aed002806964758be3 100644 (file)
@@ -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;
 }
index 64f67f1e5da3a5d2166ea2c068ecc6c616018ee9..cb268679c41124ca5a6f530c2c739c0139d32cf7 100644 (file)
@@ -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;
 }
index 1da1b2dade8f96de33a99bb7d353e139811986f5..196cd2048c7151fa2ebd8080b6a1b68a6c57d99e 100644 (file)
@@ -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