The branch, master has been updated
       via  24996c6 ctdb-tools: Fix a typo for a talloc context
       via  c715da3 ctdb-tools: Add debug to ctdb_killtcp
       via  8fb6c1a ctdb-tools: Move special case of 0 connections into 
computation
       via  fd54d47 ctdb-tools: Rework killtcp logic into a tevent_req-based 
computation
       via  44cdda4 ctdb-tools: New function ctdb_kill_tcp_init()
       via  3f78ddd ctdb-tools: Improve error handling
       via  7a2db54 ctdb-tools: Drop global variable prog
       via  6ac5cb4 ctdb-tools: Use db_hash in ctdb_killtcp
       via  c355fd9 ctdb-tools: Use ctdb_connection and ctdb_connection_list 
structs
       via  6d9fef4 ctdb-protocol: Add ctdb_connection_list utilities
       via  e50cb8c ctdb-protocol: Add marshalling for ctdb_connection_list
       via  d6f9cd1 ctdb-protocol: Add new data structure ctdb_connection_list
       via  ef676d5 ctdb-protocol: Add ctdb_connection utilities
       via  2850203 ctdb-protocol: Factor out static function 
ctdb_sock_addr_cmp_family()
       via  6f1b1a0 ctdb-protocol: Add ctdb_sock_addr_from_string()
       via  93668f5 ctdb-protocol: Optionally print port for address printing 
functions
       via  de9f05e ctdb-protocol: Add utility function ctdb_sock_addr_to_buf()
       via  22de111 ctdb-protocol: Add ctdb_sock_addr_port() and 
sock_addr_set_port()
       via  eb32b8d ctdb-protocol: Add server and client aliases in 
ctdb_connection
       via  3816270 ctdb-common: Initialise socket addresses before reading 
into them
       via  3783b66 ctdb-build: Split protocol-util as a separate subsystem
       via  2550a88 ctdb-build: Fix dependency for ctdbd
      from  2c745cf s4-torture: move lease break handler outside the lease 
testsuite.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 24996c60aafd36d10317876c702b7d4f759e405c
Author: Martin Schwenke <[email protected]>
Date:   Wed Sep 6 18:11:41 2017 +1000

    ctdb-tools: Fix a typo for a talloc context
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>
    
    Autobuild-User(master): Martin Schwenke <[email protected]>
    Autobuild-Date(master): Tue Sep 19 17:31:18 CEST 2017 on sn-devel-144

