ctdb-protocol: Fix marshalling for ctdb_srvid_message
[vlendec/samba-autobuild/.git] / ctdb / protocol / protocol_message.c
index 2e12bbb3b1fa6a3505fe49b865365877a1efb694..3760c471b73de23fd5c317a9d018122dca335f40 100644 (file)
@@ -41,7 +41,7 @@ static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
 
        switch (srvid) {
        case CTDB_SRVID_BANNING:
-               len = ctdb_uint32_len(mdata->pnn);
+               len = ctdb_uint32_len(&mdata->pnn);
                break;
 
        case CTDB_SRVID_ELECTION:
@@ -52,11 +52,11 @@ static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
                break;
 
        case CTDB_SRVID_RELEASE_IP:
-               len = ctdb_string_len(mdata->ipaddr);
+               len = ctdb_string_len(&mdata->ipaddr);
                break;
 
        case CTDB_SRVID_TAKE_IP:
-               len = ctdb_string_len(mdata->ipaddr);
+               len = ctdb_string_len(&mdata->ipaddr);
                break;
 
        case CTDB_SRVID_SET_NODE_FLAGS:
@@ -72,7 +72,7 @@ static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
                break;
 
        case CTDB_SRVID_DETACH_DATABASE:
-               len = ctdb_uint32_len(mdata->db_id);
+               len = ctdb_uint32_len(&mdata->db_id);
                break;
 
        case CTDB_SRVID_MEM_DUMP:
@@ -91,7 +91,7 @@ static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
                break;
 
        case CTDB_SRVID_REBALANCE_NODE:
-               len = ctdb_uint32_len(mdata->pnn);
+               len = ctdb_uint32_len(&mdata->pnn);
                break;
 
        case CTDB_SRVID_DISABLE_TAKEOVER_RUNS:
@@ -103,11 +103,11 @@ static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
                break;
 
        case CTDB_SRVID_DISABLE_IP_CHECK:
-               len = ctdb_uint32_len(mdata->timeout);
+               len = ctdb_uint32_len(&mdata->timeout);
                break;
 
        default:
-               len = ctdb_tdb_data_len(mdata->data);
+               len = ctdb_tdb_data_len(&mdata->data);
                break;
        }
 
@@ -117,59 +117,61 @@ static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
 static void ctdb_message_data_push(union ctdb_message_data *mdata,
                                   uint64_t srvid, uint8_t *buf)
 {
+       size_t np;
+
        switch (srvid) {
        case CTDB_SRVID_BANNING:
-               ctdb_uint32_push(mdata->pnn, buf);
+               ctdb_uint32_push(&mdata->pnn, buf, &np);
                break;
 
        case CTDB_SRVID_ELECTION:
-               ctdb_election_message_push(mdata->election, buf);
+               ctdb_election_message_push(mdata->election, buf, &np);
                break;
 
        case CTDB_SRVID_RECONFIGURE:
                break;
 
        case CTDB_SRVID_RELEASE_IP:
-               ctdb_string_push(mdata->ipaddr, buf);
+               ctdb_string_push(&mdata->ipaddr, buf, &np);
                break;
 
        case CTDB_SRVID_TAKE_IP:
-               ctdb_string_push(mdata->ipaddr, buf);
+               ctdb_string_push(&mdata->ipaddr, buf, &np);
                break;
 
        case CTDB_SRVID_SET_NODE_FLAGS:
-               ctdb_node_flag_change_push(mdata->flag_change, buf);
+               ctdb_node_flag_change_push(mdata->flag_change, buf, &np);
                break;
 
        case CTDB_SRVID_RECD_UPDATE_IP:
-               ctdb_public_ip_push(mdata->pubip, buf);
+               ctdb_public_ip_push(mdata->pubip, buf, &np);
                break;
 
        case CTDB_SRVID_VACUUM_FETCH:
-               ctdb_rec_buffer_push(mdata->recbuf, buf);
+               ctdb_rec_buffer_push(mdata->recbuf, buf, &np);
                break;
 
        case CTDB_SRVID_DETACH_DATABASE:
-               ctdb_uint32_push(mdata->db_id, buf);
+               ctdb_uint32_push(&mdata->db_id, buf, &np);
                break;
 
        case CTDB_SRVID_MEM_DUMP:
-               ctdb_srvid_message_push(mdata->msg, buf);
+               ctdb_srvid_message_push(mdata->msg, buf, &np);
                break;
 
        case CTDB_SRVID_PUSH_NODE_FLAGS:
-               ctdb_node_flag_change_push(mdata->flag_change, buf);
+               ctdb_node_flag_change_push(mdata->flag_change, buf, &np);
                break;
 
        case CTDB_SRVID_RELOAD_NODES:
                break;
 
        case CTDB_SRVID_TAKEOVER_RUN:
-               ctdb_srvid_message_push(mdata->msg, buf);
+               ctdb_srvid_message_push(mdata->msg, buf, &np);
                break;
 
        case CTDB_SRVID_REBALANCE_NODE:
-               ctdb_uint32_push(mdata->pnn, buf);
+               ctdb_uint32_push(&mdata->pnn, buf, &np);
                break;
 
        case CTDB_SRVID_DISABLE_TAKEOVER_RUNS:
@@ -181,11 +183,11 @@ static void ctdb_message_data_push(union ctdb_message_data *mdata,
                break;
 
        case CTDB_SRVID_DISABLE_IP_CHECK:
-               ctdb_uint32_push(mdata->timeout, buf);
+               ctdb_uint32_push(&mdata->timeout, buf, &np);
                break;
 
        default:
-               ctdb_tdb_data_push(mdata->data, buf);
+               ctdb_tdb_data_push(&mdata->data, buf, &np);
                break;
        }
 }
@@ -195,55 +197,58 @@ static int ctdb_message_data_pull(uint8_t *buf, size_t buflen,
                                  union ctdb_message_data *mdata)
 {
        int ret = 0;
+       size_t np;
 
        switch (srvid) {
        case CTDB_SRVID_BANNING:
-               ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &mdata->pnn);
+               ret = ctdb_uint32_pull(buf, buflen, &mdata->pnn, &np);
                break;
 
        case CTDB_SRVID_ELECTION:
                ret = ctdb_election_message_pull(buf, buflen, mem_ctx,
-                                                &mdata->election);
+                                                &mdata->election, &np);
                break;
 
        case CTDB_SRVID_RECONFIGURE:
                break;
 
        case CTDB_SRVID_RELEASE_IP:
-               ret = ctdb_string_pull(buf, buflen, mem_ctx, &mdata->ipaddr);
+               ret = ctdb_string_pull(buf, buflen, mem_ctx, &mdata->ipaddr,
+                                      &np);
                break;
 
        case CTDB_SRVID_TAKE_IP:
-               ret = ctdb_string_pull(buf, buflen, mem_ctx, &mdata->ipaddr);
+               ret = ctdb_string_pull(buf, buflen, mem_ctx, &mdata->ipaddr,
+                                      &np);
                break;
 
        case CTDB_SRVID_SET_NODE_FLAGS:
                ret = ctdb_node_flag_change_pull(buf, buflen, mem_ctx,
-                                                &mdata->flag_change);
+                                                &mdata->flag_change, &np);
                break;
 
        case CTDB_SRVID_RECD_UPDATE_IP:
                ret = ctdb_public_ip_pull(buf, buflen, mem_ctx,
-                                         &mdata->pubip);
+                                         &mdata->pubip, &np);
                break;
 
        case CTDB_SRVID_VACUUM_FETCH:
                ret = ctdb_rec_buffer_pull(buf, buflen, mem_ctx,
-                                          &mdata->recbuf);
+                                          &mdata->recbuf, &np);
                break;
 
        case CTDB_SRVID_DETACH_DATABASE:
