1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

ctdb-protocol: Fix marshalling for ctdb_iface_list

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
Amitay Isaacs 2017-07-12 18:45:42 +10:00 committed by Martin Schwenke
parent 1790509bca
commit a8569128f5
5 changed files with 128 additions and 49 deletions

View File

@ -1531,7 +1531,7 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd,
break;
case CTDB_CONTROL_GET_IFACES:
ctdb_iface_list_push(cd->data.iface_list, buf);
ctdb_iface_list_push(cd->data.iface_list, buf, &np);
break;
case CTDB_CONTROL_GET_STAT_HISTORY:
@ -1714,7 +1714,7 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen,
case CTDB_CONTROL_GET_IFACES:
ret = ctdb_iface_list_pull(buf, buflen, mem_ctx,
&cd->data.iface_list);
&cd->data.iface_list, &np);
break;
case CTDB_CONTROL_GET_STAT_HISTORY:

View File

@ -282,10 +282,11 @@ void ctdb_iface_push(struct ctdb_iface *in, uint8_t *buf, size_t *npush);
int ctdb_iface_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
struct ctdb_iface **out, size_t *npull);
size_t ctdb_iface_list_len(struct ctdb_iface_list *iface_list);
void ctdb_iface_list_push(struct ctdb_iface_list *iface_list, uint8_t *buf);
size_t ctdb_iface_list_len(struct ctdb_iface_list *in);
void ctdb_iface_list_push(struct ctdb_iface_list *in, uint8_t *buf,
size_t *npush);
int ctdb_iface_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
struct ctdb_iface_list **out);
struct ctdb_iface_list **out, size_t *npull);
size_t ctdb_public_ip_info_len(struct ctdb_public_ip_info *ipinfo);
void ctdb_public_ip_info_push(struct ctdb_public_ip_info *ipinfo, uint8_t *buf);

View File

