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 size_t ctdb_req_call_len(struct ctdb_req_header
*h
, struct ctdb_req_call
*c
)
76 return offsetof(struct ctdb_req_call_wire
, data
) +
77 ctdb_tdb_data_len(c
->key
) + ctdb_tdb_data_len(c
->calldata
);
80 int ctdb_req_call_push(struct ctdb_req_header
*h
, struct ctdb_req_call
*c
,
81 uint8_t *buf
, size_t *buflen
)
83 struct ctdb_req_call_wire
*wire
=
84 (struct ctdb_req_call_wire
*)buf
;
87 if (c
->key
.dsize
== 0) {
91 length
= ctdb_req_call_len(h
, c
);
92 if (*buflen
< length
) {
98 ctdb_req_header_push(h
, (uint8_t *)&wire
->hdr
);
100 wire
->flags
= c
->flags
;
101 wire
->db_id
= c
->db_id
;
102 wire
->callid
= c
->callid
;
103 wire
->hopcount
= c
->hopcount
;
104 wire
->keylen
= ctdb_tdb_data_len(c
->key
);
105 wire
->calldatalen
= ctdb_tdb_data_len(c
->calldata
);
106 ctdb_tdb_data_push(c
->key
, wire
->data
);
107 ctdb_tdb_data_push(c
->calldata
, wire
->data
+ wire
->keylen
);
112 int ctdb_req_call_pull(uint8_t *buf
, size_t buflen
,
113 struct ctdb_req_header
*h
,
115 struct ctdb_req_call
*c
)
117 struct ctdb_req_call_wire
*wire
=
118 (struct ctdb_req_call_wire
*)buf
;
122 length
= offsetof(struct ctdb_req_call_wire
, data
);
123 if (buflen
< length
) {
126 if (wire
->keylen
> buflen
|| wire
->calldatalen
> buflen
) {
129 if (length
+ wire
->keylen
< length
) {
132 if (length
+ wire
->keylen
+ wire
->calldatalen
< length
) {
135 if (buflen
< length
+ wire
->keylen
+ wire
->calldatalen
) {
140 ret
= ctdb_req_header_pull((uint8_t *)&wire
->hdr
, buflen
, h
);
146 c
->flags
= wire
->flags
;
147 c
->db_id
= wire
->db_id
;
148 c
->callid
= wire
->callid
;
149 c
->hopcount
= wire
->hopcount
;
151 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->keylen
, mem_ctx
, &c
->key
);
156 ret
= ctdb_tdb_data_pull(wire
->data
+ wire
->keylen
, wire
->calldatalen
,
157 mem_ctx
, &c
->calldata
);
165 size_t ctdb_reply_call_len(struct ctdb_req_header
*h
,
166 struct ctdb_reply_call
*c
)
168 return offsetof(struct ctdb_reply_call_wire
, data
) +
169 ctdb_tdb_data_len(c
->data
);
172 int ctdb_reply_call_push(struct ctdb_req_header
*h
, struct ctdb_reply_call
*c
,
173 uint8_t *buf
, size_t *buflen
)
175 struct ctdb_reply_call_wire
*wire
=
176 (struct ctdb_reply_call_wire
*)buf
;
179 length
= ctdb_reply_call_len(h
, c
);
180 if (*buflen
< length
) {
186 ctdb_req_header_push(h
, (uint8_t *)&wire
->hdr
);
188 wire
->status
= c
->status
;
189 wire
->datalen
= ctdb_tdb_data_len(c
->data
);
190 ctdb_tdb_data_push(c
->data
, wire
->data
);
195 int ctdb_reply_call_pull(uint8_t *buf
, size_t buflen
,
196 struct ctdb_req_header
*h
,
198 struct ctdb_reply_call
*c
)
200 struct ctdb_reply_call_wire
*wire
=
201 (struct ctdb_reply_call_wire
*)buf
;
205 length
= offsetof(struct ctdb_reply_call_wire
, data
);
206 if (buflen
< length
) {
209 if (wire
->datalen
> buflen
) {
212 if (length
+ wire
->datalen
< length
) {
215 if (buflen
< length
+ wire
->datalen
) {
220 ret
= ctdb_req_header_pull((uint8_t *)&wire
->hdr
, buflen
, h
);
226 c
->status
= wire
->status
;
228 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->datalen
, mem_ctx
, &c
->data
);
236 size_t ctdb_reply_error_len(struct ctdb_req_header
*h
,
237 struct ctdb_reply_error
*c
)
239 return offsetof(struct ctdb_reply_error_wire
, msg
) +
240 ctdb_tdb_data_len(c
->msg
);
243 int ctdb_reply_error_push(struct ctdb_req_header
*h
, struct ctdb_reply_error
*c
,
244 uint8_t *buf
, size_t *buflen
)
246 struct ctdb_reply_error_wire
*wire
=
247 (struct ctdb_reply_error_wire
*)buf
;
250 length
= ctdb_reply_error_len(h
, c
);
251 if (*buflen
< length
) {
257 ctdb_req_header_push(h
, (uint8_t *)&wire
->hdr
);
259 wire
->status
= c
->status
;
260 wire
->msglen
= ctdb_tdb_data_len(c
->msg
);
261 ctdb_tdb_data_push(c
->msg
, wire
->msg
);
266 int ctdb_reply_error_pull(uint8_t *buf
, size_t buflen
,
267 struct ctdb_req_header
*h
,
269 struct ctdb_reply_error
*c
)
271 struct ctdb_reply_error_wire
*wire
=
272 (struct ctdb_reply_error_wire
*)buf
;
276 length
= offsetof(struct ctdb_reply_error_wire
, msg
);
277 if (buflen
< length
) {
280 if (wire
->msglen
> buflen
) {
283 if (length
+ wire
->msglen
< length
) {
286 if (buflen
< length
+ wire
->msglen
) {
291 ret
= ctdb_req_header_pull((uint8_t *)&wire
->hdr
, buflen
, h
);
297 c
->status
= wire
->status
;
299 ret
= ctdb_tdb_data_pull(wire
->msg
, wire
->msglen
, mem_ctx
, &c
->msg
);
307 size_t ctdb_req_dmaster_len(struct ctdb_req_header
*h
,
308 struct ctdb_req_dmaster
*c
)
310 return offsetof(struct ctdb_req_dmaster_wire
, data
) +
311 ctdb_tdb_data_len(c
->key
) + ctdb_tdb_data_len(c
->data
);
314 int ctdb_req_dmaster_push(struct ctdb_req_header
*h
, struct ctdb_req_dmaster
*c
,
315 uint8_t *buf
, size_t *buflen
)
317 struct ctdb_req_dmaster_wire
*wire
=
318 (struct ctdb_req_dmaster_wire
*)buf
;
321 length
= ctdb_req_dmaster_len(h
, c
);
322 if (*buflen
< length
) {
328 ctdb_req_header_push(h
, (uint8_t *)&wire
->hdr
);
330 wire
->db_id
= c
->db_id
;
332 wire
->dmaster
= c
->dmaster
;
333 wire
->keylen
= ctdb_tdb_data_len(c
->key
);
334 wire
->datalen
= ctdb_tdb_data_len(c
->data
);
335 ctdb_tdb_data_push(c
->key
, wire
->data
);
336 ctdb_tdb_data_push(c
->data
, wire
->data
+ wire
->keylen
);
341 int ctdb_req_dmaster_pull(uint8_t *buf
, size_t buflen
,
342 struct ctdb_req_header
*h
,
344 struct ctdb_req_dmaster
*c
)
346 struct ctdb_req_dmaster_wire
*wire
=
347 (struct ctdb_req_dmaster_wire
*)buf
;
351 length
= offsetof(struct ctdb_req_dmaster_wire
, data
);
352 if (buflen
< length
) {
355 if (wire
->keylen
> buflen
|| wire
->datalen
> buflen
) {
358 if (length
+ wire
->keylen
< length
) {
361 if (length
+ wire
->keylen
+ wire
->datalen
< length
) {
364 if (buflen
< length
+ wire
->keylen
+ wire
->datalen
) {
369 ret
= ctdb_req_header_pull((uint8_t *)&wire
->hdr
, buflen
, h
);
375 c
->db_id
= wire
->db_id
;
377 c
->dmaster
= wire
->dmaster
;
379 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->keylen
, mem_ctx
, &c
->key
);
384 ret
= ctdb_tdb_data_pull(wire
->data
+ wire
->keylen
, wire
->datalen
,
393 size_t ctdb_reply_dmaster_len(struct ctdb_req_header
*h
,
394 struct ctdb_reply_dmaster
*c
)
396 return offsetof(struct ctdb_reply_dmaster_wire
, data
) +
397 ctdb_tdb_data_len(c
->key
) + ctdb_tdb_data_len(c
->data
);
400 int ctdb_reply_dmaster_push(struct ctdb_req_header
*h
,
401 struct ctdb_reply_dmaster
*c
,
402 uint8_t *buf
, size_t *buflen
)
404 struct ctdb_reply_dmaster_wire
*wire
=
405 (struct ctdb_reply_dmaster_wire
*)buf
;
408 length
= ctdb_reply_dmaster_len(h
, c
);
409 if (*buflen
< length
) {
415 ctdb_req_header_push(h
, (uint8_t *)&wire
->hdr
);
417 wire
->db_id
= c
->db_id
;
419 wire
->keylen
= ctdb_tdb_data_len(c
->key
);
420 wire
->datalen
= ctdb_tdb_data_len(c
->data
);
421 ctdb_tdb_data_push(c
->key
, wire
->data
);
422 ctdb_tdb_data_push(c
->data
, wire
->data
+ wire
->keylen
);
427 int ctdb_reply_dmaster_pull(uint8_t *buf
, size_t buflen
,
428 struct ctdb_req_header
*h
,
430 struct ctdb_reply_dmaster
*c
)
432 struct ctdb_reply_dmaster_wire
*wire
=
433 (struct ctdb_reply_dmaster_wire
*)buf
;
437 length
= offsetof(struct ctdb_reply_dmaster_wire
, data
);
438 if (buflen
< length
) {
441 if (wire
->keylen
> buflen
|| wire
->datalen
> buflen
) {
444 if (length
+ wire
->keylen
< length
) {
447 if (length
+ wire
->keylen
+ wire
->datalen
< length
) {
450 if (buflen
< length
+ wire
->keylen
+ wire
->datalen
) {
455 ret
= ctdb_req_header_pull((uint8_t *)&wire
->hdr
, buflen
, h
);
461 c
->db_id
= wire
->db_id
;
464 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->keylen
, mem_ctx
, &c
->key
);
469 ret
= ctdb_tdb_data_pull(wire
->data
+ wire
->keylen
, wire
->datalen
,