ctdb-protocol: Fix marshalling for ctdb_public_ip_list
authorAmitay Isaacs <amitay@gmail.com>
Thu, 6 Jul 2017 04:12:57 +0000 (14:12 +1000)
committerMartin Schwenke <martins@samba.org>
Wed, 30 Aug 2017 12:59:24 +0000 (14:59 +0200)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/protocol/protocol_control.c
ctdb/protocol/protocol_private.h
ctdb/protocol/protocol_types.c
ctdb/tests/src/protocol_types_compat_test.c
ctdb/tests/src/protocol_types_test.c

index 925cea1052fafdf2be2c13481efa3064f813e75f..3970b4726975cf1dee9a775377b5dc6c7c75aaa8 100644 (file)
@@ -1500,7 +1500,7 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd,
                break;
 
        case CTDB_CONTROL_GET_PUBLIC_IPS:
-               ctdb_public_ip_list_push(cd->data.pubip_list, buf);
+               ctdb_public_ip_list_push(cd->data.pubip_list, buf, &np);
                break;
 
        case CTDB_CONTROL_GET_NODEMAP:
@@ -1677,7 +1677,7 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_GET_PUBLIC_IPS:
                ret = ctdb_public_ip_list_pull(buf, buflen, mem_ctx,
-                                              &cd->data.pubip_list);
+                                              &cd->data.pubip_list, &np);
                break;
 
        case CTDB_CONTROL_GET_NODEMAP:
index 27cdeb3792478edc336cebb7216ab2dfa054bbfc..8b5a70a5d7f9207879d94a58cf03f74d7ff0c145 100644 (file)
@@ -237,11 +237,11 @@ void ctdb_public_ip_push(struct ctdb_public_ip *in, uint8_t *buf,
 int ctdb_public_ip_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
                        struct ctdb_public_ip **out, size_t *npull);
 
-size_t ctdb_public_ip_list_len(struct ctdb_public_ip_list *pubip_list);
-void ctdb_public_ip_list_push(struct ctdb_public_ip_list *pubip_list,
-                             uint8_t *buf);
+size_t ctdb_public_ip_list_len(struct ctdb_public_ip_list *in);
+void ctdb_public_ip_list_push(struct ctdb_public_ip_list *in, uint8_t *buf,
+                             size_t *npush);
 int ctdb_public_ip_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                            struct ctdb_public_ip_list **out);
+                            struct ctdb_public_ip_list **out, size_t *npull);
 
 size_t ctdb_node_and_flags_len(struct ctdb_node_and_flags *node);
 void ctdb_node_and_flags_push(struct ctdb_node_and_flags *node, uint8_t *buf);
index a28244aad44de935e7875c2b1e3e042a712bf33b..ae28ce5705f998389c042fb65e0d987cc0ddf8cd 100644 (file)
@@ -3454,97 +3454,82 @@ int ctdb_public_ip_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
        return ret;
 }
 
