ctdb-protocol: Fix marshalling for ctdb_addr_info
authorAmitay Isaacs <amitay@gmail.com>
Tue, 4 Jul 2017 08:12:04 +0000 (18:12 +1000)
committerMartin Schwenke <martins@samba.org>
Wed, 30 Aug 2017 12:59:23 +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 621290ce1a143a1369e9e3ab5bd61152bb5e0d5e..360665caf11ceca1bad40d6e04c7c214ebeb9107 100644 (file)
@@ -551,7 +551,7 @@ static void ctdb_req_control_data_push(struct ctdb_req_control_data *cd,
                break;
 
        case CTDB_CONTROL_SEND_GRATUITOUS_ARP:
-               ctdb_addr_info_push(cd->data.addr_info, buf);
+               ctdb_addr_info_push(cd->data.addr_info, buf, &np);
                break;
 
        case CTDB_CONTROL_WIPE_DATABASE:
@@ -563,11 +563,11 @@ static void ctdb_req_control_data_push(struct ctdb_req_control_data *cd,
                break;
 
        case CTDB_CONTROL_ADD_PUBLIC_IP:
-               ctdb_addr_info_push(cd->data.addr_info, buf);
+               ctdb_addr_info_push(cd->data.addr_info, buf, &np);
                break;
 
        case CTDB_CONTROL_DEL_PUBLIC_IP:
-               ctdb_addr_info_push(cd->data.addr_info, buf);
+               ctdb_addr_info_push(cd->data.addr_info, buf, &np);
                break;
 
        case CTDB_CONTROL_RELEASE_IP:
@@ -853,7 +853,7 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_SEND_GRATUITOUS_ARP:
                ret = ctdb_addr_info_pull(buf, buflen, mem_ctx,
-                                         &cd->data.addr_info);
+                                         &cd->data.addr_info, &np);
                break;
 
        case CTDB_CONTROL_WIPE_DATABASE:
@@ -868,12 +868,12 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_ADD_PUBLIC_IP:
                ret = ctdb_addr_info_pull(buf, buflen, mem_ctx,
-                                         &cd->data.addr_info);
+                                         &cd->data.addr_info, &np);
                break;
 
        case CTDB_CONTROL_DEL_PUBLIC_IP:
                ret = ctdb_addr_info_pull(buf, buflen, mem_ctx,
-                                         &cd->data.addr_info);
+                                         &cd->data.addr_info, &np);
                break;
 
        case CTDB_CONTROL_RELEASE_IP:
index 037819ac9e3465858ed03d59554838fefb7e5065..8b3c9bcbbeba40696d5fc84957426306e33251f0 100644 (file)
@@ -215,10 +215,11 @@ void ctdb_tickle_list_push(struct ctdb_tickle_list *in, uint8_t *buf,
 int ctdb_tickle_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
                          struct ctdb_tickle_list **out, size_t *npull);
 
-size_t ctdb_addr_info_len(struct ctdb_addr_info *addr_info);
-void ctdb_addr_info_push(struct ctdb_addr_info *addr_info, uint8_t *buf);
+size_t ctdb_addr_info_len(struct ctdb_addr_info *in);
+void ctdb_addr_info_push(struct ctdb_addr_info *in, uint8_t *buf,
+                        size_t *npush);
 int ctdb_addr_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                       struct ctdb_addr_info **out);
+                       struct ctdb_addr_info **out, size_t *npull);
 
 size_t ctdb_transdb_len(struct ctdb_transdb *transdb);
 void ctdb_transdb_push(struct ctdb_transdb *transdb, uint8_t *buf);
index ec9d7d5eb81eb9e46d25d461d3a79e3b736e9972..90091ff1b4ce39fc2b91798ceb73f20299c8e65d 100644 (file)
@@ -3194,80 +3194,69 @@ fail:
        return ret;
 }
 
-struct ctdb_addr_info_wire {
-       ctdb_sock_addr addr;
-       uint32_t mask;
-       uint32_t len;
-       char iface[1];
-};
+size_t ctdb_addr_info_len(struct ctdb_addr_info *in)
+{
+       return ctdb_sock_addr_len(&in->addr) +
+               ctdb_uint32_len(&in->mask) +
+               ctdb_stringn_len(&in->iface);
+}
 
