summaryrefslogtreecommitdiffstats
path: root/ctdb/server/ctdb_takeover.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctdb/server/ctdb_takeover.c')
-rw-r--r--ctdb/server/ctdb_takeover.c377
1 files changed, 203 insertions, 174 deletions
diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c
index 53f48c175a1..54581909961 100644
--- a/ctdb/server/ctdb_takeover.c
+++ b/ctdb/server/ctdb_takeover.c
@@ -56,7 +56,7 @@ struct ctdb_tcp_list {
struct ctdb_client_ip {
struct ctdb_client_ip *prev, *next;
struct ctdb_context *ctdb;
- struct sockaddr_in ip;
+ ctdb_sock_addr addr;
uint32_t client_id;
};
@@ -72,7 +72,6 @@ static void ctdb_control_send_arp(struct event_context *ev, struct timed_event *
int i, ret;
struct ctdb_tcp_array *tcparray;
-
ret = ctdb_sys_send_arp(&arp->addr, arp->vnn->iface);
if (ret != 0) {
DEBUG(DEBUG_CRIT,(__location__ " sending of arp failed (%s)\n", strerror(errno)));
@@ -81,17 +80,20 @@ static void ctdb_control_send_arp(struct event_context *ev, struct timed_event *
tcparray = arp->tcparray;
if (tcparray) {
for (i=0;i<tcparray->num;i++) {
+ struct ctdb_tcp_connection *tcon;
+
+ tcon = &tcparray->connections[i];
DEBUG(DEBUG_INFO,("sending tcp tickle ack for %u->%s:%u\n",
- (unsigned)ntohs(tcparray->connections[i].daddr.sin_port),
- inet_ntoa(tcparray->connections[i].saddr.sin_addr),
- (unsigned)ntohs(tcparray->connections[i].saddr.sin_port)));
+ (unsigned)ntohs(tcon->dst_addr.ip.sin_port),
+ ctdb_addr_to_str(&tcon->src_addr),
+ (unsigned)ntohs(tcon->src_addr.ip.sin_port)));
ret = ctdb_sys_send_tcp(
- (ctdb_sock_addr *)&tcparray->connections[i].saddr,
- (ctdb_sock_addr *)&tcparray->connections[i].daddr,
+ &tcon->src_addr,
+ &tcon->dst_addr,
0, 0, 0);
if (ret != 0) {
DEBUG(DEBUG_CRIT,(__location__ " Failed to send tcp tickle ack for %s\n",
- inet_ntoa(tcparray->connections[i].saddr.sin_addr)));
+ ctdb_addr_to_str(&tcon->src_addr)));
}
}
}
@@ -126,14 +128,9 @@ static void takeover_ip_callback(struct ctdb_context *ctdb, int status,
struct ctdb_tcp_array *tcparray;
if (status != 0) {
- char ip[128] = "";
-
- if (inet_ntop(state->addr->sa.sa_family, &state->addr->sa.sa_data[0], ip, sizeof(ip)) == NULL) {
- DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
- }
-
DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
- ip, state->vnn->iface));
+ ctdb_addr_to_str(state->addr),
+ state->vnn->iface));
ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
talloc_free(state);
return;
@@ -181,12 +178,12 @@ failed:
Find the vnn of the node that has a public ip address
returns -1 if the address is not known as a public address
*/
-static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, struct sockaddr_in ip)
+static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
{
struct ctdb_vnn *vnn;
for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
- if (ctdb_same_ipv4(&vnn->public_address, &ip)) {
+ if (ctdb_same_ip(&vnn->public_address, addr)) {
return vnn;
}
}
@@ -209,16 +206,16 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
struct ctdb_vnn *vnn;
/* update out vnn list */
- vnn = find_public_ip_vnn(ctdb, pip->sin);
+ vnn = find_public_ip_vnn(ctdb, &pip->addr);
if (vnn == NULL) {
DEBUG(DEBUG_ERR,("takeoverip called for an ip '%s' that is not a public address\n",
- inet_ntoa(pip->sin.sin_addr)));
+ ctdb_addr_to_str(&pip->addr)));
return 0;
}
vnn->pnn = pip->pnn;
/* if our kernel already has this IP, do nothing */
- if (ctdb_sys_have_ip(pip->sin)) {
+ if (ctdb_sys_have_ip(&pip->addr)) {
return 0;
}
@@ -229,24 +226,26 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
state->addr = talloc(ctdb, ctdb_sock_addr);
CTDB_NO_MEMORY(ctdb, state->addr);
- state->addr->ip = pip->sin; //qqq pip must be converted
- state->vnn = vnn;
+ *state->addr = pip->addr;
+ state->vnn = vnn;
DEBUG(DEBUG_NOTICE,("Takeover of IP %s/%u on interface %s\n",
- inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
- vnn->iface));
+ ctdb_addr_to_str(&pip->addr),
+ vnn->public_netmask_bits,
+ vnn->iface));
ret = ctdb_event_script_callback(ctdb,
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
state, takeover_ip_callback, state,
"takeip %s %s %u",
vnn->iface,
- inet_ntoa(pip->sin.sin_addr),
+ talloc_strdup(state, ctdb_addr_to_str(&pip->addr)),
vnn->public_netmask_bits);
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " Failed to takeover IP %s on interface %s\n",
- inet_ntoa(pip->sin.sin_addr), vnn->iface));
+ ctdb_addr_to_str(&pip->addr),
+ vnn->iface));
talloc_free(state);
return -1;
}
@@ -263,27 +262,32 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
static void release_kill_clients(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
{
struct ctdb_client_ip *ip;
- char cip[128] = "";
- DEBUG(DEBUG_INFO,("release_kill_clients for ip %s\n", inet_ntop(addr->sa.sa_family, &addr->sa.sa_data[0], cip, sizeof(cip))));
+ DEBUG(DEBUG_INFO,("release_kill_clients for ip %s\n",
+ ctdb_addr_to_str(addr)));
for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
ctdb_sock_addr tmp_addr;
- tmp_addr.ip = ip->ip; //qqq until ip->ip is no longer a sockaddr_in
+ tmp_addr = ip->addr;
DEBUG(DEBUG_INFO,("checking for client %u with IP %s\n",
- ip->client_id, inet_ntoa(ip->ip.sin_addr)));
+ ip->client_id,
+ ctdb_addr_to_str(&ip->addr)));
+
if (ctdb_same_ip(&tmp_addr, addr)) {
struct ctdb_client *client = ctdb_reqid_find(ctdb,
ip->client_id,
struct ctdb_client);
DEBUG(DEBUG_INFO,("matched client %u with IP %s and pid %u\n",
- ip->client_id, inet_ntoa(ip->ip.sin_addr), client->pid));
+ ip->client_id,
+ ctdb_addr_to_str(&ip->addr),
+ client->pid));
+
if (client->pid != 0) {
DEBUG(DEBUG_INFO,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
- (unsigned)client->pid,
- inet_ntop(addr->sa.sa_family, &addr->sa.sa_data[0], cip, sizeof(cip)),
- ip->client_id));
+ (unsigned)client->pid,
+ ctdb_addr_to_str(addr),
+ ip->client_id));
kill(client->pid, SIGKILL);
}
}
@@ -298,21 +302,13 @@ static void release_ip_callback(struct ctdb_context *ctdb, int status,
{
struct takeover_callback_state *state =
talloc_get_type(private_data, struct takeover_callback_state);
- char ip[128] = "";
TDB_DATA data;
/* send a message to all clients of this node telling them
that the cluster has been reconfigured and they should
release any sockets on this IP */
-#if 1
- strncpy(ip, inet_ntoa(state->addr->ip.sin_addr), sizeof(ip)-1);
-#else
- if (inet_ntop(state->addr->sa.sa_family, &state->addr->sa.sa_data[0], ip, sizeof(ip)) == NULL) {
- DEBUG(DEBUG_ERR, (__location__ " inet_ntop() failed\n"));
- }
-#endif
- data.dptr = (uint8_t *)ip;
- data.dsize = strlen(ip)+1;
+ data.dptr = (uint8_t *)talloc_strdup(state, ctdb_addr_to_str(state->addr));
+ data.dsize = strlen((char *)data.dptr)+1;
DEBUG(DEBUG_INFO,(__location__ " sending RELEASE_IP for '%s'\n", data.dptr));
@@ -340,10 +336,10 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
struct ctdb_vnn *vnn;
/* update our vnn list */
- vnn = find_public_ip_vnn(ctdb, pip->sin);
+ vnn = find_public_ip_vnn(ctdb, &pip->addr);
if (vnn == NULL) {
- DEBUG(DEBUG_INFO,("releaseip called for an ip '%s' that is not a public address\n",
- inet_ntoa(pip->sin.sin_addr)));
+ DEBUG(DEBUG_ERR,("takeoverip called for an ip '%s' that is not a public address\n",
+ ctdb_addr_to_str(&pip->addr)));
return 0;
}
vnn->pnn = pip->pnn;
@@ -352,16 +348,18 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
talloc_free(vnn->takeover_ctx);
vnn->takeover_ctx = NULL;
- if (!ctdb_sys_have_ip(pip->sin)) {
+ if (!ctdb_sys_have_ip(&pip->addr)) {
DEBUG(DEBUG_INFO,("Redundant release of IP %s/%u on interface %s (ip not held)\n",
- inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
- vnn->iface));
+ ctdb_addr_to_str(&pip->addr),
+ vnn->public_netmask_bits,
+ vnn->iface));
return 0;
}
DEBUG(DEBUG_NOTICE,("Release of IP %s/%u on interface %s\n",
- inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits,
- vnn->iface));
+ ctdb_addr_to_str(&pip->addr),
+ vnn->public_netmask_bits,
+ vnn->iface));
state = talloc(ctdb, struct takeover_callback_state);
CTDB_NO_MEMORY(ctdb, state);
@@ -369,20 +367,20 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
state->c = talloc_steal(state, c);
state->addr = talloc(state, ctdb_sock_addr);
CTDB_NO_MEMORY(ctdb, state->addr);
- state->addr->ip = pip->sin; //qqq pip must be converted
-
- state->vnn = vnn;
+ *state->addr = pip->addr;
+ state->vnn = vnn;
ret = ctdb_event_script_callback(ctdb,
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
state, release_ip_callback, state,
"releaseip %s %s %u",
vnn->iface,
- inet_ntoa(pip->sin.sin_addr),
+ talloc_strdup(state, ctdb_addr_to_str(&pip->addr)),
vnn->public_netmask_bits);
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " Failed to release IP %s on interface %s\n",
- inet_ntoa(pip->sin.sin_addr), vnn->iface));
+ ctdb_addr_to_str(&pip->addr),
+ vnn->iface));
talloc_free(state);
return -1;
}
@@ -394,15 +392,15 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
-static int ctdb_add_public_address(struct ctdb_context *ctdb, struct sockaddr_in addr, unsigned mask, const char *iface)
+static int ctdb_add_public_address(struct ctdb_context *ctdb, ctdb_sock_addr *addr, unsigned mask, const char *iface)
{
struct ctdb_vnn *vnn;
/* Verify that we dont have an entry for this ip yet */
for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
- if (ctdb_same_sockaddr(&addr, &vnn->public_address)) {
+ if (ctdb_same_sockaddr(addr, &vnn->public_address)) {
DEBUG(DEBUG_CRIT,("Same ip '%s' specified multiple times in the public address list \n",
- inet_ntoa(addr.sin_addr)));
+ ctdb_addr_to_str(addr)));
return -1;
}
}
@@ -411,7 +409,7 @@ static int ctdb_add_public_address(struct ctdb_context *ctdb, struct sockaddr_in
vnn = talloc_zero(ctdb, struct ctdb_vnn);
CTDB_NO_MEMORY_FATAL(ctdb, vnn);
vnn->iface = talloc_strdup(vnn, iface);
- vnn->public_address = addr;
+ vnn->public_address = *addr;
vnn->public_netmask_bits = mask;
vnn->pnn = -1;
@@ -451,7 +449,7 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
for (i=0;i<nlines;i++) {
unsigned mask;
- struct sockaddr_in addr;
+ ctdb_sock_addr addr;
const char *iface;
char *tok;
@@ -474,7 +472,7 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
iface = tok;
}
- if (ctdb_add_public_address(ctdb, addr, mask, iface)) {
+ if (ctdb_add_public_address(ctdb, &addr, mask, iface)) {
DEBUG(DEBUG_CRIT,("Failed to add line %u to the public address list\n", i+1));
talloc_free(lines);
return -1;
@@ -491,7 +489,7 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
struct ctdb_public_ip_list {
struct ctdb_public_ip_list *next;
uint32_t pnn;
- struct sockaddr_in sin;
+ ctdb_sock_addr addr;
};
@@ -529,7 +527,7 @@ static int can_node_serve_ip(struct ctdb_context *ctdb, int32_t pnn,
}
for (i=0;i<public_ips->num;i++) {
- if (ip->sin.sin_addr.s_addr == public_ips->ips[i].sin.sin_addr.s_addr) {
+ if (ctdb_same_ip(&ip->addr, &public_ips->ips[i].addr)) {
/* yes, this node can serve this public ip */
return 0;
}
@@ -579,7 +577,9 @@ static int find_takeover_node(struct ctdb_context *ctdb,
}
}
if (pnn == -1) {
- DEBUG(DEBUG_WARNING,(__location__ " Could not find node to take over public address '%s'\n", inet_ntoa(ip->sin.sin_addr)));
+ DEBUG(DEBUG_WARNING,(__location__ " Could not find node to take over public address '%s'\n",
+ ctdb_addr_to_str(&ip->addr)));
+
return -1;
}
@@ -598,8 +598,8 @@ add_ip_to_merged_list(struct ctdb_context *ctdb,
/* do we already have this ip in our merged list ?*/
for (tmp_ip=ip_list;tmp_ip;tmp_ip=tmp_ip->next) {
- /* we already have this public ip in the list */
- if (tmp_ip->sin.sin_addr.s_addr == ip->sin.sin_addr.s_addr) {
+ /* we already have this public ip in the list */
+ if (ctdb_same_ip(&tmp_ip->addr, &ip->addr)) {
return ip_list;
}
}
@@ -608,7 +608,7 @@ add_ip_to_merged_list(struct ctdb_context *ctdb,
tmp_ip = talloc_zero(tmp_ctx, struct ctdb_public_ip_list);
CTDB_NO_MEMORY_NULL(ctdb, tmp_ip);
tmp_ip->pnn = ip->pnn;
- tmp_ip->sin = ip->sin;
+ tmp_ip->addr = ip->addr;
tmp_ip->next = ip_list;
return tmp_ip;
@@ -734,7 +734,8 @@ try_again:
for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) {
if (tmp_ip->pnn == -1) {
if (find_takeover_node(ctdb, nodemap, mask, tmp_ip, all_ips)) {
- DEBUG(DEBUG_WARNING,("Failed to find node to cover ip %s\n", inet_ntoa(tmp_ip->sin.sin_addr)));
+ DEBUG(DEBUG_WARNING,("Failed to find node to cover ip %s\n",
+ ctdb_addr_to_str(&tmp_ip->addr)));
}
}
}
@@ -801,7 +802,9 @@ try_again:
}
}
if (maxnode == -1) {
- DEBUG(DEBUG_WARNING,(__location__ " Could not find maxnode. May not be able to serve ip '%s'\n", inet_ntoa(tmp_ip->sin.sin_addr)));
+ DEBUG(DEBUG_WARNING,(__location__ " Could not find maxnode. May not be able to serve ip '%s'\n",
+ ctdb_addr_to_str(&tmp_ip->addr)));
+
continue;
}
@@ -864,9 +867,8 @@ finished:
*/
continue;
}
- ip.pnn = tmp_ip->pnn;
- ip.sin.sin_family = AF_INET;
- ip.sin.sin_addr = tmp_ip->sin.sin_addr;
+ ip.pnn = tmp_ip->pnn;
+ ip.addr = tmp_ip->addr;
timeout = TAKEOVER_TIMEOUT();
data.dsize = sizeof(ip);
@@ -900,9 +902,8 @@ finished:
/* this IP won't be taken over */
continue;
}
- ip.pnn = tmp_ip->pnn;
- ip.sin.sin_family = AF_INET;
- ip.sin.sin_addr = tmp_ip->sin.sin_addr;
+ ip.pnn = tmp_ip->pnn;
+ ip.addr = tmp_ip->addr;
timeout = TAKEOVER_TIMEOUT();
data.dsize = sizeof(ip);
@@ -936,7 +937,10 @@ finished:
static int ctdb_client_ip_destructor(struct ctdb_client_ip *ip)
{
DEBUG(DEBUG_DEBUG,("destroying client tcp for %s:%u (client_id %u)\n",
- inet_ntoa(ip->ip.sin_addr), ntohs(ip->ip.sin_port), ip->client_id));
+ ctdb_addr_to_str(&ip->addr),
+ ntohs(ip->addr.ip.sin_port),
+ ip->client_id));
+
DLIST_REMOVE(ip->ctdb->client_ip_list, ip);
return 0;
}
@@ -945,31 +949,36 @@ 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
*/
+//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_tcp_client *p = (struct ctdb_tcp_client *)indata.dptr;
struct ctdb_tcp_list *tcp;
struct ctdb_control_tcp_vnn t;
int ret;
TDB_DATA data;
struct ctdb_client_ip *ip;
struct ctdb_vnn *vnn;
+ ctdb_sock_addr addr;
- vnn = find_public_ip_vnn(ctdb, p->dest);
+ addr.ip = p->dest;
+ 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",
- inet_ntoa(p->dest.sin_addr)));
+ ctdb_addr_to_str((ctdb_sock_addr *)&p->dest)));
}
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",
- inet_ntoa(p->dest.sin_addr),
- client_id, client->pid));
+ ctdb_addr_to_str((ctdb_sock_addr *)&p->dest),
+ client_id, client->pid));
/* failing this call will tell smbd to die */
return -1;
}
@@ -977,8 +986,8 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
ip = talloc(client, struct ctdb_client_ip);
CTDB_NO_MEMORY(ctdb, ip);
- ip->ctdb = ctdb;
- ip->ip = p->dest;
+ ip->ctdb = ctdb;
+ ip->addr.ip = p->dest;
ip->client_id = client_id;
talloc_set_destructor(ip, ctdb_client_ip_destructor);
DLIST_ADD(ctdb->client_ip_list, ip);
@@ -986,21 +995,21 @@ 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.saddr = p->src;
- tcp->connection.daddr = p->dest;
+ tcp->connection.src_addr.ip = p->src;
+ tcp->connection.dst_addr.ip = p->dest;
DLIST_ADD(client->tcp_list, tcp);
- t.src = p->src;
- t.dest = p->dest;
+ t.src.ip = p->src;
+ t.dest.ip = p->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),
- inet_ntoa(p->src.sin_addr),
- (unsigned)ntohs(p->src.sin_port), client_id, client->pid));
+ (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));
/* tell all nodes about this tcp connection */
ret = ctdb_daemon_send_control(ctdb, CTDB_BROADCAST_CONNECTED, 0,
@@ -1015,16 +1024,6 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
}
/*
- see if two sockaddr_in are the same
- */
-static bool same_sockaddr_in(struct sockaddr_in *in1, struct sockaddr_in *in2)
-{
- return in1->sin_family == in2->sin_family &&
- in1->sin_port == in2->sin_port &&
- in1->sin_addr.s_addr == in2->sin_addr.s_addr;
-}
-
-/*
find a tcp address on a list
*/
static struct ctdb_tcp_connection *ctdb_tcp_find(struct ctdb_tcp_array *array,
@@ -1037,8 +1036,8 @@ static struct ctdb_tcp_connection *ctdb_tcp_find(struct ctdb_tcp_array *array,
}
for (i=0;i<array->num;i++) {
- if (same_sockaddr_in(&array->connections[i].saddr, &tcp->saddr) &&
- same_sockaddr_in(&array->connections[i].daddr, &tcp->daddr)) {
+ if (ctdb_same_sockaddr(&array->connections[i].src_addr, &tcp->src_addr) &&
+ ctdb_same_sockaddr(&array->connections[i].dst_addr, &tcp->dst_addr)) {
return &array->connections[i];
}
}
@@ -1057,10 +1056,11 @@ int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
struct ctdb_tcp_connection tcp;
struct ctdb_vnn *vnn;
- vnn = find_public_ip_vnn(ctdb, p->dest);
+ vnn = find_public_ip_vnn(ctdb, &p->dest);
if (vnn == NULL) {
- DEBUG(DEBUG_ERR,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
- inet_ntoa(p->dest.sin_addr)));
+ DEBUG(DEBUG_ERR,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n",
+ ctdb_addr_to_str(&p->dest)));
+
return -1;
}
@@ -1079,21 +1079,21 @@ int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
tcparray->connections = talloc_size(tcparray, sizeof(struct ctdb_tcp_connection));
CTDB_NO_MEMORY(ctdb, tcparray->connections);
- tcparray->connections[tcparray->num].saddr = p->src;
- tcparray->connections[tcparray->num].daddr = p->dest;
+ tcparray->connections[tcparray->num].src_addr = p->src;
+ tcparray->connections[tcparray->num].dst_addr = p->dest;
tcparray->num++;
return 0;
}
/* Do we already have this tickle ?*/
- tcp.saddr = p->src;
- tcp.daddr = p->dest;
+ tcp.src_addr = p->src;
+ tcp.dst_addr = p->dest;
if (ctdb_tcp_find(vnn->tcp_array, &tcp) != NULL) {
DEBUG(DEBUG_DEBUG,("Already had tickle info for %s:%u for vnn:%u\n",
- inet_ntoa(tcp.daddr.sin_addr),
- ntohs(tcp.daddr.sin_port),
- vnn->pnn));
+ ctdb_addr_to_str(&tcp.dst_addr),
+ ntohs(tcp.dst_addr.ip.sin_port),
+ vnn->pnn));
return 0;
}
@@ -1104,14 +1104,14 @@ int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
CTDB_NO_MEMORY(ctdb, tcparray->connections);
vnn->tcp_array = tcparray;
- tcparray->connections[tcparray->num].saddr = p->src;
- tcparray->connections[tcparray->num].daddr = p->dest;
+ tcparray->connections[tcparray->num].src_addr = p->src;
+ tcparray->connections[tcparray->num].dst_addr = p->dest;
tcparray->num++;
DEBUG(DEBUG_INFO,("Added tickle info for %s:%u from vnn %u\n",
- inet_ntoa(tcp.daddr.sin_addr),
- ntohs(tcp.daddr.sin_port),
- vnn->pnn));
+ ctdb_addr_to_str(&tcp.dst_addr),
+ ntohs(tcp.dst_addr.ip.sin_port),
+ vnn->pnn));
return 0;
}
@@ -1125,10 +1125,11 @@ int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tcp_connection *conn)
{
struct ctdb_tcp_connection *tcpp;
- struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, conn->daddr);
+ struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, &conn->dst_addr);
if (vnn == NULL) {
- DEBUG(DEBUG_ERR,(__location__ " unable to find public address %s\n", inet_ntoa(conn->daddr.sin_addr)));
+ DEBUG(DEBUG_ERR,(__location__ " unable to find public address %s\n",
+ ctdb_addr_to_str(&conn->dst_addr)));
return;
}
@@ -1137,8 +1138,8 @@ static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tc
*/
if (vnn->tcp_array == NULL) {
DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist (array is empty) %s:%u\n",
- inet_ntoa(conn->daddr.sin_addr),
- ntohs(conn->daddr.sin_port)));
+ ctdb_addr_to_str(&conn->dst_addr),
+ ntohs(conn->dst_addr.ip.sin_port)));
return;
}
@@ -1149,8 +1150,8 @@ static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tc
tcpp = ctdb_tcp_find(vnn->tcp_array, conn);
if (tcpp == NULL) {
DEBUG(DEBUG_INFO,("Trying to remove tickle that doesnt exist %s:%u\n",
- inet_ntoa(conn->daddr.sin_addr),
- ntohs(conn->daddr.sin_port)));
+ ctdb_addr_to_str(&conn->dst_addr),
+ ntohs(conn->dst_addr.ip.sin_port)));
return;
}
@@ -1174,8 +1175,8 @@ static void ctdb_remove_tcp_connection(struct ctdb_context *ctdb, struct ctdb_tc
vnn->tcp_update_needed = true;
DEBUG(DEBUG_INFO,("Removed tickle info for %s:%u\n",
- inet_ntoa(conn->saddr.sin_addr),
- ntohs(conn->saddr.sin_port)));
+ ctdb_addr_to_str(&conn->src_addr),
+ ntohs(conn->src_addr.ip.sin_port)));
}
@@ -1212,15 +1213,14 @@ void ctdb_release_all_ips(struct ctdb_context *ctdb)
struct ctdb_vnn *vnn;
for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
- if (!ctdb_sys_have_ip(vnn->public_address)) {
+ if (!ctdb_sys_have_ip(&vnn->public_address)) {
continue;
}
ctdb_event_script(ctdb, "releaseip %s %s %u",
vnn->iface,
- inet_ntoa(vnn->public_address.sin_addr),
+ talloc_strdup(ctdb, ctdb_addr_to_str(&vnn->public_address)),
vnn->public_netmask_bits);
-// convert when vnn->public_address is no longer a sockaddr_in
- release_kill_clients(ctdb, (ctdb_sock_addr *)&vnn->public_address);
+ release_kill_clients(ctdb, &vnn->public_address);
}
}
@@ -1252,8 +1252,8 @@ int32_t ctdb_control_get_public_ips(struct ctdb_context *ctdb,
ips->num = num;
i = 0;
for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
- ips->ips[i].pnn = vnn->pnn;
- ips->ips[i].sin = vnn->public_address;
+ ips->ips[i].pnn = vnn->pnn;
+ ips->ips[i].addr = vnn->public_address;
i++;
}
@@ -1279,8 +1279,8 @@ struct ctdb_kill_tcp {
a tcp connection that is to be killed
*/
struct ctdb_killtcp_con {
- struct sockaddr_in src;
- struct sockaddr_in dst;
+ ctdb_sock_addr src_addr;
+ ctdb_sock_addr dst_addr;
int count;
struct ctdb_kill_tcp *killtcp;
};
@@ -1290,15 +1290,41 @@ struct ctdb_killtcp_con {
this key is used to insert and lookup matching socketpairs that are
to be tickled and RST
*/
-#define KILLTCP_KEYLEN 4
-static uint32_t *killtcp_key(struct sockaddr_in *src, struct sockaddr_in *dst)
+#define KILLTCP_KEYLEN 10
+static uint32_t *killtcp_key(ctdb_sock_addr *src, ctdb_sock_addr *dst)
{
static uint32_t key[KILLTCP_KEYLEN];
- key[0] = dst->sin_addr.s_addr;
- key[1] = src->sin_addr.s_addr;
- key[2] = dst->sin_port;
- key[3] = src->sin_port;
+ bzero(key, sizeof(key));
+
+ if (src->sa.sa_family != dst->sa.sa_family) {
+ DEBUG(DEBUG_ERR, (__location__ " ERROR, different families passed :%u vs %u\n", src->sa.sa_family, dst->sa.sa_family));
+ return key;
+ }
+
+ switch (src->sa.sa_family) {
+ case AF_INET:
+ key[0] = dst->ip.sin_addr.s_addr;
+ key[1] = src->ip.sin_addr.s_addr;
+ key[2] = dst->ip.sin_port;
+ key[3] = src->ip.sin_port;
+ break;
+ case AF_INET6:
+ key[0] = dst->ip6.sin6_addr.s6_addr32[3];
+ key[1] = src->ip6.sin6_addr.s6_addr32[3];
+ key[2] = dst->ip6.sin6_addr.s6_addr32[2];
+ key[3] = src->ip6.sin6_addr.s6_addr32[2];
+ key[4] = dst->ip6.sin6_addr.s6_addr32[1];
+ key[5] = src->ip6.sin6_addr.s6_addr32[1];
+ key[6] = dst->ip6.sin6_addr.s6_addr32[0];
+ key[7] = src->ip6.sin6_addr.s6_addr32[0];
+ key[8] = dst->ip6.sin6_port;
+ key[9] = src->ip6.sin6_port;
+ break;
+ default:
+ DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family passed :%u\n", src->sa.sa_family));
+ return key;
+ }
return key;
}
@@ -1311,7 +1337,7 @@ static void capture_tcp_handler(struct event_context *ev, struct fd_event *fde,
{
struct ctdb_kill_tcp *killtcp = talloc_get_type(private_data, struct ctdb_kill_tcp);
struct ctdb_killtcp_con *con;
- struct sockaddr_in src, dst;
+ ctdb_sock_addr src, dst;
uint32_t ack_seq, seq;
if (!(flags & EVENT_FD_READ)) {
@@ -1339,12 +1365,12 @@ static void capture_tcp_handler(struct event_context *ev, struct fd_event *fde,
/* This one has been tickled !
now reset him and remove him from the list.
*/
- DEBUG(DEBUG_INFO, ("sending a tcp reset to kill connection :%d -> %s:%d\n", ntohs(con->dst.sin_port), inet_ntoa(con->src.sin_addr), ntohs(con->src.sin_port)));
+ DEBUG(DEBUG_INFO, ("sending a tcp reset to kill connection :%d -> %s:%d\n",
+ ntohs(con->dst_addr.ip.sin_port),
+ ctdb_addr_to_str(&con->src_addr),
+ ntohs(con->src_addr.ip.sin_port)));
- ctdb_sys_send_tcp(
- (ctdb_sock_addr *)&con->dst,
- (ctdb_sock_addr *)&con->src,
- ack_seq, seq, 1);
+ ctdb_sys_send_tcp(&con->dst_addr, &con->src_addr, ack_seq, seq, 1);
talloc_free(con);
}
@@ -1367,8 +1393,8 @@ static void tickle_connection_traverse(void *param, void *data)
/* othervise, try tickling it again */
con->count++;
ctdb_sys_send_tcp(
- (ctdb_sock_addr *)&con->dst,
- (ctdb_sock_addr *)&con->src,
+ (ctdb_sock_addr *)&con->dst_addr,
+ (ctdb_sock_addr *)&con->src_addr,
0, 0, 0);
}
@@ -1427,20 +1453,21 @@ static void *add_killtcp_callback(void *parm, void *data)
add a tcp socket to the list of connections we want to RST
*/
static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
- struct sockaddr_in *src, struct sockaddr_in *dst)
+ ctdb_sock_addr *src,
+ ctdb_sock_addr *dst)
{
struct ctdb_kill_tcp *killtcp;
struct ctdb_killtcp_con *con;
struct ctdb_vnn *vnn;
- vnn = find_public_ip_vnn(ctdb, *dst);
+ vnn = find_public_ip_vnn(ctdb, dst);
if (vnn == NULL) {
- vnn = find_public_ip_vnn(ctdb, *src);
+ vnn = find_public_ip_vnn(ctdb, src);
}
if (vnn == NULL) {
/* if it is not a public ip it could be our 'single ip' */
if (ctdb->single_ip_vnn) {
- if (ctdb_same_ipv4(&ctdb->single_ip_vnn->public_address, dst)) {
+ if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, dst)) {
vnn = ctdb->single_ip_vnn;
}
}
@@ -1475,14 +1502,14 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
*/
con = talloc(killtcp, struct ctdb_killtcp_con);
CTDB_NO_MEMORY(ctdb, con);
- con->src = *src;
- con->dst = *dst;
- con->count = 0;
- con->killtcp = killtcp;
+ con->src_addr = *src;
+ con->dst_addr = *dst;
+ con->count = 0;
+ con->killtcp = killtcp;
trbt_insertarray32_callback(killtcp->connections,
- KILLTCP_KEYLEN, killtcp_key(&con->dst, &con->src),
+ KILLTCP_KEYLEN, killtcp_key(&con->dst_addr, &con->src_addr),
add_killtcp_callback, con);
/*
@@ -1511,8 +1538,8 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
/* tickle him once now */
ctdb_sys_send_tcp(
- (ctdb_sock_addr *)&con->dst,
- (ctdb_sock_addr *)&con->src,
+ &con->dst_addr,
+ &con->src_addr,
0, 0, 0);
return 0;
@@ -1530,7 +1557,7 @@ int32_t ctdb_control_kill_tcp(struct ctdb_context *ctdb, TDB_DATA indata)
{
struct ctdb_control_killtcp *killtcp = (struct ctdb_control_killtcp *)indata.dptr;
- return ctdb_killtcp_add_connection(ctdb, &killtcp->src, &killtcp->dst);
+ return ctdb_killtcp_add_connection(ctdb, &killtcp->src_addr, &killtcp->dst_addr);
}
/*
@@ -1563,10 +1590,11 @@ int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
return -1;
}
- vnn = find_public_ip_vnn(ctdb, list->ip);
+ vnn = find_public_ip_vnn(ctdb, &list->addr);
if (vnn == NULL) {
DEBUG(DEBUG_INFO,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n",
- inet_ntoa(list->ip.sin_addr)));
+ ctdb_addr_to_str(&list->addr)));
+
return 1;
}
@@ -1597,16 +1625,17 @@ int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
*/
int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA indata, TDB_DATA *outdata)
{
- struct sockaddr_in *ip = (struct sockaddr_in *)indata.dptr;
+ ctdb_sock_addr *addr = (ctdb_sock_addr *)indata.dptr;
struct ctdb_control_tcp_tickle_list *list;
struct ctdb_tcp_array *tcparray;
int num;
struct ctdb_vnn *vnn;
- vnn = find_public_ip_vnn(ctdb, *ip);
+ vnn = find_public_ip_vnn(ctdb, addr);
if (vnn == NULL) {
DEBUG(DEBUG_ERR,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n",
- inet_ntoa(ip->sin_addr)));
+ ctdb_addr_to_str(addr)));
+
return 1;
}
@@ -1625,7 +1654,7 @@ int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
CTDB_NO_MEMORY(ctdb, outdata->dptr);
list = (struct ctdb_control_tcp_tickle_list *)outdata->dptr;
- list->ip = *ip;
+ list->addr = *addr;
list->tickles.num = num;
if (num) {
memcpy(&list->tickles.connections[0], tcparray->connections,
@@ -1641,7 +1670,7 @@ int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
*/
static int ctdb_ctrl_set_tcp_tickles(struct ctdb_context *ctdb,
struct timeval timeout, uint32_t destnode,
- struct sockaddr_in *ip,
+ ctdb_sock_addr *addr,
struct ctdb_tcp_array *tcparray)
{
int ret, num;
@@ -1661,7 +1690,7 @@ static int ctdb_ctrl_set_tcp_tickles(struct ctdb_context *ctdb,
CTDB_NO_MEMORY(ctdb, data.dptr);
list = (struct ctdb_control_tcp_tickle_list *)data.dptr;
- list->ip = *ip;
+ list->addr = *addr;
list->tickles.num = num;
if (tcparray) {
memcpy(&list->tickles.connections[0], tcparray->connections, sizeof(struct ctdb_tcp_connection) * num);
@@ -1709,8 +1738,8 @@ static void ctdb_update_tcp_tickles(struct event_context *ev,
&vnn->public_address,
vnn->tcp_array);
if (ret != 0) {
- DEBUG(DEBUG_ERR,("Failed to send the tickle update for public address %s\n",
- inet_ntoa(vnn->public_address.sin_addr)));
+ DEBUG(DEBUG_ERR,("Failed to send the tickle update for public address %s\n",
+ ctdb_addr_to_str(&vnn->public_address)));
}
}
@@ -1833,7 +1862,7 @@ int32_t ctdb_control_add_public_address(struct ctdb_context *ctdb, TDB_DATA inda
return -1;
}
- return ctdb_add_public_address(ctdb, pub->sin, pub->mask, &pub->iface[0]);
+ return ctdb_add_public_address(ctdb, &pub->addr, pub->mask, &pub->iface[0]);
}
/*
@@ -1869,7 +1898,7 @@ int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA inda
/* walk over all public addresses until we find a match */
for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
- if (ctdb_same_ipv4(&vnn->public_address, &pub->sin)) {
+ if (ctdb_same_ip(&vnn->public_address, &pub->addr)) {
TALLOC_CTX *mem_ctx = talloc_new(ctdb);
DLIST_REMOVE(ctdb->vnn, vnn);
@@ -1879,7 +1908,7 @@ int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA inda
mem_ctx, delete_ip_callback, mem_ctx,
"releaseip %s %s %u",
vnn->iface,
- inet_ntoa(vnn->public_address.sin_addr),
+ talloc_strdup(mem_ctx, ctdb_addr_to_str(&vnn->public_address)),
vnn->public_netmask_bits);
talloc_free(vnn);
if (ret != 0) {