ctdb-protocol: Fix marshalling for ctdb_iface_list
authorAmitay Isaacs <amitay@gmail.com>
Wed, 12 Jul 2017 08:45:42 +0000 (18:45 +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 90d8d7036a276ba8393c84781bf4efd559b0ec01..bb052a2b84cbaaf1d143713ea3a8c36f5b2eb3cc 100644 (file)
@@ -1531,7 +1531,7 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd,
                break;
 
        case CTDB_CONTROL_GET_IFACES:
-               ctdb_iface_list_push(cd->data.iface_list, buf);
+               ctdb_iface_list_push(cd->data.iface_list, buf, &np);
                break;
 
        case CTDB_CONTROL_GET_STAT_HISTORY:
@@ -1714,7 +1714,7 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_GET_IFACES:
                ret = ctdb_iface_list_pull(buf, buflen, mem_ctx,
-                                          &cd->data.iface_list);
+                                          &cd->data.iface_list, &np);
                break;
 
        case CTDB_CONTROL_GET_STAT_HISTORY:
index 1f50270fd77a0478168695272271f522d62ae517..721b3d491fc80f30c102b3b6722d8a1ceaa81fa6 100644 (file)
@@ -282,10 +282,11 @@ void ctdb_iface_push(struct ctdb_iface *in, uint8_t *buf, size_t *npush);
 int ctdb_iface_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
                    struct ctdb_iface **out, size_t *npull);
 
-size_t ctdb_iface_list_len(struct ctdb_iface_list *iface_list);
-void ctdb_iface_list_push(struct ctdb_iface_list *iface_list, uint8_t *buf);
+size_t ctdb_iface_list_len(struct ctdb_iface_list *in);
+void ctdb_iface_list_push(struct ctdb_iface_list *in, uint8_t *buf,
+                         size_t *npush);
 int ctdb_iface_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                        struct ctdb_iface_list **out);
+                        struct ctdb_iface_list **out, size_t *npull);
 
 size_t ctdb_public_ip_info_len(struct ctdb_public_ip_info *ipinfo);
 void ctdb_public_ip_info_push(struct ctdb_public_ip_info *ipinfo, uint8_t *buf);
index 200d424c15e92142a0e1bcf6aee7ab707a59eecb..d4c6b0070b97a9d37b071cdcd17595847c346106 100644 (file)
@@ -4085,66 +4085,82 @@ int ctdb_iface_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
        return ret;
 }
 
-struct ctdb_iface_list_wire {
-       uint32_t num;
-       struct ctdb_iface iface[1];
-};
-
-size_t ctdb_iface_list_len(struct ctdb_iface_list *iface_list)
+size_t ctdb_iface_list_len(struct ctdb_iface_list *in)
 {
-       return sizeof(uint32_t) +
-              iface_list->num * sizeof(struct ctdb_iface);
+       size_t len;
+
+       len = ctdb_uint32_len(&in->num);
+       if (in->num > 0) {
+               len += in->num * ctdb_iface_len(&in->iface[0]);
+       }
+
+       return len;
 }
 
-void ctdb_iface_list_push(struct ctdb_iface_list *iface_list, uint8_t *buf)
+void ctdb_iface_list_push(struct ctdb_iface_list *in, uint8_t *buf,
+                         size_t *npush)
 {
-       struct ctdb_iface_list_wire *wire =
-               (struct ctdb_iface_list_wire *)buf;
+       size_t offset = 0, np;
+       uint32_t i;
+
+       ctdb_uint32_push(&in->num, buf+offset, &np);
+       offset += np;
+
+       for (i=0; i<in->num; i++) {
+               ctdb_iface_push(&in->iface[i], buf+offset, &np);
+               offset += np;
+       }
 
-       wire->num = iface_list->num;
-       memcpy(wire->iface, iface_list->iface,
-              iface_list->num * sizeof(struct ctdb_iface));
+       *npush = offset;
 }
 
 int ctdb_iface_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                        struct ctdb_iface_list **out)
