ctdbd_conn: add ctdbd_passed_ips()
authorStefan Metzmacher <metze@samba.org>
Mon, 20 Nov 2023 13:57:46 +0000 (14:57 +0100)
committerJule Anger <janger@samba.org>
Sat, 16 Dec 2023 15:07:15 +0000 (15:07 +0000)
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 <metze@samba.org>
Reviewed-by: Martin Schwenke <martin@meltin.net>
(cherry picked from commit 2e784789d78d09dfbc599085e5eb1c70c5b866b8)

source3/include/ctdbd_conn.h
source3/lib/ctdb_dummy.c
source3/lib/ctdbd_conn.c

index a0801200794685d826b91e154e463760b9014a73..312f0eea810ef4d242d24dcc4e26744d868df40a 100644 (file)
@@ -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
index 99f27d843d28679fec5286471074ad9393b7c92d..3954fac22c82693678bbe080905edc4550fc195d 100644 (file)
@@ -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,
index 408dd80e951fc2de7cb6f25d4ab41b216d519277..a739c97f3fd260e6bba4f3a7840da5870a57727e 100644 (file)
@@ -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,