diff options
author | Ronnie sahlberg <ronniesahlberg@gmail.com> | 2007-04-06 09:08:41 +1000 |
---|---|---|
committer | Ronnie sahlberg <ronniesahlberg@gmail.com> | 2007-04-06 09:08:41 +1000 |
commit | a25554be50c13bf7bcf3986ce10c32394d265c3a (patch) | |
tree | 8186cbcf8812eece956302bc0122b8bb6112f696 /ctdb/tcp | |
parent | 4d189e243702973d1eb3a829530d49b0a5564374 (diff) | |
download | samba-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.c | 17 |
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 */ |