s3:libnetapi: Return error from RequestOfflineJoin
[Samba.git] / ctdb / protocol / protocol_call.c
blob393b1181bd200838ddf9ba3218c5e00a043b673a
1 /*
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/>.
20 #include "replace.h"
21 #include "system/network.h"
23 #include <talloc.h>
24 #include <tdb.h>
26 #include "protocol.h"
27 #include "protocol_api.h"
28 #include "protocol_private.h"
30 size_t ctdb_req_call_len(struct ctdb_req_header *h, struct ctdb_req_call *c)
32 return ctdb_req_header_len(h) +
33 ctdb_uint32_len(&c->flags) +
34 ctdb_uint32_len(&c->db_id) +
35 ctdb_uint32_len(&c->callid) +
36 ctdb_uint32_len(&c->hopcount) +
37 ctdb_tdb_datan_len(&c->key) +
38 ctdb_tdb_datan_len(&c->calldata);
41 int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c,
42 uint8_t *buf, size_t *buflen)
44 size_t offset = 0;
45 size_t length, np;
46 uint32_t u32;
48 if (c->key.dsize == 0) {
49 return EINVAL;
52 length = ctdb_req_call_len(h, c);
53 if (*buflen < length) {
54 *buflen = length;
55 return EMSGSIZE;
58 h->length = *buflen;
59 ctdb_req_header_push(h, buf+offset, &np);
60 offset += np;
62 ctdb_uint32_push(&c->flags, buf+offset, &np);
63 offset += np;
65 ctdb_uint32_push(&c->db_id, buf+offset, &np);
66 offset += np;
68 ctdb_uint32_push(&c->callid, buf+offset, &np);
69 offset += np;
71 ctdb_uint32_push(&c->hopcount, buf+offset, &np);
72 offset += np;
74 u32 = ctdb_tdb_data_len(&c->key);
75 ctdb_uint32_push(&u32, buf+offset, &np);
76 offset += np;
78 u32 = ctdb_tdb_data_len(&c->calldata);
79 ctdb_uint32_push(&u32, buf+offset, &np);
80 offset += np;
82 ctdb_tdb_data_push(&c->key, buf+offset, &np);
83 offset += np;
85 ctdb_tdb_data_push(&c->calldata, buf+offset, &np);
86 offset += np;
88 return 0;
91 int ctdb_req_call_pull(uint8_t *buf, size_t buflen,
92 struct ctdb_req_header *h,
93 TALLOC_CTX *mem_ctx,
94 struct ctdb_req_call *c)
96 struct ctdb_req_header header;
97 size_t offset = 0, np;
98 uint32_t u32;
99 int ret;
101 ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
102 if (ret != 0) {
103 return ret;
105 offset += np;
107 if (h != NULL) {
108 *h = header;
111 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->flags, &np);
112 if (ret != 0) {
113 return ret;
115 offset += np;
117 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->db_id, &np);
118 if (ret != 0) {
119 return ret;
121 offset += np;
123 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->callid, &np);
124 if (ret != 0) {
125 return ret;
127 offset += np;
129 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->hopcount, &np);
130 if (ret != 0) {
131 return ret;
133 offset += np;
135 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
136 if (ret != 0) {
137 return ret;
139 offset += np;
140 c->key.dsize = u32;
142 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
143 if (ret != 0) {
144 return ret;
146 offset += np;
147 c->calldata.dsize = u32;
149 if (buflen-offset < c->key.dsize) {
150 return EMSGSIZE;
153 ret = ctdb_tdb_data_pull(buf+offset, c->key.dsize, mem_ctx, &c->key,
154 &np);
155 if (ret != 0) {
156 return ret;
158 offset += np;
160 if (buflen-offset < c->calldata.dsize) {
161 return EMSGSIZE;
164 ret = ctdb_tdb_data_pull(buf+offset, c->calldata.dsize,
165 mem_ctx, &c->calldata, &np);
166 if (ret != 0) {
167 return ret;
169 offset += np;
171 return 0;
174 size_t ctdb_reply_call_len(struct ctdb_req_header *h,
175 struct ctdb_reply_call *c)
177 return ctdb_req_header_len(h) +
178 ctdb_int32_len(&c->status) +
179 ctdb_tdb_datan_len(&c->data);
182 int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c,
183 uint8_t *buf, size_t *buflen)
185 size_t offset = 0, np;
186 size_t length;
188 length = ctdb_reply_call_len(h, c);
189 if (*buflen < length) {
190 *buflen = length;
191 return EMSGSIZE;
194 h->length = *buflen;
195 ctdb_req_header_push(h, buf+offset, &np);
196 offset += np;
198 ctdb_int32_push(&c->status, buf+offset, &np);
199 offset += np;
201 ctdb_tdb_datan_push(&c->data, buf+offset, &np);
202 offset += np;
204 return 0;
207 int ctdb_reply_call_pull(uint8_t *buf, size_t buflen,
208 struct ctdb_req_header *h,
209 TALLOC_CTX *mem_ctx,
210 struct ctdb_reply_call *c)
212 struct ctdb_req_header header;
213 size_t offset = 0, np;
214 int ret;
216 ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
217 if (ret != 0) {
218 return ret;
220 offset += np;
222 if (h != NULL) {
223 *h = header;
226 ret = ctdb_int32_pull(buf+offset, buflen-offset, &c->status, &np);
227 if (ret != 0) {
228 return ret;
230 offset += np;
232 ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset,
233 mem_ctx, &c->data, &np);
234 if (ret != 0) {
235 return ret;
237 offset += np;
239 return 0;
242 size_t ctdb_reply_error_len(struct ctdb_req_header *h,
243 struct ctdb_reply_error *c)
245 return ctdb_req_header_len(h) +
246 ctdb_int32_len(&c->status) +
247 ctdb_tdb_datan_len(&c->msg);
250 int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c,
251 uint8_t *buf, size_t *buflen)
253 size_t offset = 0, np;
254 size_t length;
256 length = ctdb_reply_error_len(h, c);
257 if (*buflen < length) {
258 *buflen = length;
259 return EMSGSIZE;
262 h->length = *buflen;
263 ctdb_req_header_push(h, buf+offset, &np);
264 offset += np;
266 ctdb_int32_push(&c->status, buf+offset, &np);
267 offset += np;
269 ctdb_tdb_datan_push(&c->msg, buf+offset, &np);
270 offset += np;
272 return 0;
275 int ctdb_reply_error_pull(uint8_t *buf, size_t buflen,
276 struct ctdb_req_header *h,
277 TALLOC_CTX *mem_ctx,
278 struct ctdb_reply_error *c)
280 struct ctdb_req_header header;
281 size_t offset = 0, np;
282 int ret;
284 ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
285 if (ret != 0) {
286 return ret;
288 offset += np;
290 if (h != NULL) {
291 *h = header;
294 ret = ctdb_int32_pull(buf+offset, buflen-offset, &c->status, &np);
295 if (ret != 0) {
296 return ret;
298 offset += np;
300 ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, mem_ctx, &c->msg,
301 &np);
302 if (ret != 0) {
303 return ret;
305 offset += np;
307 return 0;
310 size_t ctdb_req_dmaster_len(struct ctdb_req_header *h,
311 struct ctdb_req_dmaster *c)
313 return ctdb_req_header_len(h) +
314 ctdb_uint32_len(&c->db_id) +
315 ctdb_padding_len(4) +
316 ctdb_uint64_len(&c->rsn) +
317 ctdb_uint32_len(&c->dmaster) +
318 ctdb_tdb_datan_len(&c->key) +
319 ctdb_tdb_datan_len(&c->data);
322 int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c,
323 uint8_t *buf, size_t *buflen)
325 size_t offset = 0, np;
326 size_t length;
327 uint32_t u32;
329 length = ctdb_req_dmaster_len(h, c);
330 if (*buflen < length) {
331 *buflen = length;
332 return EMSGSIZE;
335 h->length = *buflen;
336 ctdb_req_header_push(h, buf+offset, &np);
337 offset += np;
339 ctdb_uint32_push(&c->db_id, buf+offset, &np);
340 offset += np;
342 ctdb_padding_push(4, buf+offset, &np);
343 offset += np;
345 ctdb_uint64_push(&c->rsn, buf+offset, &np);
346 offset += np;
348 ctdb_uint32_push(&c->dmaster, buf+offset, &np);
349 offset += np;
351 u32 = ctdb_tdb_data_len(&c->key);
352 ctdb_uint32_push(&u32, buf+offset, &np);
353 offset += np;
355 u32 = ctdb_tdb_data_len(&c->data);
356 ctdb_uint32_push(&u32, buf+offset, &np);
357 offset += np;
359 ctdb_tdb_data_push(&c->key, buf+offset, &np);
360 offset += np;
362 ctdb_tdb_data_push(&c->data, buf+offset, &np);
363 offset += np;
365 return 0;
368 int ctdb_req_dmaster_pull(uint8_t *buf, size_t buflen,
369 struct ctdb_req_header *h,
370 TALLOC_CTX *mem_ctx,
371 struct ctdb_req_dmaster *c)
373 struct ctdb_req_header header;
374 size_t offset = 0, np;
375 uint32_t u32;
376 int ret;
378 ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
379 if (ret != 0) {
380 return ret;
382 offset += np;
384 if (h != NULL) {
385 *h = header;
388 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->db_id, &np);
389 if (ret != 0) {
390 return ret;
392 offset += np;
394 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
395 if (ret != 0) {
396 return ret;
398 offset += np;
400 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->rsn, &np);
401 if (ret != 0) {
402 return ret;
404 offset += np;
406 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->dmaster, &np);
407 if (ret != 0) {
408 return ret;
410 offset += np;
412 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
413 if (ret != 0) {
414 return ret;
416 offset += np;
417 c->key.dsize = u32;
419 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
420 if (ret != 0) {
421 return ret;
423 offset += np;
424 c->data.dsize = u32;
426 if (buflen-offset < c->key.dsize) {
427 return EMSGSIZE;
430 ret = ctdb_tdb_data_pull(buf+offset, c->key.dsize, mem_ctx, &c->key,
431 &np);
432 if (ret != 0) {
433 return ret;
435 offset += np;
437 if (buflen-offset < c->data.dsize) {
438 return EMSGSIZE;
441 ret = ctdb_tdb_data_pull(buf+offset, c->data.dsize, mem_ctx, &c->data,
442 &np);
443 if (ret != 0) {
444 return ret;
446 offset += np;
448 return 0;
451 size_t ctdb_reply_dmaster_len(struct ctdb_req_header *h,
452 struct ctdb_reply_dmaster *c)
454 return ctdb_req_header_len(h) +
455 ctdb_uint32_len(&c->db_id) +
456 ctdb_padding_len(4) +
457 ctdb_uint64_len(&c->rsn) +
458 ctdb_tdb_datan_len(&c->key) +
459 ctdb_tdb_datan_len(&c->data);
462 int ctdb_reply_dmaster_push(struct ctdb_req_header *h,
463 struct ctdb_reply_dmaster *c,
464 uint8_t *buf, size_t *buflen)
466 size_t offset = 0, np;
467 size_t length;
468 uint32_t u32;
470 length = ctdb_reply_dmaster_len(h, c);
471 if (*buflen < length) {
472 *buflen = length;
473 return EMSGSIZE;
476 h->length = *buflen;
477 ctdb_req_header_push(h, buf+offset, &np);
478 offset += np;
480 ctdb_uint32_push(&c->db_id, buf+offset, &np);
481 offset += np;
483 ctdb_padding_push(4, buf+offset, &np);
484 offset += np;
486 ctdb_uint64_push(&c->rsn, buf+offset, &np);
487 offset += np;
489 u32 = ctdb_tdb_data_len(&c->key);
490 ctdb_uint32_push(&u32, buf+offset, &np);
491 offset += np;
493 u32 = ctdb_tdb_data_len(&c->data);
494 ctdb_uint32_push(&u32, buf+offset, &np);
495 offset += np;
497 ctdb_tdb_data_push(&c->key, buf+offset, &np);
498 offset += np;
500 ctdb_tdb_data_push(&c->data, buf+offset, &np);
501 offset += np;
503 return 0;
506 int ctdb_reply_dmaster_pull(uint8_t *buf, size_t buflen,
507 struct ctdb_req_header *h,
508 TALLOC_CTX *mem_ctx,
509 struct ctdb_reply_dmaster *c)
511 struct ctdb_req_header header;
512 size_t offset = 0, np;
513 uint32_t u32;
514 int ret;
516 ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
517 if (ret != 0) {
518 return ret;
520 offset += np;
522 if (h != NULL) {
523 *h = header;
526 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->db_id, &np);
527 if (ret != 0) {
528 return ret;
530 offset += np;
532 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
533 if (ret != 0) {
534 return ret;
536 offset += np;
538 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->rsn, &np);
539 if (ret != 0) {
540 return ret;
542 offset += np;
544 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
545 if (ret != 0) {
546 return ret;
548 offset += np;
549 c->key.dsize = u32;
551 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
552 if (ret != 0) {
553 return ret;
555 offset += np;
556 c->data.dsize = u32;
558 if (buflen-offset < c->key.dsize) {
559 return EMSGSIZE;
562 ret = ctdb_tdb_data_pull(buf+offset, c->key.dsize, mem_ctx, &c->key,
563 &np);
564 if (ret != 0) {
565 return ret;
567 offset += np;
569 if (buflen-offset < c->data.dsize) {
570 return EMSGSIZE;
573 ret = ctdb_tdb_data_pull(buf+offset, c->data.dsize, mem_ctx, &c->data,
574 &np);
575 if (ret != 0) {
576 return ret;
578 offset += np;
580 return 0;