summaryrefslogtreecommitdiff
path: root/ctdb/tcp
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2015-02-20 11:47:23 +1100
committerAmitay Isaacs <amitay@samba.org>2015-03-23 12:23:12 +0100
commita5be2c245d5634695bd23387913c7e2e2481879b (patch)
tree3d891e1e738045b5fd52a1dbd3b8a93315f6228c /ctdb/tcp
parent3cbeb17d0f9f1e4b6a3faa9aba2982793cf8494b (diff)
downloadsamba-a5be2c245d5634695bd23387913c7e2e2481879b.tar.gz
ctdb-daemon: Store node addresses as ctdb_sock_addr rather than strings
Every time a nodemap is contructed the node IP addresses all need to be parsed. This isn't very productive use of CPU. Instead, parse each string once when the nodes file is loaded. This results in much simpler code. This code also removes the use of ctdb_address. Duplicating the port is pointless without an abstraction layer around ctdb_address. If CTDB gets an incompatible transport in the future then add an abstraction layer. Note that the infiniband code is not updated. Compilation of the infiniband code is already broken. Fixing it will be a separate, properly tested effort. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com> Pair-programmed-with: Amitay Isaacs <amitay@gmail.com>
Diffstat (limited to 'ctdb/tcp')
-rw-r--r--ctdb/tcp/tcp_connect.c99
-rw-r--r--ctdb/tcp/tcp_init.c2
2 files changed, 23 insertions, 78 deletions
diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c
index 51aa21fc944..6950ac85522 100644
--- a/ctdb/tcp/tcp_connect.c
+++ b/ctdb/tcp/tcp_connect.c
@@ -111,16 +111,6 @@ 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, ctdb_sock_addr *addr)
-{
- if (parse_ip(address, NULL, 0, addr) == 0) {
- DEBUG(DEBUG_CRIT, (__location__ " Unparsable address : %s.\n", address));
- return -1;
- }
- return 0;
-}
-
/*
called when we should try and establish a tcp connection to a node
*/
@@ -139,25 +129,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
ctdb_tcp_stop_connection(node);
- ZERO_STRUCT(sock_out);
-#ifdef HAVE_SOCK_SIN_LEN
- sock_out.ip.sin_len = sizeof(sock_out);
-#endif
- 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 = node->address;
tnode->fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if (tnode->fd == -1) {
@@ -175,12 +147,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
* the remote side is actually routable in case CTDB traffic will run on
* a dedicated non-routeable network.
*/
- ZERO_STRUCT(sock_in);
- if (ctdb_tcp_get_address(ctdb, ctdb->address.address, &sock_in) != 0) {
- DEBUG(DEBUG_ERR, (__location__ " Failed to find our address. Failing bind.\n"));
- close(tnode->fd);
- return;
- }
+ sock_in = *ctdb->address;
/* AIX libs check to see if the socket address and length
arguments are consistent with each other on calls like
@@ -189,10 +156,12 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
*/
switch (sock_in.sa.sa_family) {
case AF_INET:
+ sock_in.ip.sin_port = 0 /* Any port */;
sockin_size = sizeof(sock_in.ip);
sockout_size = sizeof(sock_out.ip);
break;
case AF_INET6:
+ sock_in.ip6.sin6_port = 0 /* Any port */;
sockin_size = sizeof(sock_in.ip6);
sockout_size = sizeof(sock_out.ip6);
break;
@@ -202,10 +171,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
close(tnode->fd);
return;
}
-#ifdef HAVE_SOCK_SIN_LEN
- sock_in.ip.sin_len = sockin_size;
- sock_out.ip.sin_len = sockout_size;
-#endif
+
if (bind(tnode->fd, (struct sockaddr *)&sock_in, sockin_size) == -1) {
DEBUG(DEBUG_ERR, (__location__ "Failed to bind socket %s(%d)\n",
strerror(errno), errno));
@@ -249,18 +215,16 @@ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde,
int fd, nodeid;
struct ctdb_incoming *in;
int one = 1;
- const char *incoming_node;
memset(&addr, 0, sizeof(addr));
len = sizeof(addr);
fd = accept(ctcp->listen_fd, (struct sockaddr *)&addr, &len);
if (fd == -1) return;
- incoming_node = ctdb_addr_to_str(&addr);
- nodeid = ctdb_ip_to_nodeid(ctdb, incoming_node);
+ nodeid = ctdb_ip_to_nodeid(ctdb, &addr);
if (nodeid == -1) {
- DEBUG(DEBUG_ERR, ("Refused connection from unknown node %s\n", incoming_node));
+ DEBUG(DEBUG_ERR, ("Refused connection from unknown node %s\n", ctdb_addr_to_str(&addr)));
close(fd);
return;
}
@@ -279,8 +243,8 @@ static void ctdb_listen_event(struct event_context *ev, struct fd_event *fde,
strerror(errno)));
}
- in->queue = ctdb_queue_setup(ctdb, in, in->fd, CTDB_TCP_ALIGNMENT,
- ctdb_tcp_read_cb, in, "ctdbd-%s", incoming_node);
+ in->queue = ctdb_queue_setup(ctdb, in, in->fd, CTDB_TCP_ALIGNMENT,
+ ctdb_tcp_read_cb, in, "ctdbd-%s", ctdb_addr_to_str(&addr));
}
@@ -334,20 +298,13 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
continue;
}
- ZERO_STRUCT(sock);
- if (ctdb_tcp_get_address(ctdb,
- ctdb->nodes[i]->address.address,
- &sock) != 0) {
- continue;
- }
-
+ sock = ctdb->nodes[i]->address;
+
switch (sock.sa.sa_family) {
case AF_INET:
- sock.ip.sin_port = htons(ctdb->nodes[i]->address.port);
sock_size = sizeof(sock.ip);
break;
case AF_INET6:
- sock.ip6.sin6_port = htons(ctdb->nodes[i]->address.port);
sock_size = sizeof(sock.ip6);
break;
default:
@@ -355,9 +312,6 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
sock.sa.sa_family));
continue;
}
-#ifdef HAVE_SOCK_SIN_LEN
- sock.ip.sin_len = sock_size;
-#endif
ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if (ctcp->listen_fd == -1) {
@@ -390,14 +344,14 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
DEBUG(DEBUG_CRIT,("Unable to bind to any of the node addresses - giving up\n"));
goto failed;
}
- ctdb->address.address = talloc_strdup(ctdb, ctdb->nodes[i]->address.address);
- ctdb->address.port = ctdb->nodes[i]->address.port;
+ ctdb->address = talloc_memdup(ctdb,
+ &ctdb->nodes[i]->address,
+ sizeof(ctdb_sock_addr));
+ CTDB_NO_MEMORY(ctdb, ctdb->address);
ctdb->name = talloc_asprintf(ctdb, "%s:%u",
- ctdb->address.address,
- ctdb->address.port);
- DEBUG(DEBUG_INFO,("ctdb chose network address %s:%u\n",
- ctdb->address.address,
- ctdb->address.port));
+ ctdb_addr_to_str(ctdb->address),
+ ctdb_addr_to_port(ctdb->address));
+ DEBUG(DEBUG_INFO,("ctdb chose network address %s\n", ctdb->name));
if (listen(ctcp->listen_fd, 10) == -1) {
goto failed;
@@ -410,7 +364,7 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
close(lock_fd);
return 0;
-
+
failed:
close(lock_fd);
if (ctcp->listen_fd != -1) {
@@ -435,23 +389,17 @@ int ctdb_tcp_listen(struct ctdb_context *ctdb)
/* we can either auto-bind to the first available address, or we can
use a specified address */
- if (!ctdb->address.address) {
+ if (!ctdb->address) {
return ctdb_tcp_listen_automatic(ctdb);
}
- ZERO_STRUCT(sock);
- if (ctdb_tcp_get_address(ctdb, ctdb->address.address,
- &sock) != 0) {
- goto failed;
- }
-
+ sock = *ctdb->address;
+
switch (sock.sa.sa_family) {
case AF_INET:
- sock.ip.sin_port = htons(ctdb->address.port);
sock_size = sizeof(sock.ip);
break;
case AF_INET6:
- sock.ip6.sin6_port = htons(ctdb->address.port);
sock_size = sizeof(sock.ip6);
break;
default:
@@ -459,9 +407,6 @@ int ctdb_tcp_listen(struct ctdb_context *ctdb)
sock.sa.sa_family));
goto failed;
}
-#ifdef HAVE_SOCK_SIN_LEN
- sock.ip.sin_len = sock_size;
-#endif
ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
if (ctcp->listen_fd == -1) {
diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c
index a65e7320f5e..dba3be33947 100644
--- a/ctdb/tcp/tcp_init.c
+++ b/ctdb/tcp/tcp_init.c
@@ -92,7 +92,7 @@ static int ctdb_tcp_connect_node(struct ctdb_node *node)
/* startup connection to the other server - will happen on
next event loop */
- if (!ctdb_same_address(&ctdb->address, &node->address)) {
+ if (!ctdb_same_address(ctdb->address, &node->address)) {
tnode->connect_te = event_add_timed(ctdb->ev, tnode,
timeval_zero(),
ctdb_tcp_node_connect, node);