commit c715da3bdbf89ac77338876b47535b918d711f38
Author: Martin Schwenke <[email protected]>
Date:   Tue Jul 4 12:11:20 2017 +1000

    ctdb-tools: Add debug to ctdb_killtcp
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 8fb6c1adb03e33159059cb1343a27c588c4cb6d5
Author: Martin Schwenke <[email protected]>
Date:   Tue Jul 4 14:02:14 2017 +1000

    ctdb-tools: Move special case of 0 connections into computation
    
    This avoids other potential users from unnecessarily setting up file
    descriptors and such.
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit fd54d47875be20477cae45d173ba1eebd748fbbb
Author: Martin Schwenke <[email protected]>
Date:   Fri Jun 30 19:50:43 2017 +1000

    ctdb-tools: Rework killtcp logic into a tevent_req-based computation
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 44cdda4ee0494d1b40b92569429c9380b948e08a
Author: Martin Schwenke <[email protected]>
Date:   Thu Jun 29 16:35:06 2017 +1000

    ctdb-tools: New function ctdb_kill_tcp_init()
    
    This replaces ctdb_killtcp(), which did the initialisation inside a
    loop.  The new logic is inverted, making it more natural.
    
    The variable containing all the state is called "state" in
    anticipation of the next commit that will convert this to a tevent_req
    computation.  This will mean less churn.
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 3f78dddea95fb90ac01d52229d9449c6b094de64
Author: Martin Schwenke <[email protected]>
Date:   Thu Sep 14 15:19:43 2017 +1000

    ctdb-tools: Improve error handling
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 7a2db5410f745f0c745399a0190a9064fa173696
Author: Martin Schwenke <[email protected]>
Date:   Fri Jun 30 17:12:48 2017 +1000

    ctdb-tools: Drop global variable prog
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 6ac5cb4eafb475cad258e83e60c73420ea5efbdf
Author: Martin Schwenke <[email protected]>
Date:   Thu Jun 29 15:57:19 2017 +1000

    ctdb-tools: Use db_hash in ctdb_killtcp
    
    One less use of trbt_tree_t.  The code is easier to read and is
    significantly smaller.
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit c355fd979a16adaa550e21ddf3e79e5f63950f4e
Author: Martin Schwenke <[email protected]>
Date:   Thu Jun 29 14:46:31 2017 +1000

    ctdb-tools: Use ctdb_connection and ctdb_connection_list structs
    
    Also use new connection and sock addr utilities.
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 6d9fef467cf91e543c2b0084d8a41e213f40c365
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 4 17:01:05 2017 +1000

    ctdb-protocol: Add ctdb_connection_list utilities
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit e50cb8cb5213cf1f876a70638f37b2f8b3d36baa
Author: Martin Schwenke <[email protected]>
Date:   Tue Sep 5 10:52:58 2017 +1000

    ctdb-protocol: Add marshalling for ctdb_connection_list
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit d6f9cd19fdc815f898865ab5fbfd814577ad72dd
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 4 16:48:40 2017 +1000

    ctdb-protocol: Add new data structure ctdb_connection_list
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit ef676d5acf8042c02a2b50e18f4ae07a4f96f7c4
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 4 16:41:30 2017 +1000

    ctdb-protocol: Add ctdb_connection utilities
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 285020360a4142fb982ad94bb21a0e87275cfed7
Author: Martin Schwenke <[email protected]>
Date:   Wed Sep 13 16:18:29 2017 +1000

    ctdb-protocol: Factor out static function ctdb_sock_addr_cmp_family()
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 6f1b1a05fb821d49c44195c6ff91fbe21b1b10ef
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 11 16:39:38 2017 +1000

    ctdb-protocol: Add ctdb_sock_addr_from_string()
    
    This and the supporting functions duplicate functionality (parse_ip()
    and parse_ip_port()) from common/system_util.c.  The old functions
    will be removed at a later time.
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 93668f50266ce43e591f0708bc0dcd557719e2dc
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 11 15:00:10 2017 +1000

    ctdb-protocol: Optionally print port for address printing functions
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit de9f05e8fe9330eb94cc0d4259dcf37431a08578
Author: Martin Schwenke <[email protected]>
Date:   Fri Jun 30 15:11:04 2017 +1000

    ctdb-protocol: Add utility function ctdb_sock_addr_to_buf()
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 22de111ebfbbb74ae0f47e4812db967747873545
Author: Martin Schwenke <[email protected]>
Date:   Fri Jun 2 16:17:22 2017 +1000

    ctdb-protocol: Add ctdb_sock_addr_port() and sock_addr_set_port()
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit eb32b8d3a0320413db3e01019040c12aeb3f902c
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 4 16:20:55 2017 +1000

    ctdb-protocol: Add server and client aliases in ctdb_connection
    
    The current code is ambiguous in its use of src and dst.  This allows
    new code to use server and client for clarity.
    
    Signed-off-by: Amitay Isaacs <[email protected]>
    Reviewed-by: Martin Schwenke <[email protected]>

commit 3816270c76d2aab275dc92d319a1b1708c026b8b
Author: Martin Schwenke <[email protected]>
Date:   Tue Sep 19 14:54:26 2017 +1000

    ctdb-common: Initialise socket addresses before reading into them
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 3783b66fb343b9dbbb4a135ff0573c80ef2aba17
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 4 16:00:48 2017 +1000

    ctdb-build: Split protocol-util as a separate subsystem
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