-               ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &mdata->db_id);
+               ret = ctdb_uint32_pull(buf, buflen, &mdata->db_id, &np);
                break;
 
        case CTDB_SRVID_MEM_DUMP:
                ret = ctdb_srvid_message_pull(buf, buflen, mem_ctx,
-                                             &mdata->msg);
+                                             &mdata->msg, &np);
                break;
 
        case CTDB_SRVID_PUSH_NODE_FLAGS:
                ret = ctdb_node_flag_change_pull(buf, buflen, mem_ctx,
-                                                &mdata->flag_change);
+                                                &mdata->flag_change, &np);
                break;
 
        case CTDB_SRVID_RELOAD_NODES:
@@ -251,11 +256,11 @@ static int ctdb_message_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_SRVID_TAKEOVER_RUN:
                ret = ctdb_srvid_message_pull(buf, buflen, mem_ctx,
-                                             &mdata->msg);
+                                             &mdata->msg, &np);
                break;
 
        case CTDB_SRVID_REBALANCE_NODE:
-               ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &mdata->pnn);
+               ret = ctdb_uint32_pull(buf, buflen, &mdata->pnn, &np);
                break;
 
        case CTDB_SRVID_DISABLE_TAKEOVER_RUNS:
@@ -269,137 +274,152 @@ static int ctdb_message_data_pull(uint8_t *buf, size_t buflen,
                break;
 
        case CTDB_SRVID_DISABLE_IP_CHECK:
-               ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &mdata->timeout);
+               ret = ctdb_uint32_pull(buf, buflen, &mdata->timeout, &np);
                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;
        }
 
        return ret;
 }
 
+size_t ctdb_req_message_len(struct ctdb_req_header *h,
+                           struct ctdb_req_message *c)
+{
+       return offsetof(struct ctdb_req_message_wire, data) +
+               ctdb_message_data_len(&c->data, c->srvid);
+}
+
 int ctdb_req_message_push(struct ctdb_req_header *h,
                          struct ctdb_req_message *message,
-                         TALLOC_CTX *mem_ctx,
-                         uint8_t **pkt, size_t *pkt_len)
+                         uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_req_message_wire *wire;
-       uint8_t *buf;
-       size_t length, buflen, datalen;
-       int ret;
-
-       datalen = ctdb_message_data_len(&message->data, message->srvid);
-       length = offsetof(struct ctdb_req_message_wire, data) + datalen;
+       struct ctdb_req_message_wire *wire =
+               (struct ctdb_req_message_wire *)buf;
+       size_t length;
 
