diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-07-04 17:56:12 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-08-30 14:59:23 +0200 |
commit | bac67e1af536ff9e8e71921666f1d2b489cb8c9b (patch) | |
tree | 1e395b03cfaa4842a262e305dd85022cf1005cb7 | |
parent | 9573260954368d3be2b8a57ecb64c33deeb9c914 (diff) | |
download | samba-bac67e1af536ff9e8e71921666f1d2b489cb8c9b.tar.gz |
ctdb-protocol: Fix marshalling for ctdb_tickle_list
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
-rw-r--r-- | ctdb/protocol/protocol_control.c | 8 | ||||
-rw-r--r-- | ctdb/protocol/protocol_private.h | 7 | ||||
-rw-r--r-- | ctdb/protocol/protocol_types.c | 115 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_types_compat_test.c | 88 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_types_test.c | 2 |
5 files changed, 157 insertions, 63 deletions
diff --git a/ctdb/protocol/protocol_control.c b/ctdb/protocol/protocol_control.c index eaaf471b2f8..621290ce1a1 100644 --- a/ctdb/protocol/protocol_control.c +++ b/ctdb/protocol/protocol_control.c @@ -539,7 +539,7 @@ static void ctdb_req_control_data_push(struct ctdb_req_control_data *cd, break; case CTDB_CONTROL_SET_TCP_TICKLE_LIST: - ctdb_tickle_list_push(cd->data.tickles, buf); + ctdb_tickle_list_push(cd->data.tickles, buf, &np); break; case CTDB_CONTROL_DB_ATTACH_PERSISTENT: @@ -838,7 +838,7 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen, case CTDB_CONTROL_SET_TCP_TICKLE_LIST: ret = ctdb_tickle_list_pull(buf, buflen, mem_ctx, - &cd->data.tickles); + &cd->data.tickles, &np); break; case CTDB_CONTROL_DB_ATTACH_PERSISTENT: @@ -1480,7 +1480,7 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd, break; case CTDB_CONTROL_GET_TCP_TICKLE_LIST: - ctdb_tickle_list_push(cd->data.tickles, buf); + ctdb_tickle_list_push(cd->data.tickles, buf, &np); break; case CTDB_CONTROL_DB_ATTACH_PERSISTENT: @@ -1654,7 +1654,7 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen, case CTDB_CONTROL_GET_TCP_TICKLE_LIST: ret = ctdb_tickle_list_pull(buf, buflen, mem_ctx, - &cd->data.tickles); + &cd->data.tickles, &np); break; case CTDB_CONTROL_DB_ATTACH_PERSISTENT: diff --git a/ctdb/protocol/protocol_private.h b/ctdb/protocol/protocol_private.h index 84f26501461..037819ac9e3 100644 --- a/ctdb/protocol/protocol_private.h +++ b/ctdb/protocol/protocol_private.h @@ -209,10 +209,11 @@ void ctdb_tunable_list_push(struct ctdb_tunable_list *in, uint8_t *buf, int ctdb_tunable_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, struct ctdb_tunable_list **out, size_t *npull); -size_t ctdb_tickle_list_len(struct ctdb_tickle_list *tickles); -void ctdb_tickle_list_push(struct ctdb_tickle_list *tickles, uint8_t *buf); +size_t ctdb_tickle_list_len(struct ctdb_tickle_list *in); +void ctdb_tickle_list_push(struct ctdb_tickle_list *in, uint8_t *buf, + size_t *npush); int ctdb_tickle_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, - struct ctdb_tickle_list **out); + 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); diff --git a/ctdb/protocol/protocol_types.c b/ctdb/protocol/protocol_types.c index 285de5fb6fb..ec9d7d5eb81 100644 --- a/ctdb/protocol/protocol_types.c +++ b/ctdb/protocol/protocol_types.c @@ -3105,88 +3105,93 @@ int ctdb_tunable_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, return 0; } -struct ctdb_tickle_list_wire { - ctdb_sock_addr addr; - uint32_t num; - struct ctdb_connection conn[1]; -}; - -size_t ctdb_tickle_list_len(struct ctdb_tickle_list *tickles) +size_t ctdb_tickle_list_len(struct ctdb_tickle_list *in) { - return offsetof(struct ctdb_tickle_list, conn) + - tickles->num * sizeof(struct ctdb_connection); + size_t len; + + len = ctdb_sock_addr_len(&in->addr) + + ctdb_uint32_len(&in->num); + if (in->num > 0) { + len += in->num * ctdb_connection_len(&in->conn[0]); + } + + return len; } -void ctdb_tickle_list_push(struct ctdb_tickle_list *tickles, uint8_t *buf) +void ctdb_tickle_list_push(struct ctdb_tickle_list *in, uint8_t *buf, + size_t *npush) { - struct ctdb_tickle_list_wire *wire = - (struct ctdb_tickle_list_wire *)buf; - size_t offset, np; - int i; + size_t offset = 0, np; + uint32_t i; + + ctdb_sock_addr_push(&in->addr, buf+offset, &np); + offset += np; - memcpy(&wire->addr, &tickles->addr, sizeof(ctdb_sock_addr)); - wire->num = tickles->num; + ctdb_uint32_push(&in->num, buf+offset, &np); + offset += np; - offset = offsetof(struct ctdb_tickle_list_wire, conn); - for (i=0; i<tickles->num; i++) { - ctdb_connection_push(&tickles->conn[i], &buf[offset], &np); + for (i=0; i<in->num; i++) { + ctdb_connection_push(&in->conn[i], buf+offset, &np); offset += np; } + + *npush = offset; } int ctdb_tickle_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, - struct ctdb_tickle_list **out) + struct ctdb_tickle_list **out, size_t *npull) { - struct ctdb_tickle_list *tickles; - struct ctdb_tickle_list_wire *wire = - (struct ctdb_tickle_list_wire *)buf; - size_t offset, np; - int i, ret; + struct ctdb_tickle_list *val; + size_t offset = 0, np; + uint32_t i; + int ret; - if (buflen < offsetof(struct ctdb_tickle_list_wire, conn)) { - return EMSGSIZE; - } - if (wire->num > buflen / sizeof(struct ctdb_connection)) { - return EMSGSIZE; - } - if (offsetof(struct ctdb_tickle_list_wire, conn) + - wire->num * sizeof(struct ctdb_connection) < - offsetof(struct ctdb_tickle_list_wire, conn)) { - return EMSGSIZE; + val = talloc(mem_ctx, struct ctdb_tickle_list); + if (val == NULL) { + return ENOMEM; } - if (buflen < offsetof(struct ctdb_tickle_list_wire, conn) + - wire->num * sizeof(struct ctdb_connection)) { - return EMSGSIZE; + + ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, val, + &val->addr, &np); + if (ret != 0) { + goto fail; } + offset += np; - tickles = talloc(mem_ctx, struct ctdb_tickle_list); - if (tickles == NULL) { - return ENOMEM; + ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np); + if (ret != 0) { + goto fail; } + offset += np; - offset = offsetof(struct ctdb_tickle_list, conn); - memcpy(tickles, wire, offset); + if (val->num == 0) { + val->conn = NULL; + goto done; + } - tickles->conn = talloc_array(tickles, struct ctdb_connection, - wire->num); - if (tickles->conn == NULL) { - talloc_free(tickles); - return ENOMEM; + val->conn = talloc_array(val, struct ctdb_connection, val->num); + if (val->conn == NULL) { + ret = ENOMEM; + goto fail; } - for (i=0; i<wire->num; i++) { - ret = ctdb_connection_pull_elems(&buf[offset], buflen-offset, - tickles->conn, - &tickles->conn[i], &np); + for (i=0; i<val->num; i++) { + ret = ctdb_connection_pull_elems(buf+offset, buflen-offset, + val, &val->conn[i], &np); if (ret != 0) { - talloc_free(tickles); - return ret; + goto fail; } offset += np; } - *out = tickles; +done: + *out = val; + *npull = offset; return 0; + +fail: + talloc_free(val); + return ret; } struct ctdb_addr_info_wire { diff --git a/ctdb/tests/src/protocol_types_compat_test.c b/ctdb/tests/src/protocol_types_compat_test.c index 215757a77ff..cb651e37fb3 100644 --- a/ctdb/tests/src/protocol_types_compat_test.c +++ b/ctdb/tests/src/protocol_types_compat_test.c @@ -947,6 +947,92 @@ static int ctdb_tunable_list_pull_old(uint8_t *buf, size_t buflen, return 0; } +struct ctdb_tickle_list_wire { + ctdb_sock_addr addr; + uint32_t num; + struct ctdb_connection conn[1]; +}; + +static size_t ctdb_tickle_list_len_old(struct ctdb_tickle_list *in) +{ + return offsetof(struct ctdb_tickle_list, conn) + + in->num * sizeof(struct ctdb_connection); +} + +static void ctdb_tickle_list_push_old(struct ctdb_tickle_list *in, + uint8_t *buf) +{ + struct ctdb_tickle_list_wire *wire = + (struct ctdb_tickle_list_wire *)buf; + size_t offset; + int i; + + memcpy(&wire->addr, &in->addr, sizeof(ctdb_sock_addr)); + wire->num = in->num; + + offset = offsetof(struct ctdb_tickle_list_wire, conn); + for (i=0; i<in->num; i++) { + ctdb_connection_push_old(&in->conn[i], &buf[offset]); + offset += ctdb_connection_len_old(&in->conn[i]); + } +} + +static int ctdb_tickle_list_pull_old(uint8_t *buf, size_t buflen, + TALLOC_CTX *mem_ctx, + struct ctdb_tickle_list **out) +{ + struct ctdb_tickle_list *val; + struct ctdb_tickle_list_wire *wire = + (struct ctdb_tickle_list_wire *)buf; + size_t offset; + int i, ret; + + if (buflen < offsetof(struct ctdb_tickle_list_wire, conn)) { + return EMSGSIZE; + } + if (wire->num > buflen / sizeof(struct ctdb_connection)) { + return EMSGSIZE; + } + if (offsetof(struct ctdb_tickle_list_wire, conn) + + wire->num * sizeof(struct ctdb_connection) < + offsetof(struct ctdb_tickle_list_wire, conn)) { + return EMSGSIZE; + } + if (buflen < offsetof(struct ctdb_tickle_list_wire, conn) + + wire->num * sizeof(struct ctdb_connection)) { + return EMSGSIZE; + } + + val = talloc(mem_ctx, struct ctdb_tickle_list); + if (val == NULL) { + return ENOMEM; + } + + offset = offsetof(struct ctdb_tickle_list, conn); + memcpy(val, wire, offset); + + val->conn = talloc_array(val, struct ctdb_connection, wire->num); + if (val->conn == NULL) { + talloc_free(val); + return ENOMEM; + } + + for (i=0; i<wire->num; i++) { + ret = ctdb_connection_pull_elems_old(&buf[offset], + buflen-offset, + val->conn, + &val->conn[i]); + if (ret != 0) { + talloc_free(val); + return ret; + } + offset += ctdb_connection_len_old(&val->conn[i]); + } + + *out = val; + return 0; +} + COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics); COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map); @@ -968,6 +1054,7 @@ COMPAT_TYPE3_TEST(struct ctdb_tunable, ctdb_tunable); 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); int main(int argc, char *argv[]) { @@ -994,6 +1081,7 @@ int main(int argc, char *argv[]) COMPAT_TEST_FUNC(ctdb_node_flag_change)(); COMPAT_TEST_FUNC(ctdb_var_list)(); COMPAT_TEST_FUNC(ctdb_tunable_list)(); + COMPAT_TEST_FUNC(ctdb_tickle_list)(); return 0; } diff --git a/ctdb/tests/src/protocol_types_test.c b/ctdb/tests/src/protocol_types_test.c index 695a591e57e..e0468408a61 100644 --- a/ctdb/tests/src/protocol_types_test.c +++ b/ctdb/tests/src/protocol_types_test.c @@ -66,7 +66,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_tunable, ctdb_tunable); 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); -DEFINE_TEST(struct ctdb_tickle_list, ctdb_tickle_list); +PROTOCOL_TYPE3_TEST(struct ctdb_tickle_list, ctdb_tickle_list); DEFINE_TEST(struct ctdb_addr_info, ctdb_addr_info); DEFINE_TEST(struct ctdb_transdb, ctdb_transdb); DEFINE_TEST(struct ctdb_uptime, ctdb_uptime); |