[Cluster-devel] cluster/magma/lib magmamsg.h memberlist.c mess ...
lhh at sourceware.org
lhh at sourceware.org
Fri Oct 26 20:23:48 UTC 2007
CVSROOT: /cvs/cluster
Module name: cluster
Branch: RHEL4
Changes by: lhh at sourceware.org 2007-10-26 20:23:47
Modified files:
magma/lib : magmamsg.h memberlist.c message.c
Log message:
Fix bugzilla #298831 - apps using magmamsg don't connect from correct source IP on multi-homed hosts
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/magmamsg.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5&r2=1.5.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/memberlist.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.6&r2=1.6.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/magma/lib/message.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.9.2.3&r2=1.9.2.4
--- cluster/magma/lib/Attic/magmamsg.h 2004/11/02 20:11:38 1.5
+++ cluster/magma/lib/Attic/magmamsg.h 2007/10/26 20:23:46 1.5.2.1
@@ -22,6 +22,7 @@
#include <magma.h>
int msg_update(cluster_member_list_t *membership);
+int msg_set_nodeid(uint64_t nodeid);
void msg_shutdown(void);
ssize_t msg_receive_timeout(int fd, void *buf, ssize_t count,
unsigned int timeout);
--- cluster/magma/lib/Attic/memberlist.c 2004/11/02 20:11:38 1.6
+++ cluster/magma/lib/Attic/memberlist.c 2007/10/26 20:23:46 1.6.2.1
@@ -234,7 +234,7 @@
{
int x;
- if (!list)
+ if (!list || nodeid == NODE_ID_NONE)
return NULL;
for (x = 0; x < list->cml_count; x++) {
--- cluster/magma/lib/Attic/message.c 2005/04/21 17:28:29 1.9.2.3
+++ cluster/magma/lib/Attic/message.c 2007/10/26 20:23:46 1.9.2.4
@@ -61,6 +61,7 @@
*/
static pthread_mutex_t ml_mutex = PTHREAD_MUTEX_INITIALIZER;
static cluster_member_list_t *ml_membership;
+static uint64_t _local_id = NODE_ID_NONE;
/* Mutex to prevent
thread1 thread2
@@ -104,6 +105,16 @@
}
+int
+msg_set_nodeid(uint64_t my_node_id)
+{
+ pthread_mutex_lock(&ml_mutex);
+ _local_id = my_node_id;
+ pthread_mutex_unlock(&ml_mutex);
+ return 0;
+}
+
+
/**
Shut down the mssage subsystem. Closes all file descriptors and cleans up
the membership list.
@@ -300,9 +311,12 @@
@see connect_nb, ipv4_connect
*/
static int
-ipv6_connect(struct in6_addr *in6_addr, uint16_t port, int timeout)
+ipv6_connect(struct in6_addr *in6_addr, uint16_t port, int timeout,
+ cluster_member_t *me)
{
struct sockaddr_in6 _sin6;
+ struct sockaddr_in6 srcaddr;
+ struct addrinfo *ai;
int fd, ret;
fd = socket(PF_INET6, SOCK_STREAM, 0);
@@ -315,6 +329,29 @@
_sin6.sin6_flowinfo = 0;
memcpy(&_sin6.sin6_addr, in6_addr, sizeof(_sin6.sin6_addr));
+ if (me) {
+ /* if we know the local node, bind to its resolved
+ interface so other nodes don't reject the connection
+ due to improper source-routing */
+ memset(&srcaddr, 0, sizeof(srcaddr));
+ srcaddr.sin6_family = AF_INET6;
+
+ for (ai = me->cm_addrs; ai; ai = ai->ai_next) {
+ if (ai->ai_family != AF_INET6)
+ continue;
+
+ if (ai->ai_socktype != SOCK_STREAM)
+ continue;
+
+ memcpy(&((struct sockaddr_in6 *)&srcaddr)->sin6_addr,
+ &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
+ sizeof(struct in6_addr));
+
+ bind(fd, (struct sockaddr *)&srcaddr,
+ sizeof(srcaddr));
+ }
+ }
+
ret = connect_nb(fd, (struct sockaddr *)&_sin6, sizeof(_sin6), timeout);
if (ret < 0) {
close(fd);
@@ -335,15 +372,41 @@
@see connect_nb, ipv6_connect
*/
static int
-ipv4_connect(struct in_addr *in_addr, uint16_t port, int timeout)
+ipv4_connect(struct in_addr *in_addr, uint16_t port, int timeout,
+ cluster_member_t *me)
{
struct sockaddr_in _sin;
+ struct sockaddr_in srcaddr;
+ struct addrinfo *ai;
int fd, ret;
fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
return -1;
+ if (me) {
+ /* if we know the local node, bind to its resolved
+ interface so other nodes don't reject the connection
+ due to improper source-routing */
+ memset(&srcaddr, 0, sizeof(srcaddr));
+ srcaddr.sin_family = AF_INET;
+
+ for (ai = me->cm_addrs; ai; ai = ai->ai_next) {
+ if (ai->ai_family != AF_INET)
+ continue;
+
+ if (ai->ai_socktype != SOCK_STREAM)
+ continue;
+
+ memcpy(&((struct sockaddr_in *)&srcaddr)->sin_addr,
+ &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
+ sizeof(struct in_addr));
+
+ bind(fd, (struct sockaddr *)&srcaddr,
+ sizeof(srcaddr));
+ }
+ }
+
_sin.sin_family = AF_INET;
_sin.sin_port = htons(port);
memcpy(&_sin.sin_addr, in_addr, sizeof(_sin.sin_addr));
@@ -377,6 +440,7 @@
{
int fd;
cluster_member_t *nodep;
+ cluster_member_t *me;
struct addrinfo *ai;
pthread_mutex_lock(&ml_mutex);
@@ -387,6 +451,10 @@
return -1;
}
+ me = memb_id_to_p(ml_membership, _local_id);
+ if (me)
+ memb_resolve(me);
+
/* Try to resolve if we haven't done so */
if (!nodep->cm_addrs && (memb_resolve(nodep) < 0)) {
pthread_mutex_unlock(&ml_mutex);
@@ -404,7 +472,7 @@
fd = ipv6_connect(
&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
- baseport + IPV6_PORT_OFFSET, timeout);
+ baseport + IPV6_PORT_OFFSET, timeout, me);
if (fd >= 0) {
pthread_mutex_unlock(&ml_mutex);
@@ -428,7 +496,7 @@
fd = ipv4_connect(
&((struct sockaddr_in *)ai->ai_addr)->sin_addr,
- baseport, timeout);
+ baseport, timeout, me );
if (fd >= 0) {
pthread_mutex_unlock(&ml_mutex);
More information about the Cluster-devel
mailing list