commit 2550a88e2f04e45b6519c981a40de1fa5f729bd1
Author: Martin Schwenke <[email protected]>
Date:   Mon Sep 4 16:00:27 2017 +1000

    ctdb-build: Fix dependency for ctdbd
    
    Signed-off-by: Martin Schwenke <[email protected]>
    Reviewed-by: Amitay Isaacs <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 ctdb/common/system_aix.c               |   3 +
 ctdb/common/system_freebsd.c           |   3 +
 ctdb/common/system_gnu.c               |   3 +
 ctdb/common/system_kfreebsd.c          |   3 +
 ctdb/common/system_linux.c             |   3 +
 ctdb/protocol/protocol.h               |  15 +-
 ctdb/protocol/protocol_api.h           |  18 --
 ctdb/protocol/protocol_private.h       |   6 +
 ctdb/protocol/protocol_types.c         |  78 +++++
 ctdb/protocol/protocol_util.c          | 473 ++++++++++++++++++++++++++++--
 ctdb/protocol/protocol_util.h          |  72 +++++
 ctdb/server/ctdb_eventd.c              |   1 +
 ctdb/server/ctdb_takeover_helper.c     |   7 +-
 ctdb/server/ipalloc.c                  |   2 +-
 ctdb/server/ipalloc_common.c           |  13 +-
 ctdb/server/ipalloc_lcp2.c             |  16 +-
 ctdb/server/ipalloc_nondeterministic.c |   4 +-
 ctdb/tests/src/ctdb_takeover_tests.c   |   4 +-
 ctdb/tests/src/fake_ctdbd.c            |  22 +-
 ctdb/tests/src/protocol_common.c       |  28 ++
 ctdb/tests/src/protocol_common.h       |   5 +
 ctdb/tests/src/protocol_types_test.c   |   2 +
 ctdb/tests/src/protocol_util_test.c    | 315 ++++++++++++++++++--
 ctdb/tools/ctdb.c                      |  47 +--
 ctdb/tools/ctdb_event.c                |   2 +-
 ctdb/tools/ctdb_killtcp.c              | 519 ++++++++++++++++-----------------
 ctdb/wscript                           |  28 +-
 27 files changed, 1294 insertions(+), 398 deletions(-)
 create mode 100644 ctdb/protocol/protocol_util.h


Changeset truncated at 500 lines:

diff --git a/ctdb/common/system_aix.c b/ctdb/common/system_aix.c
index e44d1d6..f0a0a62 100644
--- a/ctdb/common/system_aix.c
+++ b/ctdb/common/system_aix.c
@@ -291,6 +291,9 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
                return -1;
        }
 
+       ZERO_STRUCTP(src);
+       ZERO_STRUCTP(dst);
+
        /* Ethernet */
        eth = (struct ether_header *)buffer;
 
diff --git a/ctdb/common/system_freebsd.c b/ctdb/common/system_freebsd.c
index e72fbbd..b709a5c 100644
--- a/ctdb/common/system_freebsd.c
+++ b/ctdb/common/system_freebsd.c
@@ -298,6 +298,9 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
                return -1;
        }
 
+       ZERO_STRUCTP(src);
+       ZERO_STRUCTP(dst);
+
        /* Ethernet */
        eth = (struct ether_header *)pkt;
 
diff --git a/ctdb/common/system_gnu.c b/ctdb/common/system_gnu.c
index 603345d..38ccd13 100644
--- a/ctdb/common/system_gnu.c
+++ b/ctdb/common/system_gnu.c
@@ -293,6 +293,9 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
                return -1;
        }
 
+       ZERO_STRUCTP(src);
+       ZERO_STRUCTP(dst);
+
        /* Ethernet */
        eth = (struct ether_header *)pkt;
 
diff --git a/ctdb/common/system_kfreebsd.c b/ctdb/common/system_kfreebsd.c
index 7e33990..d02f286 100644
--- a/ctdb/common/system_kfreebsd.c
+++ b/ctdb/common/system_kfreebsd.c
@@ -293,6 +293,9 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
                return -1;
        }
 
+       ZERO_STRUCTP(src);
+       ZERO_STRUCTP(dst);
+
        /* Ethernet */
        eth = (struct ether_header *)pkt;
 
diff --git a/ctdb/common/system_linux.c b/ctdb/common/system_linux.c
index 3647de9..fa77a45 100644
--- a/ctdb/common/system_linux.c
+++ b/ctdb/common/system_linux.c
@@ -518,6 +518,9 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
                return -1;
        }
 
+       ZERO_STRUCTP(src);
+       ZERO_STRUCTP(dst);
+
        /* Ethernet */
        eth = (struct ether_header *)pkt;
 
