From 8add947b2127e3a2dd2fd515d7701c396733f8e4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Nov 2023 14:57:46 +0100 Subject: [PATCH] ctdbd_conn: add ctdbd_passed_ips() This is similar to ctdbd_unregister_ips(), but with the difference that ctdb keeps the 'tickle' information for the tcp connection alive, because another smbd process took care of that tcp connection in a multichannel scenario. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523 Signed-off-by: Stefan Metzmacher Reviewed-by: Martin Schwenke (cherry picked from commit 2e784789d78d09dfbc599085e5eb1c70c5b866b8) --- source3/include/ctdbd_conn.h | 11 ++++++++ source3/lib/ctdb_dummy.c | 14 ++++++++++ source3/lib/ctdbd_conn.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h index a0801200794..312f0eea810 100644 --- a/source3/include/ctdbd_conn.h +++ b/source3/include/ctdbd_conn.h @@ -95,6 +95,17 @@ void ctdbd_unregister_ips(struct ctdbd_connection *conn, size_t msglen, void *private_data), void *private_data); +void ctdbd_passed_ips(struct ctdbd_connection *conn, + const struct sockaddr_storage *_server, + const struct sockaddr_storage *_client, + int (*cb)(struct tevent_context *ev, + uint32_t src_vnn, + uint32_t dst_vnn, + uint64_t dst_srvid, + const uint8_t *msg, + size_t msglen, + void *private_data), + void *private_data); /* * call @cb for each public IP. If @cb returns non-zero, then break the loop diff --git a/source3/lib/ctdb_dummy.c b/source3/lib/ctdb_dummy.c index 99f27d843d2..3954fac22c8 100644 --- a/source3/lib/ctdb_dummy.c +++ b/source3/lib/ctdb_dummy.c @@ -89,6 +89,20 @@ void ctdbd_unregister_ips(struct ctdbd_connection *conn, { return; } +void ctdbd_passed_ips(struct ctdbd_connection *conn, + const struct sockaddr_storage *_server, + const struct sockaddr_storage *_client, + int (*cb)(struct tevent_context *ev, + uint32_t src_vnn, + uint32_t dst_vnn, + uint64_t dst_srvid, + const uint8_t *msg, + size_t msglen, + void *private_data), + void *private_data) +{ + return; +} int ctdbd_public_ip_foreach(struct ctdbd_connection *conn, int (*cb)(uint32_t total_ip_count, diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index 408dd80e951..a739c97f3fd 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -1327,6 +1327,71 @@ void ctdbd_unregister_ips(struct ctdbd_connection *conn, return; } +void ctdbd_passed_ips(struct ctdbd_connection *conn, + const struct sockaddr_storage *_server, + const struct sockaddr_storage *_client, + int (*cb)(struct tevent_context *ev, + uint32_t src_vnn, + uint32_t dst_vnn, + uint64_t dst_srvid, + const uint8_t *msg, + size_t msglen, + void *private_data), + void *private_data) +{ + struct ctdb_connection p; + TDB_DATA data = { .dptr = (uint8_t *)&p, .dsize = sizeof(p) }; + int ret; + struct sockaddr_storage client; + struct sockaddr_storage server; + + /* + * Only one connection so far + */ + + smbd_ctdb_canonicalize_ip(_client, &client); + smbd_ctdb_canonicalize_ip(_server, &server); + + ZERO_STRUCT(p); + switch (client.ss_family) { + case AF_INET: + memcpy(&p.dst.ip, &server, sizeof(p.dst.ip)); + memcpy(&p.src.ip, &client, sizeof(p.src.ip)); + break; + case AF_INET6: + memcpy(&p.dst.ip6, &server, sizeof(p.dst.ip6)); + memcpy(&p.src.ip6, &client, sizeof(p.src.ip6)); + break; + default: + return; + } + + /* + * We no longer want to be told about IP releases + * for the given callback/private_data combination + */ + deregister_from_ctdbd(conn, CTDB_SRVID_RELEASE_IP, + cb, private_data); + + /* + * inform ctdb of our tcp connection is now passed to + * another process. + */ + ret = ctdbd_control_local(conn, + CTDB_CONTROL_TCP_CLIENT_PASSED, 0, + CTDB_CTRL_FLAG_NOREPLY, data, NULL, NULL, + NULL); + if (ret != 0) { + /* + * We ignore errors here, as we'll just + * no longer have a callback handler + * registered and messages may just be ignored + */ + } + + return; +} + static int ctdbd_control_get_public_ips(struct ctdbd_connection *conn, uint32_t flags, TALLOC_CTX *mem_ctx, -- 2.11.4.GIT