mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
ctdb-protocol: Add protocol marshalling for CTDB_REQ_TUNNEL
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
parent
24e4197195
commit
c700464d23
@ -653,6 +653,20 @@ int ctdb_req_keepalive_pull(uint8_t *buf, size_t buflen,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_keepalive *c);
|
||||
|
||||
/* From protocol/protocol_tunnel.c */
|
||||
|
||||
size_t ctdb_req_tunnel_len(struct ctdb_req_header *h,
|
||||
struct ctdb_req_tunnel *c);
|
||||
|
||||
int ctdb_req_tunnel_push(struct ctdb_req_header *h,
|
||||
struct ctdb_req_tunnel *c,
|
||||
uint8_t *buf, size_t *buflen);
|
||||
|
||||
int ctdb_req_tunnel_pull(uint8_t *buf, size_t buflen,
|
||||
struct ctdb_req_header *h,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_tunnel *c);
|
||||
|
||||
/* From protocol/protocol_event.c */
|
||||
|
||||
size_t ctdb_event_request_len(struct ctdb_event_request *in);
|
||||
|
@ -354,6 +354,24 @@ static void ctdb_srvid_print(uint64_t srvid, FILE *fp)
|
||||
}
|
||||
}
|
||||
|
||||
static void ctdb_tunnel_id_print(uint64_t tunnel_id, FILE *fp)
|
||||
{
|
||||
fprintf(fp, "0x%"PRIx64, tunnel_id);
|
||||
}
|
||||
|
||||
static void ctdb_tunnel_flags_print(uint32_t flags, FILE *fp)
|
||||
{
|
||||
if (flags & CTDB_TUNNEL_FLAG_REQUEST) {
|
||||
fprintf(fp, "REQUEST ");
|
||||
}
|
||||
if (flags & CTDB_TUNNEL_FLAG_REPLY) {
|
||||
fprintf(fp, "REPLY ");
|
||||
}
|
||||
if (flags & CTDB_TUNNEL_FLAG_NOREPLY) {
|
||||
fprintf(fp, "NOREPLY ");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print routines
|
||||
*/
|
||||
@ -472,6 +490,16 @@ static void ctdb_req_keepalive_print(struct ctdb_req_keepalive *c, FILE *fp)
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
static void ctdb_req_tunnel_print(struct ctdb_req_tunnel *c, FILE *fp)
|
||||
{
|
||||
fprintf(fp, "Data\n");
|
||||
fprintf(fp, " tunnel_id:");
|
||||
ctdb_tunnel_id_print(c->tunnel_id, fp);
|
||||
ctdb_tunnel_flags_print(c->flags, fp);
|
||||
tdb_data_print(c->data, fp);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse routines
|
||||
*/
|
||||
@ -611,6 +639,21 @@ static void ctdb_req_keepalive_parse(uint8_t *buf, size_t buflen, FILE *fp,
|
||||
ctdb_req_keepalive_print(&c, fp);
|
||||
}
|
||||
|
||||
static void ctdb_req_tunnel_parse(uint8_t *buf, size_t buflen, FILE *fp,
|
||||
TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct ctdb_req_tunnel c;
|
||||
int ret;
|
||||
|
||||
ret = ctdb_req_tunnel_pull(buf, buflen, NULL, mem_ctx, &c);
|
||||
if (ret != 0) {
|
||||
fprintf(fp, "Failed to parse CTDB_REQ_TUNNEL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ctdb_req_tunnel_print(&c, fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Packet print
|
||||
*/
|
||||
@ -679,6 +722,10 @@ void ctdb_packet_print(uint8_t *buf, size_t buflen, FILE *fp)
|
||||
ctdb_req_keepalive_parse(buf, buflen, fp, mem_ctx);
|
||||
break;
|
||||
|
||||
case CTDB_REQ_TUNNEL:
|
||||
ctdb_req_tunnel_parse(buf, buflen, fp, mem_ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(fp, "Invalid ctdb operation\n");
|
||||
break;
|
||||
|
114
ctdb/protocol/protocol_tunnel.c
Normal file
114
ctdb/protocol/protocol_tunnel.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
CTDB protocol marshalling
|
||||
|
||||
Copyright (C) Amitay Isaacs 2017
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "replace.h"
|
||||
#include "system/network.h"
|
||||
|
||||
#include <talloc.h>
|
||||
#include <tdb.h>
|
||||
|
||||
#include "protocol.h"
|
||||
#include "protocol_api.h"
|
||||
#include "protocol_private.h"
|
||||
|
||||
size_t ctdb_req_tunnel_len(struct ctdb_req_header *h,
|
||||
struct ctdb_req_tunnel *c)
|
||||
{
|
||||
return ctdb_req_header_len(h) +
|
||||
ctdb_uint64_len(&c->tunnel_id) +
|
||||
ctdb_uint32_len(&c->flags) +
|
||||
ctdb_tdb_datan_len(&c->data);
|
||||
}
|
||||
|
||||
int ctdb_req_tunnel_push(struct ctdb_req_header *h,
|
||||
struct ctdb_req_tunnel *c,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
size_t length, offset = 0, np;
|
||||
|
||||
length = ctdb_req_tunnel_len(h, c);
|
||||
if (*buflen < length) {
|
||||
*buflen = length;
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
h->length = *buflen;
|
||||
ctdb_req_header_push(h, buf, &np);
|
||||
offset += np;
|
||||
|
||||
ctdb_uint64_push(&c->tunnel_id, buf+offset, &np);
|
||||
offset += np;
|
||||
|
||||
ctdb_uint32_push(&c->flags, buf+offset, &np);
|
||||
offset += np;
|
||||
|
||||
ctdb_tdb_datan_push(&c->data, buf+offset, &np);
|
||||
offset += np;
|
||||
|
||||
if (offset > *buflen) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ctdb_req_tunnel_pull(uint8_t *buf, size_t buflen,
|
||||
struct ctdb_req_header *h,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_tunnel *c)
|
||||
{
|
||||
struct ctdb_req_header header;
|
||||
size_t offset = 0, np;
|
||||
int ret;
|
||||
|
||||
ret = ctdb_req_header_pull(buf, buflen, &header, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
if (h != NULL) {
|
||||
*h = header;
|
||||
}
|
||||
|
||||
ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->tunnel_id, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
ret = ctdb_uint32_pull(buf+offset, buflen-offset, &c->flags, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, mem_ctx,
|
||||
&c->data, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
if (offset > buflen) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -55,6 +55,7 @@ output=$(
|
||||
generate_message_output "ctdb_req_message"
|
||||
echo "ctdb_req_message_data"
|
||||
echo "ctdb_req_keepalive"
|
||||
echo "ctdb_req_tunnel"
|
||||
)
|
||||
|
||||
ok "$output"
|
||||
|
@ -2001,3 +2001,18 @@ void verify_ctdb_req_keepalive(struct ctdb_req_keepalive *c,
|
||||
assert(c->version == c2->version);
|
||||
assert(c->uptime == c2->uptime);
|
||||
}
|
||||
|
||||
void fill_ctdb_req_tunnel(TALLOC_CTX *mem_ctx, struct ctdb_req_tunnel *c)
|
||||
{
|
||||
c->tunnel_id = rand64();
|
||||
c->flags = rand32();
|
||||
fill_tdb_data(mem_ctx, &c->data);
|
||||
}
|
||||
|
||||
void verify_ctdb_req_tunnel(struct ctdb_req_tunnel *c,
|
||||
struct ctdb_req_tunnel *c2)
|
||||
{
|
||||
assert(c->tunnel_id == c2->tunnel_id);
|
||||
assert(c->flags == c2->flags);
|
||||
verify_tdb_data(&c->data, &c2->data);
|
||||
}
|
||||
|
@ -94,4 +94,8 @@ void fill_ctdb_req_keepalive(TALLOC_CTX *mem_ctx,
|
||||
void verify_ctdb_req_keepalive(struct ctdb_req_keepalive *c,
|
||||
struct ctdb_req_keepalive *c2);
|
||||
|
||||
void fill_ctdb_req_tunnel(TALLOC_CTX *mem_ctx, struct ctdb_req_tunnel *c);
|
||||
void verify_ctdb_req_tunnel(struct ctdb_req_tunnel *c,
|
||||
struct ctdb_req_tunnel *c2);
|
||||
|
||||
#endif /* __CTDB_PROTOCOL_COMMON_CTDB_H__ */
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "protocol/protocol_control.c"
|
||||
#include "protocol/protocol_message.c"
|
||||
#include "protocol/protocol_keepalive.c"
|
||||
#include "protocol/protocol_tunnel.c"
|
||||
|
||||
#include "tests/src/protocol_common.h"
|
||||
#include "tests/src/protocol_common_ctdb.h"
|
||||
@ -1107,6 +1108,90 @@ static int ctdb_req_keepalive_pull_old(uint8_t *buf, size_t buflen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ctdb_req_tunnel_wire {
|
||||
struct ctdb_req_header hdr;
|
||||
uint64_t tunnel_id;
|
||||
uint32_t flags;
|
||||
uint32_t datalen;
|
||||
uint8_t data[1];
|
||||
};
|
||||
|
||||
static size_t ctdb_req_tunnel_len_old(struct ctdb_req_header *h,
|
||||
struct ctdb_req_tunnel *c)
|
||||
{
|
||||
return offsetof(struct ctdb_req_tunnel_wire, data) +
|
||||
ctdb_tdb_data_len(&c->data);
|
||||
}
|
||||
|
||||
static int ctdb_req_tunnel_push_old(struct ctdb_req_header *h,
|
||||
struct ctdb_req_tunnel *c,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
struct ctdb_req_tunnel_wire *wire =
|
||||
(struct ctdb_req_tunnel_wire *)buf;
|
||||
size_t length, np;
|
||||
|
||||
length = ctdb_req_tunnel_len_old(h, c);
|
||||
if (*buflen < length) {
|
||||
*buflen = length;
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
h->length = *buflen;
|
||||
ctdb_req_header_push_old(h, (uint8_t *)&wire->hdr);
|
||||
|
||||
wire->tunnel_id = c->tunnel_id;
|
||||
wire->flags = c->flags;
|
||||
wire->datalen = ctdb_tdb_data_len(&c->data);
|
||||
ctdb_tdb_data_push(&c->data, wire->data, &np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctdb_req_tunnel_pull_old(uint8_t *buf, size_t buflen,
|
||||
struct ctdb_req_header *h,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_tunnel *c)
|
||||
{
|
||||
struct ctdb_req_tunnel_wire *wire =
|
||||
(struct ctdb_req_tunnel_wire *)buf;
|
||||
size_t length, np;
|
||||
int ret;
|
||||
|
||||
length = offsetof(struct ctdb_req_tunnel_wire, data);
|
||||
if (buflen < length) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (wire->datalen > buflen) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (length + wire->datalen < length) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (buflen < length + wire->datalen) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
if (h != NULL) {
|
||||
ret = ctdb_req_header_pull_old((uint8_t *)&wire->hdr, buflen,
|
||||
h);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
c->tunnel_id = wire->tunnel_id;
|
||||
c->flags = wire->flags;
|
||||
|
||||
ret = ctdb_tdb_data_pull(wire->data, wire->datalen, mem_ctx, &c->data,
|
||||
&np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
COMPAT_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header);
|
||||
|
||||
@ -1123,6 +1208,7 @@ COMPAT_CTDB7_TEST(struct ctdb_req_message, ctdb_req_message, CTDB_REQ_MESSAGE);
|
||||
COMPAT_CTDB4_TEST(struct ctdb_req_message_data, ctdb_req_message_data, CTDB_REQ_MESSAGE);
|
||||
|
||||
COMPAT_CTDB4_TEST(struct ctdb_req_keepalive, ctdb_req_keepalive, CTDB_REQ_KEEPALIVE);
|
||||
COMPAT_CTDB4_TEST(struct ctdb_req_tunnel, ctdb_req_tunnel, CTDB_REQ_TUNNEL);
|
||||
|
||||
#define NUM_CONTROLS 151
|
||||
|
||||
@ -1178,6 +1264,7 @@ int main(int argc, char *argv[])
|
||||
COMPAT_TEST_FUNC(ctdb_req_message_data)();
|
||||
|
||||
COMPAT_TEST_FUNC(ctdb_req_keepalive)();
|
||||
COMPAT_TEST_FUNC(ctdb_req_tunnel)();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "protocol/protocol_control.c"
|
||||
#include "protocol/protocol_message.c"
|
||||
#include "protocol/protocol_keepalive.c"
|
||||
#include "protocol/protocol_tunnel.c"
|
||||
#include "protocol/protocol_packet.c"
|
||||
|
||||
#include "tests/src/protocol_common.h"
|
||||
@ -301,6 +302,7 @@ PROTOCOL_CTDB4_TEST(struct ctdb_req_message_data, ctdb_req_message_data,
|
||||
|
||||
PROTOCOL_CTDB4_TEST(struct ctdb_req_keepalive, ctdb_req_keepalive,
|
||||
CTDB_REQ_KEEPALIVE);
|
||||
PROTOCOL_CTDB4_TEST(struct ctdb_req_tunnel, ctdb_req_tunnel, CTDB_REQ_TUNNEL);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@ -364,6 +366,7 @@ int main(int argc, char *argv[])
|
||||
TEST_FUNC(ctdb_req_message_data)();
|
||||
|
||||
TEST_FUNC(ctdb_req_keepalive)();
|
||||
TEST_FUNC(ctdb_req_tunnel)();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -399,6 +399,7 @@ def build(bld):
|
||||
protocol_message.c
|
||||
protocol_control.c
|
||||
protocol_keepalive.c
|
||||
protocol_tunnel.c
|
||||
protocol_client.c
|
||||
protocol_debug.c
|
||||
protocol_event.c
|
||||
|
Loading…
Reference in New Issue
Block a user