diff --git a/ctdb/protocol/protocol.h b/ctdb/protocol/protocol.h
index 266fc4b..3c57e20 100644
--- a/ctdb/protocol/protocol.h
+++ b/ctdb/protocol/protocol.h
@@ -555,8 +555,19 @@ typedef union {
 } ctdb_sock_addr;
 
 struct ctdb_connection {
-       ctdb_sock_addr src;
-       ctdb_sock_addr dst;
+       union {
+               ctdb_sock_addr src;
+               ctdb_sock_addr server;
+       };
+       union {
+               ctdb_sock_addr dst;
+               ctdb_sock_addr client;
+       };
+};
+
+struct ctdb_connection_list {
+       uint32_t num;
+       struct ctdb_connection *conn;
 };
 
 struct ctdb_tunable {
diff --git a/ctdb/protocol/protocol_api.h b/ctdb/protocol/protocol_api.h
index d165ba2..67f32a0b 100644
--- a/ctdb/protocol/protocol_api.h
+++ b/ctdb/protocol/protocol_api.h
@@ -678,22 +678,4 @@ void sock_packet_header_set_reqid(struct 
sock_packet_header *h,
 void sock_packet_header_set_length(struct sock_packet_header *h,
                                   uint32_t length);
 
-/* From protocol/protocol_util.c */
-
-const char *ctdb_runstate_to_string(enum ctdb_runstate runstate);
-enum ctdb_runstate ctdb_runstate_from_string(const char *runstate_str);
-
-const char *ctdb_event_to_string(enum ctdb_event event);
-enum ctdb_event ctdb_event_from_string(const char *event_str);
-
-const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx, ctdb_sock_addr 
*addr);
-int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
-                         const ctdb_sock_addr *addr2);
-int ctdb_sock_addr_cmp(const ctdb_sock_addr *addr1,
-                      const ctdb_sock_addr *addr2);
-bool ctdb_sock_addr_same_ip(const ctdb_sock_addr *addr1,
-                           const ctdb_sock_addr *addr2);
-bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
-                        const ctdb_sock_addr *addr2);
-
 #endif /* __CTDB_PROTOCOL_API_H__ */
diff --git a/ctdb/protocol/protocol_private.h b/ctdb/protocol/protocol_private.h
index a609930..9e3ae8d 100644
--- a/ctdb/protocol/protocol_private.h
+++ b/ctdb/protocol/protocol_private.h
@@ -187,6 +187,12 @@ void ctdb_connection_push(struct ctdb_connection *in, 
uint8_t *buf,
 int ctdb_connection_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
                         struct ctdb_connection **out, size_t *npull);
 
+size_t ctdb_connection_list_len(struct ctdb_connection_list *in);
+void ctdb_connection_list_push(struct ctdb_connection_list *in, uint8_t *buf,
+                              size_t *npush);
+int ctdb_connection_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
+                             struct ctdb_connection_list **out, size_t *npull);
+
 size_t ctdb_tunable_len(struct ctdb_tunable *in);
 void ctdb_tunable_push(struct ctdb_tunable *in, uint8_t *buf, size_t *npush);
 int ctdb_tunable_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
diff --git a/ctdb/protocol/protocol_types.c b/ctdb/protocol/protocol_types.c
index ae6f7ed..57ad07a 100644
--- a/ctdb/protocol/protocol_types.c
+++ b/ctdb/protocol/protocol_types.c
@@ -2171,6 +2171,84 @@ int ctdb_connection_pull(uint8_t *buf, size_t buflen, 
TALLOC_CTX *mem_ctx,
        return ret;
 }
 
