1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-27 14:04:05 +03:00

finish the ipv6 support.

allow clients to register either ipv4 or ipv6 client connections to the tickles list

(This used to be ctdb commit d9b44d7c3255b0fd7359b9afeb613e6ff4c4eaac)
This commit is contained in:
root 2009-01-13 16:17:20 +11:00
parent db7d239e03
commit 321866dbba
4 changed files with 90 additions and 40 deletions

View File

@ -20,6 +20,8 @@
#ifndef _CTDB_H
#define _CTDB_H
#include <netinet/in.h>
#define CTDB_IMMEDIATE_MIGRATION 0x00000001
struct ctdb_call {
int call_id;
@ -521,6 +523,33 @@ struct ctdb_uptime {
struct timeval last_recovery_finished;
};
/*
definitions for different socket structures
*/
typedef struct sockaddr_in ctdb_addr_in;
typedef struct sockaddr_in6 ctdb_addr_in6;
typedef union {
struct sockaddr sa;
ctdb_addr_in ip;
ctdb_addr_in6 ip6;
} ctdb_sock_addr;
/*
struct for tcp_client control
this is an ipv4 only version of this structure used by samba
samba will later be migrated over to use the
ctdb_control_tcp_addr structure instead
*/
struct ctdb_control_tcp {
struct sockaddr_in src; // samba uses this
struct sockaddr_in dest;// samba uses this
};
/* new style structure */
struct ctdb_control_tcp_addr {
ctdb_sock_addr src;
ctdb_sock_addr dest;
};
int ctdb_socket_connect(struct ctdb_context *ctdb);
/*

View File

@ -22,7 +22,6 @@
#include "ctdb.h"
#include <sys/socket.h>
#include <netinet/in.h>
/* location of daemon socket */
#define CTDB_PATH "/tmp/ctdb.socket"
@ -46,17 +45,6 @@ struct rd_memdump_reply {
uint64_t srvid;
};
/*
definitions for different socket structures
*/
typedef struct sockaddr_in ctdb_addr_in;
typedef struct sockaddr_in6 ctdb_addr_in6;
typedef union {
struct sockaddr sa;
ctdb_addr_in ip;
ctdb_addr_in6 ip6;
} ctdb_sock_addr;
/*
a tcp connection description
*/
@ -573,15 +561,6 @@ struct ctdb_control_set_call {
uint32_t id;
};
/*
struct for tcp_client control
used by samba can not modify
*/
struct ctdb_control_tcp {
struct sockaddr_in src; // samba uses this
struct sockaddr_in dest;// samba uses this
};
/*
struct for kill_tcp control
*/

View File

@ -305,7 +305,6 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
return ctdb_control_get_public_ips(ctdb, c, outdata);
case CTDB_CONTROL_TCP_CLIENT:
CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_tcp));
return ctdb_control_tcp_client(ctdb, client_id, indata);
case CTDB_CONTROL_STARTUP:

View File

