ctdb-protocol: Fix marshalling for ctdb_srvid_message
[vlendec/samba-autobuild/.git] / ctdb / protocol / protocol_call.c
index 0f19e1a230c4a66584c1574ff46c29de24a92938..111cdf25de0aee348dae442d751942123ea04787 100644 (file)
@@ -74,71 +74,71 @@ 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,
-                      TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
+                      uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_req_call_wire *wire;
-       uint8_t *buf;
-       size_t length, buflen;
-       int ret;
+       struct ctdb_req_call_wire *wire =
+               (struct ctdb_req_call_wire *)buf;
+       size_t length, np;
 
        if (c->key.dsize == 0) {
                return EINVAL;
        }
 
-       length = offsetof(struct ctdb_req_call_wire, data) +
-                       ctdb_tdb_data_len(c->key) +
-                       ctdb_tdb_data_len(c->calldata);
-
-       ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
-       if (ret != 0) {
-               return ret;
+       length = ctdb_req_call_len(h, c);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
        }
 
-       wire = (struct ctdb_req_call_wire *)buf;
-
-       h->length = buflen;
+       h->length = *buflen;
        ctdb_req_header_push(h, (uint8_t *)&wire->hdr);
 
        wire->flags = c->flags;
        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);
 
-       *pkt = buf;
-       *pkt_len = buflen;
        return 0;
 }
 
-int ctdb_req_call_pull(uint8_t *pkt, size_t pkt_len,
+int ctdb_req_call_pull(uint8_t *buf, size_t buflen,
                       struct ctdb_req_header *h,
                       TALLOC_CTX *mem_ctx,
                       struct ctdb_req_call *c)
 {
-       struct ctdb_req_call_wire *wire;
-       size_t length;
+       struct ctdb_req_call_wire *wire =
+               (struct ctdb_req_call_wire *)buf;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_req_call_wire, data);
-       if (pkt_len < length) {
+       if (buflen < length) {
                return EMSGSIZE;
        }
-
-       wire = (struct ctdb_req_call_wire *)pkt;
-
-       if (pkt_len < length + wire->keylen + wire->calldatalen) {
+       if (wire->keylen > buflen || wire->calldatalen > buflen) {
+               return EMSGSIZE;
+       }
+       if (length + wire->keylen < length) {
+               return EMSGSIZE;
+       }
+       if (length + wire->keylen + wire->calldatalen < length) {
+               return EMSGSIZE;
+       }
+       if (buflen < length + wire->keylen + wire->calldatalen) {
                return EMSGSIZE;
        }
 
        if (h != NULL) {
-               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, pkt_len, h);
+               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h);
                if (ret != 0) {
                        return ret;
                }
@@ -149,13 +149,14 @@ int ctdb_req_call_pull(uint8_t *pkt, size_t pkt_len,
        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;
        }
@@ -167,61 +168,58 @@ 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,
-                        TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
+                        uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_reply_call_wire *wire;
-       uint8_t *buf;
-       size_t length, buflen;
-       int ret;
+       struct ctdb_reply_call_wire *wire =
+               (struct ctdb_reply_call_wire *)buf;
+       size_t length, np;
 
-       length = offsetof(struct ctdb_reply_call_wire, data) +
-                       ctdb_tdb_data_len(c->data);
-
-       ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
-       if (ret != 0) {
-               return ret;
+       length = ctdb_reply_call_len(h, c);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
        }
 
-       wire = (struct ctdb_reply_call_wire *)buf;
-
-       h->length = buflen;
+       h->length = *buflen;
        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);
 
-       *pkt = buf;
-       *pkt_len = buflen;
        return 0;
 }
 