+size_t ctdb_connection_list_len(struct ctdb_connection_list *in)
+{
+       size_t len;
+
+       len = ctdb_uint32_len(&in->num);
+       if (in->num > 0) {
+               len += in->num * ctdb_connection_len(&in->conn[0]);
+       }
+
+       return len;
+}
+
+void ctdb_connection_list_push(struct ctdb_connection_list *in, uint8_t *buf,
+                              size_t *npush)
+{
+       size_t offset = 0, np;
+       uint32_t i;
+
+       ctdb_uint32_push(&in->num, buf+offset, &np);
+       offset += np;
+
+       for (i=0; i<in->num; i++) {
+               ctdb_connection_push(&in->conn[i], buf+offset, &np);
+               offset += np;
+       }
+
+       *npush = offset;
+}
+
+int ctdb_connection_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
+                             struct ctdb_connection_list **out, size_t *npull)
+{
+       struct ctdb_connection_list *val;
+       size_t offset = 0, np;
+       uint32_t i;
+       int ret;
+
+       val = talloc(mem_ctx, struct ctdb_connection_list);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
+       if (ret != 0) {
+               goto fail;
+       }
+       offset += np;
+
+       if (val->num == 0) {
+               val->conn = NULL;
+               goto done;
+       }
+
+       val->conn = talloc_array(val, struct ctdb_connection, val->num);
+       if (val->conn == NULL) {
+               ret = ENOMEM;
+               goto fail;
+       }
+
+       for (i=0; i<val->num; i++) {
+               ret = ctdb_connection_pull_elems(buf+offset, buflen-offset,
+                                                val, &val->conn[i], &np);
+               if (ret != 0) {
+                       goto fail;
+               }
+               offset += np;
+       }
+
+done:
+       *out = val;
+       *npull = offset;
+       return 0;
+
+fail:
+       talloc_free(val);
+       return ret;
+}
+
 size_t ctdb_tunable_len(struct ctdb_tunable *in)
 {
        return ctdb_uint32_len(&in->value) +
diff --git a/ctdb/protocol/protocol_util.c b/ctdb/protocol/protocol_util.c
index 0e1bf28..68a470f 100644
--- a/ctdb/protocol/protocol_util.c
+++ b/ctdb/protocol/protocol_util.c
@@ -21,11 +21,9 @@
 #include "system/network.h"
 
 #include <talloc.h>
-#include <tdb.h>
 
 #include "protocol.h"
-#include "protocol_private.h"
-#include "protocol_api.h"
+#include "protocol_util.h"
 
 static struct {
        enum ctdb_runstate runstate;
@@ -113,39 +111,226 @@ enum ctdb_event ctdb_event_from_string(const char 
*event_str)
        return CTDB_EVENT_MAX;
 }
 
-const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx, ctdb_sock_addr *addr)
+int ctdb_sock_addr_to_buf(char *buf, socklen_t buflen,
+                         ctdb_sock_addr *addr, bool with_port)
 {
-       char *cip;
-
-       cip = talloc_size(mem_ctx, 128);
-       if (cip == NULL) {
-               return "Memory Error";
-       }
+       const char *t;
 
        switch (addr->sa.sa_family) {
        case AF_INET:
-               inet_ntop(addr->ip.sin_family, &addr->ip.sin_addr,
-                         cip, 128);
+               t = inet_ntop(addr->ip.sin_family, &addr->ip.sin_addr,
+                             buf, buflen);
+               if (t == NULL) {
+                       return errno;
+               }
                break;
 
        case AF_INET6:
-               inet_ntop(addr->ip6.sin6_family, &addr->ip6.sin6_addr,
-                         cip, 128);
+               t = inet_ntop(addr->ip6.sin6_family, &addr->ip6.sin6_addr,
+                             buf, buflen);
+               if (t == NULL) {
+                       return errno;
+               }
                break;
 
        default:
-               sprintf(cip, "Unknown family %u", addr->sa.sa_family);
+               return EAFNOSUPPORT;
                break;
        }
 
+       if (with_port) {
+               size_t len = strlen(buf);
+               int ret;
+
+               ret = snprintf(buf+len, buflen-len,
+                              ":%u", ctdb_sock_addr_port(addr));
+               if (ret >= buflen-len) {
+                       return ENOSPC;
+               }
+       }
+
+       return 0;
+}
+
+const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx,
+                                    ctdb_sock_addr *addr, bool with_port)
+{
+       size_t len = 64;
+       char *cip;
+       int ret;
+
+       cip = talloc_size(mem_ctx, len);
+
+       if (cip == NULL) {
+               return NULL;
+       }
+
+       ret = ctdb_sock_addr_to_buf(cip, len, addr, with_port);
+       if (ret != 0) {
+               talloc_free(cip);
+               return NULL;
+       }
+
        return cip;
 }
 
