[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