ctdb-protocol: Fix marshalling for ctdb_event_request_script_disable
[vlendec/samba-autobuild/.git] / ctdb / protocol / protocol_message.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
31 static size_t ctdb_message_data_len(union ctdb_message_data *mdata,
32                                     uint64_t srvid)
33 {
34         size_t len = 0;
35
36         switch (srvid) {
37         case CTDB_SRVID_BANNING:
38                 len = ctdb_uint32_len(&mdata->pnn);
39                 break;
40
41         case CTDB_SRVID_ELECTION:
42                 len = ctdb_election_message_len(mdata->election);
43                 break;
44
45         case CTDB_SRVID_RECONFIGURE:
46                 break;
47
48         case CTDB_SRVID_RELEASE_IP:
49                 len = ctdb_string_len(&mdata->ipaddr);
50                 break;
51
52         case CTDB_SRVID_TAKE_IP:
53                 len = ctdb_string_len(&mdata->ipaddr);
54                 break;
55
56         case CTDB_SRVID_SET_NODE_FLAGS:
57                 len = ctdb_node_flag_change_len(mdata->flag_change);
58                 break;
59
60         case CTDB_SRVID_RECD_UPDATE_IP:
61                 len = ctdb_public_ip_len(mdata->pubip);
62                 break;
63
64         case CTDB_SRVID_VACUUM_FETCH:
65                 len = ctdb_rec_buffer_len(mdata->recbuf);
66                 break;
67
68         case CTDB_SRVID_DETACH_DATABASE:
69                 len = ctdb_uint32_len(&mdata->db_id);
70                 break;
71
72         case CTDB_SRVID_MEM_DUMP:
73                 len = ctdb_srvid_message_len(mdata->msg);
74                 break;
75
76         case CTDB_SRVID_GETLOG:
77                 break;
78
79         case CTDB_SRVID_CLEARLOG:
80                 break;
81
82         case CTDB_SRVID_PUSH_NODE_FLAGS:
83                 len = ctdb_node_flag_change_len(mdata->flag_change);
84                 break;
85
86         case CTDB_SRVID_RELOAD_NODES:
87                 break;
88
89         case CTDB_SRVID_TAKEOVER_RUN:
90                 len = ctdb_srvid_message_len(mdata->msg);
91                 break;
92
93         case CTDB_SRVID_REBALANCE_NODE:
94                 len = ctdb_uint32_len(&mdata->pnn);
95                 break;
96
97         case CTDB_SRVID_DISABLE_TAKEOVER_RUNS:
98                 len = ctdb_disable_message_len(mdata->disable);
99                 break;
100
101         case CTDB_SRVID_DISABLE_RECOVERIES:
102                 len = ctdb_disable_message_len(mdata->disable);
103                 break;
104
105         case CTDB_SRVID_DISABLE_IP_CHECK:
106                 len = ctdb_uint32_len(&mdata->timeout);
107                 break;
108
109         default:
110                 len = ctdb_tdb_data_len(&mdata->data);
111                 break;
112         }
113
114         return len;
115 }
116
117 static void ctdb_message_data_push(union ctdb_message_data *mdata,
118                                    uint64_t srvid, uint8_t *buf,
119                                    size_t *npush)
120 {
121         size_t np = 0;
122
123         switch (srvid) {
124         case CTDB_SRVID_BANNING:
125                 ctdb_uint32_push(&mdata->pnn, buf, &np);
126                 break;
127
128         case CTDB_SRVID_ELECTION:
129                 ctdb_election_message_push(mdata->election, buf, &np);
130                 break;
131
132         case CTDB_SRVID_RECONFIGURE:
133                 break;
134
135         case CTDB_SRVID_RELEASE_IP:
136                 ctdb_string_push(&mdata->ipaddr, buf, &np);
137                 break;
138
139         case CTDB_SRVID_TAKE_IP:
140                 ctdb_string_push(&mdata->ipaddr, buf, &np);
141                 break;
142
143         case CTDB_SRVID_SET_NODE_FLAGS:
144                 ctdb_node_flag_change_push(mdata->flag_change, buf, &np);
145                 break;
146
147         case CTDB_SRVID_RECD_UPDATE_IP:
148                 ctdb_public_ip_push(mdata->pubip, buf, &np);
149                 break;
150
151         case CTDB_SRVID_VACUUM_FETCH:
152                 ctdb_rec_buffer_push(mdata->recbuf, buf, &np);
153                 break;
154
155         case CTDB_SRVID_DETACH_DATABASE:
156                 ctdb_uint32_push(&mdata->db_id, buf, &np);
157                 break;
158
159         case CTDB_SRVID_MEM_DUMP:
160                 ctdb_srvid_message_push(mdata->msg, buf, &np);
161                 break;
162
163         case CTDB_SRVID_GETLOG:
164                 break;
165
166         case CTDB_SRVID_CLEARLOG:
167                 break;
168
169         case CTDB_SRVID_PUSH_NODE_FLAGS:
170                 ctdb_node_flag_change_push(mdata->flag_change, buf, &np);
171                 break;
172
173         case CTDB_SRVID_RELOAD_NODES:
174                 break;
175
176         case CTDB_SRVID_TAKEOVER_RUN:
177                 ctdb_srvid_message_push(mdata->msg, buf, &np);
178                 break;
179
180         case CTDB_SRVID_REBALANCE_NODE:
181                 ctdb_uint32_push(&mdata->pnn, buf, &np);
182                 break;
183
184         case CTDB_SRVID_DISABLE_TAKEOVER_RUNS:
185                 ctdb_disable_message_push(mdata->disable, buf, &np);
186                 break;
187
188         case CTDB_SRVID_DISABLE_RECOVERIES:
189                 ctdb_disable_message_push(mdata->disable, buf, &np);
190                 break;
191
192         case CTDB_SRVID_DISABLE_IP_CHECK:
193                 ctdb_uint32_push(&mdata->timeout, buf, &np);
194                 break;
195
196         default:
197                 ctdb_tdb_data_push(&mdata->data, buf, &np);
198                 break;
199         }
200
201         *npush = np;
202 }
203
204 static int ctdb_message_data_pull(uint8_t *buf, size_t buflen,
205                                   uint64_t srvid, TALLOC_CTX *mem_ctx,
206                                   union ctdb_message_data *mdata,
207                                   size_t *npull)
208 {
209         int ret = 0;
210         size_t np = 0;
211
212         switch (srvid) {
213         case CTDB_SRVID_BANNING:
214                 ret = ctdb_uint32_pull(buf, buflen, &mdata->pnn, &np);
215                 break;
216
217         case CTDB_SRVID_ELECTION:
218                 ret = ctdb_election_message_pull(buf, buflen, mem_ctx,
219                                                  &mdata->election, &np);
220                 break;
221
222         case CTDB_SRVID_RECONFIGURE:
223                 break;
224
225         case CTDB_SRVID_RELEASE_IP:
226                 ret = ctdb_string_pull(buf, buflen, mem_ctx, &mdata->ipaddr,
227                                        &np);
228                 break;
229
230         case CTDB_SRVID_TAKE_IP:
231                 ret = ctdb_string_pull(buf, buflen, mem_ctx, &mdata->ipaddr,
232                                        &np);
233                 break;
234
235         case CTDB_SRVID_SET_NODE_FLAGS:
236                 ret = ctdb_node_flag_change_pull(buf, buflen, mem_ctx,
237                                                  &mdata->flag_change, &np);
238                 break;
239
240         case CTDB_SRVID_RECD_UPDATE_IP:
241                 ret = ctdb_public_ip_pull(buf, buflen, mem_ctx,
242                                           &mdata->pubip, &np);
243                 break;
244
245         case CTDB_SRVID_VACUUM_FETCH:
246                 ret = ctdb_rec_buffer_pull(buf, buflen, mem_ctx,
247                                            &mdata->recbuf, &np);
248                 break;
249
250         case CTDB_SRVID_DETACH_DATABASE:
251                 ret = ctdb_uint32_pull(buf, buflen, &mdata->db_id, &np);
252                 break;
253
254         case CTDB_SRVID_MEM_DUMP:
255                 ret = ctdb_srvid_message_pull(buf, buflen, mem_ctx,
256                                               &mdata->msg, &np);
257                 break;
258
259         case CTDB_SRVID_GETLOG:
260                 break;
261
262         case CTDB_SRVID_CLEARLOG:
263                 break;
264
265         case CTDB_SRVID_PUSH_NODE_FLAGS:
266                 ret = ctdb_node_flag_change_pull(buf, buflen, mem_ctx,
267                                                  &mdata->flag_change, &np);
268                 break;
269
270         case CTDB_SRVID_RELOAD_NODES:
271                 break;
272
273         case CTDB_SRVID_TAKEOVER_RUN:
274                 ret = ctdb_srvid_message_pull(buf, buflen, mem_ctx,
275                                               &mdata->msg, &np);
276                 break;
277
278         case CTDB_SRVID_REBALANCE_NODE:
279                 ret = ctdb_uint32_pull(buf, buflen, &mdata->pnn, &np);
280                 break;
281
282         case CTDB_SRVID_DISABLE_TAKEOVER_RUNS:
283                 ret = ctdb_disable_message_pull(buf, buflen, mem_ctx,
284                                                 &mdata->disable, &np);
285                 break;
286
287         case CTDB_SRVID_DISABLE_RECOVERIES:
288                 ret = ctdb_disable_message_pull(buf, buflen, mem_ctx,
289                                                 &mdata->disable, &np);
290                 break;
291
292         case CTDB_SRVID_DISABLE_IP_CHECK:
293                 ret = ctdb_uint32_pull(buf, buflen, &mdata->timeout, &np);
294                 break;
295
296         default:
297                 ret = ctdb_tdb_data_pull(buf, buflen, mem_ctx, &mdata->data,
298                                          &np);
299                 break;
300         }
301
302         if (ret != 0) {
303                 return ret;
304         }
305
306         *npull = np;
307         return 0;
308 }
309
310 size_t ctdb_req_message_len(struct ctdb_req_header *h,
311                             struct ctdb_req_message *c)
312 {
313         uint32_t u32 = ctdb_message_data_len(&c->data, c->srvid);
314
315         return ctdb_req_header_len(h) +
316                 ctdb_uint64_len(&c->srvid) +
317                 ctdb_uint32_len(&u32) + u32;
318 }
319
320 int ctdb_req_message_push(struct ctdb_req_header *h,
321                           struct ctdb_req_message *c,
322                           uint8_t *buf, size_t *buflen)
323 {
324         size_t offset = 0, np;
325         size_t length;
326         uint32_t u32;
327
328         length = ctdb_req_message_len(h, c);
329         if (*buflen < length) {
330                 *buflen = length;
331                 return EMSGSIZE;
332         }
333
334         h->length = *buflen;
335         ctdb_req_header_push(h, buf+offset, &np);
336         offset += np;
337
338         ctdb_uint64_push(&c->srvid, buf+offset, &np);
339         offset += np;
340
341         u32 = ctdb_message_data_len(&c->data, c->srvid);
342         ctdb_uint32_push(&u32, buf+offset, &np);
343         offset += np;
344
345         ctdb_message_data_push(&c->data, c->srvid, buf+offset, &np);
346         offset += np;
347
348         return 0;
349 }
350
351 int ctdb_req_message_pull(uint8_t *buf, size_t buflen,
352                           struct ctdb_req_header *h,
353                           TALLOC_CTX *mem_ctx,
354                           struct ctdb_req_message *c)
355 {
356         struct ctdb_req_header header;
357         size_t offset = 0, np;
358         uint32_t u32;
359         int ret;
360
361         ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
362         if (ret != 0) {
363                 return ret;
364         }
365         offset += np;
366
367         if (h != NULL) {
368                 *h = header;
369         }
370
371         ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->srvid, &np);
372         if (ret != 0) {
373                 return ret;
374         }
375         offset += np;
376
377         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
378         if (ret != 0) {
379                 return ret;
380         }
381         offset += np;
382
383         if (buflen-offset < u32) {
384                 return EMSGSIZE;
385         }
386
387         ret = ctdb_message_data_pull(buf+offset, u32, c->srvid,
388                                      mem_ctx, &c->data, &np);
389         if (ret != 0) {
390                 return ret;
391         }
392         offset += np;
393
394         return ret;
395 }
396
397 size_t ctdb_req_message_data_len(struct ctdb_req_header *h,
398                                  struct ctdb_req_message_data *c)
399 {
400         return ctdb_req_header_len(h) +
401                 ctdb_uint64_len(&c->srvid) +
402                 ctdb_tdb_datan_len(&c->data);
403 }
404
405 int ctdb_req_message_data_push(struct ctdb_req_header *h,
406                                struct ctdb_req_message_data *c,
407                                uint8_t *buf, size_t *buflen)
408 {
409         size_t offset = 0, np;
410         size_t length;
411
412         length = ctdb_req_message_data_len(h, c);
413         if (*buflen < length) {
414                 *buflen = length;
415                 return EMSGSIZE;
416         }
417
418         h->length = *buflen;
419         ctdb_req_header_push(h, buf+offset, &np);
420         offset += np;
421
422         ctdb_uint64_push(&c->srvid, buf+offset, &np);
423         offset += np;
424
425         ctdb_tdb_datan_push(&c->data, buf+offset, &np);
426         offset += np;
427
428         return 0;
429 }
430
431 int ctdb_req_message_data_pull(uint8_t *buf, size_t buflen,
432                                struct ctdb_req_header *h,
433                                TALLOC_CTX *mem_ctx,
434                                struct ctdb_req_message_data *c)
435 {
436         struct ctdb_req_header header;
437         size_t offset = 0, np;
438         int ret;
439
440         ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
441         if (ret != 0) {
442                 return ret;
443         }
444         offset += np;
445
446         if (h != NULL) {
447                 *h = header;
448         }
449
450         ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->srvid, &np);
451         if (ret != 0) {
452                 return ret;
453         }
454         offset += np;
455
456         ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset,
457                                   mem_ctx, &c->data, &np);
458         if (ret != 0) {
459                 return ret;
460         }
461         offset += np;
462
463         return 0;
464 }