summaryrefslogtreecommitdiff
path: root/ctdb/tcp
diff options
context:
space:
mode:
authorRonnie sahlberg <ronniesahlberg@gmail.com>2007-04-06 09:08:41 +1000
committerRonnie sahlberg <ronniesahlberg@gmail.com>2007-04-06 09:08:41 +1000
commita25554be50c13bf7bcf3986ce10c32394d265c3a (patch)
tree8186cbcf8812eece956302bc0122b8bb6112f696 /ctdb/tcp
parent4d189e243702973d1eb3a829530d49b0a5564374 (diff)
downloadsamba-a25554be50c13bf7bcf3986ce10c32394d265c3a.tar.gz
When we create a tcp connection to a remote ctdb node do an explicit bind() to set our source side to the same ip address as we use to listen to ctdb traffic.
We need this since there is no guarantee that INADDR_ANY (which would be defaulted to if we dont bind) would be routable from the remote host. This is entirely possible to happen since CTDB traffic is likely to be isolated to a private non-routable network. (This used to be ctdb commit e0743d2f84ca0088734c912e210deb93a6b78860)
Diffstat (limited to 'ctdb/tcp')
-rw-r--r--ctdb/tcp/tcp_connect.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c
index fe0fc210baf..85fffc2f703 100644
--- a/ctdb/tcp/tcp_connect.c
+++ b/ctdb/tcp/tcp_connect.c
@@ -98,6 +98,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
struct ctdb_tcp_node *tnode = talloc_get_type(node->private,
struct ctdb_tcp_node);
struct ctdb_context *ctdb = node->ctdb;
+ struct sockaddr_in sock_in;
struct sockaddr_in sock_out;
tnode->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -109,7 +110,21 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
}
sock_out.sin_port = htons(node->address.port);
sock_out.sin_family = PF_INET;
-
+
+
+ /* Bind our side of the socketpair to the same address we use to listen
+ * on incoming CTDB traffic.
+ * We must specify this address to make sure that the address we expose to
+ * the remote side is actually routable in case CTDB traffic will run on
+ * a dedicated non-routeable network.
+ */
+ if (ctdb_tcp_get_address(ctdb, ctdb->address.address, &sock_in.sin_addr) != 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 &&
errno != EINPROGRESS) {
/* try again once a second */