From 10dbeddab5237b401c1eb42a50a27dde19a580c9 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Sun, 1 May 2016 22:13:35 +1000 Subject: ctdb-protocol: Return required buffer size in push functions If the buffer size provided is not sufficient, then return the required buffer length. Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke --- ctdb/client/client_call.c | 2 +- ctdb/client/client_control.c | 2 +- ctdb/client/client_message.c | 2 +- ctdb/protocol/protocol_api.h | 18 +++++----- ctdb/protocol/protocol_call.c | 35 +++++++++++-------- ctdb/protocol/protocol_control.c | 14 ++++---- ctdb/protocol/protocol_message.c | 14 ++++---- ctdb/tests/src/protocol_client_test.c | 64 ++++++++++++++++++++++++++--------- 8 files changed, 96 insertions(+), 55 deletions(-) diff --git a/ctdb/client/client_call.c b/ctdb/client/client_call.c index d1a6c2164f6..088ba67a503 100644 --- a/ctdb/client/client_call.c +++ b/ctdb/client/client_call.c @@ -98,7 +98,7 @@ struct tevent_req *ctdb_client_call_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - ret = ctdb_req_call_push(&h, request, buf, buflen); + ret = ctdb_req_call_push(&h, request, buf, &buflen); if (ret != 0) { tevent_req_error(req, ret); return tevent_req_post(req, ev); diff --git a/ctdb/client/client_control.c b/ctdb/client/client_control.c index ecbdb2dd6a4..1755eccf65d 100644 --- a/ctdb/client/client_control.c +++ b/ctdb/client/client_control.c @@ -105,7 +105,7 @@ struct tevent_req *ctdb_client_control_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - ret = ctdb_req_control_push(&h, request, buf, buflen); + ret = ctdb_req_control_push(&h, request, buf, &buflen); if (ret != 0) { tevent_req_error(req, ret); return tevent_req_post(req, ev); diff --git a/ctdb/client/client_message.c b/ctdb/client/client_message.c index 9fb60a89ee1..03fcfc6690f 100644 --- a/ctdb/client/client_message.c +++ b/ctdb/client/client_message.c @@ -92,7 +92,7 @@ struct tevent_req *ctdb_client_message_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - ret = ctdb_req_message_push(&h, message, buf, buflen); + ret = ctdb_req_message_push(&h, message, buf, &buflen); if (ret != 0) { tevent_req_error(req, ret); return tevent_req_post(req, ev); diff --git a/ctdb/protocol/protocol_api.h b/ctdb/protocol/protocol_api.h index 78cc6212787..0f781ccce7a 100644 --- a/ctdb/protocol/protocol_api.h +++ b/ctdb/protocol/protocol_api.h @@ -90,7 +90,7 @@ size_t ctdb_req_call_len(struct ctdb_req_header *h, int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_req_call_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, @@ -102,7 +102,7 @@ size_t ctdb_reply_call_len(struct ctdb_req_header *h, int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_reply_call_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, @@ -114,7 +114,7 @@ size_t ctdb_reply_error_len(struct ctdb_req_header *h, int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_reply_error_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, @@ -126,7 +126,7 @@ size_t ctdb_req_dmaster_len(struct ctdb_req_header *h, int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_req_dmaster_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, @@ -138,7 +138,7 @@ size_t ctdb_reply_dmaster_len(struct ctdb_req_header *h, int ctdb_reply_dmaster_push(struct ctdb_req_header *h, struct ctdb_reply_dmaster *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_reply_dmaster_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, @@ -152,7 +152,7 @@ size_t ctdb_req_control_len(struct ctdb_req_header *h, int ctdb_req_control_push(struct ctdb_req_header *h, struct ctdb_req_control *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_req_control_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, @@ -164,7 +164,7 @@ size_t ctdb_reply_control_len(struct ctdb_req_header *h, int ctdb_reply_control_push(struct ctdb_req_header *h, struct ctdb_reply_control *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_reply_control_pull(uint8_t *buf, size_t buflen, uint32_t opcode, struct ctdb_req_header *h, @@ -654,7 +654,7 @@ size_t ctdb_req_message_len(struct ctdb_req_header *h, int ctdb_req_message_push(struct ctdb_req_header *h, struct ctdb_req_message *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_req_message_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, @@ -666,7 +666,7 @@ size_t ctdb_req_message_data_len(struct ctdb_req_header *h, int ctdb_req_message_data_push(struct ctdb_req_header *h, struct ctdb_req_message_data *c, - uint8_t *buf, size_t buflen); + uint8_t *buf, size_t *buflen); int ctdb_req_message_data_pull(uint8_t *buf, size_t buflen, struct ctdb_req_header *h, diff --git a/ctdb/protocol/protocol_call.c b/ctdb/protocol/protocol_call.c index 441bf6048a2..a2b24cf0843 100644 --- a/ctdb/protocol/protocol_call.c +++ b/ctdb/protocol/protocol_call.c @@ -78,7 +78,7 @@ size_t ctdb_req_call_len(struct ctdb_req_header *h, struct ctdb_req_call *c) } int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_req_call_wire *wire = (struct ctdb_req_call_wire *)buf; @@ -89,11 +89,12 @@ int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c, } length = ctdb_req_call_len(h, c); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->flags = c->flags; @@ -160,18 +161,19 @@ size_t ctdb_reply_call_len(struct ctdb_req_header *h, } int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_reply_call_wire *wire = (struct ctdb_reply_call_wire *)buf; size_t length; length = ctdb_reply_call_len(h, c); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->status = c->status; @@ -224,18 +226,19 @@ size_t ctdb_reply_error_len(struct ctdb_req_header *h, } int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_reply_error_wire *wire = (struct ctdb_reply_error_wire *)buf; size_t length; length = ctdb_reply_error_len(h, c); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->status = c->status; @@ -288,18 +291,19 @@ size_t ctdb_req_dmaster_len(struct ctdb_req_header *h, } int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_req_dmaster_wire *wire = (struct ctdb_req_dmaster_wire *)buf; size_t length; length = ctdb_req_dmaster_len(h, c); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->db_id = c->db_id; @@ -365,18 +369,19 @@ size_t ctdb_reply_dmaster_len(struct ctdb_req_header *h, int ctdb_reply_dmaster_push(struct ctdb_req_header *h, struct ctdb_reply_dmaster *c, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_reply_dmaster_wire *wire = (struct ctdb_reply_dmaster_wire *)buf; size_t length; length = ctdb_reply_dmaster_len(h, c); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->db_id = c->db_id; diff --git a/ctdb/protocol/protocol_control.c b/ctdb/protocol/protocol_control.c index 83ddfbee4fc..fc2e6da0277 100644 --- a/ctdb/protocol/protocol_control.c +++ b/ctdb/protocol/protocol_control.c @@ -1899,18 +1899,19 @@ size_t ctdb_req_control_len(struct ctdb_req_header *h, int ctdb_req_control_push(struct ctdb_req_header *h, struct ctdb_req_control *request, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_req_control_wire *wire = (struct ctdb_req_control_wire *)buf; size_t length; length = ctdb_req_control_len(h, request); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->opcode = request->opcode; @@ -1976,18 +1977,19 @@ size_t ctdb_reply_control_len(struct ctdb_req_header *h, int ctdb_reply_control_push(struct ctdb_req_header *h, struct ctdb_reply_control *reply, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_reply_control_wire *wire = (struct ctdb_reply_control_wire *)buf; size_t length; length = ctdb_reply_control_len(h, reply); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->status = reply->status; diff --git a/ctdb/protocol/protocol_message.c b/ctdb/protocol/protocol_message.c index 2b45a63d7a2..291ebe6f679 100644 --- a/ctdb/protocol/protocol_message.c +++ b/ctdb/protocol/protocol_message.c @@ -289,18 +289,19 @@ size_t ctdb_req_message_len(struct ctdb_req_header *h, int ctdb_req_message_push(struct ctdb_req_header *h, struct ctdb_req_message *message, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_req_message_wire *wire = (struct ctdb_req_message_wire *)buf; size_t length; length = ctdb_req_message_len(h, message); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->srvid = message->srvid; @@ -350,18 +351,19 @@ size_t ctdb_req_message_data_len(struct ctdb_req_header *h, int ctdb_req_message_data_push(struct ctdb_req_header *h, struct ctdb_req_message_data *message, - uint8_t *buf, size_t buflen) + uint8_t *buf, size_t *buflen) { struct ctdb_req_message_wire *wire = (struct ctdb_req_message_wire *)buf; size_t length; length = ctdb_req_message_data_len(h, message); - if (buflen < length) { + if (*buflen < length) { + *buflen = length; return EMSGSIZE; } - h->length = buflen; + h->length = *buflen; ctdb_req_header_push(h, (uint8_t *)&wire->hdr); wire->srvid = message->srvid; diff --git a/ctdb/tests/src/protocol_client_test.c b/ctdb/tests/src/protocol_client_test.c index c03ad3bdac2..16ec8452ea2 100644 --- a/ctdb/tests/src/protocol_client_test.c +++ b/ctdb/tests/src/protocol_client_test.c @@ -1977,7 +1977,7 @@ static void test_req_call_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_req_call c, c2; @@ -1997,7 +1997,11 @@ static void test_req_call_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_req_call_push(&h, &c, pkt, pkt_len); + len = 0; + ret = ctdb_req_call_push(&h, &c, pkt, &len); + assert(ret == EMSGSIZE); + assert(len == datalen); + ret = ctdb_req_call_push(&h, &c, pkt, &pkt_len); assert(ret == 0); ret = ctdb_req_call_pull(pkt, pkt_len, &h2, mem_ctx, &c2); assert(ret == 0); @@ -2012,7 +2016,7 @@ static void test_reply_call_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_reply_call c, c2; @@ -2032,7 +2036,11 @@ static void test_reply_call_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_reply_call_push(&h, &c, pkt, pkt_len); + 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); @@ -2047,7 +2055,7 @@ static void test_reply_error_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_reply_error c, c2; @@ -2067,7 +2075,11 @@ static void test_reply_error_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_reply_error_push(&h, &c, pkt, pkt_len); + len = 0; + ret = ctdb_reply_error_push(&h, &c, pkt, &len); + assert(ret == EMSGSIZE); + assert(len == datalen); + ret = ctdb_reply_error_push(&h, &c, pkt, &pkt_len); assert(ret == 0); ret = ctdb_reply_error_pull(pkt, pkt_len, &h2, mem_ctx, &c2); assert(ret == 0); @@ -2082,7 +2094,7 @@ static void test_req_dmaster_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_req_dmaster c, c2; @@ -2102,7 +2114,11 @@ static void test_req_dmaster_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_req_dmaster_push(&h, &c, pkt, pkt_len); + len = 0; + ret = ctdb_req_dmaster_push(&h, &c, pkt, &len); + assert(ret == EMSGSIZE); + assert(len == datalen); + ret = ctdb_req_dmaster_push(&h, &c, pkt, &pkt_len); assert(ret == 0); ret = ctdb_req_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2); assert(ret == 0); @@ -2117,7 +2133,7 @@ static void test_reply_dmaster_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_reply_dmaster c, c2; @@ -2137,7 +2153,11 @@ static void test_reply_dmaster_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_reply_dmaster_push(&h, &c, pkt, pkt_len); + len = 0; + ret = ctdb_reply_dmaster_push(&h, &c, pkt, &len); + assert(ret == EMSGSIZE); + assert(len == datalen); + ret = ctdb_reply_dmaster_push(&h, &c, pkt, &pkt_len); assert(ret == 0); ret = ctdb_reply_dmaster_pull(pkt, pkt_len, &h2, mem_ctx, &c2); assert(ret == 0); @@ -2214,7 +2234,7 @@ static void test_req_control_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_req_control c, c2; @@ -2238,7 +2258,11 @@ static void test_req_control_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_req_control_push(&h, &c, pkt, pkt_len); + len = 0; + ret = ctdb_req_control_push(&h, &c, pkt, &len); + assert(ret == EMSGSIZE); + assert(len == datalen); + ret = ctdb_req_control_push(&h, &c, pkt, &pkt_len); assert(ret == 0); ret = ctdb_req_control_pull(pkt, pkt_len, &h2, mem_ctx, &c2); assert(ret == 0); @@ -2257,7 +2281,7 @@ static void test_reply_control_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_reply_control c, c2; @@ -2281,7 +2305,11 @@ static void test_reply_control_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_reply_control_push(&h, &c, pkt, pkt_len); + len = 0; + ret = ctdb_reply_control_push(&h, &c, pkt, &len); + assert(ret == EMSGSIZE); + assert(len == datalen); + ret = ctdb_reply_control_push(&h, &c, pkt, &pkt_len); assert(ret == 0); ret = ctdb_reply_control_pull(pkt, pkt_len, opcode, &h2, mem_ctx, &c2); assert(ret == 0); @@ -2300,7 +2328,7 @@ static void test_req_message_test(void) { TALLOC_CTX *mem_ctx; uint8_t *pkt; - size_t datalen, pkt_len; + size_t datalen, pkt_len, len; int ret; struct ctdb_req_header h, h2; struct ctdb_req_message_data c, c2; @@ -2320,7 +2348,11 @@ static void test_req_message_test(void) assert(ret == 0); assert(pkt != NULL); assert(pkt_len >= datalen); - ret = ctdb_req_message_data_push(&h, &c, pkt, pkt_len); + len = 0; + ret = ctdb_req_message_data_push(&h, &c, pkt, &len); + assert(ret == EMSGSIZE); + assert(len == datalen); + ret = ctdb_req_message_data_push(&h, &c, pkt, &pkt_len); assert(ret == 0); ret = ctdb_req_message_data_pull(pkt, pkt_len, &h2, mem_ctx, &c2); assert(ret == 0); -- cgit v1.2.1