From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 26 Oct 2007 20:23:48 -0000 Subject: [Cluster-devel] cluster/magma/lib magmamsg.h memberlist.c mess ... Message-ID: <20071026202348.11818.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 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);