summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ctdb/client/ctdb_client.c6
-rw-r--r--ctdb/common/ctdb_util.c109
-rw-r--r--ctdb/common/system_aix.c85
-rw-r--r--ctdb/common/system_linux.c108
-rw-r--r--ctdb/include/ctdb_private.h53
-rw-r--r--ctdb/server/ctdb_control.c4
-rw-r--r--ctdb/server/ctdb_daemon.c2
-rw-r--r--ctdb/server/ctdb_recover.c5
-rw-r--r--ctdb/server/ctdb_recoverd.c11
-rw-r--r--ctdb/server/ctdb_takeover.c377
-rw-r--r--ctdb/server/ctdbd.c6
-rw-r--r--ctdb/tcp/tcp_connect.c131
-rw-r--r--ctdb/tests/nodes.txt8
-rw-r--r--ctdb/tests/nodes6.txt11
-rwxr-xr-xctdb/tests/start_daemons.sh9
-rw-r--r--ctdb/tools/ctdb.c94
-rw-r--r--ctdb/utils/ipmux/ipmux.c8
17 files changed, 573 insertions, 454 deletions
diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
index 0d853746aac..dfcd4d90e79 100644
--- a/ctdb/client/ctdb_client.c
+++ b/ctdb/client/ctdb_client.c
@@ -2422,15 +2422,15 @@ int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
struct timeval timeout, uint32_t destnode,
TALLOC_CTX *mem_ctx,
- struct sockaddr_in *ip,
+ ctdb_sock_addr *addr,
struct ctdb_control_tcp_tickle_list **list)
{
int ret;
TDB_DATA data, outdata;
int32_t status;
- data.dptr = (uint8_t*)ip;
- data.dsize = sizeof(struct sockaddr_in);
+ data.dptr = (uint8_t*)addr;
+ data.dsize = sizeof(ctdb_sock_addr);
ret = ctdb_control(ctdb, destnode, 0,
CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
diff --git a/ctdb/common/ctdb_util.c b/ctdb/common/ctdb_util.c
index b096a52946b..20238363b60 100644
--- a/ctdb/common/ctdb_util.c
+++ b/ctdb/common/ctdb_util.c
@@ -362,40 +362,6 @@ void set_close_on_exec(int fd)
}
-/*
- parse a ip:num pair with the given separator
- */
-static bool parse_ip_num(const char *s, struct in_addr *addr, unsigned *num, const char sep)
-{
- const char *p;
- char *endp = NULL;
- char buf[16];
-
- p = strchr(s, sep);
- if (p == NULL) {
- return false;
- }
-
- if (p - s > 15) {
- return false;
- }
-
- *num = strtoul(p+1, &endp, 10);
- if (endp == NULL || *endp != 0) {
- /* trailing garbage */
- return false;
- }
-
- strlcpy(buf, s, 1+p-s);
-
- if (inet_aton(buf, addr) == 0) {
- return false;
- }
-
- return true;
-}
-
-
static bool parse_ipv4(const char *s, unsigned port, ctdb_sock_addr *saddr)
{
saddr->ip.sin_family = AF_INET;
@@ -492,31 +458,51 @@ bool parse_ip(const char *addr, ctdb_sock_addr *saddr)
/*
parse a ip/mask pair
*/
-bool parse_ip_mask(const char *s, struct sockaddr_in *ip, unsigned *mask)
+bool parse_ip_mask(const char *str, ctdb_sock_addr *addr, unsigned *mask)
{
- ZERO_STRUCT(*ip);
+ TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+ char *s, *p;
+ char *endp = NULL;
+ bool ret;
+
+ ZERO_STRUCT(*addr);
+ s = talloc_strdup(tmp_ctx, str);
+ if (s == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " Failed strdup()\n"));
+ talloc_free(tmp_ctx);
+ return false;
+ }
- if (!parse_ip_num(s, &ip->sin_addr, mask, '/')) {
+ p = rindex(s, '/');
+ if (p == NULL) {
+ DEBUG(DEBUG_ERR, (__location__ " This addr: %s does not contain a mask\n", s));
+ talloc_free(tmp_ctx);
return false;
}
- if (*mask > 32) {
+
+ *mask = strtoul(p+1, &endp, 10);
+ if (endp == NULL || *endp != 0) {
+ /* trailing garbage */
+ DEBUG(DEBUG_ERR, (__location__ " Trailing garbage after the mask in %s\n", s));
+ talloc_free(tmp_ctx);
return false;
}
- ip->sin_family = AF_INET;
- ip->sin_port = 0;
- return true;
-}
+ *p = 0;
-/*
- compare two sockaddr_in structures - matching only on IP
- */
-bool ctdb_same_ipv4(const struct sockaddr_in *ip1, const struct sockaddr_in *ip2)
-{
- return ip1->sin_family == ip2->sin_family &&
- ip1->sin_addr.s_addr == ip2->sin_addr.s_addr;
+
+ /* now is this a ipv4 or ipv6 address ?*/
+ p = index(s, ':');
+ if (p == NULL) {
+ ret = parse_ipv4(s, 0, addr);
+ } else {
+ ret = parse_ipv6(s, 0, addr);
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
}
-bool ctdb_same_ip(ctdb_sock_addr *ip1, ctdb_sock_addr *ip2)
+bool ctdb_same_ip(const ctdb_sock_addr *ip1, const ctdb_sock_addr *ip2)
{
if (ip1->sa.sa_family != ip2->sa.sa_family) {
return false;
@@ -538,13 +524,30 @@ bool ctdb_same_ip(ctdb_sock_addr *ip1, ctdb_sock_addr *ip2)
}
/*
- compare two sockaddr_in structures
+ compare two ctdb_sock_addr structures
*/
-bool ctdb_same_sockaddr(const struct sockaddr_in *ip1, const struct sockaddr_in *ip2)
+bool ctdb_same_sockaddr(const ctdb_sock_addr *ip1, const ctdb_sock_addr *ip2)
{
- return ctdb_same_ipv4(ip1, ip2) && ip1->sin_port == ip2->sin_port;
+ return ctdb_same_ip(ip1, ip2) && ip1->ip.sin_port == ip2->ip.sin_port;
}
+char *ctdb_addr_to_str(ctdb_sock_addr *addr)
+{
+ static char cip[128] = "";
+
+ switch (addr->sa.sa_family) {
+ case AF_INET:
+ inet_ntop(addr->ip.sin_family, &addr->ip.sin_addr, cip, sizeof(cip));
+ break;
+ case AF_INET6:
+ inet_ntop(addr->ip6.sin6_family, &addr->ip6.sin6_addr, cip, sizeof(cip));
+ break;
+ default:
+ DEBUG(DEBUG_ERR, (__location__ " ERROR, unknown family %u\n", addr->sa.sa_family));
+ }
+
+ return cip;
+}
void ctdb_block_signal(int signum)
diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c
index b08692d1774..03d997ff6fc 100644
--- a/ctdb/common/system_aix.c
+++ b/ctdb/common/system_aix.c
@@ -194,17 +194,17 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
we try to bind to it, and if that fails then we don't have that IP
on an interface
*/
-bool ctdb_sys_have_ip(struct sockaddr_in ip)
+bool ctdb_sys_have_ip(ctdb_sock_addr *addr)
{
int s;
int ret;
- ip.sin_port = 0;
- s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ addr->sa.sa_port = 0;
+ s = socket(addr->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if (s == -1) {
return false;
}
- ret = bind(s, (struct sockaddr *)&ip, sizeof(ip));
+ ret = bind(s, (struct sockaddr *)addr, sizeof(ctdb_sock_addr));
close(s);
return ret == 0;
}
@@ -306,7 +306,7 @@ static int aix_get_mac_addr(const char *device_name, uint8_t mac[6])
}
int ctdb_sys_read_tcp_packet(int s, void *private_data,
- struct sockaddr_in *src, struct sockaddr_in *dst,
+ ctdb_sock_addr *src, ctdb_sock_addr *dst,
uint32_t *ack_seq, uint32_t *seq)
{
int ret;
@@ -326,44 +326,53 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
/* Ethernet */
eth = (struct ether_header *)buffer;
- /* We are only interested in IP packets */
- if (eth->ether_type != htons(ETHERTYPE_IP)) {
- return -1;
- }
+ /* we want either IPv4 or IPv6 */
+ if (eth->ether_type == htons(ETHERTYPE_IP)) {
+ /* IP */
+ ip = (struct ip *)(eth+1);
- /* IP */
- ip = (struct ip *)(eth+1);
+ /* We only want IPv4 packets */
+ if (ip->ip_v != 4) {
+ return -1;
+ }
+ /* Dont look at fragments */
+ if ((ntohs(ip->ip_off)&0x1fff) != 0) {
+ return -1;
+ }
+ /* we only want TCP */
+ if (ip->ip_p != IPPROTO_TCP) {
+ return -1;
+ }
- /* We only want IPv4 packets */
- if (ip->ip_v != 4) {
- return -1;
- }
- /* Dont look at fragments */
- if ((ntohs(ip->ip_off)&0x1fff) != 0) {
- return -1;
- }
- /* we only want TCP */
- if (ip->ip_p != IPPROTO_TCP) {
- return -1;
- }
+ /* make sure its not a short packet */
+ if (offsetof(struct tcphdr, th_ack) + 4 +
+ (ip->ip_hl*4) > ret) {
+ return -1;
+ }
+ /* TCP */
+ tcp = (struct tcphdr *)((ip->ip_hl*4) + (char *)ip);
+
+ /* tell the caller which one we've found */
+ src->ip.sin_family = AF_INET;
+ src->sin_addr.s_addr = ip->ip_src.s_addr;
+ src->sin_port = tcp->th_sport;
+ dst->ip.sin_family = AF_INET;
+ dst->sin_addr.s_addr = ip->ip_dst.s_addr;
+ dst->sin_port = tcp->th_dport;
+ *ack_seq = tcp->th_ack;
+ *seq = tcp->th_seq;
- /* make sure its not a short packet */
- if (offsetof(struct tcphdr, th_ack) + 4 +
- (ip->ip_hl*4) > ret) {
- return -1;
+
+ return 0;
+#ifndef ETHERTYPE_IP6
+#define ETHERTYPE_IP6 0x86dd
+#endif
+ } else if (eth->ether_type == htons(ETHERTYPE_IP)) {
+see system_linux.c for what should go in here
+ return 0;
}
- /* TCP */
- tcp = (struct tcphdr *)((ip->ip_hl*4) + (char *)ip);
-
- /* tell the caller which one we've found */
- src->sin_addr.s_addr = ip->ip_src.s_addr;
- src->sin_port = tcp->th_sport;
- dst->sin_addr.s_addr = ip->ip_dst.s_addr;
- dst->sin_port = tcp->th_dport;
- *ack_seq = tcp->th_ack;
- *seq = tcp->th_seq;
- return 0;
+ return -1;
}
diff --git a/ctdb/common/system_linux.c b/ctdb/common/system_linux.c
index 32db545b09f..760877fe3ad 100644
--- a/ctdb/common/system_linux.c
+++ b/ctdb/common/system_linux.c
@@ -344,17 +344,17 @@ int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
ifname, if non-NULL, will return the name of the interface this ip is tied to
*/
-bool ctdb_sys_have_ip(struct sockaddr_in ip)
+bool ctdb_sys_have_ip(ctdb_sock_addr *addr)
{
int s;
int ret;
- ip.sin_port = 0;
- s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ addr->ip.sin_port = 0;
+ s = socket(addr->sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if (s == -1) {
return false;
}
- ret = bind(s, (struct sockaddr *)&ip, sizeof(ip));
+ ret = bind(s, (struct sockaddr *)addr, sizeof(ctdb_sock_addr));
close(s);
return ret == 0;
@@ -395,7 +395,7 @@ int ctdb_sys_close_capture_socket(void *private_data)
called when the raw socket becomes readable
*/
int ctdb_sys_read_tcp_packet(int s, void *private_data,
- struct sockaddr_in *src, struct sockaddr_in *dst,
+ ctdb_sock_addr *src, ctdb_sock_addr *dst,
uint32_t *ack_seq, uint32_t *seq)
{
int ret;
@@ -403,6 +403,7 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
char pkt[RCVPKTSIZE];
struct ether_header *eth;
struct iphdr *ip;
+ struct ip6_hdr *ip6;
struct tcphdr *tcp;
ret = recv(s, pkt, RCVPKTSIZE, MSG_TRUNC);
@@ -413,45 +414,74 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
/* Ethernet */
eth = (struct ether_header *)pkt;
- /* We only want IP packets */
- if (ntohs(eth->ether_type) != ETHERTYPE_IP) {
- return -1;
- }
-
- /* IP */
- ip = (struct iphdr *)(eth+1);
+ /* we want either IPv4 or IPv6 */
+ if (ntohs(eth->ether_type) == ETHERTYPE_IP) {
+ /* IP */
+ ip = (struct iphdr *)(eth+1);
- /* We only want IPv4 packets */
- if (ip->version != 4) {
- return -1;
- }
- /* Dont look at fragments */
- if ((ntohs(ip->frag_off)&0x1fff) != 0) {
- return -1;
- }
- /* we only want TCP */
- if (ip->protocol != IPPROTO_TCP) {
- return -1;
- }
+ /* We only want IPv4 packets */
+ if (ip->version != 4) {
+ return -1;
+ }
+ /* Dont look at fragments */
+ if ((ntohs(ip->frag_off)&0x1fff) != 0) {
+ return -1;
+ }
+ /* we only want TCP */
+ if (ip->protocol != IPPROTO_TCP) {
+ return -1;
+ }
- /* make sure its not a short packet */
- if (offsetof(struct tcphdr, ack_seq) + 4 +
- (ip->ihl*4) + sizeof(*eth) > ret) {
- return -1;
- }
+ /* make sure its not a short packet */
+ if (offsetof(struct tcphdr, ack_seq) + 4 +
+ (ip->ihl*4) + sizeof(*eth) > ret) {
+ return -1;
+ }
+ /* TCP */
+ tcp = (struct tcphdr *)((ip->ihl*4) + (char *)ip);
+
+ /* tell the caller which one we've found */
+ src->ip.sin_family = AF_INET;
+ src->ip.sin_addr.s_addr = ip->saddr;
+ src->ip.sin_port = tcp->source;
+ dst->ip.sin_family = AF_INET;
+ dst->ip.sin_addr.s_addr = ip->daddr;
+ dst->ip.sin_port = tcp->dest;
+ *ack_seq = tcp->ack_seq;
+ *seq = tcp->seq;
+
+ return 0;
+#ifndef ETHERTYPE_IP6
+#define ETHERTYPE_IP6 0x86dd
+#endif
+ } else if (ntohs(eth->ether_type) == ETHERTYPE_IP6) {
+ /* IP6 */
+ ip6 = (struct ip6_hdr *)(eth+1);
+
+ /* we only want TCP */
+ if (ip6->ip6_nxt != IPPROTO_TCP) {
+ return -1;
+ }
- /* TCP */
- tcp = (struct tcphdr *)((ip->ihl*4) + (char *)ip);
+ /* TCP */
+ tcp = (struct tcphdr *)(ip6+1);
- /* tell the caller which one we've found */
- src->sin_addr.s_addr = ip->saddr;
- src->sin_port = tcp->source;
- dst->sin_addr.s_addr = ip->daddr;
- dst->sin_port = tcp->dest;
- *ack_seq = tcp->ack_seq;
- *seq = tcp->seq;
+ /* tell the caller which one we've found */
+ src->ip6.sin6_family = AF_INET6;
+ src->ip6.sin6_port = tcp->source;
+ src->ip6.sin6_addr = ip6->ip6_src;
- return 0;
+ dst->ip6.sin6_family = AF_INET6;
+ dst->ip6.sin6_port = tcp->source;
+ dst->ip6.sin6_addr = ip6->ip6_dst;
+
+ *ack_seq = tcp->ack_seq;
+ *seq = tcp->seq;
+
+ return 0;
+ }
+
+ return -1;
}
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index f44a940a84e..f73f9ef963f 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -61,8 +61,8 @@ typedef union {
a tcp connection description
*/
struct ctdb_tcp_connection {
- struct sockaddr_in saddr;
- struct sockaddr_in daddr;
+ ctdb_sock_addr src_addr;
+ ctdb_sock_addr dst_addr;
};
/* the wire representation for a tcp tickle array */
@@ -73,7 +73,7 @@ struct ctdb_tcp_wire_array {
/* the list of tcp tickles used by get/set tcp tickle list */
struct ctdb_control_tcp_tickle_list {
- struct sockaddr_in ip;
+ ctdb_sock_addr addr;
struct ctdb_tcp_wire_array tickles;
};
@@ -170,7 +170,7 @@ struct ctdb_vnn {
struct ctdb_vnn *prev, *next;
const char *iface;
- struct sockaddr_in public_address;
+ ctdb_sock_addr public_address;
uint8_t public_netmask_bits;
/* the node number that is serving this public address, if any.
@@ -563,26 +563,27 @@ struct ctdb_control_set_call {
/*
struct for tcp_client control
+ used by samba can not modify
*/
-struct ctdb_control_tcp {
- struct sockaddr_in src;
- struct sockaddr_in dest;
+struct ctdb_tcp_client {
+ struct sockaddr_in src; // samba uses this
+ struct sockaddr_in dest;// samba uses this
};
/*
struct for kill_tcp control
*/
struct ctdb_control_killtcp {
- struct sockaddr_in src;
- struct sockaddr_in dst;
+ ctdb_sock_addr src_addr;
+ ctdb_sock_addr dst_addr;
};
/*
- struct holding a sockaddr_in and an interface name,
+ struct holding a ctdb_sock_addr and an interface name,
used to add/remove public addresses
*/
struct ctdb_control_ip_iface {
- struct sockaddr_in sin;
+ ctdb_sock_addr addr;
uint32_t mask;
uint32_t len;
char iface[1];
@@ -603,8 +604,8 @@ struct ctdb_control_gratious_arp {
struct for tcp_add and tcp_remove controls
*/
struct ctdb_control_tcp_vnn {
- struct sockaddr_in src;
- struct sockaddr_in dest;
+ ctdb_sock_addr src;
+ ctdb_sock_addr dest;
};
/*
@@ -804,13 +805,11 @@ enum ctdb_trans2_commit_error {
void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void ctdb_fatal(struct ctdb_context *ctdb, const char *msg);
bool ctdb_same_address(struct ctdb_address *a1, struct ctdb_address *a2);
-bool parse_ip_mask(const char *s, struct sockaddr_in *ip, unsigned *mask);
int ctdb_parse_address(struct ctdb_context *ctdb,
TALLOC_CTX *mem_ctx, const char *str,
struct ctdb_address *address);
-bool ctdb_same_ipv4(const struct sockaddr_in *ip1, const struct sockaddr_in *ip2);
-bool ctdb_same_ip(ctdb_sock_addr *ip1, ctdb_sock_addr *ip2);
-bool ctdb_same_sockaddr(const struct sockaddr_in *ip1, const struct sockaddr_in *ip2);
+bool ctdb_same_ip(const ctdb_sock_addr *ip1, const ctdb_sock_addr *ip2);
+bool ctdb_same_sockaddr(const ctdb_sock_addr *ip1, const ctdb_sock_addr *ip2);
uint32_t ctdb_hash(const TDB_DATA *key);
uint32_t ctdb_hash_string(const char *str);
void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
@@ -1085,8 +1084,7 @@ struct ctdb_control_list_tunable {
struct ctdb_node_and_flags {
uint32_t pnn;
uint32_t flags;
- struct sockaddr_in sin;
-
+ ctdb_sock_addr addr;
};
struct ctdb_node_map {
@@ -1191,7 +1189,7 @@ int32_t ctdb_control_end_recovery(struct ctdb_context *ctdb,
struct ctdb_public_ip {
uint32_t pnn;
- struct sockaddr_in sin;
+ ctdb_sock_addr addr;
};
int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
uint32_t destnode, struct ctdb_public_ip *ip);
@@ -1210,7 +1208,7 @@ int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
/* from takeover/system.c */
int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface);
-bool ctdb_sys_have_ip(struct sockaddr_in ip);
+bool ctdb_sys_have_ip(ctdb_sock_addr *addr);
int ctdb_sys_send_tcp(const ctdb_sock_addr *dest,
const ctdb_sock_addr *src,
uint32_t seq, uint32_t ack, int rst);
@@ -1266,13 +1264,14 @@ int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
void ctdb_start_freeze(struct ctdb_context *ctdb);
-bool parse_ip_port(const char *s, ctdb_sock_addr *saddr);
-bool parse_ip(const char *s, ctdb_sock_addr *saddr);
+bool parse_ip_mask(const char *s, ctdb_sock_addr *addr, unsigned *mask);
+bool parse_ip_port(const char *s, ctdb_sock_addr *addr);
+bool parse_ip(const char *s, ctdb_sock_addr *addr);
+
int ctdb_sys_open_capture_socket(const char *iface, void **private_data);
int ctdb_sys_close_capture_socket(void *private_data);
-int ctdb_sys_read_tcp_packet(int s, void *private_data, struct sockaddr_in *src, struct sockaddr_in *dst,
- uint32_t *ack_seq, uint32_t *seq);
+int ctdb_sys_read_tcp_packet(int s, void *private_data, ctdb_sock_addr *src, ctdb_sock_addr *dst, uint32_t *ack_seq, uint32_t *seq);
int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
struct timeval timeout,
@@ -1299,7 +1298,7 @@ int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
struct timeval timeout,
uint32_t destnode,
TALLOC_CTX *mem_ctx,
- struct sockaddr_in *ip,
+ ctdb_sock_addr *addr,
struct ctdb_control_tcp_tickle_list **list);
@@ -1376,4 +1375,6 @@ int32_t ctdb_control_trans2_finished(struct ctdb_context *ctdb,
int32_t ctdb_control_trans2_error(struct ctdb_context *ctdb,
struct ctdb_req_control *c);
+char *ctdb_addr_to_str(ctdb_sock_addr *addr);
+
#endif
diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c
index edfe344fdb9..68635d6b439 100644
--- a/ctdb/server/ctdb_control.c
+++ b/ctdb/server/ctdb_control.c
@@ -296,7 +296,7 @@ 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));
+ CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_tcp_client));
return ctdb_control_tcp_client(ctdb, client_id, indata);
case CTDB_CONTROL_STARTUP:
@@ -325,7 +325,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
return ctdb_control_kill_tcp(ctdb, indata);
case CTDB_CONTROL_GET_TCP_TICKLE_LIST:
- CHECK_CONTROL_DATA_SIZE(sizeof(struct sockaddr_in));
+ CHECK_CONTROL_DATA_SIZE(sizeof(ctdb_sock_addr));
return ctdb_control_get_tcp_tickle_list(ctdb, indata, outdata);
case CTDB_CONTROL_SET_TCP_TICKLE_LIST:
diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c
index 3978e28fdf4..efe3d753498 100644
--- a/ctdb/server/ctdb_daemon.c
+++ b/ctdb/server/ctdb_daemon.c
@@ -535,7 +535,7 @@ static void ctdb_daemon_read_cb(uint8_t *data, size_t cnt, void *args)
static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde,
uint16_t flags, void *private_data)
{
- struct sockaddr_in addr;
+ struct sockaddr_un addr;
socklen_t len;
int fd;
struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
diff --git a/ctdb/server/ctdb_recover.c b/ctdb/server/ctdb_recover.c
index f0b97acdeed..3243f42faa7 100644
--- a/ctdb/server/ctdb_recover.c
+++ b/ctdb/server/ctdb_recover.c
@@ -163,7 +163,10 @@ ctdb_control_getnodemap(struct ctdb_context *ctdb, uint32_t opcode, TDB_DATA ind
node_map = (struct ctdb_node_map *)outdata->dptr;
node_map->num = num_nodes;
for (i=0; i<num_nodes; i++) {
- inet_aton(ctdb->nodes[i]->address.address, &node_map->nodes[i].sin.sin_addr);
+ if (parse_ip(ctdb->nodes[i]->address.address, &node_map->nodes[i].addr) == 0) {
+ DEBUG(DEBUG_ERR, (__location__ " Failed to parse %s into a sockaddr\n", ctdb->nodes[i]->address.address));
+ }
+
node_map->nodes[i].pnn = ctdb->nodes[i]->pnn;
node_map->nodes[i].flags = ctdb->nodes[i]->flags;
}
diff --git a/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c
index c503aa5489a..c6a4ab322a3 100644
--- a/ctdb/server/ctdb_recoverd.c
+++ b/ctdb/server/ctdb_recoverd.c
@@ -2207,8 +2207,9 @@ static int verify_ip_allocation(struct ctdb_context *ctdb, uint32_t pnn)
*/
for (j=0; j<ips->num; j++) {
if (ips->ips[j].pnn == pnn) {
- if (!ctdb_sys_have_ip(ips->ips[j].sin)) {
- DEBUG(DEBUG_CRIT,("Public address '%s' is missing and we should serve this ip\n", inet_ntoa(ips->ips[j].sin.sin_addr)));
+ if (!ctdb_sys_have_ip(&ips->ips[j].addr)) {
+ DEBUG(DEBUG_CRIT,("Public address '%s' is missing and we should serve this ip\n",
+ ctdb_addr_to_str(&ips->ips[j].addr)));
ret = ctdb_ctrl_freeze(ctdb, CONTROL_TIMEOUT(), CTDB_CURRENT_NODE);
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " Failed to freeze node due to public ip address mismatches\n"));
@@ -2225,8 +2226,10 @@ static int verify_ip_allocation(struct ctdb_context *ctdb, uint32_t pnn)
}
}
} else {
- if (ctdb_sys_have_ip(ips->ips[j].sin)) {
- DEBUG(DEBUG_CRIT,("We are still serving a public address '%s' that we should not be serving.\n", inet_ntoa(ips->ips[j].sin.sin_addr)));
+ if (ctdb_sys_have_ip(&ips->ips[j].addr)) {
+ DEBUG(DEBUG_CRIT,("We are still serving a public address '%s' that we should not be serving.\n",
+ ctdb_addr_to_str(&ips->ips[j].addr)));
+
ret = ctdb_ctrl_freeze(ctdb, CONTROL_TIMEOUT(), CTDB_CURRENT_NODE);
if (ret != 0) {
DEBUG(DEBUG_ERR,(__location__ " Failed to freeze node due to public ip address mismatches\n"));
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) {
diff --git a/ctdb/server/ctdbd.c b/ctdb/server/ctdbd.c
index b7979049c19..4dc0f74b209 100644
--- a/ctdb/server/ctdbd.c
+++ b/ctdb/server/ctdbd.c
@@ -271,13 +271,11 @@ int main(int argc, const char *argv[])
svnn->iface = talloc_strdup(svnn, options.public_interface);
CTDB_NO_MEMORY(ctdb, svnn->iface);
- if (inet_aton(options.single_public_ip,
- &svnn->public_address.sin_addr) == 0) {
+ if (parse_ip(options.single_public_ip,
+ &svnn->public_address) == 0) {
DEBUG(DEBUG_ALERT,("Invalid --single-public-ip argument : %s . This is not a valid ip address. Exiting.\n", options.single_public_ip));
exit(10);
}
- svnn->public_address.sin_family = AF_INET;
- svnn->public_address.sin_port = 0;
}
if (options.public_address_list) {
diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c
index 906a665d044..0e892affe91 100644
--- a/ctdb/tcp/tcp_connect.c
+++ b/ctdb/tcp/tcp_connect.c
@@ -104,16 +104,11 @@ static void ctdb_node_connect_write(struct event_context *ev, struct fd_event *f
static int ctdb_tcp_get_address(struct ctdb_context *ctdb,
- const char *address, struct in_addr *addr)
+ const char *address, ctdb_sock_addr *addr)
{
- if (inet_pton(AF_INET, address, addr) <= 0) {
- struct hostent *he = gethostbyname(address);
- if (he == NULL || he->h_length > sizeof(*addr)) {
- ctdb_set_error(ctdb, "invalid nework address '%s'\n",
- address);
- return -1;
- }
- memcpy(addr, he->h_addr, he->h_length);
+ if (parse_ip(address, addr) == 0) {
+ DEBUG(DEBUG_CRIT, (__location__ " Unparsable address : %s.\n", address));
+ return -1;
}
return 0;
}
@@ -129,26 +124,34 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
struct ctdb_tcp_node *tnode = talloc_get_type(node->private_data,
struct ctdb_tcp_node);
struct ctdb_context *ctdb = node->ctdb;
- struct sockaddr_in sock_in;
- struct sockaddr_in sock_out;
+ ctdb_sock_addr sock_in;
+ ctdb_sock_addr sock_out;
ctdb_tcp_stop_connection(node);
- tnode->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-
- set_nonblocking(tnode->fd);
- set_close_on_exec(tnode->fd);
-
ZERO_STRUCT(sock_out);
#ifdef HAVE_SOCK_SIN_LEN
- sock_out.sin_len = sizeof(sock_out);
+ sock_out.ip.sin_len = sizeof(sock_out);
#endif
- if (ctdb_tcp_get_address(ctdb, node->address.address, &sock_out.sin_addr) != 0) {
+ if (ctdb_tcp_get_address(ctdb, node->address.address, &sock_out) != 0) {
+ return;
+ }
+ switch (sock_out.sa.sa_family) {
+ case AF_INET:
+ sock_out.ip.sin_port = htons(node->address.port);
+ break;
+ case AF_INET6:
+ sock_out.ip6.sin6_port = htons(node->address.port);
+ break;
+ default:
+ DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
+ sock_out.sa.sa_family));
return;
}
- sock_out.sin_port = htons(node->address.port);
- sock_out.sin_family = PF_INET;
+ tnode->fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+ set_nonblocking(tnode->fd);
+ set_close_on_exec(tnode->fd);
/* Bind our side of the socketpair to the same address we use to listen
* on incoming CTDB traffic.
@@ -158,13 +161,11 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
*/
ZERO_STRUCT(sock_in);
#ifdef HAVE_SOCK_SIN_LEN
- sock_in.sin_len = sizeof(sock_in);
+ sock_in.ip.sin_len = sizeof(sock_in);
#endif
- if (ctdb_tcp_get_address(ctdb, ctdb->address.address, &sock_in.sin_addr) != 0) {
+ if (ctdb_tcp_get_address(ctdb, ctdb->address.address, &sock_in) != 0) {
return;
}
- sock_in.sin_port = htons(0); /* INPORT_ANY is not always available */
- sock_in.sin_family = PF_INET;
bind(tnode->fd, (struct sockaddr *)&sock_in, sizeof(sock_in));
if (connect(tnode->fd, (struct sockaddr *)&sock_out, sizeof(sock_out)) != 0 &&
@@ -198,7 +199,7 @@ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde,
{
struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data, struct ctdb_tcp);
- struct sockaddr_in addr;
+ ctdb_sock_addr addr;
socklen_t len;
int fd, nodeid;
struct ctdb_incoming *in;
@@ -210,7 +211,7 @@ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde,
fd = accept(ctcp->listen_fd, (struct sockaddr *)&addr, &len);
if (fd == -1) return;
- incoming_node = inet_ntoa(addr.sin_addr);
+ incoming_node = ctdb_addr_to_str(&addr);
nodeid = ctdb_ip_to_nodeid(ctdb, incoming_node);
if (nodeid == -1) {
@@ -240,10 +241,11 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
{
struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data,
struct ctdb_tcp);
- struct sockaddr_in sock;
+ ctdb_sock_addr sock;
int lock_fd, i;
const char *lock_path = "/tmp/.ctdb_socket_lock";
struct flock lock;
+ int one = 1;
/* in order to ensure that we don't get two nodes with the
same adddress, we must make the bind() and listen() calls
@@ -279,16 +281,37 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
ZERO_STRUCT(sock);
#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
+ sock.ip.sin_len = sizeof(sock);
#endif
- sock.sin_port = htons(ctdb->nodes[i]->address.port);
- sock.sin_family = PF_INET;
if (ctdb_tcp_get_address(ctdb,
ctdb->nodes[i]->address.address,
- &sock.sin_addr) != 0) {
+ &sock) != 0) {
continue;
}
+ switch (sock.sa.sa_family) {
+ case AF_INET:
+ sock.ip.sin_port = htons(ctdb->nodes[i]->address.port);
+ break;
+ case AF_INET6:
+ sock.ip6.sin6_port = htons(ctdb->nodes[i]->address.port);
+ break;
+ default:
+ DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
+ sock.sa.sa_family));
+ continue;
+ }
+
+ ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+ if (ctcp->listen_fd == -1) {
+ ctdb_set_error(ctdb, "socket failed\n");
+ continue;
+ }
+
+ set_close_on_exec(ctcp->listen_fd);
+
+ setsockopt(ctcp->listen_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+
if (bind(ctcp->listen_fd, (struct sockaddr * )&sock,
sizeof(sock)) == 0) {
break;
@@ -341,19 +364,9 @@ int ctdb_tcp_listen(struct ctdb_context *ctdb)
{
struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data,
struct ctdb_tcp);
- struct sockaddr_in sock;
+ ctdb_sock_addr sock;
int one = 1;
- ctcp->listen_fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (ctcp->listen_fd == -1) {
- ctdb_set_error(ctdb, "socket failed\n");
- return -1;
- }
-
- set_close_on_exec(ctcp->listen_fd);
-
- setsockopt(ctcp->listen_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
-
/* we can either auto-bind to the first available address, or we can
use a specified address */
if (!ctdb->address.address) {
@@ -362,16 +375,36 @@ int ctdb_tcp_listen(struct ctdb_context *ctdb)
ZERO_STRUCT(sock);
#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
+ sock.ip.sin_len = sizeof(sock);
#endif
- sock.sin_port = htons(ctdb->address.port);
- sock.sin_family = PF_INET;
-
if (ctdb_tcp_get_address(ctdb, ctdb->address.address,
- &sock.sin_addr) != 0) {
+ &sock) != 0) {
goto failed;
}
+ switch (sock.sa.sa_family) {
+ case AF_INET:
+ sock.ip.sin_port = htons(ctdb->address.port);
+ break;
+ case AF_INET6:
+ sock.ip6.sin6_port = htons(ctdb->address.port);
+ break;
+ default:
+ DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
+ sock.sa.sa_family));
+ goto failed;
+ }
+
+ ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+ if (ctcp->listen_fd == -1) {
+ ctdb_set_error(ctdb, "socket failed\n");
+ return -1;
+ }
+
+ set_close_on_exec(ctcp->listen_fd);
+
+ setsockopt(ctcp->listen_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
+
if (bind(ctcp->listen_fd, (struct sockaddr * )&sock, sizeof(sock)) != 0) {
goto failed;
}
@@ -386,7 +419,9 @@ int ctdb_tcp_listen(struct ctdb_context *ctdb)
return 0;
failed:
- close(ctcp->listen_fd);
+ if (ctcp->listen_fd != -1) {
+ close(ctcp->listen_fd);
+ }
ctcp->listen_fd = -1;
return -1;
}
diff --git a/ctdb/tests/nodes.txt b/ctdb/tests/nodes.txt
index 99b07328b38..2563adcc702 100644
--- a/ctdb/tests/nodes.txt
+++ b/ctdb/tests/nodes.txt
@@ -1,4 +1,4 @@
-127.0.0.1
-127.0.0.2
-127.0.0.3
-127.0.0.4
+::1
+::2
+::3
+::4
diff --git a/ctdb/tests/nodes6.txt b/ctdb/tests/nodes6.txt
new file mode 100644
index 00000000000..7e1d085fdf0
--- /dev/null
+++ b/ctdb/tests/nodes6.txt
@@ -0,0 +1,11 @@
+::1
+::2
+::3
+::4
+
+::2
+::3
+::4
+::2
+::3
+::4
diff --git a/ctdb/tests/start_daemons.sh b/ctdb/tests/start_daemons.sh
index afcf23e0095..cf6b738f4a1 100755
--- a/ctdb/tests/start_daemons.sh
+++ b/ctdb/tests/start_daemons.sh
@@ -4,12 +4,17 @@ NUMNODES=2
if [ $# -gt 0 ]; then
NUMNODES=$1
fi
-NODES="./tests/nodes.txt"
shift
+NODES="./tests/nodes.txt"
rm -f $NODES
for i in `seq 1 $NUMNODES`; do
- echo 127.0.0.$i >> $NODES
+ if [ "${CTDB_USE_IPV6}x" != "x" ]; then
+ echo ::$i >> $NODES
+ ip addr add ::$i/128 dev lo
+ else
+ echo 127.0.0.$i >> $NODES
+ fi
done
killall -q ctdbd
diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c
index eed92d3773d..90af2a8e1bd 100644
--- a/ctdb/tools/ctdb.c
+++ b/ctdb/tools/ctdb.c
@@ -332,7 +332,7 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv
printf(":Node:IP:Disconnected:Banned:Disabled:Unhealthy:\n");
for(i=0;i<nodemap->num;i++){
printf(":%d:%s:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
- inet_ntoa(nodemap->nodes[i].sin.sin_addr),
+ ctdb_addr_to_str(&nodemap->nodes[i].addr),
!!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
!!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
!!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
@@ -370,7 +370,7 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv
CTDB_NO_MEMORY_FATAL(ctdb, flags_str);
}
printf("pnn:%d %-16s %s%s\n", nodemap->nodes[i].pnn,
- inet_ntoa(nodemap->nodes[i].sin.sin_addr),
+ ctdb_addr_to_str(&nodemap->nodes[i].addr),
flags_str,
nodemap->nodes[i].pnn == mypnn?" (THIS NODE)":"");
talloc_free(flags_str);
@@ -414,30 +414,29 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv
static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char **argv)
{
struct ctdb_control_tcp_tickle_list *list;
- struct sockaddr_in ip;
+ ctdb_sock_addr addr;
int i, ret;
if (argc < 1) {
usage();
}
- ip.sin_family = AF_INET;
- if (inet_aton(argv[0], &ip.sin_addr) == 0) {
+ if (parse_ip(argv[0], &addr) == 0) {
DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
return -1;
}
- ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &ip, &list);
+ ret = ctdb_ctrl_get_tcp_tickles(ctdb, TIMELIMIT(), options.pnn, ctdb, &addr, &list);
if (ret == -1) {
DEBUG(DEBUG_ERR, ("Unable to list tickles\n"));
return -1;
}
- printf("Tickles for ip:%s\n", inet_ntoa(list->ip.sin_addr));
+ printf("Tickles for ip:%s\n", ctdb_addr_to_str(&list->addr));
printf("Num tickles:%u\n", list->tickles.num);
for (i=0;i<list->tickles.num;i++) {
- printf("SRC: %s:%u ", inet_ntoa(list->tickles.connections[i].saddr.sin_addr), ntohs(list->tickles.connections[i].saddr.sin_port));
- printf("DST: %s:%u\n", inet_ntoa(list->tickles.connections[i].daddr.sin_addr), ntohs(list->tickles.connections[i].daddr.sin_port));
+ printf("SRC: %s:%u ", ctdb_addr_to_str(&list->tickles.connections[i].src_addr), ntohs(list->tickles.connections[i].src_addr.ip.sin_port));
+ printf("DST: %s:%u\n", ctdb_addr_to_str(&list->tickles.connections[i].dst_addr), ntohs(list->tickles.connections[i].dst_addr.ip.sin_port));
}
talloc_free(list);
@@ -447,7 +446,7 @@ static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char *
/* send a release ip to all nodes */
static int control_send_release(struct ctdb_context *ctdb, uint32_t pnn,
-struct sockaddr_in *sin)
+ctdb_sock_addr *addr)
{
int ret;
struct ctdb_public_ip pip;
@@ -461,11 +460,10 @@ struct sockaddr_in *sin)
}
/* send a moveip message to the recovery master */
- pip.pnn = pnn;
- pip.sin.sin_family = AF_INET;
- pip.sin.sin_addr = sin->sin_addr;
+ pip.pnn = pnn;
+ pip.addr = *addr;
data.dsize = sizeof(pip);
- data.dptr = (unsigned char *)&pip;
+ data.dptr = (unsigned char *)&pip;
/* send release ip to all nodes */
@@ -486,7 +484,7 @@ struct sockaddr_in *sin)
static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
{
uint32_t pnn;
- struct sockaddr_in ip;
+ ctdb_sock_addr addr;
uint32_t value;
struct ctdb_all_public_ips *ips;
int i, ret;
@@ -495,8 +493,7 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
usage();
}
- ip.sin_family = AF_INET;
- if (inet_aton(argv[0], &ip.sin_addr) == 0) {
+ if (parse_ip(argv[0], &addr) == 0) {
DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
return -1;
}
@@ -535,22 +532,22 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
}
for (i=0;i<ips->num;i++) {
- if (ctdb_same_ipv4(&ip, &ips->ips[i].sin)) {
+ if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
break;
}
}
if (i==ips->num) {
DEBUG(DEBUG_ERR, ("Node %u can not host ip address '%s'\n",
- pnn, inet_ntoa(ip.sin_addr)));
+ pnn, ctdb_addr_to_str(&addr)));
return -1;
}
if (ips->ips[i].pnn == pnn) {
DEBUG(DEBUG_ERR, ("Host %u is already hosting '%s'\n",
- pnn, inet_ntoa(ips->ips[i].sin.sin_addr)));
+ pnn, ctdb_addr_to_str(&ips->ips[i].addr)));
return -1;
}
- ret = control_send_release(ctdb, pnn, &ips->ips[i].sin);
+ ret = control_send_release(ctdb, pnn, &ips->ips[i].addr);
if (ret != 0) {
DEBUG(DEBUG_ERR, ("Failed to send 'change ip' to all nodes\n"));;
return -1;
@@ -559,20 +556,15 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
return 0;
}
-struct node_ip {
- uint32_t pnn;
- struct sockaddr_in sin;
-};
-
void getips_store_callback(void *param, void *data)
{
- struct node_ip *node_ip = (struct node_ip *)data;
+ struct ctdb_public_ip *node_ip = (struct ctdb_public_ip *)data;
struct ctdb_all_public_ips *ips = param;
int i;
i = ips->num++;
- ips->ips[i].pnn = node_ip->pnn;
- ips->ips[i].sin = node_ip->sin;
+ ips->ips[i].pnn = node_ip->pnn;
+ ips->ips[i].addr = node_ip->addr;
}
void getips_count_callback(void *param, void *data)
@@ -612,13 +604,13 @@ control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struc
}
for (j=0; j<tmp_ips->num;j++) {
- struct node_ip *node_ip;
+ struct ctdb_public_ip *node_ip;
- node_ip = talloc(tmp_ctx, struct node_ip);
- node_ip->pnn = tmp_ips->ips[j].pnn;
- node_ip->sin = tmp_ips->ips[j].sin;
+ node_ip = talloc(tmp_ctx, struct ctdb_public_ip);
+ node_ip->pnn = tmp_ips->ips[j].pnn;
+ node_ip->addr = tmp_ips->ips[j].addr;
- trbt_insert32(tree, tmp_ips->ips[j].sin.sin_addr.s_addr, node_ip);
+ trbt_insert32(tree, tmp_ips->ips[j].addr.ip.sin_addr.s_addr, node_ip);
}
talloc_free(tmp_ips);
}
@@ -643,7 +635,7 @@ control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struc
* ip address or -1
*/
static int
-find_other_host_for_public_ip(struct ctdb_context *ctdb, struct sockaddr_in *addr)
+find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr)
{
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
struct ctdb_all_public_ips *ips;
@@ -673,7 +665,7 @@ find_other_host_for_public_ip(struct ctdb_context *ctdb, struct sockaddr_in *add
}
for (j=0;j<ips->num;j++) {
- if (ctdb_same_ipv4(addr, &ips->ips[j].sin)) {
+ if (ctdb_same_ip(addr, &ips->ips[j].addr)) {
talloc_free(tmp_ctx);
return nodemap->nodes[i].pnn;
}
@@ -693,7 +685,7 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
int i, ret;
int len;
unsigned mask;
- struct sockaddr_in addr;
+ ctdb_sock_addr addr;
struct ctdb_control_ip_iface *pub;
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
struct ctdb_all_public_ips *ips;
@@ -721,7 +713,7 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
pub = talloc_size(tmp_ctx, len);
CTDB_NO_MEMORY(ctdb, pub);
- pub->sin = addr;
+ pub->addr = addr;
pub->mask = mask;
pub->len = strlen(argv[1])+1;
memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
@@ -738,7 +730,7 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
* we will claim it
*/
for (i=0;i<ips->num;i++) {
- if (ctdb_same_ipv4(&addr, &ips->ips[i].sin)) {
+ if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
break;
}
}
@@ -764,7 +756,7 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
{
int i, ret;
- struct sockaddr_in addr;
+ ctdb_sock_addr addr;
struct ctdb_control_ip_iface pub;
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
struct ctdb_all_public_ips *ips;
@@ -774,13 +766,12 @@ static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
usage();
}
- addr.sin_family = AF_INET;
- if (inet_aton(argv[0], &addr.sin_addr) == 0) {
+ if (parse_ip(argv[0], &addr) == 0) {
DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
return -1;
}
- pub.sin = addr;
+ pub.addr = addr;
pub.mask = 0;
pub.len = 0;
@@ -792,14 +783,14 @@ static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
}
for (i=0;i<ips->num;i++) {
- if (ctdb_same_ipv4(&addr, &ips->ips[i].sin)) {
+ if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
break;
}
}
if (i==ips->num) {
DEBUG(DEBUG_ERR, ("This node does not support this public address '%s'\n",
- inet_ntoa(addr.sin_addr)));
+ ctdb_addr_to_str(&addr)));
talloc_free(tmp_ctx);
return -1;
}
@@ -837,12 +828,12 @@ static int kill_tcp(struct ctdb_context *ctdb, int argc, const char **argv)
usage();
}
- if (!parse_ip_port(argv[0], (ctdb_sock_addr *)&killtcp.src)) {
+ if (!parse_ip_port(argv[0], &killtcp.src_addr)) {
DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[0]));
return -1;
}
- if (!parse_ip_port(argv[1], (ctdb_sock_addr *)&killtcp.dst)) {
+ if (!parse_ip_port(argv[1], &killtcp.dst_addr)) {
DEBUG(DEBUG_ERR, ("Bad IP:port '%s'\n", argv[1]));
return -1;
}
@@ -1052,9 +1043,9 @@ static int control_ip(struct ctdb_context *ctdb, int argc, const char **argv)
for (i=1;i<=ips->num;i++) {
if (options.machinereadable){
- printf(":%s:%d:\n", inet_ntoa(ips->ips[ips->num-i].sin.sin_addr), ips->ips[ips->num-i].pnn);
+ printf(":%s:%d:\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
} else {
- printf("%s %d\n", inet_ntoa(ips->ips[ips->num-i].sin.sin_addr), ips->ips[ips->num-i].pnn);
+ printf("%s %d\n", ctdb_addr_to_str(&ips->ips[ips->num-i].addr), ips->ips[ips->num-i].pnn);
}
}
@@ -1316,7 +1307,8 @@ static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv)
}
}
- printf("%d:%s\n", i, inet_ntoa(nodemap->nodes[i].sin.sin_addr));
+ printf("%d:%s\n", i,
+ ctdb_addr_to_str(&nodemap->nodes[i].addr));
}
return 0;
@@ -2194,7 +2186,7 @@ static int control_listnodes(struct ctdb_context *ctdb, int argc, const char **a
}
for(i=0;i<nodemap->num;i++){
- printf("%s\n", inet_ntoa(nodemap->nodes[i].sin.sin_addr));
+ printf("%s\n", ctdb_addr_to_str(&nodemap->nodes[i].addr));
}
return 0;
diff --git a/ctdb/utils/ipmux/ipmux.c b/ctdb/utils/ipmux/ipmux.c
index 539490e674d..598e9dcb6f2 100644
--- a/ctdb/utils/ipmux/ipmux.c
+++ b/ctdb/utils/ipmux/ipmux.c
@@ -34,7 +34,7 @@
struct ipmux_node {
uint32_t pnn;
- struct sockaddr_in sin;
+ ctdb_sock_addr addr;
};
struct ipmux_node *ipmux_nodes;
@@ -188,8 +188,8 @@ int main(int argc, const char *argv[])
if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
continue;
}
- ipmux_nodes[num_nodes].pnn = i;
- ipmux_nodes[num_nodes].sin = nodemap->nodes[i].sin;
+ ipmux_nodes[num_nodes].pnn = i;
+ ipmux_nodes[num_nodes].addr = nodemap->nodes[i].addr;
num_nodes++;
}
@@ -251,7 +251,7 @@ int main(int argc, const char *argv[])
send the packet off and tell the kernel to not worry
about this packet any more
*/
- ret = sendto(s, &ipqp->payload[0], ipqp->data_len, 0, &ipmux_nodes[hash].sin, sizeof(struct sockaddr_in));
+ ret = sendto(s, &ipqp->payload[0], ipqp->data_len, 0, (struct sockaddr_in *)&ipmux_nodes[hash].addr, sizeof(ctdb_sock_addr));
ipq_set_verdict(ipqh, ipqp->packet_id, NF_DROP, 0, pktbuf);
}