[SCM] Samba Shared Repository - branch v4-19-test updated
Jule Anger
janger at samba.org
Sat Dec 16 16:09:01 UTC 2023
The branch, v4-19-test has been updated
via 853efb9dd7b ctdb-server: Drop unnecessary copy of destination address
via 2e93e358ef9 ctdb-daemon: Use ctdb_connection_to_buf() to simplify
via 2640bae75e3 smbd: Remove callback for release_ip when "state" is free'ed
via 43b7068676a s3:selftest: add samba3.blackbox.smbXsrv_client_ctdb_registered_ips
via d96cb627b66 selftest: export/use CTDB related envvars in order to run the ctdb command
via 8add947b212 ctdbd_conn: add ctdbd_passed_ips()
via e3a4feda112 ctdbd_conn: add ctdbd_unregister_ips()
via acf080817b5 ctdbd_conn: Add deregister_from_ctdbd()
via d039fa07f7e ctdbd_conn: let register_with_ctdbd() call CTDB_CONTROL_REGISTER_SRVID just once
via e09f92422eb ctdbd_conn: don't use uninitialized memory in ctdbd_register_ips()
via 118d6c81ec9 ctdb: add/implement CTDB_CONTROL_TCP_CLIENT_PASSED
via b6906f37c66 ctdb: add/implement CTDB_CONTROL_TCP_CLIENT_DISCONNECTED
via 24bd10ebfc1 ctdb: add ctdb_connection_same() helper
via 0d6a38604b2 ctdb: make use of ctdb_canonicalize_ip_inplace() in ctdb_control_tcp_client()
via 69c4f498c84 ctdb: add ctdb_canonicalize_ip_inplace() helper
via 38134f374ca ctdb: remove unused ctdb->client_ip_list and print debug on ctdb_tcp_list instead
from 1b6096a1dff s3:utils: Fix auth callback with smburl
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-19-test
- Log -----------------------------------------------------------------
commit 853efb9dd7b7eccebc5bd8a4129f2dc487ad8120
Author: Martin Schwenke <mschwenke at ddn.com>
Date: Wed Dec 13 10:29:05 2023 +1100
ctdb-server: Drop unnecessary copy of destination address
Modernise debug while touching the code.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Martin Schwenke <mschwenke at ddn.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Fri Dec 15 12:09:21 UTC 2023 on atb-devel-224
(cherry picked from commit 4b7329f15820f1b4d9a7b7f0947719c4217b312a)
Autobuild-User(v4-19-test): Jule Anger <janger at samba.org>
Autobuild-Date(v4-19-test): Sat Dec 16 16:08:41 UTC 2023 on atb-devel-224
commit 2e93e358ef9f3d55065cd5e9ad1b03126df06b63
Author: Martin Schwenke <mschwenke at ddn.com>
Date: Wed Dec 13 10:22:04 2023 +1100
ctdb-daemon: Use ctdb_connection_to_buf() to simplify
The one case that is no longer handled specially is when the
destination address is IPv4 loopback. This may previously have been
used to avoid flooding the logs when testing. However, that seems
unnecessary - if testing with 127.0.0.1 then make it a public address.
Modernise debug while touching the code.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Martin Schwenke <mschwenke at ddn.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
(cherry picked from commit 8fc3872557f715dc38f9898754a785fd073ace96)
commit 2640bae75e3abab1a9959b2de14dad29020852de
Author: Volker Lendecke <vl at samba.org>
Date: Thu Oct 12 17:19:45 2023 +0200
smbd: Remove callback for release_ip when "state" is free'ed
If a client connects to a non-public address first followed by a connect
to public address with the same client_guid and a connection to
the non-public address gets disconnected first, we hit by a use-after-free
talloc_get_type_abort() called from release_ip() as
"xconn" is already gone, taking smbd_release_ip_state with it.
We need to decide between calling ctdbd_unregister_ips() by default, as
it means the tcp connection is really gone and ctdb needs to remove the
'tickle' information. But when a connection was passed to a different
smbd process, we need to use ctdbd_passed_ips() as the tcp connection is
still alive and the 'tickle' information should not be removed within
ctdb.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Volker Lendecke <vl at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit ddf47e7fe314e0f5bf71ff53e35350e0ba530d08)
commit 43b7068676a00a5169ac6f34e97a1bacf8d0c29d
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Nov 17 11:46:27 2023 +0100
s3:selftest: add samba3.blackbox.smbXsrv_client_ctdb_registered_ips
This demonstrates the crash that happens if a client connects to a
non-public address first followed by a connect
to public address with the same client_guid and a connection to
the non-public address gets disconnected first, we hit by a
use-after-free talloc_get_type_abort() called from release_ip() as
"xconn" is already gone, taking smbd_release_ip_state with it.
Note that we also need to mark some subtests as flapping
as there's a 2nd problem that happens in the interaction
between smbd processes and ctdb when passing a multichannel
connection to an existing process, it means we sometimes
loose the 'tickle' information within ctdb to that tcp connection.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 082c7df4d04c2a94c5413c1d6b7eae7be610f950)
commit d96cb627b66d4c63d0407f4e434b429bb03a47af
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Nov 17 11:45:30 2023 +0100
selftest: export/use CTDB related envvars in order to run the ctdb command
This makes it easier to test things...
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 38b74d4ca9a59e7f12850c20c410f9df26cbad0a)
commit 8add947b2127e3a2dd2fd515d7701c396733f8e4
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Nov 20 14:57:46 2023 +0100
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 <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 2e784789d78d09dfbc599085e5eb1c70c5b866b8)
commit e3a4feda112a174eebf9c866032aff899202eed7
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Nov 16 13:18:03 2023 +0100
ctdbd_conn: add ctdbd_unregister_ips()
This reverts the effect of ctdbd_register_ips().
We'll use this in order to disconnect individual
multichannel connections.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit f3a03f3f774f0795fc1a163f12cccb9cedeebec1)
commit acf080817b538968d6e7cbcd5a037399c9a66c28
Author: Volker Lendecke <vl at samba.org>
Date: Thu Oct 12 17:11:42 2023 +0200
ctdbd_conn: Add deregister_from_ctdbd()
This is to remove a callback during rundown of smbds.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Volker Lendecke <vl at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 75aa6693940201a928b46f6880b43820c0e1c555)
commit d039fa07f7ee1f0eed6777f812a0ba4913e76ac7
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Nov 16 13:04:12 2023 +0100
ctdbd_conn: let register_with_ctdbd() call CTDB_CONTROL_REGISTER_SRVID just once
We do the dispatching to multiple handlers in ctdbd_msg_call_back()
and we don't need more than one message from ctdb.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 77a559432ffde2d435e29bed126d20a09d33f48e)
commit e09f92422ebff3454332ebbb28d578d8103e7203
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Nov 16 13:29:18 2023 +0100
ctdbd_conn: don't use uninitialized memory in ctdbd_register_ips()
We dump the structure into the socket, so we need to zero the content
including possible padding.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 240139370aa19f53dd3de0ff468afd994d3bd973)
commit 118d6c81ec9fd19a98d5f674ccff2a57aed81881
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Nov 17 15:59:57 2023 +0100
ctdb: add/implement CTDB_CONTROL_TCP_CLIENT_PASSED
With multichannel a tcp connection is registered first with
a temporary smbd process, that calls CTDB_CONTROL_TCP_CLIENT
first and then passes the tcp connection to the longterm smbd
that already handles all connections belonging to the specific
client_guid. That smbd process calls CTDB_CONTROL_TCP_CLIENT
again, but the 'tickle' information is already there.
When the temporary smbd process exists/disconnects from ctdb
or calls CTDB_CONTROL_TCP_CLIENT_DISCONNECTED, the 'tickle'
information is removed, while the longterm smbd process
still serves the tcp connection.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 037e8e449deb136ad5ed5e4de05439411b545b6d)
commit b6906f37c667677dcac9bcfd6cc182869cb6f569
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Nov 15 16:31:53 2023 +0100
ctdb: add/implement CTDB_CONTROL_TCP_CLIENT_DISCONNECTED
With multichannel a ctdb connection from smbd may hold multiple
tcp connections, which can be disconnected before the smbd
process terminates the whole ctdb connection, so we a
way to remove undo 'CTDB_CONTROL_TCP_CLIENT' again.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit c6602b686b4e50d93272667ef86d3904181fb1ab)
commit 24bd10ebfc12a150bee214f830c328d61c42e591
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 12 13:39:21 2023 +0100
ctdb: add ctdb_connection_same() helper
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 8395fd369d3c9d216817e922423727748581f133)
commit 0d6a38604b247d94869d80a2caf310175a27f605
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 12 13:27:17 2023 +0100
ctdb: make use of ctdb_canonicalize_ip_inplace() in ctdb_control_tcp_client()
We could also remove the src_addr and dest_addr helper variables
completely, but that would be too much for this commit.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 5f52d140f7b676ed68b5ce49d4445357bcbcb1a6)
commit 69c4f498c84f42626efd71773a5e4509cbfaf29f
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Dec 12 13:26:46 2023 +0100
ctdb: add ctdb_canonicalize_ip_inplace() helper
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit f2d9c012fc803b48564c3203ed640c02f99bcbaa)
commit 38134f374ca5c76cf636dd9d10ab8e2cf5e4bf1e
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Nov 16 11:56:59 2023 +0100
ctdb: remove unused ctdb->client_ip_list and print debug on ctdb_tcp_list instead
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15523
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
(cherry picked from commit 92badd3bdd82d1fa79727efcf81b6f479016811f)
-----------------------------------------------------------------------
Summary of changes:
ctdb/common/common.h | 1 +
ctdb/common/ctdb_util.c | 7 +
ctdb/include/ctdb_private.h | 7 +-
ctdb/protocol/protocol.h | 2 +
ctdb/protocol/protocol_control.c | 30 +++
ctdb/protocol/protocol_debug.c | 2 +
ctdb/protocol/protocol_util.c | 18 ++
ctdb/protocol/protocol_util.h | 3 +
ctdb/server/ctdb_control.c | 8 +
ctdb/server/ctdb_takeover.c | 292 ++++++++++++++-------
selftest/target/Samba.pm | 19 ++
selftest/target/Samba3.pm | 22 +-
source3/include/ctdbd_conn.h | 32 +++
source3/lib/ctdb_dummy.c | 42 +++
source3/lib/ctdbd_conn.c | 228 +++++++++++++++-
.../test_smbXsrv_client_ctdb_registered_ips.sh | 159 +++++++++++
source3/selftest/tests.py | 8 +-
source3/smbd/smb2_negprot.c | 7 +
source3/smbd/smb2_process.c | 33 +++
19 files changed, 808 insertions(+), 112 deletions(-)
create mode 100755 source3/script/tests/test_smbXsrv_client_ctdb_registered_ips.sh
Changeset truncated at 500 lines:
diff --git a/ctdb/common/common.h b/ctdb/common/common.h
index c50b52a5eb5..9a73bec1ac6 100644
--- a/ctdb/common/common.h
+++ b/ctdb/common/common.h
@@ -132,6 +132,7 @@ struct ctdb_rec_data_old *ctdb_marshall_loop_next(
TDB_DATA *key, TDB_DATA *data);
void ctdb_canonicalize_ip(const ctdb_sock_addr *ip, ctdb_sock_addr *cip);
+void ctdb_canonicalize_ip_inplace(ctdb_sock_addr *ip);
bool ctdb_same_ip(const ctdb_sock_addr *tip1, const ctdb_sock_addr *tip2);
diff --git a/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c
index 3f8fff925f0..5c7731c5d2a 100644
--- a/ctdb/common/ctdb_util.c
+++ b/ctdb/common/ctdb_util.c
@@ -388,6 +388,13 @@ void ctdb_canonicalize_ip(const ctdb_sock_addr *ip, ctdb_sock_addr *cip)
}
}
+void ctdb_canonicalize_ip_inplace(ctdb_sock_addr *ip)
+{
+ ctdb_sock_addr tmp;
+ ctdb_canonicalize_ip(ip, &tmp);
+ memcpy(ip, &tmp, sizeof(tmp));
+}
+
bool ctdb_same_ip(const ctdb_sock_addr *tip1, const ctdb_sock_addr *tip2)
{
ctdb_sock_addr ip1, ip2;
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index 3395f077ab9..80278123778 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -296,7 +296,6 @@ struct ctdb_context {
struct ctdb_statistics statistics_history[MAX_STAT_HISTORY];
struct ctdb_vnn_map *vnn_map;
uint32_t num_clients;
- struct ctdb_client_ip *client_ip_list;
bool do_checkpublicip;
bool do_setsched;
const char *event_script_dir;
@@ -893,6 +892,12 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, bool check_addresses);
int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
TDB_DATA indata);
+int32_t ctdb_control_tcp_client_disconnected(struct ctdb_context *ctdb,
+ uint32_t client_id,
+ TDB_DATA indata);
+int32_t ctdb_control_tcp_client_passed(struct ctdb_context *ctdb,
+ uint32_t client_id,
+ TDB_DATA indata);
int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata,
bool tcp_update_needed);
int32_t ctdb_control_tcp_remove(struct ctdb_context *ctdb, TDB_DATA indata);
diff --git a/ctdb/protocol/protocol.h b/ctdb/protocol/protocol.h
index fb6e39f33b5..3b66c403ab8 100644
--- a/ctdb/protocol/protocol.h
+++ b/ctdb/protocol/protocol.h
@@ -381,6 +381,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0,
CTDB_CONTROL_ECHO_DATA = 156,
CTDB_CONTROL_DISABLE_NODE = 157,
CTDB_CONTROL_ENABLE_NODE = 158,
+ CTDB_CONTROL_TCP_CLIENT_DISCONNECTED = 159,
+ CTDB_CONTROL_TCP_CLIENT_PASSED = 160,
};
#define MAX_COUNT_BUCKETS 16
diff --git a/ctdb/protocol/protocol_control.c b/ctdb/protocol/protocol_control.c
index a7c797f5dbc..83ed6cb4ee1 100644
--- a/ctdb/protocol/protocol_control.c
+++ b/ctdb/protocol/protocol_control.c
@@ -410,6 +410,14 @@ static size_t ctdb_req_control_data_len(struct ctdb_req_control_data *cd)
case CTDB_CONTROL_ENABLE_NODE:
break;
+
+ case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
+ len = ctdb_connection_len(cd->data.conn);
+ break;
+
+ case CTDB_CONTROL_TCP_CLIENT_PASSED:
+ len = ctdb_connection_len(cd->data.conn);
+ break;
}
return len;
@@ -1016,6 +1024,22 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen,
&cd->data.echo_data,
&np);
break;
+
+ case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
+ ret = ctdb_connection_pull(buf,
+ buflen,
+ mem_ctx,
+ &cd->data.conn,
+ &np);
+ break;
+
+ case CTDB_CONTROL_TCP_CLIENT_PASSED:
+ ret = ctdb_connection_pull(buf,
+ buflen,
+ mem_ctx,
+ &cd->data.conn,
+ &np);
+ break;
}
if (ret != 0) {
@@ -1376,6 +1400,12 @@ static size_t ctdb_reply_control_data_len(struct ctdb_reply_control_data *cd)
case CTDB_CONTROL_ENABLE_NODE:
break;
+
+ case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
+ break;
+
+ case CTDB_CONTROL_TCP_CLIENT_PASSED:
+ break;
}
return len;
diff --git a/ctdb/protocol/protocol_debug.c b/ctdb/protocol/protocol_debug.c
index d94cb548d68..ae091b04d32 100644
--- a/ctdb/protocol/protocol_debug.c
+++ b/ctdb/protocol/protocol_debug.c
@@ -245,6 +245,8 @@ static void ctdb_opcode_print(uint32_t opcode, FILE *fp)
{ CTDB_CONTROL_ECHO_DATA, "ECHO_DATA" },
{ CTDB_CONTROL_DISABLE_NODE, "DISABLE_NODE" },
{ CTDB_CONTROL_ENABLE_NODE, "ENABLE_NODE" },
+ { CTDB_CONTROL_TCP_CLIENT_DISCONNECTED, "TCP_CLIENT_DISCONNECTED" },
+ { CTDB_CONTROL_TCP_CLIENT_PASSED, "TCP_CLIENT_PASSED" },
{ MAP_END, "" },
};
diff --git a/ctdb/protocol/protocol_util.c b/ctdb/protocol/protocol_util.c
index fe757658f48..87ecc87ac36 100644
--- a/ctdb/protocol/protocol_util.c
+++ b/ctdb/protocol/protocol_util.c
@@ -497,6 +497,24 @@ bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
return (ctdb_sock_addr_cmp(addr1, addr2) == 0);
}
+bool ctdb_connection_same(const struct ctdb_connection *conn1,
+ const struct ctdb_connection *conn2)
+{
+ bool same;
+
+ same = ctdb_sock_addr_same(&conn1->src, &conn2->src);
+ if (!same) {
+ return false;
+ }
+
+ same = ctdb_sock_addr_same(&conn1->dst, &conn2->dst);
+ if (!same) {
+ return false;
+ }
+
+ return true;
+}
+
int ctdb_connection_to_buf(char *buf,
size_t buflen,
struct ctdb_connection *conn,
diff --git a/ctdb/protocol/protocol_util.h b/ctdb/protocol/protocol_util.h
index 2bdbb0c2ad0..70f35d122a8 100644
--- a/ctdb/protocol/protocol_util.h
+++ b/ctdb/protocol/protocol_util.h
@@ -55,6 +55,9 @@ bool ctdb_sock_addr_same_ip(const ctdb_sock_addr *addr1,
bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
const ctdb_sock_addr *addr2);
+bool ctdb_connection_same(const struct ctdb_connection *conn1,
+ const struct ctdb_connection *conn2);
+
int ctdb_connection_to_buf(char *buf,
size_t buflen,
struct ctdb_connection * conn,
diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c
index 08268512bfa..422c4cf1e58 100644
--- a/ctdb/server/ctdb_control.c
+++ b/ctdb/server/ctdb_control.c
@@ -868,6 +868,14 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
CHECK_CONTROL_DATA_SIZE(0);
return ctdb_control_enable_node(ctdb);
+ case CTDB_CONTROL_TCP_CLIENT_DISCONNECTED:
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
+ return ctdb_control_tcp_client_disconnected(ctdb, client_id, indata);
+
+ case CTDB_CONTROL_TCP_CLIENT_PASSED:
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_connection));
+ return ctdb_control_tcp_client_passed(ctdb, client_id, indata);
+
default:
DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
return -1;
diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c
index 26cca1aefff..e333105e633 100644
--- a/ctdb/server/ctdb_takeover.c
+++ b/ctdb/server/ctdb_takeover.c
@@ -348,20 +348,10 @@ struct ctdb_takeover_arp {
*/
struct ctdb_tcp_list {
struct ctdb_tcp_list *prev, *next;
+ struct ctdb_client *client;
struct ctdb_connection connection;
};
-/*
- list of clients to kill on IP release
- */
-struct ctdb_client_ip {
- struct ctdb_client_ip *prev, *next;
- struct ctdb_context *ctdb;
- ctdb_sock_addr addr;
- uint32_t client_id;
-};
-
-
/*
send a gratuitous arp
*/
@@ -1233,16 +1223,37 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, bool check_addresses)
}
/*
- destroy a ctdb_client_ip structure
+ destroy a ctdb_tcp_list structure
*/
-static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
+static int ctdb_tcp_list_destructor(struct ctdb_tcp_list *tcp)
{
- DEBUG(DEBUG_DEBUG,("destroying client tcp for %s:%u (client_id %u)\n",
- ctdb_addr_to_str(&ip->addr),
- ntohs(ip->addr.ip.sin_port),
- ip->client_id));
+ struct ctdb_client *client = tcp->client;
+ struct ctdb_connection *conn = &tcp->connection;
+ char conn_str[132] = { 0, };
+ int ret;
+
+ ret = ctdb_connection_to_buf(conn_str,
+ sizeof(conn_str),
+ conn,
+ false,
+ " -> ");
+ if (ret != 0) {
+ strlcpy(conn_str, "UNKNOWN", sizeof(conn_str));
+ }
+
+ D_DEBUG("removing client TCP connection %s "
+ "(client_id %u pid %d)\n",
+ conn_str, client->client_id, client->pid);
+
+ DLIST_REMOVE(client->tcp_list, tcp);
+
+ /*
+ * We don't call ctdb_remove_connection(vnn, conn) here
+ * as we want the caller to decide if it's called
+ * directly (local only) or indirectly via a
+ * CTDB_CONTROL_TCP_REMOVE broadcast
+ */
- DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
return 0;
}
@@ -1259,10 +1270,8 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
struct ctdb_connection t;
int ret;
TDB_DATA data;
- struct ctdb_client_ip *ip;
struct ctdb_vnn *vnn;
- ctdb_sock_addr src_addr;
- ctdb_sock_addr dst_addr;
+ char conn_str[132] = { 0, };
/* If we don't have public IPs, tickles are useless */
if (ctdb->vnn == NULL) {
@@ -1271,75 +1280,44 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
tcp_sock = (struct ctdb_connection *)indata.dptr;
- src_addr = tcp_sock->src;
- ctdb_canonicalize_ip(&src_addr, &tcp_sock->src);
- ZERO_STRUCT(src_addr);
- memcpy(&src_addr, &tcp_sock->src, sizeof(src_addr));
+ ctdb_canonicalize_ip_inplace(&tcp_sock->src);
+ ctdb_canonicalize_ip_inplace(&tcp_sock->dst);
- dst_addr = tcp_sock->dst;
- ctdb_canonicalize_ip(&dst_addr, &tcp_sock->dst);
- ZERO_STRUCT(dst_addr);
- memcpy(&dst_addr, &tcp_sock->dst, sizeof(dst_addr));
+ ret = ctdb_connection_to_buf(conn_str,
+ sizeof(conn_str),
+ tcp_sock,
+ false,
+ " -> ");
+ if (ret != 0) {
+ strlcpy(conn_str, "UNKNOWN", sizeof(conn_str));
+ }
- vnn = find_public_ip_vnn(ctdb, &dst_addr);
+ vnn = find_public_ip_vnn(ctdb, &tcp_sock->dst);
if (vnn == NULL) {
- char *src_addr_str = NULL;
- char *dst_addr_str = NULL;
-
- switch (dst_addr.sa.sa_family) {
- case AF_INET:
- if (ntohl(dst_addr.ip.sin_addr.s_addr) == INADDR_LOOPBACK) {
- /* ignore ... */
- return 0;
- }
- break;
- case AF_INET6:
- break;
- default:
- DEBUG(DEBUG_ERR,(__location__ " Unknown family type %d\n",
- dst_addr.sa.sa_family));
- return 0;
- }
-
- src_addr_str = ctdb_sock_addr_to_string(client, &src_addr, false);
- dst_addr_str = ctdb_sock_addr_to_string(client, &dst_addr, false);
- DEBUG(DEBUG_ERR,(
- "Could not register TCP connection from "
- "%s to %s (not a public address) (port %u) "
- "(client_id %u pid %u).\n",
- src_addr_str,
- dst_addr_str,
- ctdb_sock_addr_port(&dst_addr),
- client_id, client->pid));
- TALLOC_FREE(src_addr_str);
- TALLOC_FREE(dst_addr_str);
+ D_ERR("Could not register TCP connection %s - "
+ "not a public address (client_id %u pid %u)\n",
+ conn_str, client_id, client->pid);
return 0;
}
if (vnn->pnn != ctdb->pnn) {
- DEBUG(DEBUG_ERR,("Attempt to register tcp client for IP %s we don't hold - failing (client_id %u pid %u)\n",
- ctdb_addr_to_str(&dst_addr),
- client_id, client->pid));
+ D_ERR("Attempt to register tcp client for IP %s we don't hold - "
+ "failing (client_id %u pid %u)\n",
+ ctdb_addr_to_str(&tcp_sock->dst),
+ client_id, client->pid);
/* failing this call will tell smbd to die */
return -1;
}
- ip = talloc(client, struct ctdb_client_ip);
- CTDB_NO_MEMORY(ctdb, ip);
-
- ip->ctdb = ctdb;
- ip->addr = dst_addr;
- ip->client_id = client_id;
- talloc_set_destructor(ip, ctdb_client_ip_destructor);
- DLIST_ADD(ctdb->client_ip_list, ip);
-
tcp = talloc(client, struct ctdb_tcp_list);
CTDB_NO_MEMORY(ctdb, tcp);
+ tcp->client = client;
tcp->connection.src = tcp_sock->src;
tcp->connection.dst = tcp_sock->dst;
DLIST_ADD(client->tcp_list, tcp);
+ talloc_set_destructor(tcp, ctdb_tcp_list_destructor);
t.src = tcp_sock->src;
t.dst = tcp_sock->dst;
@@ -1347,24 +1325,8 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
data.dptr = (uint8_t *)&t;
data.dsize = sizeof(t);
- switch (dst_addr.sa.sa_family) {
- case AF_INET:
- DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
- (unsigned)ntohs(tcp_sock->dst.ip.sin_port),
- ctdb_addr_to_str(&tcp_sock->src),
- (unsigned)ntohs(tcp_sock->src.ip.sin_port), client_id, client->pid));
- break;
- case AF_INET6:
- DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
- (unsigned)ntohs(tcp_sock->dst.ip6.sin6_port),
- ctdb_addr_to_str(&tcp_sock->src),
- (unsigned)ntohs(tcp_sock->src.ip6.sin6_port), client_id, client->pid));
- break;
- default:
- DEBUG(DEBUG_ERR,(__location__ " Unknown family %d\n",
- dst_addr.sa.sa_family));
- }
-
+ D_INFO("Registered TCP connection %s (client_id %u pid %u)\n",
+ conn_str, client_id, client->pid);
/* tell all nodes about this tcp connection */
ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
@@ -1378,6 +1340,141 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
return 0;
}
+static bool ctdb_client_remove_tcp(struct ctdb_client *client,
+ const struct ctdb_connection *conn)
+{
+ struct ctdb_tcp_list *tcp = NULL;
+ struct ctdb_tcp_list *tcp_next = NULL;
+ bool found = false;
+
+ for (tcp = client->tcp_list; tcp != NULL; tcp = tcp_next) {
+ bool same;
+
+ tcp_next = tcp->next;
+
+ same = ctdb_connection_same(conn, &tcp->connection);
+ if (!same) {
+ continue;
+ }
+
+ TALLOC_FREE(tcp);
+ found = true;
+ }
+
+ return found;
+}
+
+/*
+ called by a client to inform us of a TCP connection that was disconnected
+ */
+int32_t ctdb_control_tcp_client_disconnected(struct ctdb_context *ctdb,
+ uint32_t client_id,
+ TDB_DATA indata)
+{
+ struct ctdb_client *client = reqid_find(ctdb->idr, client_id, struct ctdb_client);
+ struct ctdb_connection *tcp_sock = NULL;
+ int ret;
+ TDB_DATA data;
+ char conn_str[132] = { 0, };
+ bool found = false;
+
+ tcp_sock = (struct ctdb_connection *)indata.dptr;
+
+ ctdb_canonicalize_ip_inplace(&tcp_sock->src);
+ ctdb_canonicalize_ip_inplace(&tcp_sock->dst);
+
+ ret = ctdb_connection_to_buf(conn_str,
+ sizeof(conn_str),
+ tcp_sock,
+ false,
+ " -> ");
+ if (ret != 0) {
+ strlcpy(conn_str, "UNKNOWN", sizeof(conn_str));
+ }
+
+ found = ctdb_client_remove_tcp(client, tcp_sock);
+ if (!found) {
+ DBG_DEBUG("TCP connection %s not found "
+ "(client_id %u pid %u).\n",
+ conn_str, client_id, client->pid);
+ return 0;
+ }
+
+ D_INFO("deregistered TCP connection %s "
+ "(client_id %u pid %u)\n",
+ conn_str, client_id, client->pid);
+
+ data.dptr = (uint8_t *)tcp_sock;
+ data.dsize = sizeof(*tcp_sock);
+
+ /* tell all nodes about this tcp connection is gone */
+ ret = ctdb_daemon_send_control(ctdb,
+ CTDB_BROADCAST_CONNECTED,
+ 0,
+ CTDB_CONTROL_TCP_REMOVE,
+ 0,
+ CTDB_CTRL_FLAG_NOREPLY,
+ data,
+ NULL,
+ NULL);
+ if (ret != 0) {
+ DBG_ERR("Failed to send CTDB_CONTROL_TCP_REMOVE: %s\n",
+ conn_str);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ called by a client to inform us of a TCP connection was passed to a different
+ "client" (typically with multichannel to another smbd process).
+ */
+int32_t ctdb_control_tcp_client_passed(struct ctdb_context *ctdb,
+ uint32_t client_id,
--
Samba Shared Repository
More information about the samba-cvs
mailing list