From: Amitay Isaacs Date: Wed, 19 Jul 2017 04:36:45 +0000 (+1000) Subject: ctdb-protocol: Fix marshalling for ctdb_reply_call X-Git-Tag: ldb-1.2.2~80 X-Git-Url: http://git.samba.org/samba.git/?p=vlendec%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=aad7a3e0be400cfabe0c12f935a4e5707d3ddd77 ctdb-protocol: Fix marshalling for ctdb_reply_call Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke --- diff --git a/ctdb/protocol/protocol_call.c b/ctdb/protocol/protocol_call.c index 43f258d8c1c..0e3cd9577e4 100644 --- a/ctdb/protocol/protocol_call.c +++ b/ctdb/protocol/protocol_call.c @@ -27,13 +27,6 @@ #include "protocol_api.h" #include "protocol_private.h" -struct ctdb_reply_call_wire { - struct ctdb_req_header hdr; - uint32_t status; - uint32_t datalen; - uint8_t data[1]; -}; - struct ctdb_reply_error_wire { struct ctdb_req_header hdr; uint32_t status; @@ -207,16 +200,16 @@ int ctdb_req_call_pull(uint8_t *buf, size_t buflen, size_t ctdb_reply_call_len(struct ctdb_req_header *h, struct ctdb_reply_call *c) { - return offsetof(struct ctdb_reply_call_wire, data) + - ctdb_tdb_data_len(&c->data); + return ctdb_req_header_len(h) + + ctdb_int32_len(&c->status) + + ctdb_tdb_datan_len(&c->data); } int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c, uint8_t *buf, size_t *buflen) { - struct ctdb_reply_call_wire *wire = - (struct ctdb_reply_call_wire *)buf; - size_t length, np; + size_t offset = 0, np; + size_t length; length = ctdb_reply_call_len(h, c); if (*buflen < length) { @@ -225,11 +218,14 @@ int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c, } h->length = *buflen; - ctdb_req_header_push(h, (uint8_t *)&wire->hdr, &np); + ctdb_req_header_push(h, buf+offset, &np); + offset += np; - wire->status = c->status; - wire->datalen = ctdb_tdb_data_len(&c->data); - ctdb_tdb_data_push(&c->data, wire->data, &np); + ctdb_int32_push(&c->status, buf+offset, &np); + offset += np; + + ctdb_tdb_datan_push(&c->data, buf+offset, &np); + offset += np; return 0; } @@ -239,40 +235,32 @@ int ctdb_reply_call_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, struct ctdb_reply_call *c) { - struct ctdb_reply_call_wire *wire = - (struct ctdb_reply_call_wire *)buf; - size_t length, np; + struct ctdb_req_header header; + size_t offset = 0, np; int ret; - length = offsetof(struct ctdb_reply_call_wire, data); - if (buflen < length) { - return EMSGSIZE; - } - if (wire->datalen > buflen) { - return EMSGSIZE; - } - if (length + wire->datalen < length) { - return EMSGSIZE; - } - if (buflen < length + wire->datalen) { - return EMSGSIZE; + ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np); + if (ret != 0) { + return ret; } + offset += np; if (h != NULL) { - ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h, - &np); - if (ret != 0) { - return ret; - } + *h = header; } - c->status = wire->status; + ret = ctdb_int32_pull(buf+offset, buflen-offset, &c->status, &np); + if (ret != 0) { + return ret; + } + offset += np; - ret = ctdb_tdb_data_pull(wire->data, wire->datalen, mem_ctx, &c->data, - &np); + ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, + mem_ctx, &c->data, &np); if (ret != 0) { return ret; } + offset += np; return 0; } diff --git a/ctdb/tests/src/protocol_ctdb_compat_test.c b/ctdb/tests/src/protocol_ctdb_compat_test.c index aedff4e63ba..08712947437 100644 --- a/ctdb/tests/src/protocol_ctdb_compat_test.c +++ b/ctdb/tests/src/protocol_ctdb_compat_test.c @@ -334,10 +334,92 @@ static int ctdb_req_call_pull_old(uint8_t *buf, size_t buflen, return 0; } +struct ctdb_reply_call_wire { + struct ctdb_req_header hdr; + uint32_t status; + uint32_t datalen; + uint8_t data[1]; +}; + +static size_t ctdb_reply_call_len_old(struct ctdb_req_header *h, + struct ctdb_reply_call *c) +{ + return offsetof(struct ctdb_reply_call_wire, data) + + ctdb_tdb_data_len(&c->data); +} + +static int ctdb_reply_call_push_old(struct ctdb_req_header *h, + struct ctdb_reply_call *c, + uint8_t *buf, size_t *buflen) +{ + struct ctdb_reply_call_wire *wire = + (struct ctdb_reply_call_wire *)buf; + size_t length, np; + + length = ctdb_reply_call_len_old(h, c); + if (*buflen < length) { + *buflen = length; + return EMSGSIZE; + } + + h->length = *buflen; + ctdb_req_header_push_old(h, (uint8_t *)&wire->hdr); + + wire->status = c->status; + wire->datalen = ctdb_tdb_data_len(&c->data); + ctdb_tdb_data_push(&c->data, wire->data, &np); + + return 0; +} + +static int ctdb_reply_call_pull_old(uint8_t *buf, size_t buflen, + struct ctdb_req_header *h, + TALLOC_CTX *mem_ctx, + struct ctdb_reply_call *c) +{ + struct ctdb_reply_call_wire *wire = + (struct ctdb_reply_call_wire *)buf; + size_t length, np; + int ret; + + length = offsetof(struct ctdb_reply_call_wire, data); + if (buflen < length) { + return EMSGSIZE; + } + if (wire->datalen > buflen) { + return EMSGSIZE; + } + if (length + wire->datalen < length) { + return EMSGSIZE; + } + if (buflen < length + wire->datalen) { + return EMSGSIZE; + } + + if (h != NULL) { + ret = ctdb_req_header_pull_old((uint8_t *)&wire->hdr, buflen, + h); + if (ret != 0) { + return ret; + } + } + + c->status = wire->status; + + ret = ctdb_tdb_data_pull(wire->data, wire->datalen, mem_ctx, &c->data, + &np); + if (ret != 0) { + return ret; + } + + return 0; +} + COMPAT_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header); COMPAT_CTDB4_TEST(struct ctdb_req_call, ctdb_req_call, CTDB_REQ_CALL); +COMPAT_CTDB4_TEST(struct ctdb_reply_call, ctdb_reply_call, CTDB_REPLY_CALL); int main(int argc, char *argv[]) { @@ -349,6 +431,7 @@ int main(int argc, char *argv[]) COMPAT_TEST_FUNC(ctdb_req_header)(); COMPAT_TEST_FUNC(ctdb_req_call)(); + COMPAT_TEST_FUNC(ctdb_reply_call)(); return 0; } diff --git a/ctdb/tests/src/protocol_ctdb_test.c b/ctdb/tests/src/protocol_ctdb_test.c index 1beb0e76889..3d14c3b1eaa 100644 --- a/ctdb/tests/src/protocol_ctdb_test.c +++ b/ctdb/tests/src/protocol_ctdb_test.c @@ -281,45 +281,7 @@ static void TEST_FUNC(NAME)(uint64_t srvid) \ PROTOCOL_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header); PROTOCOL_CTDB4_TEST(struct ctdb_req_call, ctdb_req_call, CTDB_REQ_CALL); - -static void test_ctdb_reply_call(void) -{ - TALLOC_CTX *mem_ctx; - uint8_t *pkt; - size_t datalen, pkt_len, len; - int ret; - struct ctdb_req_header h, h2; - struct ctdb_reply_call c, c2; - - printf("ctdb_reply_call\n"); - fflush(stdout); - - mem_ctx = talloc_new(NULL); - assert(mem_ctx != NULL); - - ctdb_req_header_fill(&h, GENERATION, CTDB_REPLY_CALL, - DESTNODE, SRCNODE, REQID); - - fill_ctdb_reply_call(mem_ctx, &c); - datalen = ctdb_reply_call_len(&h, &c); - ret = ctdb_allocate_pkt(mem_ctx, datalen, &pkt, &pkt_len); - assert(ret == 0); - assert(pkt != NULL); - assert(pkt_len >= datalen); - len = 0; - ret = ctdb_reply_call_push(&h, &c, pkt, &len); - assert(ret == EMSGSIZE); - assert(len == datalen); - ret = ctdb_reply_call_push(&h, &c, pkt, &pkt_len); - assert(ret == 0); - ret = ctdb_reply_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2); - assert(ret == 0); - verify_ctdb_req_header(&h, &h2); - assert(h2.length == pkt_len); - verify_ctdb_reply_call(&c, &c2); - - talloc_free(mem_ctx); -} +PROTOCOL_CTDB4_TEST(struct ctdb_reply_call, ctdb_reply_call, CTDB_REPLY_CALL); static void test_ctdb_reply_error(void) { @@ -643,7 +605,7 @@ int main(int argc, char *argv[]) TEST_FUNC(ctdb_req_header)(); TEST_FUNC(ctdb_req_call)(); - test_ctdb_reply_call(); + TEST_FUNC(ctdb_reply_call)(); test_ctdb_reply_error(); test_ctdb_req_dmaster(); test_ctdb_reply_dmaster();