diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-07-12 18:29:12 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-08-30 14:59:24 +0200 |
commit | 091ef60ed28f6cbfb91402e4e12556f57ff20681 (patch) | |
tree | e858b44c76fe7d7d6674e3ed28372b305bc7b645 /ctdb | |
parent | 57a4d2e6317ccef6c4d3e7c1a0de81d1ca259ee7 (diff) | |
download | samba-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.c | 4 | ||||
-rw-r--r-- | ctdb/protocol/protocol_private.h | 7 | ||||
-rw-r--r-- | ctdb/protocol/protocol_types.c | 76 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_types_compat_test.c | 64 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_types_test.c | 2 |
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); |