2 CTDB protocol marshalling
4 Copyright (C) Amitay Isaacs 2015
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/network.h"
27 #include "protocol_api.h"
28 #include "protocol_private.h"
30 struct ctdb_req_call_wire
{
31 struct ctdb_req_header hdr
;
38 uint8_t data
[1]; /* key[] followed by calldata[] */
41 struct ctdb_reply_call_wire
{
42 struct ctdb_req_header hdr
;
48 struct ctdb_reply_error_wire
{
49 struct ctdb_req_header hdr
;
55 struct ctdb_req_dmaster_wire
{
56 struct ctdb_req_header hdr
;
65 struct ctdb_reply_dmaster_wire
{
66 struct ctdb_req_header hdr
;
74 int ctdb_req_call_push(struct ctdb_req_header
*h
, struct ctdb_req_call
*c
,
75 TALLOC_CTX
*mem_ctx
, uint8_t **pkt
, size_t *pkt_len
)
77 struct ctdb_req_call_wire
*wire
;
79 size_t length
, buflen
;
82 if (c
->key
.dsize
== 0) {
86 length
= offsetof(struct ctdb_req_call_wire
, data
) +
87 c
->key
.dsize
+ c
->calldata
.dsize
;
89 ret
= allocate_pkt(mem_ctx
, length
, &buf
, &buflen
);
94 wire
= (struct ctdb_req_call_wire
*)buf
;
97 memcpy(&wire
->hdr
, h
, sizeof(struct ctdb_req_header
));
99 wire
->flags
= c
->flags
;
100 wire
->db_id
= c
->db_id
;
101 wire
->callid
= c
->callid
;
102 wire
->hopcount
= c
->hopcount
;
103 wire
->keylen
= c
->key
.dsize
;
104 wire
->calldatalen
= c
->calldata
.dsize
;
105 memcpy(wire
->data
, c
->key
.dptr
, c
->key
.dsize
);
106 if (c
->calldata
.dsize
> 0) {
107 memcpy(wire
->data
+ c
->key
.dsize
, c
->calldata
.dptr
,
116 int ctdb_req_call_pull(uint8_t *pkt
, size_t pkt_len
,
117 struct ctdb_req_header
*h
,
119 struct ctdb_req_call
*c
)
121 struct ctdb_req_call_wire
*wire
;
124 length
= offsetof(struct ctdb_req_call_wire
, data
);
125 if (pkt_len
< length
) {
129 wire
= (struct ctdb_req_call_wire
*)pkt
;
131 if (pkt_len
< length
+ wire
->keylen
+ wire
->calldatalen
) {
135 memcpy(h
, &wire
->hdr
, sizeof(struct ctdb_req_header
));
137 c
->flags
= wire
->flags
;
138 c
->db_id
= wire
->db_id
;
139 c
->callid
= wire
->callid
;
140 c
->hopcount
= wire
->hopcount
;
141 c
->key
.dsize
= wire
->keylen
;
142 c
->key
.dptr
= talloc_memdup(mem_ctx
, wire
->data
, wire
->keylen
);
143 if (c
->key
.dptr
== NULL
) {
146 c
->calldata
.dsize
= wire
->calldatalen
;
147 if (wire
->calldatalen
> 0) {
148 c
->calldata
.dptr
= talloc_memdup(mem_ctx
,
149 wire
->data
+ wire
->keylen
,
151 if (c
->calldata
.dptr
== NULL
) {
152 talloc_free(c
->key
.dptr
);
160 int ctdb_reply_call_push(struct ctdb_req_header
*h
, struct ctdb_reply_call
*c
,
161 TALLOC_CTX
*mem_ctx
, uint8_t **pkt
, size_t *pkt_len
)
163 struct ctdb_reply_call_wire
*wire
;
165 size_t length
, buflen
;
168 length
= offsetof(struct ctdb_reply_call_wire
, data
) + c
->data
.dsize
;
170 ret
= allocate_pkt(mem_ctx
, length
, &buf
, &buflen
);
175 wire
= (struct ctdb_reply_call_wire
*)buf
;
178 memcpy(&wire
->hdr
, h
, sizeof(struct ctdb_req_header
));
180 wire
->status
= c
->status
;
181 wire
->datalen
= c
->data
.dsize
;
182 if (c
->data
.dsize
> 0) {
183 memcpy(wire
->data
, c
->data
.dptr
, c
->data
.dsize
);
191 int ctdb_reply_call_pull(uint8_t *pkt
, size_t pkt_len
,
192 struct ctdb_req_header
*h
,
194 struct ctdb_reply_call
*c
)
196 struct ctdb_reply_call_wire
*wire
;
199 length
= offsetof(struct ctdb_reply_call_wire
, data
);
200 if (pkt_len
< length
) {
204 wire
= (struct ctdb_reply_call_wire
*)pkt
;
206 if (pkt_len
< length
+ wire
->datalen
) {
210 memcpy(h
, &wire
->hdr
, sizeof(struct ctdb_req_header
));
212 c
->status
= wire
->status
;
213 c
->data
.dsize
= wire
->datalen
;
214 if (wire
->datalen
> 0) {
215 c
->data
.dptr
= talloc_memdup(mem_ctx
, wire
->data
,
217 if (c
->data
.dptr
== NULL
) {
225 int ctdb_reply_error_push(struct ctdb_req_header
*h
, struct ctdb_reply_error
*c
,
226 TALLOC_CTX
*mem_ctx
, uint8_t **pkt
, size_t *pkt_len
)
228 struct ctdb_reply_error_wire
*wire
;
230 size_t length
, buflen
;
233 length
= offsetof(struct ctdb_reply_error_wire
, msg
) + c
->msg
.dsize
;
235 ret
= allocate_pkt(mem_ctx
, length
, &buf
, &buflen
);
240 wire
= (struct ctdb_reply_error_wire
*)buf
;
243 memcpy(&wire
->hdr
, h
, sizeof(struct ctdb_req_header
));
245 wire
->status
= c
->status
;
246 wire
->msglen
= c
->msg
.dsize
;
247 if (c
->msg
.dsize
> 0) {
248 memcpy(wire
->msg
, c
->msg
.dptr
, c
->msg
.dsize
);
256 int ctdb_reply_error_pull(uint8_t *pkt
, size_t pkt_len
,
257 struct ctdb_req_header
*h
,
259 struct ctdb_reply_error
*c
)
261 struct ctdb_reply_error_wire
*wire
;
264 length
= offsetof(struct ctdb_reply_error_wire
, msg
);
265 if (pkt_len
< length
) {
269 wire
= (struct ctdb_reply_error_wire
*)pkt
;
271 if (pkt_len
< length
+ wire
->msglen
) {
275 memcpy(h
, &wire
->hdr
, sizeof(struct ctdb_req_header
));
277 c
->status
= wire
->status
;
278 c
->msg
.dsize
= wire
->msglen
;
279 if (wire
->msglen
> 0) {
280 c
->msg
.dptr
= talloc_memdup(mem_ctx
, wire
->msg
, wire
->msglen
);
281 if (c
->msg
.dptr
== NULL
) {
289 int ctdb_req_dmaster_push(struct ctdb_req_header
*h
, struct ctdb_req_dmaster
*c
,
290 TALLOC_CTX
*mem_ctx
, uint8_t **pkt
, size_t *pkt_len
)
292 struct ctdb_req_dmaster_wire
*wire
;
294 size_t length
, buflen
;
297 length
= offsetof(struct ctdb_req_dmaster_wire
, data
) +
298 c
->key
.dsize
+ c
->data
.dsize
;
300 ret
= allocate_pkt(mem_ctx
, length
, &buf
, &buflen
);
305 wire
= (struct ctdb_req_dmaster_wire
*)buf
;
308 memcpy(&wire
->hdr
, h
, sizeof(struct ctdb_req_header
));
310 wire
->db_id
= c
->db_id
;
312 wire
->dmaster
= c
->dmaster
;
313 wire
->keylen
= c
->key
.dsize
;
314 if (c
->key
.dsize
> 0) {
315 memcpy(wire
->data
, c
->key
.dptr
, c
->key
.dsize
);
317 wire
->datalen
= c
->data
.dsize
;
318 if (c
->data
.dsize
> 0) {
319 memcpy(wire
->data
+ c
->key
.dsize
, c
->data
.dptr
, c
->data
.dsize
);
327 int ctdb_req_dmaster_pull(uint8_t *pkt
, size_t pkt_len
,
328 struct ctdb_req_header
*h
,
330 struct ctdb_req_dmaster
*c
)
332 struct ctdb_req_dmaster_wire
*wire
;
335 length
= offsetof(struct ctdb_req_dmaster_wire
, data
);
336 if (pkt_len
< length
) {
340 wire
= (struct ctdb_req_dmaster_wire
*)pkt
;
342 if (pkt_len
< length
+ wire
->keylen
+ wire
->datalen
) {
346 memcpy(h
, &wire
->hdr
, sizeof(struct ctdb_req_header
));
348 c
->db_id
= wire
->db_id
;
350 c
->dmaster
= wire
->dmaster
;
351 c
->key
.dsize
= wire
->keylen
;
352 c
->key
.dptr
= talloc_memdup(mem_ctx
, wire
->data
, wire
->keylen
);
353 if (c
->key
.dptr
== NULL
) {
356 c
->data
.dsize
= wire
->datalen
;
357 if (wire
->datalen
> 0) {
358 c
->data
.dptr
= talloc_memdup(mem_ctx
, wire
->data
+ wire
->keylen
,
360 if (c
->data
.dptr
== NULL
) {
361 talloc_free(c
->key
.dptr
);
369 int ctdb_reply_dmaster_push(struct ctdb_req_header
*h
,
370 struct ctdb_reply_dmaster
*c
,
371 TALLOC_CTX
*mem_ctx
, uint8_t **pkt
, size_t *pkt_len
)
373 struct ctdb_reply_dmaster_wire
*wire
;
375 size_t length
, buflen
;
378 length
= offsetof(struct ctdb_reply_dmaster_wire
, data
) +
379 c
->key
.dsize
+ c
->data
.dsize
;
381 ret
= allocate_pkt(mem_ctx
, length
, &buf
, &buflen
);
386 wire
= (struct ctdb_reply_dmaster_wire
*)buf
;
389 memcpy(&wire
->hdr
, h
, sizeof(struct ctdb_req_header
));
391 wire
->db_id
= c
->db_id
;
393 wire
->keylen
= c
->key
.dsize
;
394 if (c
->key
.dsize
> 0) {
395 memcpy(wire
->data
, c
->key
.dptr
, c
->key
.dsize
);
397 wire
->datalen
= c
->data
.dsize
;
398 if (c
->data
.dsize
> 0) {
399 memcpy(wire
->data
+ c
->key
.dsize
, c
->data
.dptr
, c
->data
.dsize
);
407 int ctdb_reply_dmaster_pull(uint8_t *pkt
, size_t pkt_len
,
408 struct ctdb_req_header
*h
,
410 struct ctdb_reply_dmaster
*c
)
412 struct ctdb_reply_dmaster_wire
*wire
;
415 length
= offsetof(struct ctdb_reply_dmaster_wire
, data
);
416 if (pkt_len
< length
) {
420 wire
= (struct ctdb_reply_dmaster_wire
*)pkt
;
422 if (pkt_len
< length
+ wire
->keylen
+ wire
->datalen
) {
426 memcpy(h
, &wire
->hdr
, sizeof(struct ctdb_req_header
));
428 c
->db_id
= wire
->db_id
;
430 c
->key
.dsize
= wire
->keylen
;
431 c
->key
.dptr
= talloc_memdup(mem_ctx
, wire
->data
, wire
->keylen
);
432 if (c
->key
.dptr
== NULL
) {
435 c
->data
.dsize
= wire
->datalen
;
436 if (wire
->datalen
> 0) {
437 c
->data
.dptr
= talloc_memdup(mem_ctx
, wire
->data
+ wire
->keylen
,
439 if (c
->data
.dptr
== NULL
) {
440 talloc_free(c
->key
.dptr
);