-size_t ctdb_addr_info_len(struct ctdb_addr_info *arp)
+void ctdb_addr_info_push(struct ctdb_addr_info *in, uint8_t *buf,
+                        size_t *npush)
 {
-       uint32_t len;
+       size_t offset = 0, np;
 
-       len = offsetof(struct ctdb_addr_info_wire, iface);
-       if (arp->iface != NULL) {
-              len += strlen(arp->iface)+1;
-       }
+       ctdb_sock_addr_push(&in->addr, buf+offset, &np);
+       offset += np;
 
-       return len;
-}
+       ctdb_uint32_push(&in->mask, buf+offset, &np);
+       offset += np;
 
-void ctdb_addr_info_push(struct ctdb_addr_info *addr_info, uint8_t *buf)
-{
-       struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
+       ctdb_stringn_push(&in->iface, buf+offset, &np);
+       offset += np;
 
-       wire->addr = addr_info->addr;
-       wire->mask = addr_info->mask;
-       if (addr_info->iface == NULL) {
-               wire->len = 0;
-       } else {
-               wire->len = strlen(addr_info->iface)+1;
-               memcpy(wire->iface, addr_info->iface, wire->len);
-       }
+       *npush = offset;
 }
 
 int ctdb_addr_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                       struct ctdb_addr_info **out)
+                       struct ctdb_addr_info **out, size_t *npull)
 {
-       struct ctdb_addr_info *addr_info;
-       struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
+       struct ctdb_addr_info *val;
+       size_t offset = 0, np;
+       int ret;
 
-       if (buflen < offsetof(struct ctdb_addr_info_wire, iface)) {
-               return EMSGSIZE;
-       }
-       if (wire->len > buflen) {
-               return EMSGSIZE;
-       }
-       if (offsetof(struct ctdb_addr_info_wire, iface) + wire->len <
-           offsetof(struct ctdb_addr_info_wire, iface)) {
-               return EMSGSIZE;
-       }
-       if (buflen < offsetof(struct ctdb_addr_info_wire, iface) + wire->len) {
-               return EMSGSIZE;
+       val = talloc(mem_ctx, struct ctdb_addr_info);
+       if (val == NULL) {
+               return ENOMEM;
        }
 
-       addr_info = talloc(mem_ctx, struct ctdb_addr_info);
-       if (addr_info == NULL) {
-               return ENOMEM;
+       ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, val,
+                                       &val->addr, &np);
+       if (ret != 0) {
+               goto fail;
        }
+       offset += np;
 
-       addr_info->addr = wire->addr;
-       addr_info->mask = wire->mask;
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->mask, &np);
+       if (ret != 0) {
+               goto fail;
+       }
+       offset += np;
 
-       if (wire->len == 0) {
-               addr_info->iface = NULL;
-       } else {
-               addr_info->iface = talloc_strndup(addr_info, wire->iface,
-                                                 wire->len);
-               if (addr_info->iface == NULL) {
-                       talloc_free(addr_info);
-                       return ENOMEM;
-               }
+       ret = ctdb_stringn_pull(buf+offset, buflen-offset, val, &val->iface,
+                               &np);
+       if (ret != 0) {
+               goto fail;
        }
+       offset += np;
 
-       *out = addr_info;
+       *out = val;
+       *npull = offset;
        return 0;
+
+fail:
+       talloc_free(val);
+       return ret;
 }
 
 size_t ctdb_transdb_len(struct ctdb_transdb *transdb)
index cb651e37fb3d1ae979ed5bdd2531b8433abb9de4..040d1a57e57097e24a5d1da1404e7e583e97cfd1 100644 (file)
@@ -1033,6 +1033,82 @@ static int ctdb_tickle_list_pull_old(uint8_t *buf, size_t buflen,
        return 0;
 }
 
+struct ctdb_addr_info_wire {
+       ctdb_sock_addr addr;
+       uint32_t mask;
+       uint32_t len;
+       char iface[1];
+};
+
+static size_t ctdb_addr_info_len_old(struct ctdb_addr_info *in)
+{
+       uint32_t len;
+
+       len = offsetof(struct ctdb_addr_info_wire, iface);
+       if (in->iface != NULL) {
+              len += strlen(in->iface)+1;
+       }
+
+       return len;
+}
+
+static void ctdb_addr_info_push_old(struct ctdb_addr_info *in, uint8_t *buf)
+{
+       struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
+
+       wire->addr = in->addr;
+       wire->mask = in->mask;
+       if (in->iface == NULL) {
+               wire->len = 0;
+       } else {
+               wire->len = strlen(in->iface)+1;
+               memcpy(wire->iface, in->iface, wire->len);
+       }
+}
+
+static int ctdb_addr_info_pull_old(uint8_t *buf, size_t buflen,
+                                  TALLOC_CTX *mem_ctx,
+                                  struct ctdb_addr_info **out)
+{
+       struct ctdb_addr_info *val;
+       struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
+
+       if (buflen < offsetof(struct ctdb_addr_info_wire, iface)) {
+               return EMSGSIZE;
+       }
+       if (wire->len > buflen) {
+               return EMSGSIZE;
+       }
+       if (offsetof(struct ctdb_addr_info_wire, iface) + wire->len <
+           offsetof(struct ctdb_addr_info_wire, iface)) {
+               return EMSGSIZE;
+       }
+       if (buflen < offsetof(struct ctdb_addr_info_wire, iface) + wire->len) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_addr_info);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->addr = wire->addr;
+       val->mask = wire->mask;
+
+       if (wire->len == 0) {
+               val->iface = NULL;
+       } else {
+               val->iface = talloc_strndup(val, wire->iface, wire->len);
+               if (val->iface == NULL) {
+                       talloc_free(val);
+                       return ENOMEM;
+               }
+       }
+
+       *out = val;
+       return 0;
+}
+
 
 COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
 COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