-int ctdb_reply_call_pull(uint8_t *pkt, size_t pkt_len,
+int ctdb_reply_call_pull(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;
-       size_t length;
+       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 (pkt_len < length) {
+       if (buflen < length) {
                return EMSGSIZE;
        }
-
-       wire = (struct ctdb_reply_call_wire *)pkt;
-
-       if (pkt_len < length + wire->datalen) {
+       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((uint8_t *)&wire->hdr, pkt_len, h);
+               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h);
                if (ret != 0) {
                        return ret;
                }
@@ -229,7 +227,8 @@ int ctdb_reply_call_pull(uint8_t *pkt, size_t pkt_len,
 
        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;
        }
@@ -241,61 +240,58 @@ 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,
-                         TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
+                         uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_reply_error_wire *wire;
-       uint8_t *buf;
-       size_t length, buflen;
-       int ret;
+       struct ctdb_reply_error_wire *wire =
+               (struct ctdb_reply_error_wire *)buf;
+       size_t length, np;
 
-       length = offsetof(struct ctdb_reply_error_wire, msg) +
-                       ctdb_tdb_data_len(c->msg);
-
-       ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
-       if (ret != 0) {
-               return ret;
+       length = ctdb_reply_error_len(h, c);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
        }
 
-       wire = (struct ctdb_reply_error_wire *)buf;
-
-       h->length = buflen;
+       h->length = *buflen;
        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);
 
-       *pkt = buf;
-       *pkt_len = buflen;
        return 0;
 }
 
-int ctdb_reply_error_pull(uint8_t *pkt, size_t pkt_len,
+int ctdb_reply_error_pull(uint8_t *buf, size_t buflen,
                          struct ctdb_req_header *h,
                          TALLOC_CTX *mem_ctx,
                          struct ctdb_reply_error *c)
 {
-       struct ctdb_reply_error_wire *wire;
-       size_t length;
+       struct ctdb_reply_error_wire *wire =
+               (struct ctdb_reply_error_wire *)buf;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_reply_error_wire, msg);
-       if (pkt_len < length) {
+       if (buflen < length) {
                return EMSGSIZE;
        }
-
-       wire = (struct ctdb_reply_error_wire *)pkt;
-
-       if (pkt_len < length + wire->msglen) {
+       if (wire->msglen > buflen) {
+               return EMSGSIZE;
+       }
+       if (length + wire->msglen < length) {
+               return EMSGSIZE;
+       }
+       if (buflen < length + wire->msglen) {
                return EMSGSIZE;
        }
 
        if (h != NULL) {
-               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, pkt_len, h);
+               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h);
                if (ret != 0) {
                        return ret;
                }
@@ -303,7 +299,8 @@ int ctdb_reply_error_pull(uint8_t *pkt, size_t pkt_len,
 
        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;
        }
@@ -315,66 +312,66 @@ 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,
-                         TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
+                         uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_req_dmaster_wire *wire;
-       uint8_t *buf;
-       size_t length, buflen;
-       int ret;
-
-       length = offsetof(struct ctdb_req_dmaster_wire, data) +
-                       ctdb_tdb_data_len(c->key) +
-                       ctdb_tdb_data_len(c->data);
+       struct ctdb_req_dmaster_wire *wire =
+               (struct ctdb_req_dmaster_wire *)buf;
+       size_t length, np;
 
-       ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
-       if (ret != 0) {
-               return ret;
+       length = ctdb_req_dmaster_len(h, c);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
        }
 
-       wire = (struct ctdb_req_dmaster_wire *)buf;
-
-       h->length = buflen;
+       h->length = *buflen;
        ctdb_req_header_push(h, (uint8_t *)&wire->hdr);
 
        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);
 
-       *pkt = buf;
-       *pkt_len = buflen;
        return 0;
 }
 
-int ctdb_req_dmaster_pull(uint8_t *pkt, size_t pkt_len,
+int ctdb_req_dmaster_pull(uint8_t *buf, size_t buflen,
                          struct ctdb_req_header *h,
                          TALLOC_CTX *mem_ctx,
                          struct ctdb_req_dmaster *c)
 {
-       struct ctdb_req_dmaster_wire *wire;
-       size_t length;
+       struct ctdb_req_dmaster_wire *wire =
+               (struct ctdb_req_dmaster_wire *)buf;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_req_dmaster_wire, data);
-       if (pkt_len < length) {
+       if (buflen < length) {
                return EMSGSIZE;
        }
-
-       wire = (struct ctdb_req_dmaster_wire *)pkt;
-
-       if (pkt_len < length + wire->keylen + wire->datalen) {
+       if (wire->keylen > buflen || wire->datalen > buflen) {
+               return EMSGSIZE;
+       }
+       if (length + wire->keylen < length) {
+               return EMSGSIZE;
+       }
+       if (length + wire->keylen + wire->datalen < length) {
+               return EMSGSIZE;
+       }
+       if (buflen < length + wire->keylen + wire->datalen) {
                return EMSGSIZE;
        }
 
        if (h != NULL) {
-               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, pkt_len, h);
+               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h);
                if (ret != 0) {
                        return ret;
                }
@@ -384,13 +381,14 @@ int ctdb_req_dmaster_pull(uint8_t *pkt, size_t pkt_len,
        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;
        }
@@ -402,66 +400,66 @@ 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,
                            struct ctdb_reply_dmaster *c,
-                           TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
+                           uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_reply_dmaster_wire *wire;
-       uint8_t *buf;
-       size_t length, buflen;
-       int ret;
-
-       length = offsetof(struct ctdb_reply_dmaster_wire, data) +
-                       ctdb_tdb_data_len(c->key) +
-                       ctdb_tdb_data_len(c->data);
+       struct ctdb_reply_dmaster_wire *wire =
+               (struct ctdb_reply_dmaster_wire *)buf;
+       size_t length, np;
 
-       ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
-       if (ret != 0) {
-               return ret;
+       length = ctdb_reply_dmaster_len(h, c);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
        }
 
-       wire = (struct ctdb_reply_dmaster_wire *)buf;
-
-       h->length = buflen;
+       h->length = *buflen;
        ctdb_req_header_push(h, (uint8_t *)&wire->hdr);
 
        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);
 
-       *pkt = buf;
-       *pkt_len = buflen;
        return 0;
 }
 
-int ctdb_reply_dmaster_pull(uint8_t *pkt, size_t pkt_len,
+int ctdb_reply_dmaster_pull(uint8_t *buf, size_t buflen,
                            struct ctdb_req_header *h,
                            TALLOC_CTX *mem_ctx,
                            struct ctdb_reply_dmaster *c)
 {
-       struct ctdb_reply_dmaster_wire *wire;
-       size_t length;
+       struct ctdb_reply_dmaster_wire *wire =
+               (struct ctdb_reply_dmaster_wire *)buf;
+       size_t length, np;
        int ret;
 
        length = offsetof(struct ctdb_reply_dmaster_wire, data);
-       if (pkt_len < length) {
+       if (buflen < length) {
                return EMSGSIZE;
        }
-
-       wire = (struct ctdb_reply_dmaster_wire *)pkt;
-
-       if (pkt_len < length + wire->keylen + wire->datalen) {
+       if (wire->keylen > buflen || wire->datalen > buflen) {
+               return EMSGSIZE;
+       }
+       if (length + wire->keylen < length) {
+               return EMSGSIZE;
+       }
+       if (length + wire->keylen + wire->datalen < length) {
+               return EMSGSIZE;
+       }
+       if (buflen < length + wire->keylen + wire->datalen) {
                return EMSGSIZE;
        }
 
        if (h != NULL) {
-               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, pkt_len, h);
+               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h);
                if (ret != 0) {
                        return ret;
                }
@@ -470,13 +468,14 @@ int ctdb_reply_dmaster_pull(uint8_t *pkt, size_t pkt_len,
        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;
        }