mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
initial ipv6 patch
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com> (This used to be ctdb commit 1f131f21386f428bbbbb29098d56c2f64596583b)
This commit is contained in:
parent
ed6ca6a84d
commit
ef997d344f
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
if (!parse_ip_num(s, &ip->sin_addr, mask, '/')) {
|
||||
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 (*mask > 32) {
|
||||
|
||||
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;
|
||||
}
|
||||
ip->sin_family = AF_INET;
|
||||
ip->sin_port = 0;
|
||||
return true;
|
||||
|
||||
*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;
|
||||
}
|
||||
*p = 0;
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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);
|
||||
/* 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->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;
|
||||
/* 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;
|
||||
|
||||
return 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
/* 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 *)(ip6+1);
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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->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;
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"));
|
||||
|
@ -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,
|
||||
@ -1014,16 +1023,6 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
127.0.0.1
|
||||
127.0.0.2
|
||||
127.0.0.3
|
||||
127.0.0.4
|
||||
::1
|
||||
::2
|
||||
::3
|
||||
::4
|
||||
|
11
ctdb/tests/nodes6.txt
Normal file
11
ctdb/tests/nodes6.txt
Normal file
@ -0,0 +1,11 @@
|
||||
::1
|
||||
::2
|
||||
::3
|
||||
::4
|
||||
|
||||
::2
|
||||
::3
|
||||
::4
|
||||
::2
|
||||
::3
|
||||
::4
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user