]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
- use struct sockaddr_in more consistently instead of string addresses
authorAndrew Tridgell <tridge@samba.org>
Mon, 10 Sep 2007 04:27:29 +0000 (14:27 +1000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 10 Sep 2007 04:27:29 +0000 (14:27 +1000)
- allow for public_address lines with a defaulting interface

(This used to be ctdb commit 29cb760f76e639a0f2ce1d553645a9dc26ee09e5)

ctdb/common/ctdb_util.c
ctdb/common/system_aix.c
ctdb/common/system_linux.c
ctdb/include/ctdb_private.h
ctdb/server/ctdb_takeover.c

index 54b1e4e7ff5f68887b7f1c169533401b253cf651..dc8128aa20fb62d1d902c8b05bd1622b256aaa31 100644 (file)
@@ -248,18 +248,15 @@ void set_close_on_exec(int fd)
 
 
 /*
-  parse a ip:port pair
+  parse a ip:num pair with the given separator
  */
-bool parse_ip_port(const char *s, struct sockaddr_in *ip)
+static bool parse_ip_num(const char *s, struct in_addr *addr, unsigned *num, const char sep)
 {
        const char *p;
        char *endp = NULL;
-       unsigned port;
        char buf[16];
 
-       ip->sin_family = AF_INET;
-
-       p = strchr(s, ':');
+       p = strchr(s, sep);
        if (p == NULL) {
                return false;
        }
@@ -268,18 +265,65 @@ bool parse_ip_port(const char *s, struct sockaddr_in *ip)
                return false;
        }
 
-       port = strtoul(p+1, &endp, 10);
+       *num = strtoul(p+1, &endp, 10);
        if (endp == NULL || *endp != 0) {
                /* trailing garbage */
                return false;
        }
-       ip->sin_port = htons(port);
 
        strlcpy(buf, s, 1+p-s);
 
-       if (inet_aton(buf, &ip->sin_addr) == 0) {
+       if (inet_aton(buf, addr) == 0) {
                return false;
        }
 
        return true;
 }
+
+
+/*
+  parse a ip:port pair
+ */
+bool parse_ip_port(const char *s, struct sockaddr_in *ip)
+{
+       unsigned port;
+       if (!parse_ip_num(s, &ip->sin_addr, &port, ':')) {
+               return false;
+       }
+       ip->sin_family = AF_INET;
+       ip->sin_port   = htons(port);
+       return true;
+}
+
+/*
+  parse a ip/mask pair
+ */
+bool parse_ip_mask(const char *s, struct sockaddr_in *ip, unsigned *mask)
+{
+       if (!parse_ip_num(s, &ip->sin_addr, mask, '/')) {
+               return false;
+       }
+       if (*mask > 32) {
+               return false;
+       }
+       ip->sin_family = AF_INET;
+       ip->sin_port   = 0;
+       return true;
+}
+
+/*
+  compare two sockaddr_in structures - matching only on IP
+ */
+bool ctdb_same_ip(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;
+}
+
+/*
+  compare two sockaddr_in structures
+ */
+bool ctdb_same_sockaddr(const struct sockaddr_in *ip1, const struct sockaddr_in *ip2)
+{
+       return ctdb_same_ip(ip1, ip2) && ip1->sin_port == ip2->sin_port;
+}
index 0587e83f03289d1e79727a4138ab4479e773855b..5d5af10336244808b1bbce3060e85c2d638ee96b 100644 (file)
@@ -165,24 +165,21 @@ int ctdb_sys_send_tcp(int s,
   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(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname)
+bool ctdb_sys_have_ip(struct sockaddr_in ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname)
 {
-       struct sockaddr_in sin;
        int s;
        int ret;
-
+       
        if (is_loopback) {
                DEBUG(0,(__location__ " NOT IMPLEMENTED YET: ctdb_sys_have_ip() does not yet support is_loopback on AIX. This needs to be implemented similar to system_linux.c\n"));
        }
 
-       sin.sin_port = 0;
-       inet_aton(ip, &sin.sin_addr);
-       sin.sin_family = AF_INET;
+       ip.sin_port = 0;
        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s == -1) {
                return false;
        }
-       ret = bind(s, (struct sockaddr *)&sin, sizeof(sin));
+       ret = bind(s, (struct sockaddr *)&ip, sizeof(ip));
        close(s);
        return ret == 0;
 }
index fc94bd14eefeb3fca5e776af1ce319f263977e92..82a6575bab333198a2fbe042cfd2bb1b73045757 100644 (file)
@@ -246,9 +246,8 @@ int ctdb_sys_send_tcp(int s,
 
   ifname, if non-NULL, will return the name of the interface this ip is tied to
  */
-bool ctdb_sys_have_ip(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname)
+bool ctdb_sys_have_ip(struct sockaddr_in ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname)
 {
-       struct sockaddr_in sin;
        struct ifreq *ifr = NULL;
        struct ifconf ifc;
        int s, i, num_ifs;
@@ -261,14 +260,12 @@ bool ctdb_sys_have_ip(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, ch
                *ifname = NULL;
        }
        
-       sin.sin_port = 0;
-       inet_aton(ip, &sin.sin_addr);
-       sin.sin_family = AF_INET;
+       ip.sin_port = 0;
        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s == -1) {
                return false;
        }
-       ret = bind(s, (struct sockaddr *)&sin, sizeof(sin));
+       ret = bind(s, (struct sockaddr *)&ip, sizeof(ip));
        if (ret) {
                goto finished;
        }
@@ -305,7 +302,7 @@ bool ctdb_sys_have_ip(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, ch
                }
 
                /* this is not the interface you are looking for */
-               if(strcmp(inet_ntoa(sa->sin_addr), ip)){
+               if (!ctdb_same_ip(sa, &ip)) {
                        continue;
                }
 
@@ -320,7 +317,7 @@ bool ctdb_sys_have_ip(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, ch
                }
 
                /* was this ip tied to a loopback interface ? */
-               if(ifr[i].ifr_flags & IFF_LOOPBACK) {
+               if (ifr[i].ifr_flags & IFF_LOOPBACK) {
                        if (is_loopback != NULL) {
                                *is_loopback = true;
                        }
index 69d6a41454b108909efce338867022531cdab3f5..8c8e8b151a4dd4574bcd92e86f993a49e0b592e4 100644 (file)
@@ -141,7 +141,7 @@ struct ctdb_vnn {
        struct ctdb_vnn *prev, *next;
 
        const char *iface;
-       const char *public_address;
+       struct sockaddr_in public_address;
        uint8_t public_netmask_bits;
 
        /* the node number that is serving this public address, if any. 
@@ -358,6 +358,7 @@ struct ctdb_context {
        void *saved_scheduler_param;
        struct _trbt_tree_t *server_ids;        
        const char *event_script_dir;
+       const char *default_public_interface;
 };
 
 struct ctdb_db_context {
@@ -693,9 +694,12 @@ struct ctdb_req_keepalive {
 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_ip(const struct sockaddr_in *ip1, const struct sockaddr_in *ip2);
+bool ctdb_same_sockaddr(const struct sockaddr_in *ip1, const struct sockaddr_in *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);
@@ -1058,7 +1062,7 @@ int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
 
 /* from takeover/system.c */
 int ctdb_sys_send_arp(const struct sockaddr_in *saddr, const char *iface);
-bool ctdb_sys_have_ip(const char *ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname);
+bool ctdb_sys_have_ip(struct sockaddr_in ip, bool *is_loopback, TALLOC_CTX *mem_ctx, char **ifname);
 int ctdb_sys_send_tcp(int fd,
                      const struct sockaddr_in *dest, 
                      const struct sockaddr_in *src,
index 71c294da44caeacfd7c67eca3deea8d17b04170c..85e969776481a49c19acb1fde05e9e4af4c42236 100644 (file)
@@ -183,12 +183,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, char *ip)
+static struct ctdb_vnn *find_public_ip_vnn(struct ctdb_context *ctdb, struct sockaddr_in ip)
 {
        struct ctdb_vnn *vnn;
 
        for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
-               if (!strcmp(vnn->public_address, ip)) {
+               if (ctdb_same_ip(&vnn->public_address, &ip)) {
                        return vnn;
                }
        }
@@ -210,21 +210,21 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
        struct takeover_callback_state *state;
        struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
        struct ctdb_vnn *vnn;
-       char *ip = talloc_strdup(tmp_ctx, inet_ntoa(pip->sin.sin_addr));
        bool have_ip, is_loopback;
        char *ifname = NULL;
 
        /* update out vnn list */
-       vnn = find_public_ip_vnn(ctdb, ip);
+       vnn = find_public_ip_vnn(ctdb, pip->sin);
        if (vnn == NULL) {
-               DEBUG(0,("takeoverip called for an ip '%s' that is not a public address\n", ip));
+               DEBUG(0,("takeoverip called for an ip '%s' that is not a public address\n", 
+                        inet_ntoa(pip->sin.sin_addr)));
                talloc_free(tmp_ctx);
                return 0;
        }
        vnn->pnn = pip->pnn;
 
        /* if our kernel already has this IP, do nothing */
-       have_ip = ctdb_sys_have_ip(ip, &is_loopback, tmp_ctx, &ifname);
+       have_ip = ctdb_sys_have_ip(pip->sin, &is_loopback, tmp_ctx, &ifname);
        /* if we have the ip and it is not set to a loopback address */
        if (have_ip && !is_loopback) {
                talloc_free(tmp_ctx);
@@ -242,7 +242,7 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
        state->vnn = vnn;
 
        DEBUG(0,("Takeover of IP %s/%u on interface %s\n", 
-                ip, vnn->public_netmask_bits, 
+                inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits, 
                 vnn->iface));
 
        ctdb_stop_monitoring(ctdb);
@@ -252,11 +252,11 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
                                         state, takeover_ip_callback, state,
                                         "takeip %s %s %u",
                                         vnn->iface, 
-                                        ip,
+                                        inet_ntoa(pip->sin.sin_addr),
                                         vnn->public_netmask_bits);
        if (ret != 0) {
                DEBUG(0,(__location__ " Failed to takeover IP %s on interface %s\n",
-                        ip, vnn->iface));
+                        inet_ntoa(pip->sin.sin_addr), vnn->iface));
                talloc_free(tmp_ctx);
                talloc_free(state);
                return -1;
@@ -272,18 +272,18 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
 /*
   kill any clients that are registered with a IP that is being released
  */
-static void release_kill_clients(struct ctdb_context *ctdb, struct in_addr in)
+static void release_kill_clients(struct ctdb_context *ctdb, struct sockaddr_in in)
 {
        struct ctdb_client_ip *ip;
 
        for (ip=ctdb->client_ip_list; ip; ip=ip->next) {
-               if (ip->ip.sin_addr.s_addr == in.s_addr) {
+               if (ctdb_same_ip(&ip->ip, &in)) {
                        struct ctdb_client *client = ctdb_reqid_find(ctdb, 
                                                                     ip->client_id, 
                                                                     struct ctdb_client);
                        if (client->pid != 0) {
                                DEBUG(0,(__location__ " Killing client pid %u for IP %s on client_id %u\n",
-                                        (unsigned)client->pid, inet_ntoa(in),
+                                        (unsigned)client->pid, inet_ntoa(in.sin_addr),
                                         ip->client_id));
                                kill(client->pid, SIGKILL);
                        }
@@ -313,7 +313,7 @@ static void release_ip_callback(struct ctdb_context *ctdb, int status,
        ctdb_daemon_send_message(ctdb, ctdb->pnn, CTDB_SRVID_RELEASE_IP, data);
 
        /* kill clients that have registered with this IP */
-       release_kill_clients(ctdb, state->sin->sin_addr);
+       release_kill_clients(ctdb, *state->sin);
        
        /* the control succeeded */
        ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
@@ -332,31 +332,31 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
        int ret;
        struct takeover_callback_state *state;
        struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
-       char *ip = talloc_strdup(tmp_ctx, inet_ntoa(pip->sin.sin_addr));
        struct ctdb_vnn *vnn;
        bool have_ip, is_loopback;
        char *ifname = NULL;
 
        /* update our vnn list */
-       vnn = find_public_ip_vnn(ctdb, ip);
+       vnn = find_public_ip_vnn(ctdb, pip->sin);
        if (vnn == NULL) {
-               DEBUG(0,("releaseip called for an ip '%s' that is not a public address\n", ip));
+               DEBUG(0,("releaseip called for an ip '%s' that is not a public address\n", 
+                        inet_ntoa(pip->sin.sin_addr)));
                talloc_free(tmp_ctx);
                return 0;
        }
        vnn->pnn = pip->pnn;
 
-       have_ip = ctdb_sys_have_ip(ip, &is_loopback, tmp_ctx, &ifname);
+       have_ip = ctdb_sys_have_ip(pip->sin, &is_loopback, tmp_ctx, &ifname);
        if ( (!have_ip) || is_loopback) { 
                DEBUG(0,("Redundant release of IP %s/%u on interface %s (ip not held)\n", 
-                        ip, vnn->public_netmask_bits, 
+                        inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits, 
                         vnn->iface));
                talloc_free(tmp_ctx);
                return 0;
        }
 
        DEBUG(0,("Release of IP %s/%u on interface %s\n", 
-                ip, vnn->public_netmask_bits, 
+                inet_ntoa(pip->sin.sin_addr), vnn->public_netmask_bits, 
                 vnn->iface));
 
        /* stop any previous arps */
@@ -380,11 +380,11 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
                                         state, release_ip_callback, state,
                                         "releaseip %s %s %u",
                                         vnn->iface, 
-                                        ip,
+                                        inet_ntoa(pip->sin.sin_addr),
                                         vnn->public_netmask_bits);
        if (ret != 0) {
                DEBUG(0,(__location__ " Failed to release IP %s on interface %s\n",
-                        ip, vnn->iface));
+                        inet_ntoa(pip->sin.sin_addr), vnn->iface));
                talloc_free(tmp_ctx);
                talloc_free(state);
                return -1;
@@ -399,39 +399,26 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
 
 
 
-static int add_public_address(struct ctdb_context *ctdb, int ip0, int ip1, int ip2, int ip3, int nm, char *iface)
+static int add_public_address(struct ctdb_context *ctdb, struct sockaddr_in addr, unsigned mask, const char *iface)
 {
        struct ctdb_vnn      *vnn;
-       char *public_address;
 
        /* Verify that we dont have an entry for this ip yet */
-       public_address = talloc_asprintf(ctdb, "%d.%d.%d.%d", ip0, ip1, ip2, ip3);
-       CTDB_NO_MEMORY_FATAL(ctdb, public_address);
        for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
-               if (!strcmp(public_address, vnn->public_address)) {
-                       DEBUG(0,("Same ip '%s' specified multiple times in the public address list \n", public_address));
-                       talloc_free(public_address);
+               if (ctdb_same_sockaddr(&addr, &vnn->public_address)) {
+                       DEBUG(0,("Same ip '%s' specified multiple times in the public address list \n", 
+                                inet_ntoa(addr.sin_addr)));
                        exit(1);
                }               
        }
 
-       
-       /* make sure the netmask is ok */
-       if (nm > 32) {
-               DEBUG(0, ("Illegal netmask for IP %s\n", public_address));
-               talloc_free(public_address);
-               exit(1);
-       }
-
        /* create a new vnn structure for this ip address */
        vnn = talloc_zero(ctdb, struct ctdb_vnn);
        CTDB_NO_MEMORY_FATAL(ctdb, vnn);
-       if (iface) {
-               vnn->iface = talloc_strdup(vnn, iface);
-       }
-       vnn->public_address      = talloc_steal(vnn, public_address);
-       vnn->public_netmask_bits = nm;
-       vnn->pnn        = -1;
+       vnn->iface = talloc_strdup(vnn, iface);
+       vnn->public_address      = addr;
+       vnn->public_netmask_bits = mask;
+       vnn->pnn                 = -1;
        
        DLIST_ADD(ctdb->vnn, vnn);
 
@@ -468,17 +455,33 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
        }
 
        for (i=0;i<nlines;i++) {
-               int ip0, ip1, ip2, ip3, nm;
-               char iface[256];
-
-               if (sscanf(lines[i], "%d.%d.%d.%d/%d %255s", &ip0, &ip1, &ip2, &ip3, &nm, iface) != 6) {
-                       DEBUG(0,("Badly formed line '%s' in public address list\n", lines[i]));
+               unsigned mask;
+               struct sockaddr_in addr;
+               char ifacebuf[100];
+               const char *iface;
+               char *tok;
+
+               tok = strtok(lines[i], " \t");
+               if (!tok || !parse_ip_mask(tok, &addr, &mask)) {
+                       DEBUG(0,("Badly formed line %u in public address list\n", i+1));
                        talloc_free(lines);
                        return -1;
                }
+               tok = strtok(NULL, " \t");
+               if (tok == NULL) {
+                       if (NULL == ctdb->default_public_interface) {
+                               DEBUG(0,("No default public interface and no interface specified at line %u of public address list\n",
+                                        i+1));
+                               talloc_free(lines);
+                               return -1;
+                       }
+                       iface = ctdb->default_public_interface;
+               } else {
+                       iface = ifacebuf;
+               }
 
-               if (add_public_address(ctdb, ip0, ip1, ip2, ip3, nm, iface)) {
-                       DEBUG(0,("Failed to add '%s' to the public address list\n", lines[i]));
+               if (add_public_address(ctdb, addr, mask, iface)) {
+                       DEBUG(0,("Failed to add line %u to the public address list\n", i+1));
                        talloc_free(lines);
                        return -1;
                }
@@ -551,7 +554,7 @@ static int find_takeover_node(struct ctdb_context *ctdb,
                struct ctdb_public_ip_list *ip,
                struct ctdb_public_ip_list *all_ips)
 {
-       int pnn, min, num;
+       int pnn, min=0, num;
        int i;
 
        pnn    = -1;
@@ -651,7 +654,7 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap)
        struct ctdb_public_ip ip;
        uint32_t mask;
        struct ctdb_public_ip_list *all_ips, *tmp_ip;
-       int maxnode, maxnum, minnode, minnum, num;
+       int maxnode, maxnum=0, minnode, minnum=0, num;
        TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 
 
@@ -882,14 +885,11 @@ int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
        int ret;
        TDB_DATA data;
        struct ctdb_client_ip *ip;
-       char *addr;
        struct ctdb_vnn *vnn;
 
-       addr = inet_ntoa(p->dest.sin_addr);
-
-       vnn = find_public_ip_vnn(ctdb, addr);
+       vnn = find_public_ip_vnn(ctdb, p->dest);
        if (vnn == NULL) {
-               DEBUG(3,("Could not add client IP %s. This is not a public address.\n", addr)); 
+               DEBUG(3,("Could not add client IP %s. This is not a public address.\n", inet_ntoa(p->dest.sin_addr))); 
                return 0;
        }
 
@@ -975,12 +975,11 @@ int32_t ctdb_control_tcp_add(struct ctdb_context *ctdb, TDB_DATA indata)
        struct ctdb_tcp_array *tcparray;
        struct ctdb_tcp_connection tcp;
        struct ctdb_vnn *vnn;
-       char *addr;
 
-       addr = inet_ntoa(p->dest.sin_addr);
-       vnn = find_public_ip_vnn(ctdb, addr);
+       vnn = find_public_ip_vnn(ctdb, p->dest);
        if (vnn == NULL) {
-               DEBUG(0,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n", addr));
+               DEBUG(0,(__location__ " got TCP_ADD control for an address which is not a public address '%s'\n", 
+                        inet_ntoa(p->dest.sin_addr)));
                return-1;
        }
 
@@ -1045,7 +1044,7 @@ 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, inet_ntoa(conn->daddr.sin_addr));
+       struct ctdb_vnn *vnn = find_public_ip_vnn(ctdb, conn->daddr);
 
        if (vnn == NULL) {
                DEBUG(0,(__location__ " unable to find public address %s\n", inet_ntoa(conn->daddr.sin_addr)));
@@ -1137,15 +1136,11 @@ void ctdb_release_all_ips(struct ctdb_context *ctdb)
        for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
                have_ip = ctdb_sys_have_ip(vnn->public_address, &is_loopback, tmp_ctx, &ifname);
                if (have_ip && !is_loopback) {
-                       struct in_addr in;
-
                        ctdb_event_script(ctdb, "releaseip %s %s %u",
                                          vnn->iface, 
-                                         vnn->public_address,
+                                         inet_ntoa(vnn->public_address.sin_addr),
                                          vnn->public_netmask_bits);
-                       if (inet_aton(vnn->public_address, &in) != 0) {
-                               release_kill_clients(ctdb, in);
-                       }
+                       release_kill_clients(ctdb, vnn->public_address);
                }
        }
        talloc_free(tmp_ctx);
@@ -1179,10 +1174,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.sin_family = AF_INET;
-               inet_aton(vnn->public_address, 
-                         &ips->ips[i].sin.sin_addr);
+               ips->ips[i].pnn = vnn->pnn;
+               ips->ips[i].sin = vnn->public_address;
                i++;
        }
 
@@ -1363,9 +1356,9 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
        struct ctdb_killtcp_con *con;
        struct ctdb_vnn *vnn;
 
-       vnn = find_public_ip_vnn(ctdb, inet_ntoa(dst->sin_addr));
+       vnn = find_public_ip_vnn(ctdb, *dst);
        if (vnn == NULL) {
-               vnn = find_public_ip_vnn(ctdb, inet_ntoa(src->sin_addr));
+               vnn = find_public_ip_vnn(ctdb, *src);
        }
        if (vnn == NULL) {
                DEBUG(0,(__location__ " Could not killtcp, not a public address\n")); 
@@ -1474,7 +1467,6 @@ int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
 {
        struct ctdb_control_tcp_tickle_list *list = (struct ctdb_control_tcp_tickle_list *)indata.dptr;
        struct ctdb_tcp_array *tcparray;
-       char *addr;
        struct ctdb_vnn *vnn;
 
        /* We must at least have tickles.num or else we cant verify the size
@@ -1495,11 +1487,10 @@ int32_t ctdb_control_set_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
                return -1;
        }       
 
-       addr = inet_ntoa(list->ip.sin_addr);
-
-       vnn = find_public_ip_vnn(ctdb, addr);
+       vnn = find_public_ip_vnn(ctdb, list->ip);
        if (vnn == NULL) {
-               DEBUG(0,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n", addr)); 
+               DEBUG(0,(__location__ " Could not set tcp tickle list, '%s' is not a public address\n", 
+                        inet_ntoa(list->ip.sin_addr))); 
                return 1;
        }
 
@@ -1534,15 +1525,12 @@ int32_t ctdb_control_get_tcp_tickle_list(struct ctdb_context *ctdb, TDB_DATA ind
        struct ctdb_control_tcp_tickle_list *list;
        struct ctdb_tcp_array *tcparray;
        int num;
-       char *addr;
        struct ctdb_vnn *vnn;
 
-
-       addr = inet_ntoa(ip->sin_addr);
-
-       vnn = find_public_ip_vnn(ctdb, addr);
+       vnn = find_public_ip_vnn(ctdb, *ip);
        if (vnn == NULL) {
-               DEBUG(0,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n", addr)); 
+               DEBUG(0,(__location__ " Could not get tcp tickle list, '%s' is not a public address\n", 
+                        inet_ntoa(ip->sin_addr))); 
                return 1;
        }
 
@@ -1627,7 +1615,6 @@ static void ctdb_update_tcp_tickles(struct event_context *ev,
        struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
        int ret;
        struct ctdb_vnn *vnn;
-       struct sockaddr_in ip;
 
        for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
                /* we only send out updates for public addresses that 
@@ -1640,14 +1627,14 @@ static void ctdb_update_tcp_tickles(struct event_context *ev,
                if (!vnn->tcp_update_needed) {
                        continue;
                }
-               inet_aton(vnn->public_address, &ip.sin_addr);
                ret = ctdb_ctrl_set_tcp_tickles(ctdb, 
                                TAKEOVER_TIMEOUT(),
                                CTDB_BROADCAST_CONNECTED,
-                               &ip,
+                               &vnn->public_address,
                                vnn->tcp_array);
                if (ret != 0) {
-                       DEBUG(0,("Failed to send the tickle update for public address %s\n", vnn->public_address));
+                       DEBUG(0,("Failed to send the tickle update for public address %s\n", 
+                                inet_ntoa(vnn->public_address.sin_addr)));
                }
        }