@ -4085,66 +4085,82 @@ int ctdb_iface_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
return ret;
}
struct ctdb_iface_list_wire {
uint32_t num;
struct ctdb_iface iface[1];
};
size_t ctdb_iface_list_len(struct ctdb_iface_list *iface_list)
size_t ctdb_iface_list_len(struct ctdb_iface_list *in)
{
return sizeof(uint32_t) +
iface_list->num * sizeof(struct ctdb_iface);
size_t len;
len = ctdb_uint32_len(&in->num);
if (in->num > 0) {
len += in->num * ctdb_iface_len(&in->iface[0]);
}
return len;
}
void ctdb_iface_list_push(struct ctdb_iface_list *iface_list, uint8_t *buf)
void ctdb_iface_list_push(struct ctdb_iface_list *in, uint8_t *buf,
size_t *npush)
{
struct ctdb_iface_list_wire *wire =
(struct ctdb_iface_list_wire *)buf;
size_t offset = 0, np;
uint32_t i;
wire->num = iface_list->num;
memcpy(wire->iface, iface_list->iface,
iface_list->num * sizeof(struct ctdb_iface));
ctdb_uint32_push(&in->num, buf+offset, &np);
offset += np;
for (i=0; i<in->num; i++) {
ctdb_iface_push(&in->iface[i], buf+offset, &np);
offset += np;
}
*npush = offset;
}
int ctdb_iface_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
struct ctdb_iface_list **out)
struct ctdb_iface_list **out, size_t *npull)
{
struct ctdb_iface_list *iface_list;
struct ctdb_iface_list_wire *wire =
(struct ctdb_iface_list_wire *)buf;
struct ctdb_iface_list *val;
size_t offset = 0, np;
uint32_t i;
int ret;
if (buflen < sizeof(uint32_t)) {
return EMSGSIZE;
}
if (wire->num > buflen / sizeof(struct ctdb_iface)) {
return EMSGSIZE;
}
if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface) <
sizeof(uint32_t)) {
return EMSGSIZE;
}
if (buflen < sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface)) {
return EMSGSIZE;
}
iface_list = talloc(mem_ctx, struct ctdb_iface_list);
if (iface_list == NULL) {
val = talloc(mem_ctx, struct ctdb_iface_list);
if (val == NULL) {
return ENOMEM;
}
iface_list->num = wire->num;
iface_list->iface = talloc_array(iface_list, struct ctdb_iface,
wire->num);
if (iface_list->iface == NULL) {
talloc_free(iface_list);
return ENOMEM;
ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
if (ret != 0) {
goto fail;
}
offset += np;
if (val->num == 0) {
val->iface = NULL;
goto done;
}
memcpy(iface_list->iface, wire->iface,
wire->num * sizeof(struct ctdb_iface));
val->iface = talloc_array(val, struct ctdb_iface, val->num);
if (val->iface == NULL) {
ret = ENOMEM;
goto fail;
}
*out = iface_list;
for (i=0; i<val->num; i++) {
ret = ctdb_iface_pull_elems(buf+offset, buflen-offset,
val, &val->iface[i], &np);
if (ret != 0) {
goto fail;
}
offset += np;
}
done:
*out = val;
*npull = offset;
return 0;
fail:
talloc_free(val);
return ret;
}
struct ctdb_public_ip_info_wire {

View File

@ -1712,6 +1712,66 @@ static int ctdb_iface_pull_old(uint8_t *buf, size_t buflen,
return ret;
}
struct ctdb_iface_list_wire {
uint32_t num;
struct ctdb_iface iface[1];
};
static size_t ctdb_iface_list_len_old(struct ctdb_iface_list *in)
{
return sizeof(uint32_t) +
in->num * sizeof(struct ctdb_iface);
}
static void ctdb_iface_list_push_old(struct ctdb_iface_list *in, uint8_t *buf)
{
struct ctdb_iface_list_wire *wire =
(struct ctdb_iface_list_wire *)buf;
wire->num = in->num;
memcpy(wire->iface, in->iface, in->num * sizeof(struct ctdb_iface));
}
static int ctdb_iface_list_pull_old(uint8_t *buf, size_t buflen,
TALLOC_CTX *mem_ctx,
struct ctdb_iface_list **out)
{
struct ctdb_iface_list *val;
struct ctdb_iface_list_wire *wire =
(struct ctdb_iface_list_wire *)buf;
if (buflen < sizeof(uint32_t)) {
return EMSGSIZE;
}
if (wire->num > buflen / sizeof(struct ctdb_iface)) {
return EMSGSIZE;
}
if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface) <
sizeof(uint32_t)) {
return EMSGSIZE;
}
if (buflen < sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface)) {
return EMSGSIZE;
}
val = talloc(mem_ctx, struct ctdb_iface_list);
if (val == NULL) {
return ENOMEM;
}
val->num = wire->num;
val->iface = talloc_array(val, struct ctdb_iface, wire->num);
if (val->iface == NULL) {
talloc_free(val);
return ENOMEM;
}
memcpy(val->iface, wire->iface, wire->num * sizeof(struct ctdb_iface));
*out = val;
return 0;
}
COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
@ -1746,6 +1806,7 @@ 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);
COMPAT_TYPE3_TEST(struct ctdb_iface, ctdb_iface);
COMPAT_TYPE3_TEST(struct ctdb_iface_list, ctdb_iface_list);
int main(int argc, char *argv[])
{
@ -1785,6 +1846,7 @@ int main(int argc, char *argv[])
COMPAT_TEST_FUNC(ctdb_ban_state)();
COMPAT_TEST_FUNC(ctdb_notify_data)();
COMPAT_TEST_FUNC(ctdb_iface)();
COMPAT_TEST_FUNC(ctdb_iface_list)();
return 0;
}

View File

@ -79,7 +79,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_script_list, ctdb_script_list);
PROTOCOL_TYPE3_TEST(struct ctdb_ban_state, ctdb_ban_state);
PROTOCOL_TYPE3_TEST(struct ctdb_notify_data, ctdb_notify_data);
PROTOCOL_TYPE3_TEST(struct ctdb_iface, ctdb_iface);
DEFINE_TEST(struct ctdb_iface_list, ctdb_iface_list);
PROTOCOL_TYPE3_TEST(struct ctdb_iface_list, ctdb_iface_list);
DEFINE_TEST(struct ctdb_public_ip_info, ctdb_public_ip_info);
DEFINE_TEST(struct ctdb_statistics_list, ctdb_statistics_list);
DEFINE_TEST(struct ctdb_key_data, ctdb_key_data);