ldb_tdb: Use mem_ctx and so avoid leak onto long-term memory on duplicated add.
[Samba.git] / ctdb / protocol / protocol_basic.c
blob4e86ef32df7aae386a3dad952d84a72763c67381
1 /*
2 CTDB protocol marshalling
4 Copyright (C) Amitay Isaacs 2015-2017
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_private.h"
30 * Basic data types
33 size_t ctdb_uint8_len(uint8_t *in)
35 return sizeof(uint8_t);
38 void ctdb_uint8_push(uint8_t *in, uint8_t *buf, size_t *npush)
40 *buf = *in;
41 *npush = sizeof(uint8_t);
44 int ctdb_uint8_pull(uint8_t *buf, size_t buflen, uint8_t *out, size_t *npull)
46 if (buflen < sizeof(uint8_t)) {
47 return EMSGSIZE;
50 *out = *buf;
51 *npull = sizeof(uint8_t);
52 return 0;
55 size_t ctdb_uint16_len(uint16_t *in)
57 return sizeof(uint16_t);
60 void ctdb_uint16_push(uint16_t *in, uint8_t *buf, size_t *npush)
62 memcpy(buf, in, sizeof(uint16_t));
63 *npush = sizeof(uint16_t);
66 int ctdb_uint16_pull(uint8_t *buf, size_t buflen, uint16_t *out, size_t *npull)
68 if (buflen < sizeof(uint16_t)) {
69 return EMSGSIZE;
72 memcpy(out, buf, sizeof(uint16_t));
73 *npull = sizeof(uint16_t);
74 return 0;
77 size_t ctdb_int32_len(int32_t *in)
79 return sizeof(int32_t);
82 void ctdb_int32_push(int32_t *in, uint8_t *buf, size_t *npush)
84 memcpy(buf, in, sizeof(int32_t));
85 *npush = sizeof(int32_t);
88 int ctdb_int32_pull(uint8_t *buf, size_t buflen, int32_t *out, size_t *npull)
90 if (buflen < sizeof(int32_t)) {
91 return EMSGSIZE;
94 memcpy(out, buf, sizeof(int32_t));
95 *npull = sizeof(int32_t);
96 return 0;
99 size_t ctdb_uint32_len(uint32_t *in)
101 return sizeof(uint32_t);
104 void ctdb_uint32_push(uint32_t *in, uint8_t *buf, size_t *npush)
106 memcpy(buf, in, sizeof(uint32_t));
107 *npush = sizeof(uint32_t);
110 int ctdb_uint32_pull(uint8_t *buf, size_t buflen, uint32_t *out, size_t *npull)
112 if (buflen < sizeof(uint32_t)) {
113 return EMSGSIZE;
116 memcpy(out, buf, sizeof(uint32_t));
117 *npull = sizeof(uint32_t);
118 return 0;
121 size_t ctdb_uint64_len(uint64_t *in)
123 return sizeof(uint64_t);
126 void ctdb_uint64_push(uint64_t *in, uint8_t *buf, size_t *npush)
128 memcpy(buf, in, sizeof(uint64_t));
129 *npush = sizeof(uint64_t);
132 int ctdb_uint64_pull(uint8_t *buf, size_t buflen, uint64_t *out, size_t *npull)
134 if (buflen < sizeof(uint64_t)) {
135 return EMSGSIZE;
138 memcpy(out, buf, sizeof(uint64_t));
139 *npull = sizeof(uint64_t);
140 return 0;
143 size_t ctdb_double_len(double *in)
145 return sizeof(double);
148 void ctdb_double_push(double *in, uint8_t *buf, size_t *npush)
150 memcpy(buf, in, sizeof(double));
151 *npush = sizeof(double);
154 int ctdb_double_pull(uint8_t *buf, size_t buflen, double *out, size_t *npull)
156 if (buflen < sizeof(double)) {
157 return EMSGSIZE;
160 memcpy(out, buf, sizeof(double));
161 *npull = sizeof(double);
162 return 0;
165 size_t ctdb_bool_len(bool *in)
167 uint8_t u8 = *in;
169 return ctdb_uint8_len(&u8);
172 void ctdb_bool_push(bool *in, uint8_t *buf, size_t *npush)
174 size_t np;
175 uint8_t u8 = *in;
177 ctdb_uint8_push(&u8, buf, &np);
178 *npush = np;
181 int ctdb_bool_pull(uint8_t *buf, size_t buflen, bool *out, size_t *npull)
183 size_t np;
184 uint8_t u8;
185 int ret;
187 ret = ctdb_uint8_pull(buf, buflen, &u8, &np);
188 if (ret != 0) {
189 return ret;
192 if (u8 == 0) {
193 *out = false;
194 } else if (u8 == 1) {
195 *out = true;
196 } else {
197 return EINVAL;
200 *npull = np;
201 return 0;
204 size_t ctdb_chararray_len(char *in, size_t len)
206 return len;
209 void ctdb_chararray_push(char *in, size_t len, uint8_t *buf, size_t *npush)
211 memcpy(buf, in, len);
212 *npush = len;
215 int ctdb_chararray_pull(uint8_t *buf, size_t buflen, char *out, size_t len,
216 size_t *npull)
218 if (buflen < len) {
219 return EMSGSIZE;
222 memcpy(out, buf, len);
223 out[len-1] = '\0';
224 *npull = len;
225 return 0;
228 size_t ctdb_string_len(const char **in)
230 if (*in == NULL) {
231 return 0;
234 return strlen(*in) + 1;
237 void ctdb_string_push(const char **in, uint8_t *buf, size_t *npush)
239 size_t len;
241 len = ctdb_string_len(in);
242 if (len > 0) {
243 memcpy(buf, *in, len);
246 *npush = len;
249 int ctdb_string_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
250 const char **out, size_t *npull)
252 const char *str;
254 if (buflen > UINT32_MAX) {
255 return EMSGSIZE;
258 if (buflen == 0) {
259 *out = NULL;
260 *npull = 0;
261 return 0;
264 str = talloc_strndup(mem_ctx, (char *)buf, buflen);
265 if (str == NULL) {
266 return ENOMEM;
269 *out = str;
270 *npull = ctdb_string_len(&str);
271 return 0;
274 size_t ctdb_stringn_len(const char **in)
276 uint32_t u32 = ctdb_string_len(in);
278 return ctdb_uint32_len(&u32) + u32;
281 void ctdb_stringn_push(const char **in, uint8_t *buf, size_t *npush)
283 size_t offset = 0, np;
284 uint32_t u32 = ctdb_string_len(in);
286 ctdb_uint32_push(&u32, buf+offset, &np);
287 offset += np;
289 ctdb_string_push(in, buf+offset, &np);
290 offset += np;
292 *npush = offset;
295 int ctdb_stringn_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
296 const char **out, size_t *npull)
298 size_t offset = 0, np;
299 uint32_t u32;
300 int ret;
302 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
303 if (ret != 0) {
304 return ret;
306 offset += np;
308 if (buflen-offset < u32) {
309 return EMSGSIZE;
312 ret = ctdb_string_pull(buf+offset, u32, mem_ctx, out, &np);
313 if (ret != 0) {
314 return ret;
316 offset += np;
318 *npull = offset;
319 return 0;
323 * System defined data types
326 size_t ctdb_pid_len(pid_t *in)
328 return sizeof(pid_t);
331 void ctdb_pid_push(pid_t *in, uint8_t *buf, size_t *npush)
333 memcpy(buf, in, sizeof(pid_t));
334 *npush = sizeof(pid_t);
337 int ctdb_pid_pull(uint8_t *buf, size_t buflen, pid_t *out, size_t *npull)
339 if (buflen < sizeof(pid_t)) {
340 return EMSGSIZE;
343 memcpy(out, buf, sizeof(pid_t));
344 *npull = sizeof(pid_t);
345 return 0;
348 size_t ctdb_timeval_len(struct timeval *in)
350 return sizeof(struct timeval);
353 void ctdb_timeval_push(struct timeval *in, uint8_t *buf, size_t *npush)
355 memcpy(buf, in, sizeof(struct timeval));
356 *npush = sizeof(struct timeval);
359 int ctdb_timeval_pull(uint8_t *buf, size_t buflen, struct timeval *out,
360 size_t *npull)
362 if (buflen < sizeof(struct timeval)) {
363 return EMSGSIZE;
366 memcpy(out, buf, sizeof(struct timeval));
367 *npull = sizeof(struct timeval);
368 return 0;
372 * Dummy type to tackle structure padding
375 size_t ctdb_padding_len(int count)
377 return count % SIZEOF_VOID_P;
380 void ctdb_padding_push(int count, uint8_t *buf, size_t *npush)
382 uint8_t padding[count];
383 size_t aligned_count = count % SIZEOF_VOID_P;
385 if (aligned_count > 0) {
386 memset(padding, 0, aligned_count);
387 memcpy(buf, padding, aligned_count);
389 *npush = aligned_count;
392 int ctdb_padding_pull(uint8_t *buf, size_t buflen, int count, size_t *npull)
394 size_t aligned_count = count % SIZEOF_VOID_P;
396 if (buflen < aligned_count) {
397 return EMSGSIZE;
400 *npull = aligned_count;
401 return 0;