ctdb-scripts: Drop CTDB_NOTIFY_SCRIPT configuration option
[kai/samba-autobuild/.git] / ctdb / protocol / protocol_call.c
1 /*
2    CTDB protocol marshalling
3
4    Copyright (C) Amitay Isaacs  2015
5
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.
10
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.
15
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/>.
18 */
19
20 #include "replace.h"
21 #include "system/network.h"
22
23 #include <talloc.h>
24 #include <tdb.h>
25
26 #include "protocol.h"
27 #include "protocol_api.h"
28 #include "protocol_private.h"
29
30 size_t ctdb_req_call_len(struct ctdb_req_header *h, struct ctdb_req_call *c)
31 {
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);
39 }
40
41 int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c,
42                        uint8_t *buf, size_t *buflen)
43 {
44         size_t offset = 0;
45         size_t length, np;
46         uint32_t u32;
47
48         if (c->key.dsize == 0) {
49                 return EINVAL;
50         }
51
52         length = ctdb_req_call_len(h, c);
53         if (*buflen < length) {
54                 *buflen = length;
55                 return EMSGSIZE;
56         }
57
58         h->length = *buflen;
59         ctdb_req_header_push(h, buf+offset, &np);
60         offset += np;
61
62         ctdb_uint32_push(&c->flags, buf+offset, &np);
63         offset += np;
64
65         ctdb_uint32_push(&c->db_id, buf+offset, &np);
66         offset += np;
67
68         ctdb_uint32_push(&c->callid, buf+offset, &np);
69         offset += np;
70
71         ctdb_uint32_push(&c->hopcount, buf+offset, &np);
72         offset += np;
73
74         u32 = ctdb_tdb_data_len(&c->key);
75         ctdb_uint32_push(&u32, buf+offset, &np);
76         offset += np;
77
78         u32 = ctdb_tdb_data_len(&c->calldata);
79         ctdb_uint32_push(&u32, buf+offset, &np);
80         offset += np;
81
82         ctdb_tdb_data_push(&c->key, buf+offset, &np);
83         offset += np;
84
85         ctdb_tdb_data_push(&c->calldata, buf+offset, &np);
86         offset += np;
87
88         return 0;
89 }
90
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)
95 {
96         struct ctdb_req_header header;
97         size_t offset = 0, np;
98         uint32_t u32;
99         int ret;
100
101         ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
102         if (ret != 0) {
103                 return ret;
104         }
105         offset += np;
106
107         if (h != NULL) {
108                 *h = header;
109         }
110
111         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->flags, &np);
112         if (ret != 0) {
113                 return ret;
114         }
115         offset += np;
116
117         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->db_id, &np);
118         if (ret != 0) {
119                 return ret;
120         }
121         offset += np;
122
123         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->callid, &np);
124         if (ret != 0) {
125                 return ret;
126         }
127         offset += np;
128
129         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->hopcount, &np);
130         if (ret != 0) {
131                 return ret;
132         }
133         offset += np;
134
135         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
136         if (ret != 0) {
137                 return ret;
138         }
139         offset += np;
140         c->key.dsize = u32;
141
142         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
143         if (ret != 0) {
144                 return ret;
145         }
146         offset += np;
147         c->calldata.dsize = u32;
148
149         if (buflen-offset < c->key.dsize) {
150                 return EMSGSIZE;
151         }
152
153         ret = ctdb_tdb_data_pull(buf+offset, c->key.dsize, mem_ctx, &c->key,
154                                  &np);
155         if (ret != 0) {
156                 return ret;
157         }
158         offset += np;
159
160         if (buflen-offset < c->calldata.dsize) {
161                 return EMSGSIZE;
162         }
163
164         ret = ctdb_tdb_data_pull(buf+offset, c->calldata.dsize,
165                                  mem_ctx, &c->calldata, &np);
166         if (ret != 0) {
167                 return ret;
168         }
169         offset += np;
170
171         return 0;
172 }
173
174 size_t ctdb_reply_call_len(struct ctdb_req_header *h,
175                            struct ctdb_reply_call *c)
176 {
177         return ctdb_req_header_len(h) +
178                 ctdb_int32_len(&c->status) +
179                 ctdb_tdb_datan_len(&c->data);
180 }
181
182 int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c,
183                          uint8_t *buf, size_t *buflen)
184 {
185         size_t offset = 0, np;
186         size_t length;
187
188         length = ctdb_reply_call_len(h, c);
189         if (*buflen < length) {
190                 *buflen = length;
191                 return EMSGSIZE;
192         }
193
194         h->length = *buflen;
195         ctdb_req_header_push(h, buf+offset, &np);
196         offset += np;
197
198         ctdb_int32_push(&c->status, buf+offset, &np);
199         offset += np;
200
201         ctdb_tdb_datan_push(&c->data, buf+offset, &np);
202         offset += np;
203
204         return 0;
205 }
206
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)
211 {
212         struct ctdb_req_header header;
213         size_t offset = 0, np;
214         int ret;
215
216         ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
217         if (ret != 0) {
218                 return ret;
219         }
220         offset += np;
221
222         if (h != NULL) {
223                 *h = header;
224         }
225
226         ret = ctdb_int32_pull(buf+offset, buflen-offset, &c->status, &np);
227         if (ret != 0) {
228                 return ret;
229         }
230         offset += np;
231
232         ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset,
233                                   mem_ctx, &c->data, &np);
234         if (ret != 0) {
235                 return ret;
236         }
237         offset += np;
238
239         return 0;
240 }
241
242 size_t ctdb_reply_error_len(struct ctdb_req_header *h,
243                             struct ctdb_reply_error *c)
244 {
245         return ctdb_req_header_len(h) +
246                 ctdb_int32_len(&c->status) +
247                 ctdb_tdb_datan_len(&c->msg);
248 }
249
250 int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c,
251                           uint8_t *buf, size_t *buflen)
252 {
253         size_t offset = 0, np;
254         size_t length;
255
256         length = ctdb_reply_error_len(h, c);
257         if (*buflen < length) {
258                 *buflen = length;
259                 return EMSGSIZE;
260         }
261
262         h->length = *buflen;
263         ctdb_req_header_push(h, buf+offset, &np);
264         offset += np;
265
266         ctdb_int32_push(&c->status, buf+offset, &np);
267         offset += np;
268
269         ctdb_tdb_datan_push(&c->msg, buf+offset, &np);
270         offset += np;
271
272         return 0;
273 }
274
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)
279 {
280         struct ctdb_req_header header;
281         size_t offset = 0, np;
282         int ret;
283
284         ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
285         if (ret != 0) {
286                 return ret;
287         }
288         offset += np;
289
290         if (h != NULL) {
291                 *h = header;
292         }
293
294         ret = ctdb_int32_pull(buf+offset, buflen-offset, &c->status, &np);
295         if (ret != 0) {
296                 return ret;
297         }
298         offset += np;
299
300         ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, mem_ctx, &c->msg,
301                                   &np);
302         if (ret != 0) {
303                 return ret;
304         }
305         offset += np;
306
307         return 0;
308 }
309
310 size_t ctdb_req_dmaster_len(struct ctdb_req_header *h,
311                             struct ctdb_req_dmaster *c)
312 {
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);
320 }
321
322 int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c,
323                           uint8_t *buf, size_t *buflen)
324 {
325         size_t offset = 0, np;
326         size_t length;
327         uint32_t u32;
328
329         length = ctdb_req_dmaster_len(h, c);
330         if (*buflen < length) {
331                 *buflen = length;
332                 return EMSGSIZE;
333         }
334
335         h->length = *buflen;
336         ctdb_req_header_push(h, buf+offset, &np);
337         offset += np;
338
339         ctdb_uint32_push(&c->db_id, buf+offset, &np);
340         offset += np;
341
342         ctdb_padding_push(4, buf+offset, &np);
343         offset += np;
344
345         ctdb_uint64_push(&c->rsn, buf+offset, &np);
346         offset += np;
347
348         ctdb_uint32_push(&c->dmaster, buf+offset, &np);
349         offset += np;
350
351         u32 = ctdb_tdb_data_len(&c->key);
352         ctdb_uint32_push(&u32, buf+offset, &np);
353         offset += np;
354
355         u32 = ctdb_tdb_data_len(&c->data);
356         ctdb_uint32_push(&u32, buf+offset, &np);
357         offset += np;
358
359         ctdb_tdb_data_push(&c->key, buf+offset, &np);
360         offset += np;
361
362         ctdb_tdb_data_push(&c->data, buf+offset, &np);
363         offset += np;
364
365         return 0;
366 }
367
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)
372 {
373         struct ctdb_req_header header;
374         size_t offset = 0, np;
375         uint32_t u32;
376         int ret;
377
378         ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
379         if (ret != 0) {
380                 return ret;
381         }
382         offset += np;
383
384         if (h != NULL) {
385                 *h = header;
386         }
387
388         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->db_id, &np);
389         if (ret != 0) {
390                 return ret;
391         }
392         offset += np;
393
394         ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
395         if (ret != 0) {
396                 return ret;
397         }
398         offset += np;
399
400         ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->rsn, &np);
401         if (ret != 0) {
402                 return ret;
403         }
404         offset += np;
405
406         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->dmaster, &np);
407         if (ret != 0) {
408                 return ret;
409         }
410         offset += np;
411
412         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
413         if (ret != 0) {
414                 return ret;
415         }
416         offset += np;
417         c->key.dsize = u32;
418
419         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
420         if (ret != 0) {
421                 return ret;
422         }
423         offset += np;
424         c->data.dsize = u32;
425
426         if (buflen-offset < c->key.dsize) {
427                 return EMSGSIZE;
428         }
429
430         ret = ctdb_tdb_data_pull(buf+offset, c->key.dsize, mem_ctx, &c->key,
431                                  &np);
432         if (ret != 0) {
433                 return ret;
434         }
435         offset += np;
436
437         if (buflen-offset < c->data.dsize) {
438                 return EMSGSIZE;
439         }
440
441         ret = ctdb_tdb_data_pull(buf+offset, c->data.dsize, mem_ctx, &c->data,
442                                  &np);
443         if (ret != 0) {
444                 return ret;
445         }
446         offset += np;
447
448         return 0;
449 }
450
451 size_t ctdb_reply_dmaster_len(struct ctdb_req_header *h,
452                               struct ctdb_reply_dmaster *c)
453 {
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);
460 }
461
462 int ctdb_reply_dmaster_push(struct ctdb_req_header *h,
463                             struct ctdb_reply_dmaster *c,
464                             uint8_t *buf, size_t *buflen)
465 {
466         size_t offset = 0, np;
467         size_t length;
468         uint32_t u32;
469
470         length = ctdb_reply_dmaster_len(h, c);
471         if (*buflen < length) {
472                 *buflen = length;
473                 return EMSGSIZE;
474         }
475
476         h->length = *buflen;
477         ctdb_req_header_push(h, buf+offset, &np);
478         offset += np;
479
480         ctdb_uint32_push(&c->db_id, buf+offset, &np);
481         offset += np;
482
483         ctdb_padding_push(4, buf+offset, &np);
484         offset += np;
485
486         ctdb_uint64_push(&c->rsn, buf+offset, &np);
487         offset += np;
488
489         u32 = ctdb_tdb_data_len(&c->key);
490         ctdb_uint32_push(&u32, buf+offset, &np);
491         offset += np;
492
493         u32 = ctdb_tdb_data_len(&c->data);
494         ctdb_uint32_push(&u32, buf+offset, &np);
495         offset += np;
496
497         ctdb_tdb_data_push(&c->key, buf+offset, &np);
498         offset += np;
499
500         ctdb_tdb_data_push(&c->data, buf+offset, &np);
501         offset += np;
502
503         return 0;
504 }
505
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)
510 {
511         struct ctdb_req_header header;
512         size_t offset = 0, np;
513         uint32_t u32;
514         int ret;
515
516         ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
517         if (ret != 0) {
518                 return ret;
519         }
520         offset += np;
521
522         if (h != NULL) {
523                 *h = header;
524         }
525
526         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->db_id, &np);
527         if (ret != 0) {
528                 return ret;
529         }
530         offset += np;
531
532         ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
533         if (ret != 0) {
534                 return ret;
535         }
536         offset += np;
537
538         ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->rsn, &np);
539         if (ret != 0) {
540                 return ret;
541         }
542         offset += np;
543
544         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
545         if (ret != 0) {
546                 return ret;
547         }
548         offset += np;
549         c->key.dsize = u32;
550
551         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
552         if (ret != 0) {
553                 return ret;
554         }
555         offset += np;
556         c->data.dsize = u32;
557
558         if (buflen-offset < c->key.dsize) {
559                 return EMSGSIZE;
560         }
561
562         ret = ctdb_tdb_data_pull(buf+offset, c->key.dsize, mem_ctx, &c->key,
563                                  &np);
564         if (ret != 0) {
565                 return ret;
566         }
567         offset += np;
568
569         if (buflen-offset < c->data.dsize) {
570                 return EMSGSIZE;
571         }
572
573         ret = ctdb_tdb_data_pull(buf+offset, c->data.dsize, mem_ctx, &c->data,
574                                  &np);
575         if (ret != 0) {
576                 return ret;
577         }
578         offset += np;
579
580         return 0;
581 }