+                        struct ctdb_iface_list **out, size_t *npull)
 {
-       struct ctdb_iface_list *iface_list;
-       struct ctdb_iface_list_wire *wire =
-               (struct ctdb_iface_list_wire *)buf;
+       struct ctdb_iface_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_iface)) {
-               return EMSGSIZE;
-       }
-       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface) <
-           sizeof(uint32_t)) {
-               return EMSGSIZE;
+       val = talloc(mem_ctx, struct ctdb_iface_list);
+       if (val == NULL) {
+               return ENOMEM;
        }
-       if (buflen < sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface)) {
-               return EMSGSIZE;
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
+       if (ret != 0) {
+               goto fail;
        }
+       offset += np;
 
-       iface_list = talloc(mem_ctx, struct ctdb_iface_list);
-       if (iface_list == NULL) {
-               return ENOMEM;
+       if (val->num == 0) {
+               val->iface = NULL;
+               goto done;
        }
 
-       iface_list->num = wire->num;
-       iface_list->iface = talloc_array(iface_list, struct ctdb_iface,
-                                        wire->num);
-       if (iface_list->iface == NULL) {
-               talloc_free(iface_list);
-               return ENOMEM;
+       val->iface = talloc_array(val, struct ctdb_iface, val->num);
+       if (val->iface == NULL) {
+               ret = ENOMEM;
+               goto fail;
        }
 
-       memcpy(iface_list->iface, wire->iface,
-              wire->num * sizeof(struct ctdb_iface));
+       for (i=0; i<val->num; i++) {
+               ret = ctdb_iface_pull_elems(buf+offset, buflen-offset,
+                                           val, &val->iface[i], &np);
+               if (ret != 0) {
+                       goto fail;
+               }
+               offset += np;
+       }
 
-       *out = iface_list;
+done:
+       *out = val;
+       *npull = offset;
        return 0;
+
+fail:
+       talloc_free(val);
+       return ret;
 }
 
 struct ctdb_public_ip_info_wire {
index 6ee576aaef140cd685473f08545d6e6613d207f1..eac33d5e465068493ef35e362a87e73ab9a9cea0 100644 (file)
@@ -1712,6 +1712,66 @@ static int ctdb_iface_pull_old(uint8_t *buf, size_t buflen,
        return ret;
 }
 
+struct ctdb_iface_list_wire {
+       uint32_t num;
+       struct ctdb_iface iface[1];
+};
+
+static size_t ctdb_iface_list_len_old(struct ctdb_iface_list *in)
+{
+       return sizeof(uint32_t) +
+              in->num * sizeof(struct ctdb_iface);
+}
+
+static void ctdb_iface_list_push_old(struct ctdb_iface_list *in, uint8_t *buf)
+{
+       struct ctdb_iface_list_wire *wire =
+               (struct ctdb_iface_list_wire *)buf;
+
+       wire->num = in->num;
+       memcpy(wire->iface, in->iface, in->num * sizeof(struct ctdb_iface));
+}
+
+static int ctdb_iface_list_pull_old(uint8_t *buf, size_t buflen,
+                                   TALLOC_CTX *mem_ctx,
+                                   struct ctdb_iface_list **out)
+{
+       struct ctdb_iface_list *val;
+       struct ctdb_iface_list_wire *wire =
+               (struct ctdb_iface_list_wire *)buf;
+
+       if (buflen < sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (wire->num > buflen / sizeof(struct ctdb_iface)) {
+               return EMSGSIZE;
+       }
+       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface) <
+           sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (buflen < sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_iface_list);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->num = wire->num;
+       val->iface = talloc_array(val, struct ctdb_iface, wire->num);
+       if (val->iface == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       memcpy(val->iface, wire->iface, wire->num * sizeof(struct ctdb_iface));
+
+       *out = val;
+       return 0;
+}
+
 
 COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
 COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
@@ -1746,6 +1806,7 @@ COMPAT_TYPE3_TEST(struct ctdb_script_list, ctdb_script_list);
 COMPAT_TYPE3_TEST(struct ctdb_ban_state, ctdb_ban_state);
 COMPAT_TYPE3_TEST(struct ctdb_notify_data, ctdb_notify_data);
 COMPAT_TYPE3_TEST(struct ctdb_iface, ctdb_iface);
+COMPAT_TYPE3_TEST(struct ctdb_iface_list, ctdb_iface_list);
 
 int main(int argc, char *argv[])
 {
@@ -1785,6 +1846,7 @@ int main(int argc, char *argv[])
        COMPAT_TEST_FUNC(ctdb_ban_state)();
        COMPAT_TEST_FUNC(ctdb_notify_data)();
        COMPAT_TEST_FUNC(ctdb_iface)();
+       COMPAT_TEST_FUNC(ctdb_iface_list)();
 
        return 0;
 }
index 36f3e4a0d2320ae060e20298ff15d150d99c9ae4..c0ccc137887fa5d87672609c3a178e738818e9c0 100644 (file)
@@ -79,7 +79,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_script_list, ctdb_script_list);
 PROTOCOL_TYPE3_TEST(struct ctdb_ban_state, ctdb_ban_state);
 PROTOCOL_TYPE3_TEST(struct ctdb_notify_data, ctdb_notify_data);
 PROTOCOL_TYPE3_TEST(struct ctdb_iface, ctdb_iface);
-DEFINE_TEST(struct ctdb_iface_list, ctdb_iface_list);
+PROTOCOL_TYPE3_TEST(struct ctdb_iface_list, ctdb_iface_list);
 DEFINE_TEST(struct ctdb_public_ip_info, ctdb_public_ip_info);
 DEFINE_TEST(struct ctdb_statistics_list, ctdb_statistics_list);
 DEFINE_TEST(struct ctdb_key_data, ctdb_key_data);