ctdb-protocol: Fix marshalling for tdb_data
authorAmitay Isaacs <amitay@gmail.com>
Fri, 30 Jun 2017 07:15:47 +0000 (17:15 +1000)
committerMartin Schwenke <martins@samba.org>
Wed, 30 Aug 2017 12:59:22 +0000 (14:59 +0200)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/protocol/protocol_call.c
ctdb/protocol/protocol_message.c
ctdb/protocol/protocol_private.h
ctdb/protocol/protocol_types.c
ctdb/tests/src/protocol_common.c
ctdb/tests/src/protocol_common.h
ctdb/tests/src/protocol_types_test.c

index 2dbd309317b1ea1b776d9a8e5c9bf317f7565d40..111cdf25de0aee348dae442d751942123ea04787 100644 (file)
@@ -74,7 +74,8 @@ struct ctdb_reply_dmaster_wire {
 size_t ctdb_req_call_len(struct ctdb_req_header *h, struct ctdb_req_call *c)
 {
        return offsetof(struct ctdb_req_call_wire, data) +
-               ctdb_tdb_data_len(c->key) + ctdb_tdb_data_len(c->calldata);
+               ctdb_tdb_data_len(&c->key) +
+               ctdb_tdb_data_len(&c->calldata);
 }
 
 int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c,
@@ -82,7 +83,7 @@ int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c,
 {
        struct ctdb_req_call_wire *wire =
                (struct ctdb_req_call_wire *)buf;
-       size_t length;
+       size_t length, np;
 
        if (c->key.dsize == 0) {
                return EINVAL;
@@ -101,10 +102,10 @@ int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c,
        wire->db_id = c->db_id;
        wire->callid = c->callid;
        wire->hopcount = c->hopcount;
-       wire->keylen = ctdb_tdb_data_len(c->key);
-       wire->calldatalen = ctdb_tdb_data_len(c->calldata);
-       ctdb_tdb_data_push(c->key, wire->data);
-       ctdb_tdb_data_push(c->calldata, wire->data + wire->keylen);
+       wire->keylen = ctdb_tdb_data_len(&c->key);
+       wire->calldatalen = ctdb_tdb_data_len(&c->calldata);
+       ctdb_tdb_data_push(&c->key, wire->data, &np);
+       ctdb_tdb_data_push(&c->calldata, wire->data + wire->keylen, &np);
 
        return 0;
 }
@@ -116,7 +117,7 @@ int ctdb_req_call_pull(uint8_t *buf, size_t buflen,
 {
        struct ctdb_req_call_wire *wire =
                (struct ctdb_req_call_wire *)buf;
-       size_t length;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_req_call_wire, data);
@@ -148,13 +149,14 @@ int ctdb_req_call_pull(uint8_t *buf, size_t buflen,
        c->callid = wire->callid;
        c->hopcount = wire->hopcount;
 
-       ret = ctdb_tdb_data_pull(wire->data, wire->keylen, mem_ctx, &c->key);
+       ret = ctdb_tdb_data_pull(wire->data, wire->keylen, mem_ctx, &c->key,
+                                &np);
        if (ret != 0) {
                return ret;
        }
 
        ret = ctdb_tdb_data_pull(wire->data + wire->keylen, wire->calldatalen,
-                                mem_ctx, &c->calldata);
+                                mem_ctx, &c->calldata, &np);
        if (ret != 0) {
                return ret;
        }
@@ -166,7 +168,7 @@ 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);
+               ctdb_tdb_data_len(&c->data);
 }
 
 int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c,
@@ -174,7 +176,7 @@ int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c,
 {
        struct ctdb_reply_call_wire *wire =
                (struct ctdb_reply_call_wire *)buf;
-       size_t length;
+       size_t length, np;
 
        length = ctdb_reply_call_len(h, c);
        if (*buflen < length) {
@@ -186,8 +188,8 @@ int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c,
        ctdb_req_header_push(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);
+       wire->datalen = ctdb_tdb_data_len(&c->data);
+       ctdb_tdb_data_push(&c->data, wire->data, &np);
 
        return 0;
 }
@@ -199,7 +201,7 @@ int ctdb_reply_call_pull(uint8_t *buf, size_t buflen,
 {
        struct ctdb_reply_call_wire *wire =
                (struct ctdb_reply_call_wire *)buf;
-       size_t length;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_reply_call_wire, data);
@@ -225,7 +227,8 @@ int ctdb_reply_call_pull(uint8_t *buf, size_t buflen,
 
        c->status = wire->status;
 
-       ret = ctdb_tdb_data_pull(wire->data, wire->datalen, mem_ctx, &c->data);
+       ret = ctdb_tdb_data_pull(wire->data, wire->datalen, mem_ctx, &c->data,
+                                &np);
        if (ret != 0) {
                return ret;
        }
@@ -237,7 +240,7 @@ size_t ctdb_reply_error_len(struct ctdb_req_header *h,
                            struct ctdb_reply_error *c)
 {
        return offsetof(struct ctdb_reply_error_wire, msg) +
-               ctdb_tdb_data_len(c->msg);
+               ctdb_tdb_data_len(&c->msg);
 }
 
 int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c,
@@ -245,7 +248,7 @@ int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c,
 {
        struct ctdb_reply_error_wire *wire =
                (struct ctdb_reply_error_wire *)buf;
-       size_t length;
+       size_t length, np;
 
        length = ctdb_reply_error_len(h, c);
        if (*buflen < length) {
@@ -257,8 +260,8 @@ int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c,
        ctdb_req_header_push(h, (uint8_t *)&wire->hdr);
 
        wire->status = c->status;
-       wire->msglen = ctdb_tdb_data_len(c->msg);
-       ctdb_tdb_data_push(c->msg, wire->msg);
+       wire->msglen = ctdb_tdb_data_len(&c->msg);
+       ctdb_tdb_data_push(&c->msg, wire->msg, &np);
 
        return 0;
 }
@@ -270,7 +273,7 @@ int ctdb_reply_error_pull(uint8_t *buf, size_t buflen,
 {
        struct ctdb_reply_error_wire *wire =
                (struct ctdb_reply_error_wire *)buf;
-       size_t length;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_reply_error_wire, msg);
@@ -296,7 +299,8 @@ int ctdb_reply_error_pull(uint8_t *buf, size_t buflen,
 
        c->status = wire->status;
 
-       ret = ctdb_tdb_data_pull(wire->msg, wire->msglen, mem_ctx, &c->msg);
+       ret = ctdb_tdb_data_pull(wire->msg, wire->msglen, mem_ctx, &c->msg,
+                                &np);
        if (ret != 0) {
                return ret;
        }
@@ -308,7 +312,8 @@ size_t ctdb_req_dmaster_len(struct ctdb_req_header *h,
                            struct ctdb_req_dmaster *c)
 {
        return offsetof(struct ctdb_req_dmaster_wire, data) +
-               ctdb_tdb_data_len(c->key) + ctdb_tdb_data_len(c->data);
+               ctdb_tdb_data_len(&c->key) +
+               ctdb_tdb_data_len(&c->data);
 }
 
 int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c,
@@ -316,7 +321,7 @@ int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c,
 {
        struct ctdb_req_dmaster_wire *wire =
                (struct ctdb_req_dmaster_wire *)buf;
-       size_t length;
+       size_t length, np;
 
        length = ctdb_req_dmaster_len(h, c);
        if (*buflen < length) {
@@ -330,10 +335,10 @@ int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c,
        wire->db_id = c->db_id;
        wire->rsn = c->rsn;
        wire->dmaster = c->dmaster;
-       wire->keylen = ctdb_tdb_data_len(c->key);
-       wire->datalen = ctdb_tdb_data_len(c->data);
-       ctdb_tdb_data_push(c->key, wire->data);
-       ctdb_tdb_data_push(c->data, wire->data + wire->keylen);
+       wire->keylen = ctdb_tdb_data_len(&c->key);
+       wire->datalen = ctdb_tdb_data_len(&c->data);
+       ctdb_tdb_data_push(&c->key, wire->data, &np);
+       ctdb_tdb_data_push(&c->data, wire->data + wire->keylen, &np);
 
        return 0;
 }
@@ -345,7 +350,7 @@ int ctdb_req_dmaster_pull(uint8_t *buf, size_t buflen,
 {
        struct ctdb_req_dmaster_wire *wire =
                (struct ctdb_req_dmaster_wire *)buf;
-       size_t length;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_req_dmaster_wire, data);
@@ -376,13 +381,14 @@ int ctdb_req_dmaster_pull(uint8_t *buf, size_t buflen,
        c->rsn = wire->rsn;
        c->dmaster = wire->dmaster;
 
-       ret = ctdb_tdb_data_pull(wire->data, wire->keylen, mem_ctx, &c->key);
+       ret = ctdb_tdb_data_pull(wire->data, wire->keylen, mem_ctx, &c->key,
+                                &np);
        if (ret != 0) {
                return ret;
        }
 
        ret = ctdb_tdb_data_pull(wire->data + wire->keylen, wire->datalen,
-                                mem_ctx, &c->data);
+                                mem_ctx, &c->data, &np);
        if (ret != 0) {
                return ret;
        }
@@ -394,7 +400,8 @@ size_t ctdb_reply_dmaster_len(struct ctdb_req_header *h,
                              struct ctdb_reply_dmaster *c)
 {
        return offsetof(struct ctdb_reply_dmaster_wire, data) +
-               ctdb_tdb_data_len(c->key) + ctdb_tdb_data_len(c->data);
+               ctdb_tdb_data_len(&c->key) +
+               ctdb_tdb_data_len(&c->data);
 }
 
 int ctdb_reply_dmaster_push(struct ctdb_req_header *h,
@@ -403,7 +410,7 @@ int ctdb_reply_dmaster_push(struct ctdb_req_header *h,
 {
        struct ctdb_reply_dmaster_wire *wire =
                (struct ctdb_reply_dmaster_wire *)buf;
-       size_t length;
+       size_t length, np;
 
        length = ctdb_reply_dmaster_len(h, c);
        if (*buflen < length) {
@@ -416,10 +423,10 @@ int ctdb_reply_dmaster_push(struct ctdb_req_header *h,
 
        wire->db_id = c->db_id;
        wire->rsn = c->rsn;
-       wire->keylen = ctdb_tdb_data_len(c->key);
-       wire->datalen = ctdb_tdb_data_len(c->data);
-       ctdb_tdb_data_push(c->key, wire->data);
-       ctdb_tdb_data_push(c->data, wire->data + wire->keylen);
+       wire->keylen = ctdb_tdb_data_len(&c->key);
+       wire->datalen = ctdb_tdb_data_len(&c->data);
+       ctdb_tdb_data_push(&c->key, wire->data, &np);
+       ctdb_tdb_data_push(&c->data, wire->data + wire->keylen, &np);
 
        return 0;
 }
@@ -431,7 +438,7 @@ int ctdb_reply_dmaster_pull(uint8_t *buf, size_t buflen,
 {
        struct ctdb_reply_dmaster_wire *wire =
                (struct ctdb_reply_dmaster_wire *)buf;
-       size_t length;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_reply_dmaster_wire, data);
@@ -461,13 +468,14 @@ int ctdb_reply_dmaster_pull(uint8_t *buf, size_t buflen,
        c->db_id = wire->db_id;
        c->rsn = wire->rsn;
 
-       ret = ctdb_tdb_data_pull(wire->data, wire->keylen, mem_ctx, &c->key);
+       ret = ctdb_tdb_data_pull(wire->data, wire->keylen, mem_ctx, &c->key,
+                                &np);
        if (ret != 0) {
                return ret;
        }
 
        ret = ctdb_tdb_data_pull(wire->data + wire->keylen, wire->datalen,
-                                mem_ctx, &c->data);
+                                mem_ctx, &c->data, &np);
        if (ret != 0) {
                return ret;
        }
index f15c35b7a153997a786066a20eb05d53abfafc70..8d83b9bd6feefcd9a3ad032e56378ad305fbfe47 100644 (file)
@@ -107,7 +107,7 @@ static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
                break;
 
        default:
-               len = ctdb_tdb_data_len(mdata->data);
+               len = ctdb_tdb_data_len(&mdata->data);
                break;
        }
 
@@ -187,7 +187,7 @@ static void ctdb_message_data_push(union ctdb_message_data *mdata,
                break;
 
        default:
-               ctdb_tdb_data_push(mdata->data, buf);
+               ctdb_tdb_data_push(&mdata->data, buf, &np);
                break;
        }
 }
@@ -278,7 +278,8 @@ static int ctdb_message_data_pull(uint8_t *buf, size_t buflen,
                break;
 
        default:
-               ret = ctdb_tdb_data_pull(buf, buflen, mem_ctx, &mdata->data);
+               ret = ctdb_tdb_data_pull(buf, buflen, mem_ctx, &mdata->data,
+                                        &np);
                break;
        }
 
@@ -357,7 +358,7 @@ size_t ctdb_req_message_data_len(struct ctdb_req_header *h,
                                 struct ctdb_req_message_data *c)
 {
        return offsetof(struct ctdb_req_message_wire, data) +
-               ctdb_tdb_data_len(c->data);
+               ctdb_tdb_data_len(&c->data);
 }
 
 int ctdb_req_message_data_push(struct ctdb_req_header *h,
@@ -366,7 +367,7 @@ int ctdb_req_message_data_push(struct ctdb_req_header *h,
 {
        struct ctdb_req_message_wire *wire =
                (struct ctdb_req_message_wire *)buf;
-       size_t length;
+       size_t length, np;
 
        length = ctdb_req_message_data_len(h, message);
        if (*buflen < length) {
@@ -378,8 +379,8 @@ int ctdb_req_message_data_push(struct ctdb_req_header *h,
        ctdb_req_header_push(h, (uint8_t *)&wire->hdr);
 
        wire->srvid = message->srvid;
-       wire->datalen = ctdb_tdb_data_len(message->data);
-       ctdb_tdb_data_push(message->data, wire->data);
+       wire->datalen = ctdb_tdb_data_len(&message->data);
+       ctdb_tdb_data_push(&message->data, wire->data, &np);
 
        return 0;
 }
@@ -391,7 +392,7 @@ int ctdb_req_message_data_pull(uint8_t *buf, size_t buflen,
 {
        struct ctdb_req_message_wire *wire =
                (struct ctdb_req_message_wire *)buf;
-       size_t length;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_req_message_wire, data);
@@ -418,7 +419,7 @@ int ctdb_req_message_data_pull(uint8_t *buf, size_t buflen,
        c->srvid = wire->srvid;
 
        ret = ctdb_tdb_data_pull(wire->data, wire->datalen,
-                                mem_ctx, &c->data);
+                                mem_ctx, &c->data, &np);
        if (ret != 0) {
                return ret;
        }
index c8b9d9c30cfa68b6a47fd8828a3751a585405464..1f1dca1e35ba639e532faaf235f4c7c30f9a6aa4 100644 (file)
@@ -89,10 +89,10 @@ int ctdb_padding_pull(uint8_t *buf, size_t buflen, int count, size_t *npull);
  * From protocol/protocol_types.c
  */
 
-size_t ctdb_tdb_data_len(TDB_DATA data);
-void ctdb_tdb_data_push(TDB_DATA data, uint8_t *buf);
+size_t ctdb_tdb_data_len(TDB_DATA *in);
+void ctdb_tdb_data_push(TDB_DATA *in, uint8_t *buf, size_t *npush);
 int ctdb_tdb_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                      TDB_DATA *out);
+                      TDB_DATA *out, size_t *npull);
 
 size_t ctdb_statistics_len(struct ctdb_statistics *stats);
 void ctdb_statistics_push(struct ctdb_statistics *stats, uint8_t *buf);
index 85a661db8fe451ae02fe36508c12e552ccbb794f..cd8897086b1c538afaffc27015467ba5c347b277 100644 (file)
 #include "protocol_private.h"
 #include "protocol_api.h"
 
-size_t ctdb_tdb_data_len(TDB_DATA data)
+size_t ctdb_tdb_data_len(TDB_DATA *in)
 {
-       return data.dsize;
+       return in->dsize > UINT32_MAX ? UINT32_MAX : in->dsize;
 }
 
-void ctdb_tdb_data_push(TDB_DATA data, uint8_t *buf)
+void ctdb_tdb_data_push(TDB_DATA *in, uint8_t *buf, size_t *npush)
 {
-       if (data.dsize > 0) {
-               memcpy(buf, data.dptr, data.dsize);
+       size_t len = ctdb_tdb_data_len(in);
+
+       if (len > 0) {
+               memcpy(buf, in->dptr, len);
        }
+
+       *npush = len;
 }
 
 int ctdb_tdb_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                      TDB_DATA *out)
+                      TDB_DATA *out, size_t *npull)
 {
-       TDB_DATA data;
+       TDB_DATA val;
 
-       data.dsize = buflen;
-       if (data.dsize > 0) {
-               data.dptr = talloc_memdup(mem_ctx, buf, buflen);
-               if (data.dptr == NULL) {
+       if (buflen > UINT32_MAX) {
+               return EMSGSIZE;
+       }
+
+       val.dsize = buflen;
+       if (val.dsize > 0) {
+               val.dptr = talloc_memdup(mem_ctx, buf, buflen);
+               if (val.dptr == NULL) {
                        return ENOMEM;
                }
        } else {
-               data.dptr = NULL;
+               val.dptr = NULL;
        }
 
-       *out = data;
+       *out = val;
+       *npull = buflen;
        return 0;
 }
 
index f01ead5f2cf6946e42d7d80ad7880e4922ef72d7..a133a2abf07a6de1e9aef8addb5305335aff9428 100644 (file)
@@ -256,6 +256,16 @@ void verify_tdb_data(TDB_DATA *p1, TDB_DATA *p2)
        verify_buffer(p1->dptr, p2->dptr, p1->dsize);
 }
 
+void fill_ctdb_tdb_data(TALLOC_CTX *mem_ctx, TDB_DATA *p)
+{
+       fill_tdb_data(mem_ctx, p);
+}
+
+void verify_ctdb_tdb_data(TDB_DATA *p1, TDB_DATA *p2)
+{
+       verify_tdb_data(p1, p2);
+}
+
 void fill_ctdb_statistics(TALLOC_CTX *mem_ctx, struct ctdb_statistics *p)
 {
        fill_buffer((uint8_t *)p, sizeof(struct ctdb_statistics));
index fd7fc32a07cff5409aaee943ad94c0e089190e54..b7d0fc537a7bed0d63107b646504756b01b737f6 100644 (file)
@@ -189,6 +189,9 @@ void fill_tdb_data_nonnull(TALLOC_CTX *mem_ctx, TDB_DATA *p);
 void fill_tdb_data(TALLOC_CTX *mem_ctx, TDB_DATA *p);
 void verify_tdb_data(TDB_DATA *p1, TDB_DATA *p2);
 
+void fill_ctdb_tdb_data(TALLOC_CTX *mem_ctx, TDB_DATA *p);
+void verify_ctdb_tdb_data(TDB_DATA *p1, TDB_DATA *p2);
+
 void fill_ctdb_statistics(TALLOC_CTX *mem_ctx, struct ctdb_statistics *p);
 void verify_ctdb_statistics(struct ctdb_statistics *p1,
                            struct ctdb_statistics *p2);
index 457a9107bd96a5eff21004d29477e88f8565ab2d..3990fbae3e4b84d66379dce1a286dea30fc04681 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "tests/src/protocol_common.h"
 
+PROTOCOL_TYPE2_TEST(TDB_DATA, ctdb_tdb_data);
+
 static void test_ctdb_ltdb_header(void)
 {
        TALLOC_CTX *mem_ctx = talloc_new(NULL);
@@ -152,6 +154,7 @@ int main(int argc, char *argv[])
                srandom(seed);
        }
 
+       TEST_FUNC(ctdb_tdb_data)();
        test_ctdb_ltdb_header();
        test_ctdb_g_lock();