summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-01-28 18:55:13 +0100
committerStefan Metzmacher <metze@samba.org>2009-01-29 17:40:13 +0100
commit7540d13956a8a69d25f6fbbc4f9a3417e91db1d2 (patch)
tree14e5784e6488348d2ca52b0365281bcb854e8a40 /source3/lib
parentba482e6b8d375449bcce52bfa383b95046d89fc1 (diff)
downloadsamba-7540d13956a8a69d25f6fbbc4f9a3417e91db1d2.tar.gz
samba-7540d13956a8a69d25f6fbbc4f9a3417e91db1d2.tar.bz2
samba-7540d13956a8a69d25f6fbbc4f9a3417e91db1d2.zip
s3:ctdbd_conn: canonicalize ips before sending them to ctdbd
This makes samba work with older ctdb versions. metze
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/ctdbd_conn.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index f8dae8fbd6..88d82caab8 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -1177,45 +1177,75 @@ NTSTATUS ctdbd_traverse(uint32 db_id,
}
/*
+ This is used to canonicalize a ctdb_sock_addr structure.
+*/
+static void smbd_ctdb_canonicalize_ip(const struct sockaddr_storage *in,
+ struct sockaddr_storage *out)
+{
+ memcpy(out, in, sizeof (*out));
+
+#ifdef HAVE_IPV6
+ if (in->ss_family == AF_INET6) {
+ const char prefix[12] = { 0,0,0,0,0,0,0,0,0,0,0xff,0xff };
+ const struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in;
+ struct sockaddr_in *out4 = (struct sockaddr_in *)out;
+ if (memcmp(&in6->sin6_addr, prefix, 12) == 0) {
+ memset(out, 0, sizeof(*out));
+#ifdef HAVE_SOCK_SIN_LEN
+ out4->sin_len = sizeof(*out);
+#endif
+ out4->sin_family = AF_INET;
+ out4->sin_port = in6->sin6_port;
+ memcpy(&out4->sin_addr, &in6->sin6_addr.s6_addr32[3], 4);
+ }
+ }
+#endif
+}
+
+/*
* Register us as a server for a particular tcp connection
*/
NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
- const struct sockaddr_storage *server,
- const struct sockaddr_storage *client,
+ const struct sockaddr_storage *_server,
+ const struct sockaddr_storage *_client,
void (*release_ip_handler)(const char *ip_addr,
void *private_data),
void *private_data)
{
- struct sockaddr *sock = (struct sockaddr *)client;
/*
* we still use ctdb_control_tcp for ipv4
* because we want to work against older ctdb
* versions at runtime
*/
struct ctdb_control_tcp p4;
-#ifdef HAVE_IPV6
+#ifdef HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR
struct ctdb_control_tcp_addr p;
#endif
TDB_DATA data;
NTSTATUS status;
+ struct sockaddr_storage client;
+ struct sockaddr_storage server;
/*
* Only one connection so far
*/
SMB_ASSERT(conn->release_ip_handler == NULL);
- switch (sock->sa_family) {
+ smbd_ctdb_canonicalize_ip(_client, &client);
+ smbd_ctdb_canonicalize_ip(_server, &server);
+
+ switch (client.ss_family) {
case AF_INET:
- p4.dest = *(struct sockaddr_in *)server;
- p4.src = *(struct sockaddr_in *)client;
+ p4.dest = *(struct sockaddr_in *)&server;
+ p4.src = *(struct sockaddr_in *)&client;
data.dptr = (uint8_t *)&p4;
data.dsize = sizeof(p4);
break;
-#ifdef HAVE_IPV6
+#ifdef HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR
case AF_INET6:
- p.dest.ip6 = *(struct sockaddr_in6 *)server;
- p.src.ip6 = *(struct sockaddr_in6 *)client;
+ p.dest.ip6 = *(struct sockaddr_in6 *)&server;
+ p.src.ip6 = *(struct sockaddr_in6 *)&client;
data.dptr = (uint8_t *)&p;
data.dsize = sizeof(p);
break;