-       ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
-       if (ret != 0) {
-               return ret;
+       length = ctdb_req_message_len(h, message);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
        }
 
-       wire = (struct ctdb_req_message_wire *)buf;
-
-       h->length = buflen;
-       memcpy(&wire->hdr, h, sizeof(struct ctdb_req_header));
+       h->length = *buflen;
+       ctdb_req_header_push(h, (uint8_t *)&wire->hdr);
 
        wire->srvid = message->srvid;
-       wire->datalen = datalen;
+       wire->datalen = ctdb_message_data_len(&message->data, message->srvid);
        ctdb_message_data_push(&message->data, message->srvid, wire->data);
 
-       *pkt = buf;
-       *pkt_len = buflen;
        return 0;
 }
 
-int ctdb_req_message_pull(uint8_t *pkt, size_t pkt_len,
+int ctdb_req_message_pull(uint8_t *buf, size_t buflen,
                          struct ctdb_req_header *h,
                          TALLOC_CTX *mem_ctx,
-                         struct ctdb_req_message *message)
+                         struct ctdb_req_message *c)
 {
        struct ctdb_req_message_wire *wire =
-               (struct ctdb_req_message_wire *)pkt;
+               (struct ctdb_req_message_wire *)buf;
        size_t length;
        int ret;
 
        length = offsetof(struct ctdb_req_message_wire, data);
-
-       if (pkt_len < length) {
+       if (buflen < length) {
+               return EMSGSIZE;
+       }
+       if (wire->datalen > buflen) {
+               return EMSGSIZE;
+       }
+       if (length + wire->datalen < length) {
                return EMSGSIZE;
        }
-       if (pkt_len < length + wire->datalen) {
+       if (buflen < length + wire->datalen) {
                return EMSGSIZE;
        }
 
        if (h != NULL) {
-               memcpy(h, &wire->hdr, sizeof(struct ctdb_req_header));
+               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h);
+               if (ret != 0) {
+                       return ret;
+               }
        }
 
-       message->srvid = wire->srvid;
+       c->srvid = wire->srvid;
        ret = ctdb_message_data_pull(wire->data, wire->datalen, wire->srvid,
-                                    mem_ctx, &message->data);
+                                    mem_ctx, &c->data);
        return ret;
 }
 
+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);
+}
+
 int ctdb_req_message_data_push(struct ctdb_req_header *h,
                               struct ctdb_req_message_data *message,
-                              TALLOC_CTX *mem_ctx,
-                              uint8_t **pkt, size_t *pkt_len)
+                              uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_req_message_wire *wire;
-       uint8_t *buf;
-       size_t length, buflen;
-       int ret;
-
-       length = offsetof(struct ctdb_req_message_wire, data) +
-                       ctdb_tdb_data_len(message->data);
+       struct ctdb_req_message_wire *wire =
+               (struct ctdb_req_message_wire *)buf;
+       size_t length, np;
 
-       ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
-       if (ret != 0) {
-               return ret;
+       length = ctdb_req_message_data_len(h, message);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
        }
 
-       wire = (struct ctdb_req_message_wire *)buf;
-
-       h->length = buflen;
-       memcpy(&wire->hdr, h, sizeof(struct ctdb_req_header));
+       h->length = *buflen;
+       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);
 
-       *pkt = buf;
-       *pkt_len = buflen;
        return 0;
 }
 
-int ctdb_req_message_data_pull(uint8_t *pkt, size_t pkt_len,
+int ctdb_req_message_data_pull(uint8_t *buf, size_t buflen,
                               struct ctdb_req_header *h,
                               TALLOC_CTX *mem_ctx,
-                              struct ctdb_req_message_data *message)
+                              struct ctdb_req_message_data *c)
 {
        struct ctdb_req_message_wire *wire =
-               (struct ctdb_req_message_wire *)pkt;
-       size_t length;
+               (struct ctdb_req_message_wire *)buf;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_req_message_wire, data);
-
-       if (pkt_len < length) {
+       if (buflen < length) {
+               return EMSGSIZE;
+       }
+       if (wire->datalen > buflen) {
+               return EMSGSIZE;
+       }
+       if (length + wire->datalen < length) {
                return EMSGSIZE;
        }
-       if (pkt_len < length + wire->datalen) {
+       if (buflen < length + wire->datalen) {
                return EMSGSIZE;
        }
 
        if (h != NULL) {
-               memcpy(h, &wire->hdr, sizeof(struct ctdb_req_header));
+               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h);
+               if (ret != 0) {
+                       return ret;
+               }
        }
 
-       message->srvid = wire->srvid;
+       c->srvid = wire->srvid;
 
        ret = ctdb_tdb_data_pull(wire->data, wire->datalen,
-                                mem_ctx, &message->data);
+                                mem_ctx, &c->data, &np);
        if (ret != 0) {
                return ret;
        }