-int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
-                         const ctdb_sock_addr *addr2)
+static int ipv4_from_string(const char *str, struct sockaddr_in *ip)
 {
-       int ret = 0;
+       int ret;
+
+       *ip = (struct sockaddr_in) {
+               .sin_family = AF_INET,
+       };
+
+       ret = inet_pton(AF_INET, str, &ip->sin_addr);
+       if (ret != 1) {
+               return EINVAL;
+       }
+
+#ifdef HAVE_SOCK_SIN_LEN
+       ip->sin_len = sizeof(*ip);
+#endif
+       return 0;
+}
+
+static int ipv6_from_string(const char *str, struct sockaddr_in6 *ip6)
+{
+       int ret;
+
+       *ip6 = (struct sockaddr_in6) {
+               .sin6_family   = AF_INET6,
+       };
+
+       ret = inet_pton(AF_INET6, str, &ip6->sin6_addr);
+       if (ret != 1) {
+               return EINVAL;
+       }
+
+#ifdef HAVE_SOCK_SIN_LEN
+       ip6->sin6_len = sizeof(*ip6);
+#endif
+       return 0;
+}
+
+static int ip_from_string(const char *str, ctdb_sock_addr *addr)
+{
+       char *p;
+       int ret;
+
+       if (addr == NULL) {
+               return EINVAL;
+       }
+
+       ZERO_STRUCTP(addr); /* valgrind :-) */
+
+       /* IPv4 or IPv6 address?
+        *
+        * Use rindex() because we need the right-most ':' below for
+        * IPv4-mapped IPv6 addresses anyway...
+        */
+       p = rindex(str, ':');
+       if (p == NULL) {
+               ret = ipv4_from_string(str, &addr->ip);
+       } else {
+               uint8_t ipv4_mapped_prefix[12] = {
+                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
+               };
+
+               ret = ipv6_from_string(str, &addr->ip6);
+               if (ret != 0) {
+                       return ret;
+               }
+
+               /*
+                * Check for IPv4-mapped IPv6 address
+                * (e.g. ::ffff:192.0.2.128) - reparse as IPv4 if
+                * necessary
+                */
+               if (memcmp(&addr->ip6.sin6_addr.s6_addr[0],
+                          ipv4_mapped_prefix,
+                          sizeof(ipv4_mapped_prefix)) == 0) {
+                       /* Reparse as IPv4 */
+                       ret = ipv4_from_string(p+1, &addr->ip);
+               }
+       }
+
+       return ret;
+}
 
+int ctdb_sock_addr_from_string(const char *str,
+                              ctdb_sock_addr *addr, bool with_port)
+{
+       char *p;
+       char s[64]; /* Much longer than INET6_ADDRSTRLEN */
+       unsigned port;
+       char *endp = NULL;
+       size_t len;
+       bool ret;
+
+       if (! with_port) {
+               ret = ip_from_string(str, addr);
+               return ret;
+       }
+
+       /* Parse out port number and then IP address */
+
+       len = strlen(str);
+       if (len >= sizeof(s)) {
+               return EINVAL;
+       }
+
+       strncpy(s, str, len+1);
+
+       p = rindex(s, ':');
+       if (p == NULL) {
+               return EINVAL;
+       }
+
+       port = strtoul(p+1, &endp, 10);
+       if (endp == p+1 || *endp != '\0') {
+               /* Empty string or trailing garbage */
+               return EINVAL;
+       }
+
+       *p = '\0';
+       ret = ip_from_string(s, addr);
+
+       ctdb_sock_addr_set_port(addr, port);
+
+       return ret;
+}
+
+unsigned int ctdb_sock_addr_port(ctdb_sock_addr *addr)
+{
+       switch (addr->sa.sa_family) {
+       case AF_INET:
+               return ntohs(addr->ip.sin_port);
+               break;
+       case AF_INET6:
+               return ntohs(addr->ip6.sin6_port);
+               break;
+       default:
+               return 0;
+       }
+}
+
+void ctdb_sock_addr_set_port(ctdb_sock_addr *addr, unsigned int port)
+{
+       switch (addr->sa.sa_family) {
+       case AF_INET:
+               addr->ip.sin_port = htons(port);
+               break;
+       case AF_INET6:
+               addr->ip6.sin6_port = htons(port);
+               break;
+       default:
+               break;
+       }
+}
+
+static int ctdb_sock_addr_cmp_family(const ctdb_sock_addr *addr1,
+                                    const ctdb_sock_addr *addr2)
+{
        /* This is somewhat arbitrary.  However, when used for sorting
         * it just needs to be consistent.
         */
@@ -156,6 +341,19 @@ int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
                return 1;
        }
 
+       return 0;
+}
+
+int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
+                         const ctdb_sock_addr *addr2)
+{
+       int ret;
+


-- 
Samba Shared Repository

Reply via email to