@ -1022,15 +1022,15 @@ static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
/*
called by a client to inform us of a TCP connection that it is managing
that should tickled with an ACK when IP takeover is done
we handle both the old ipv4 style of packets as well as the new ipv4/6
pdus.
*/
//qqq we need a new version of this control that takes ctdb_sock_addr
//and have samba move to that instead.
// This is IPV4 ONLY
int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
TDB_DATA indata)
{
struct ctdb_client *client = ctdb_reqid_find(ctdb, client_id, struct ctdb_client);
struct ctdb_control_tcp *p = (struct ctdb_control_tcp *)indata.dptr;
struct ctdb_control_tcp *old_addr = NULL;
struct ctdb_control_tcp_addr *tcp_sock = NULL;
struct ctdb_tcp_list *tcp;
struct ctdb_control_tcp_vnn t;
int ret;
@ -1039,20 +1039,50 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
struct ctdb_vnn *vnn;
ctdb_sock_addr addr;
switch (indata.dsize) {
case sizeof(struct ctdb_control_tcp):
old_addr = (struct ctdb_control_tcp *)indata.dptr;
tcp_sock->src.ip = old_addr->src;
tcp_sock->dest.ip = old_addr->dest;
break;
case sizeof(struct ctdb_control_tcp_addr):
tcp_sock = (struct ctdb_control_tcp_addr *)indata.dptr;
break;
default:
DEBUG(DEBUG_ERR,(__location__ " Invalid data structure passed to ctdb_control_tcp_client. size was %d but only allowed sizes are %lu and %lu\n", (int)indata.dsize, sizeof(struct ctdb_control_tcp), sizeof(struct ctdb_control_tcp_addr)));
return -1;
}
addr = tcp_sock->src;
ctdb_canonicalize_ip(&addr, &tcp_sock->src);
addr = tcp_sock->dest;
ctdb_canonicalize_ip(&addr, &tcp_sock->dest);
ZERO_STRUCT(addr);
addr.ip = p->dest;
memcpy(&addr, &tcp_sock->dest, sizeof(addr));
vnn = find_public_ip_vnn(ctdb, &addr);
if (vnn == NULL) {
if (ntohl(p->dest.sin_addr.s_addr) != INADDR_LOOPBACK) {
DEBUG(DEBUG_INFO,("Could not add client IP %s. This is not a public address.\n",
ctdb_addr_to_str((ctdb_sock_addr *)&p->dest)));
switch (addr.sa.sa_family) {
case AF_INET:
if (ntohl(addr.ip.sin_addr.s_addr) != INADDR_LOOPBACK) {
DEBUG(DEBUG_ERR,("Could not add client IP %s. This is not a public address.\n",
ctdb_addr_to_str(&addr)));
}
break;
case AF_INET6:
DEBUG(DEBUG_ERR,("Could not add client IP %s. This is not a public ipv6 address.\n",
ctdb_addr_to_str(&addr)));
break;
default:
DEBUG(DEBUG_ERR,(__location__ " Unknown family type %d\n", addr.sa.sa_family));
}
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((ctdb_sock_addr *)&p->dest),
ctdb_addr_to_str(&addr),
client_id, client->pid));
/* failing this call will tell smbd to die */
return -1;
@ -1062,7 +1092,7 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
CTDB_NO_MEMORY(ctdb, ip);
ip->ctdb = ctdb;
ip->addr.ip = p->dest;
ip->addr = addr;
ip->client_id = client_id;
talloc_set_destructor(ip, ctdb_client_ip_destructor);
DLIST_ADD(ctdb->client_ip_list, ip);
@ -1070,21 +1100,34 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
tcp = talloc(client, struct ctdb_tcp_list);
CTDB_NO_MEMORY(ctdb, tcp);
tcp->connection.src_addr.ip = p->src;
tcp->connection.dst_addr.ip = p->dest;
tcp->connection.src_addr = tcp_sock->src;
tcp->connection.dst_addr = tcp_sock->dest;
DLIST_ADD(client->tcp_list, tcp);
t.src.ip = p->src;
t.dest.ip = p->dest;
t.src = tcp_sock->src;
t.dest = tcp_sock->dest;
data.dptr = (uint8_t *)&t;
data.dsize = sizeof(t);
DEBUG(DEBUG_INFO,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
(unsigned)ntohs(p->dest.sin_port),
ctdb_addr_to_str((ctdb_sock_addr *)&p->src),
(unsigned)ntohs(p->src.sin_port), client_id, client->pid));
switch (addr.sa.sa_family) {
case AF_INET:
DEBUG(DEBUG_ERR,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
(unsigned)ntohs(tcp_sock->dest.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_ERR,("registered tcp client for %u->%s:%u (client_id %u pid %u)\n",
(unsigned)ntohs(tcp_sock->dest.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", addr.sa.sa_family));
}
/* tell all nodes about this tcp connection */
ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,