source: vendor/current/ctdb/protocol/protocol_call.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 9.9 KB
Line 
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
30struct ctdb_req_call_wire {
31 struct ctdb_req_header hdr;
32 uint32_t flags;
33 uint32_t db_id;
34 uint32_t callid;
35 uint32_t hopcount;
36 uint32_t keylen;
37 uint32_t calldatalen;
38 uint8_t data[1]; /* key[] followed by calldata[] */
39};
40
41struct ctdb_reply_call_wire {
42 struct ctdb_req_header hdr;
43 uint32_t status;
44 uint32_t datalen;
45 uint8_t data[1];
46};
47
48struct ctdb_reply_error_wire {
49 struct ctdb_req_header hdr;
50 uint32_t status;
51 uint32_t msglen;
52 uint8_t msg[1];
53};
54
55struct ctdb_req_dmaster_wire {
56 struct ctdb_req_header hdr;
57 uint32_t db_id;
58 uint64_t rsn;
59 uint32_t dmaster;
60 uint32_t keylen;
61 uint32_t datalen;
62 uint8_t data[1];
63};
64
65struct ctdb_reply_dmaster_wire {
66 struct ctdb_req_header hdr;
67 uint32_t db_id;
68 uint64_t rsn;
69 uint32_t keylen;
70 uint32_t datalen;
71 uint8_t data[1];
72};
73
74int ctdb_req_call_push(struct ctdb_req_header *h, struct ctdb_req_call *c,
75 TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
76{
77 struct ctdb_req_call_wire *wire;
78 uint8_t *buf;
79 size_t length, buflen;
80 int ret;
81
82 if (c->key.dsize == 0) {
83 return EINVAL;
84 }
85
86 length = offsetof(struct ctdb_req_call_wire, data) +
87 c->key.dsize + c->calldata.dsize;
88
89 ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
90 if (ret != 0) {
91 return ret;
92 }
93
94 wire = (struct ctdb_req_call_wire *)buf;
95
96 h->length = buflen;
97 memcpy(&wire->hdr, h, sizeof(struct ctdb_req_header));
98
99 wire->flags = c->flags;
100 wire->db_id = c->db_id;
101 wire->callid = c->callid;
102 wire->hopcount = c->hopcount;
103 wire->keylen = c->key.dsize;
104 wire->calldatalen = c->calldata.dsize;
105 memcpy(wire->data, c->key.dptr, c->key.dsize);
106 if (c->calldata.dsize > 0) {
107 memcpy(wire->data + c->key.dsize, c->calldata.dptr,
108 c->calldata.dsize);
109 }
110
111 *pkt = buf;
112 *pkt_len = buflen;
113 return 0;
114}
115
116int ctdb_req_call_pull(uint8_t *pkt, size_t pkt_len,
117 struct ctdb_req_header *h,
118 TALLOC_CTX *mem_ctx,
119 struct ctdb_req_call *c)
120{
121 struct ctdb_req_call_wire *wire;
122 size_t length;
123
124 length = offsetof(struct ctdb_req_call_wire, data);
125 if (pkt_len < length) {
126 return EMSGSIZE;
127 }
128
129 wire = (struct ctdb_req_call_wire *)pkt;
130
131 if (pkt_len < length + wire->keylen + wire->calldatalen) {
132 return EMSGSIZE;
133 }
134
135 memcpy(h, &wire->hdr, sizeof(struct ctdb_req_header));
136
137 c->flags = wire->flags;
138 c->db_id = wire->db_id;
139 c->callid = wire->callid;
140 c->hopcount = wire->hopcount;
141 c->key.dsize = wire->keylen;
142 c->key.dptr = talloc_memdup(mem_ctx, wire->data, wire->keylen);
143 if (c->key.dptr == NULL) {
144 return ENOMEM;
145 }
146 c->calldata.dsize = wire->calldatalen;
147 if (wire->calldatalen > 0) {
148 c->calldata.dptr = talloc_memdup(mem_ctx,
149 wire->data + wire->keylen,
150 wire->calldatalen);
151 if (c->calldata.dptr == NULL) {
152 talloc_free(c->key.dptr);
153 return ENOMEM;
154 }
155 }
156
157 return 0;
158}
159
160int ctdb_reply_call_push(struct ctdb_req_header *h, struct ctdb_reply_call *c,
161 TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
162{
163 struct ctdb_reply_call_wire *wire;
164 uint8_t *buf;
165 size_t length, buflen;
166 int ret;
167
168 length = offsetof(struct ctdb_reply_call_wire, data) + c->data.dsize;
169
170 ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
171 if (ret != 0) {
172 return ret;
173 }
174
175 wire = (struct ctdb_reply_call_wire *)buf;
176
177 h->length = buflen;
178 memcpy(&wire->hdr, h, sizeof(struct ctdb_req_header));
179
180 wire->status = c->status;
181 wire->datalen = c->data.dsize;
182 if (c->data.dsize > 0) {
183 memcpy(wire->data, c->data.dptr, c->data.dsize);
184 }
185
186 *pkt = buf;
187 *pkt_len = buflen;
188 return 0;
189}
190
191int ctdb_reply_call_pull(uint8_t *pkt, size_t pkt_len,
192 struct ctdb_req_header *h,
193 TALLOC_CTX *mem_ctx,
194 struct ctdb_reply_call *c)
195{
196 struct ctdb_reply_call_wire *wire;
197 size_t length;
198
199 length = offsetof(struct ctdb_reply_call_wire, data);
200 if (pkt_len < length) {
201 return EMSGSIZE;
202 }
203
204 wire = (struct ctdb_reply_call_wire *)pkt;
205
206 if (pkt_len < length + wire->datalen) {
207 return EMSGSIZE;
208 }
209
210 memcpy(h, &wire->hdr, sizeof(struct ctdb_req_header));
211
212 c->status = wire->status;
213 c->data.dsize = wire->datalen;
214 if (wire->datalen > 0) {
215 c->data.dptr = talloc_memdup(mem_ctx, wire->data,
216 wire->datalen);
217 if (c->data.dptr == NULL) {
218 return ENOMEM;
219 }
220 }
221
222 return 0;
223}
224
225int ctdb_reply_error_push(struct ctdb_req_header *h, struct ctdb_reply_error *c,
226 TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
227{
228 struct ctdb_reply_error_wire *wire;
229 uint8_t *buf;
230 size_t length, buflen;
231 int ret;
232
233 length = offsetof(struct ctdb_reply_error_wire, msg) + c->msg.dsize;
234
235 ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
236 if (ret != 0) {
237 return ret;
238 }
239
240 wire = (struct ctdb_reply_error_wire *)buf;
241
242 h->length = buflen;
243 memcpy(&wire->hdr, h, sizeof(struct ctdb_req_header));
244
245 wire->status = c->status;
246 wire->msglen = c->msg.dsize;
247 if (c->msg.dsize > 0) {
248 memcpy(wire->msg, c->msg.dptr, c->msg.dsize);
249 }
250
251 *pkt = buf;
252 *pkt_len = buflen;
253 return 0;
254}
255
256int ctdb_reply_error_pull(uint8_t *pkt, size_t pkt_len,
257 struct ctdb_req_header *h,
258 TALLOC_CTX *mem_ctx,
259 struct ctdb_reply_error *c)
260{
261 struct ctdb_reply_error_wire *wire;
262 size_t length;
263
264 length = offsetof(struct ctdb_reply_error_wire, msg);
265 if (pkt_len < length) {
266 return EMSGSIZE;
267 }
268
269 wire = (struct ctdb_reply_error_wire *)pkt;
270
271 if (pkt_len < length + wire->msglen) {
272 return EMSGSIZE;
273 }
274
275 memcpy(h, &wire->hdr, sizeof(struct ctdb_req_header));
276
277 c->status = wire->status;
278 c->msg.dsize = wire->msglen;
279 if (wire->msglen > 0) {
280 c->msg.dptr = talloc_memdup(mem_ctx, wire->msg, wire->msglen);
281 if (c->msg.dptr == NULL) {
282 return ENOMEM;
283 }
284 }
285
286 return 0;
287}
288
289int ctdb_req_dmaster_push(struct ctdb_req_header *h, struct ctdb_req_dmaster *c,
290 TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
291{
292 struct ctdb_req_dmaster_wire *wire;
293 uint8_t *buf;
294 size_t length, buflen;
295 int ret;
296
297 length = offsetof(struct ctdb_req_dmaster_wire, data) +
298 c->key.dsize + c->data.dsize;
299
300 ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
301 if (ret != 0) {
302 return ret;
303 }
304
305 wire = (struct ctdb_req_dmaster_wire *)buf;
306
307 h->length = buflen;
308 memcpy(&wire->hdr, h, sizeof(struct ctdb_req_header));
309
310 wire->db_id = c->db_id;
311 wire->rsn = c->rsn;
312 wire->dmaster = c->dmaster;
313 wire->keylen = c->key.dsize;
314 if (c->key.dsize > 0) {
315 memcpy(wire->data, c->key.dptr, c->key.dsize);
316 }
317 wire->datalen = c->data.dsize;
318 if (c->data.dsize > 0) {
319 memcpy(wire->data + c->key.dsize, c->data.dptr, c->data.dsize);
320 }
321
322 *pkt = buf;
323 *pkt_len = buflen;
324 return 0;
325}
326
327int ctdb_req_dmaster_pull(uint8_t *pkt, size_t pkt_len,
328 struct ctdb_req_header *h,
329 TALLOC_CTX *mem_ctx,
330 struct ctdb_req_dmaster *c)
331{
332 struct ctdb_req_dmaster_wire *wire;
333 size_t length;
334
335 length = offsetof(struct ctdb_req_dmaster_wire, data);
336 if (pkt_len < length) {
337 return EMSGSIZE;
338 }
339
340 wire = (struct ctdb_req_dmaster_wire *)pkt;
341
342 if (pkt_len < length + wire->keylen + wire->datalen) {
343 return EMSGSIZE;
344 }
345
346 memcpy(h, &wire->hdr, sizeof(struct ctdb_req_header));
347
348 c->db_id = wire->db_id;
349 c->rsn = wire->rsn;
350 c->dmaster = wire->dmaster;
351 c->key.dsize = wire->keylen;
352 c->key.dptr = talloc_memdup(mem_ctx, wire->data, wire->keylen);
353 if (c->key.dptr == NULL) {
354 return ENOMEM;
355 }
356 c->data.dsize = wire->datalen;
357 if (wire->datalen > 0) {
358 c->data.dptr = talloc_memdup(mem_ctx, wire->data + wire->keylen,
359 wire->datalen);
360 if (c->data.dptr == NULL) {
361 talloc_free(c->key.dptr);
362 return ENOMEM;
363 }
364 }
365
366 return 0;
367}
368
369int ctdb_reply_dmaster_push(struct ctdb_req_header *h,
370 struct ctdb_reply_dmaster *c,
371 TALLOC_CTX *mem_ctx, uint8_t **pkt, size_t *pkt_len)
372{
373 struct ctdb_reply_dmaster_wire *wire;
374 uint8_t *buf;
375 size_t length, buflen;
376 int ret;
377
378 length = offsetof(struct ctdb_reply_dmaster_wire, data) +
379 c->key.dsize + c->data.dsize;
380
381 ret = allocate_pkt(mem_ctx, length, &buf, &buflen);
382 if (ret != 0) {
383 return ret;
384 }
385
386 wire = (struct ctdb_reply_dmaster_wire *)buf;
387
388 h->length = buflen;
389 memcpy(&wire->hdr, h, sizeof(struct ctdb_req_header));
390
391 wire->db_id = c->db_id;
392 wire->rsn = c->rsn;
393 wire->keylen = c->key.dsize;
394 if (c->key.dsize > 0) {
395 memcpy(wire->data, c->key.dptr, c->key.dsize);
396 }
397 wire->datalen = c->data.dsize;
398 if (c->data.dsize > 0) {
399 memcpy(wire->data + c->key.dsize, c->data.dptr, c->data.dsize);
400 }
401
402 *pkt = buf;
403 *pkt_len = buflen;
404 return 0;
405}
406
407int ctdb_reply_dmaster_pull(uint8_t *pkt, size_t pkt_len,
408 struct ctdb_req_header *h,
409 TALLOC_CTX *mem_ctx,
410 struct ctdb_reply_dmaster *c)
411{
412 struct ctdb_reply_dmaster_wire *wire;
413 size_t length;
414
415 length = offsetof(struct ctdb_reply_dmaster_wire, data);
416 if (pkt_len < length) {
417 return EMSGSIZE;
418 }
419
420 wire = (struct ctdb_reply_dmaster_wire *)pkt;
421
422 if (pkt_len < length + wire->keylen + wire->datalen) {
423 return EMSGSIZE;
424 }
425
426 memcpy(h, &wire->hdr, sizeof(struct ctdb_req_header));
427
428 c->db_id = wire->db_id;
429 c->rsn = wire->rsn;
430 c->key.dsize = wire->keylen;
431 c->key.dptr = talloc_memdup(mem_ctx, wire->data, wire->keylen);
432 if (c->key.dptr == NULL) {
433 return ENOMEM;
434 }
435 c->data.dsize = wire->datalen;
436 if (wire->datalen > 0) {
437 c->data.dptr = talloc_memdup(mem_ctx, wire->data + wire->keylen,
438 wire->datalen);
439 if (c->data.dptr == NULL) {
440 talloc_free(c->key.dptr);
441 return ENOMEM;
442 }
443 }
444
445 return 0;
446}
Note: See TracBrowser for help on using the repository browser.