@@ -1055,6 +1131,7 @@ COMPAT_TYPE3_TEST(struct ctdb_node_flag_change, ctdb_node_flag_change);
 COMPAT_TYPE3_TEST(struct ctdb_var_list, ctdb_var_list);
 COMPAT_TYPE3_TEST(struct ctdb_tunable_list, ctdb_tunable_list);
 COMPAT_TYPE3_TEST(struct ctdb_tickle_list, ctdb_tickle_list);
+COMPAT_TYPE3_TEST(struct ctdb_addr_info, ctdb_addr_info);
 
 int main(int argc, char *argv[])
 {
@@ -1082,6 +1159,7 @@ int main(int argc, char *argv[])
        COMPAT_TEST_FUNC(ctdb_var_list)();
        COMPAT_TEST_FUNC(ctdb_tunable_list)();
        COMPAT_TEST_FUNC(ctdb_tickle_list)();
+       COMPAT_TEST_FUNC(ctdb_addr_info)();
 
        return 0;
 }
index e0468408a61892cbe2a2fa5eda00e55c614596ac..3db2722fde46c568818aa97a2fdb21b627810440 100644 (file)
@@ -67,7 +67,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_node_flag_change, ctdb_node_flag_change);
 PROTOCOL_TYPE3_TEST(struct ctdb_var_list, ctdb_var_list);
 PROTOCOL_TYPE3_TEST(struct ctdb_tunable_list, ctdb_tunable_list);
 PROTOCOL_TYPE3_TEST(struct ctdb_tickle_list, ctdb_tickle_list);
-DEFINE_TEST(struct ctdb_addr_info, ctdb_addr_info);
+PROTOCOL_TYPE3_TEST(struct ctdb_addr_info, ctdb_addr_info);
 DEFINE_TEST(struct ctdb_transdb, ctdb_transdb);
 DEFINE_TEST(struct ctdb_uptime, ctdb_uptime);
 DEFINE_TEST(struct ctdb_public_ip, ctdb_public_ip);