summaryrefslogtreecommitdiff
path: root/ctdb
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2017-07-12 18:29:12 +1000
committerMartin Schwenke <martins@samba.org>2017-08-30 14:59:24 +0200
commit091ef60ed28f6cbfb91402e4e12556f57ff20681 (patch)
treee858b44c76fe7d7d6674e3ed28372b305bc7b645 /ctdb
parent57a4d2e6317ccef6c4d3e7c1a0de81d1ca259ee7 (diff)
downloadsamba-091ef60ed28f6cbfb91402e4e12556f57ff20681.tar.gz
ctdb-protocol: Fix marshalling for ctdb_notify_data
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/protocol/protocol_control.c4
-rw-r--r--ctdb/protocol/protocol_private.h7
-rw-r--r--ctdb/protocol/protocol_types.c76
-rw-r--r--ctdb/tests/src/protocol_types_compat_test.c64
-rw-r--r--ctdb/tests/src/protocol_types_test.c2
5 files changed, 106 insertions, 47 deletions
diff --git a/ctdb/protocol/protocol_control.c b/ctdb/protocol/protocol_control.c
index 39bbeeefbe4..ff770b07259 100644
--- a/ctdb/protocol/protocol_control.c
+++ b/ctdb/protocol/protocol_control.c
@@ -599,7 +599,7 @@ static void ctdb_req_control_data_push(struct ctdb_req_control_data *cd,
break;
case CTDB_CONTROL_REGISTER_NOTIFY:
- ctdb_notify_data_push(cd->data.notify, buf);
+ ctdb_notify_data_push(cd->data.notify, buf, &np);
break;
case CTDB_CONTROL_DEREGISTER_NOTIFY:
@@ -911,7 +911,7 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen,
case CTDB_CONTROL_REGISTER_NOTIFY:
ret = ctdb_notify_data_pull(buf, buflen, mem_ctx,
- &cd->data.notify);
+ &cd->data.notify, &np);
break;
case CTDB_CONTROL_DEREGISTER_NOTIFY:
diff --git a/ctdb/protocol/protocol_private.h b/ctdb/protocol/protocol_private.h
index 219a714bb0b..0067ac13abc 100644
--- a/ctdb/protocol/protocol_private.h
+++ b/ctdb/protocol/protocol_private.h
@@ -271,10 +271,11 @@ void ctdb_ban_state_push(struct ctdb_ban_state *in, uint8_t *buf,
int ctdb_ban_state_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
struct ctdb_ban_state **out, size_t *npull);
-size_t ctdb_notify_data_len(struct ctdb_notify_data *notify);
-void ctdb_notify_data_push(struct ctdb_notify_data *notify, uint8_t *buf);
+size_t ctdb_notify_data_len(struct ctdb_notify_data *in);
+void ctdb_notify_data_push(struct ctdb_notify_data *in, uint8_t *buf,
+ size_t *npush);
int ctdb_notify_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
- struct ctdb_notify_data **out);
+ struct ctdb_notify_data **out, size_t *npull);
size_t ctdb_iface_len(struct ctdb_iface *iface);
void ctdb_iface_push(struct ctdb_iface *iface, uint8_t *buf);
diff --git a/ctdb/protocol/protocol_types.c b/ctdb/protocol/protocol_types.c
index 77a54bd3dbb..7239615be9d 100644
--- a/ctdb/protocol/protocol_types.c
+++ b/ctdb/protocol/protocol_types.c
@@ -3953,64 +3953,58 @@ fail:
return ret;
}
-struct ctdb_notify_data_wire {
- uint64_t srvid;
- uint32_t len;
- uint8_t data[1];
-};
-
-size_t ctdb_notify_data_len(struct ctdb_notify_data *notify)
+size_t ctdb_notify_data_len(struct ctdb_notify_data *in)
{
- return offsetof(struct ctdb_notify_data_wire, data) +
- notify->data.dsize;
+ return ctdb_uint64_len(&in->srvid) +
+ ctdb_tdb_datan_len(&in->data);
}
-void ctdb_notify_data_push(struct ctdb_notify_data *notify, uint8_t *buf)
+void ctdb_notify_data_push(struct ctdb_notify_data *in, uint8_t *buf,
+ size_t *npush)
{
- struct ctdb_notify_data_wire *wire =
- (struct ctdb_notify_data_wire *)buf;
+ size_t offset = 0, np;
+
+ ctdb_uint64_push(&in->srvid, buf+offset, &np);
+ offset += np;
+
+ ctdb_tdb_datan_push(&in->data, buf+offset, &np);
+ offset += np;
- wire->srvid = notify->srvid;
- wire->len = notify->data.dsize;
- memcpy(wire->data, notify->data.dptr, notify->data.dsize);
+ *npush = offset;
}
int ctdb_notify_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
- struct ctdb_notify_data **out)
+ struct ctdb_notify_data **out, size_t *npull)
{
- struct ctdb_notify_data *notify;
- struct ctdb_notify_data_wire *wire =
- (struct ctdb_notify_data_wire *)buf;
+ struct ctdb_notify_data *val;
+ size_t offset = 0, np;
+ int ret;
- if (buflen < offsetof(struct ctdb_notify_data_wire, data)) {
- return EMSGSIZE;
- }
- if (wire->len > buflen) {
- return EMSGSIZE;
- }
- if (offsetof(struct ctdb_notify_data_wire, data) + wire->len <
- offsetof(struct ctdb_notify_data_wire, data)) {
- return EMSGSIZE;
- }
- if (buflen < offsetof(struct ctdb_notify_data_wire, data) + wire->len) {
- return EMSGSIZE;
+ val = talloc(mem_ctx, struct ctdb_notify_data);
+ if (val == NULL) {
+ return ENOMEM;
}
- notify = talloc(mem_ctx, struct ctdb_notify_data);
- if (notify == NULL) {
- return ENOMEM;
+ ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
+ if (ret != 0) {
+ goto fail;
}
+ offset += np;
- notify->srvid = wire->srvid;
- notify->data.dsize = wire->len;
- notify->data.dptr = talloc_memdup(notify, wire->data, wire->len);
- if (notify->data.dptr == NULL) {
- talloc_free(notify);
- return ENOMEM;
+ ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, val, &val->data,
+ &np);
+ if (ret != 0) {
+ goto fail;
}
+ offset += np;
- *out = notify;
+ *out = val;
+ *npull = offset;
return 0;
+
+fail:
+ talloc_free(val);
+ return ret;
}
size_t ctdb_iface_len(struct ctdb_iface *iface)
diff --git a/ctdb/tests/src/protocol_types_compat_test.c b/ctdb/tests/src/protocol_types_compat_test.c
index 97f28157726..408ba72937a 100644
--- a/ctdb/tests/src/protocol_types_compat_test.c
+++ b/ctdb/tests/src/protocol_types_compat_test.c
@@ -1606,6 +1606,68 @@ static int ctdb_ban_state_pull_old(uint8_t *buf, size_t buflen,
return 0;
}
+struct ctdb_notify_data_wire {
+ uint64_t srvid;
+ uint32_t len;
+ uint8_t data[1];
+};
+
+static size_t ctdb_notify_data_len_old(struct ctdb_notify_data *in)
+{
+ return offsetof(struct ctdb_notify_data_wire, data) +
+ in->data.dsize;
+}
+
+static void ctdb_notify_data_push_old(struct ctdb_notify_data *in,
+ uint8_t *buf)
+{
+ struct ctdb_notify_data_wire *wire =
+ (struct ctdb_notify_data_wire *)buf;
+
+ wire->srvid = in->srvid;
+ wire->len = in->data.dsize;
+ memcpy(wire->data, in->data.dptr, in->data.dsize);
+}
+
+static int ctdb_notify_data_pull_old(uint8_t *buf, size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_notify_data **out)
+{
+ struct ctdb_notify_data *val;
+ struct ctdb_notify_data_wire *wire =
+ (struct ctdb_notify_data_wire *)buf;
+
+ if (buflen < offsetof(struct ctdb_notify_data_wire, data)) {
+ return EMSGSIZE;
+ }
+ if (wire->len > buflen) {
+ return EMSGSIZE;
+ }
+ if (offsetof(struct ctdb_notify_data_wire, data) + wire->len <
+ offsetof(struct ctdb_notify_data_wire, data)) {
+ return EMSGSIZE;
+ }
+ if (buflen < offsetof(struct ctdb_notify_data_wire, data) + wire->len) {
+ return EMSGSIZE;
+ }
+
+ val = talloc(mem_ctx, struct ctdb_notify_data);
+ if (val == NULL) {
+ return ENOMEM;
+ }
+
+ val->srvid = wire->srvid;
+ val->data.dsize = wire->len;
+ val->data.dptr = talloc_memdup(val, wire->data, wire->len);
+ if (val->data.dptr == 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);
@@ -1638,6 +1700,7 @@ COMPAT_TYPE3_TEST(struct ctdb_node_map, ctdb_node_map);
COMPAT_TYPE3_TEST(struct ctdb_script, ctdb_script);
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);
int main(int argc, char *argv[])
{
@@ -1675,6 +1738,7 @@ int main(int argc, char *argv[])
COMPAT_TEST_FUNC(ctdb_script)();
COMPAT_TEST_FUNC(ctdb_script_list)();
COMPAT_TEST_FUNC(ctdb_ban_state)();
+ COMPAT_TEST_FUNC(ctdb_notify_data)();
return 0;
}
diff --git a/ctdb/tests/src/protocol_types_test.c b/ctdb/tests/src/protocol_types_test.c
index 96f503c911c..f3c0ad70eb7 100644
--- a/ctdb/tests/src/protocol_types_test.c
+++ b/ctdb/tests/src/protocol_types_test.c
@@ -77,7 +77,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_node_map, ctdb_node_map);
PROTOCOL_TYPE3_TEST(struct ctdb_script, ctdb_script);
PROTOCOL_TYPE3_TEST(struct ctdb_script_list, ctdb_script_list);
PROTOCOL_TYPE3_TEST(struct ctdb_ban_state, ctdb_ban_state);
-DEFINE_TEST(struct ctdb_notify_data, ctdb_notify_data);
+PROTOCOL_TYPE3_TEST(struct ctdb_notify_data, ctdb_notify_data);
DEFINE_TEST(struct ctdb_iface, ctdb_iface);
DEFINE_TEST(struct ctdb_iface_list, ctdb_iface_list);
DEFINE_TEST(struct ctdb_public_ip_info, ctdb_public_ip_info);