-struct ctdb_public_ip_list_wire {
-       uint32_t num;
-       struct ctdb_public_ip ip[1];
-};
-
-size_t ctdb_public_ip_list_len(struct ctdb_public_ip_list *pubip_list)
+size_t ctdb_public_ip_list_len(struct ctdb_public_ip_list *in)
 {
-       int i;
        size_t len;
 
-       len = sizeof(uint32_t);
-       for (i=0; i<pubip_list->num; i++) {
-               len += ctdb_public_ip_len(&pubip_list->ip[i]);
+       len = ctdb_uint32_len(&in->num);
+       if (in->num > 0) {
+               len += in->num * ctdb_public_ip_len(&in->ip[0]);
        }
+
        return len;
 }
 
-void ctdb_public_ip_list_push(struct ctdb_public_ip_list *pubip_list,
-                             uint8_t *buf)
+void ctdb_public_ip_list_push(struct ctdb_public_ip_list *in, uint8_t *buf,
+                             size_t *npush)
 {
-       struct ctdb_public_ip_list_wire *wire =
-               (struct ctdb_public_ip_list_wire *)buf;
-       size_t offset, np;
-       int i;
+       size_t offset = 0, np;
+       uint32_t i;
 
-       wire->num = pubip_list->num;
+       ctdb_uint32_push(&in->num, buf+offset, &np);
+       offset += np;
 
-       offset = offsetof(struct ctdb_public_ip_list_wire, ip);
-       for (i=0; i<pubip_list->num; i++) {
-               ctdb_public_ip_push(&pubip_list->ip[i], &buf[offset], &np);
+       for (i=0; i<in->num; i++) {
+               ctdb_public_ip_push(&in->ip[i], buf+offset, &np);
                offset += np;
        }
+
+       *npush = offset;
 }
 
 int ctdb_public_ip_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                            struct ctdb_public_ip_list **out)
+                            struct ctdb_public_ip_list **out, size_t *npull)
 {
-       struct ctdb_public_ip_list *pubip_list;
-       struct ctdb_public_ip_list_wire *wire =
-               (struct ctdb_public_ip_list_wire *)buf;
-       size_t offset, np;
-       int i;
-       bool ret;
+       struct ctdb_public_ip_list *val;
+       size_t offset = 0, np;
+       uint32_t i;
+       int ret;
 
-       if (buflen < sizeof(uint32_t)) {
-               return EMSGSIZE;
-       }
-       if (wire->num > buflen / sizeof(struct ctdb_public_ip)) {
-               return EMSGSIZE;
-       }
-       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_public_ip) <
-           sizeof(uint32_t)) {
-               return EMSGSIZE;
-       }
-       if (buflen < sizeof(uint32_t) +
-                    wire->num * sizeof(struct ctdb_public_ip)) {
-               return EMSGSIZE;
+       val = talloc(mem_ctx, struct ctdb_public_ip_list);
+       if (val == NULL) {
+               return ENOMEM;
        }
 
-       pubip_list = talloc(mem_ctx, struct ctdb_public_ip_list);
-       if (pubip_list == NULL) {
-               return ENOMEM;
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
+       if (ret != 0) {
+               goto fail;
        }
+       offset += np;
 
-       pubip_list->num = wire->num;
-       if (wire->num == 0) {
-               pubip_list->ip = NULL;
-               *out = pubip_list;
-               return 0;
+       if (val->num == 0) {
+               val->ip = NULL;
+               goto done;
        }
-       pubip_list->ip = talloc_array(pubip_list, struct ctdb_public_ip,
-                                     wire->num);
-       if (pubip_list->ip == NULL) {
-               talloc_free(pubip_list);
-               return ENOMEM;
+
+       val->ip = talloc_array(val, struct ctdb_public_ip, val->num);
+       if (val->ip == NULL) {
+               ret = ENOMEM;
+               goto fail;
        }
 
-       offset = offsetof(struct ctdb_public_ip_list_wire, ip);
-       for (i=0; i<wire->num; i++) {
-               ret = ctdb_public_ip_pull_elems(&buf[offset], buflen-offset,
-                                               pubip_list->ip,
-                                               &pubip_list->ip[i], &np);
+       for (i=0; i<val->num; i++) {
+               ret = ctdb_public_ip_pull_elems(buf+offset, buflen-offset,
+                                               val->ip, &val->ip[i], &np);
                if (ret != 0) {
-                       talloc_free(pubip_list);
-                       return ret;
+                       goto fail;
                }
                offset += np;
        }
 
-       *out = pubip_list;
+done:
+       *out = val;
+       *npull = offset;
        return 0;
+
+fail:
+       talloc_free(val);
+       return ret;
 }
 
 size_t ctdb_node_and_flags_len(struct ctdb_node_and_flags *node)
index a69d8d891f67ac240b357553bfae064bd9eecdc8..9be5b425cec9b4eb5d5c42424038c1e1615794d1 100644 (file)
@@ -1211,6 +1211,100 @@ static int ctdb_public_ip_pull_old(uint8_t *buf, size_t buflen,
        return ret;
 }
 
+struct ctdb_public_ip_list_wire {
+       uint32_t num;
+       struct ctdb_public_ip ip[1];
+};
+
+static size_t ctdb_public_ip_list_len_old(struct ctdb_public_ip_list *in)
+{
+       int i;
+       size_t len;
+
+       len = sizeof(uint32_t);
+       for (i=0; i<in->num; i++) {
+               len += ctdb_public_ip_len_old(&in->ip[i]);
+       }
+       return len;
+}
+
+static void ctdb_public_ip_list_push_old(struct ctdb_public_ip_list *in,
+                                        uint8_t *buf)
+{
+       struct ctdb_public_ip_list_wire *wire =
+               (struct ctdb_public_ip_list_wire *)buf;
+       size_t offset;
+       int i;
+
+       wire->num = in->num;
+
+       offset = offsetof(struct ctdb_public_ip_list_wire, ip);
+       for (i=0; i<in->num; i++) {
+               ctdb_public_ip_push_old(&in->ip[i], &buf[offset]);
+               offset += ctdb_public_ip_len_old(&in->ip[i]);
+       }
+}
+
+static int ctdb_public_ip_list_pull_old(uint8_t *buf, size_t buflen,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct ctdb_public_ip_list **out)
+{
+       struct ctdb_public_ip_list *val;
+       struct ctdb_public_ip_list_wire *wire =
+               (struct ctdb_public_ip_list_wire *)buf;
+       size_t offset;
+       int i;
+       bool ret;
+
+       if (buflen < sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (wire->num > buflen / sizeof(struct ctdb_public_ip)) {
+               return EMSGSIZE;
+       }
+       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_public_ip) <
+           sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (buflen < sizeof(uint32_t) +
+                    wire->num * sizeof(struct ctdb_public_ip)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_public_ip_list);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->num = wire->num;
+       if (wire->num == 0) {
+               val->ip = NULL;
+               *out = val;
+               return 0;
+       }
+       val->ip = talloc_array(val, struct ctdb_public_ip, wire->num);
+       if (val->ip == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       offset = offsetof(struct ctdb_public_ip_list_wire, ip);
+       for (i=0; i<wire->num; i++) {
+               ret = ctdb_public_ip_pull_elems_old(&buf[offset],
+                                                   buflen-offset,
+                                                   val->ip,
+                                                   &val->ip[i]);
+               if (ret != 0) {
+                       talloc_free(val);
+                       return ret;
+               }
+               offset += ctdb_public_ip_len_old(&val->ip[i]);
+       }
+
+       *out = val;
+       return 0;
+}
+
 
 COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
 COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
@@ -1237,6 +1331,7 @@ COMPAT_TYPE3_TEST(struct ctdb_addr_info, ctdb_addr_info);
 COMPAT_TYPE3_TEST(struct ctdb_transdb, ctdb_transdb);
 COMPAT_TYPE3_TEST(struct ctdb_uptime, ctdb_uptime);
 COMPAT_TYPE3_TEST(struct ctdb_public_ip, ctdb_public_ip);
+COMPAT_TYPE3_TEST(struct ctdb_public_ip_list, ctdb_public_ip_list);
 
 int main(int argc, char *argv[])
 {
@@ -1268,6 +1363,7 @@ int main(int argc, char *argv[])
        COMPAT_TEST_FUNC(ctdb_transdb)();
        COMPAT_TEST_FUNC(ctdb_uptime)();
        COMPAT_TEST_FUNC(ctdb_public_ip)();
+       COMPAT_TEST_FUNC(ctdb_public_ip_list)();
 
        return 0;
 }
index 2360304ccd40ad1ce4d5b80301ade0326e836447..f51e5f545d933e87c63adf118314175bd6d77122 100644 (file)
@@ -71,7 +71,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_addr_info, ctdb_addr_info);
 PROTOCOL_TYPE3_TEST(struct ctdb_transdb, ctdb_transdb);
 PROTOCOL_TYPE3_TEST(struct ctdb_uptime, ctdb_uptime);
 PROTOCOL_TYPE3_TEST(struct ctdb_public_ip, ctdb_public_ip);
-DEFINE_TEST(struct ctdb_public_ip_list, ctdb_public_ip_list);
+PROTOCOL_TYPE3_TEST(struct ctdb_public_ip_list, ctdb_public_ip_list);
 DEFINE_TEST(struct ctdb_node_and_flags, ctdb_node_and_flags);
 DEFINE_TEST(struct ctdb_node_map, ctdb_node_map);
 DEFINE_TEST(struct ctdb_script, ctdb_script);