From d6ff14ed61e53e4d0330768e059419f310d4adbf Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Wed, 25 Oct 2006 15:09:30 +0000 Subject: [PATCH] Hand-pack the connection information for each peer rather than just packing a sockaddr_in, as there are some endianness and padding issues with sending a sockaddr_in. Note that the sin_port and sin_addr are already in network byte order, which is why we pack them as a byte string. Refs trac:493 This commit was SVN r12301. The following Trac tickets were found above: Ticket 493 --> https://svn.open-mpi.org/trac/ompi/ticket/493 --- orte/mca/oob/tcp/oob_tcp_addr.c | 59 ++++++++++++++++++++++++++++++--- orte/mca/oob/tcp/oob_tcp_addr.h | 2 ++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/orte/mca/oob/tcp/oob_tcp_addr.c b/orte/mca/oob/tcp/oob_tcp_addr.c index 37284b1ad9..6857bea799 100644 --- a/orte/mca/oob/tcp/oob_tcp_addr.c +++ b/orte/mca/oob/tcp/oob_tcp_addr.c @@ -83,12 +83,33 @@ int mca_oob_tcp_addr_pack(orte_buffer_t* buffer) for(i=opal_ifbegin(); i>0; i=opal_ifnext(i)) { struct sockaddr_in inaddr; + uint8_t type; + uint32_t ipaddr; + uint16_t port; + opal_ifindextoaddr(i, (struct sockaddr*)&inaddr, sizeof(inaddr)); if(opal_ifcount() > 1 && opal_ifislocalhost((struct sockaddr*) &inaddr)) continue; - inaddr.sin_port = mca_oob_tcp_component.tcp_listen_port; - orte_dss.pack(buffer,&inaddr,sizeof(inaddr),ORTE_BYTE); + + switch (inaddr.sin_family) { + case AF_INET: + type = MCA_OOB_TCP_ADDR_TYPE_AFINET; + break; + default: + /* shouldn't get here, as opal_if shouldn't allow anything + but AFINET. Will need another case once IPv6 code is + committed. */ + continue; + } + orte_dss.pack(buffer, &type, 1, ORTE_INT8); + + port = mca_oob_tcp_component.tcp_listen_port; + orte_dss.pack(buffer, &port, sizeof(port), ORTE_BYTE); + + /* This will need to be adjusted for IPv6 */ + ipaddr = (uint32_t) inaddr.sin_addr.s_addr; + orte_dss.pack(buffer, &ipaddr, sizeof(ipaddr), ORTE_BYTE); } return ORTE_SUCCESS; } @@ -125,12 +146,42 @@ mca_oob_tcp_addr_t* mca_oob_tcp_addr_unpack(orte_buffer_t* buffer) } addr->addr_alloc = addr->addr_count; for(i=0; iaddr_count; i++) { - orte_std_cntr_t inaddr_size = sizeof(struct sockaddr_in); - rc = orte_dss.unpack(buffer, addr->addr_inet+i, &inaddr_size, ORTE_BYTE); + uint8_t type; + uint32_t ipaddr; + uint16_t port; + /* unpack and expand family */ + count = 1; + rc = orte_dss.unpack(buffer, &type, &count, ORTE_INT8); if(rc != ORTE_SUCCESS) { OBJ_RELEASE(addr); return NULL; } + switch (type) { + case MCA_OOB_TCP_ADDR_TYPE_AFINET: + addr->addr_inet[i].sin_family = AF_INET; + break; + default: + OBJ_RELEASE(addr); + return NULL; + } + + /* and the listen port */ + count = sizeof(port); + rc = orte_dss.unpack(buffer, &port, &count, ORTE_BYTE); + if(rc != ORTE_SUCCESS) { + OBJ_RELEASE(addr); + return NULL; + } + addr->addr_inet[i].sin_port = port; + + /* and the address. need to fix for IPv6 */ + count = sizeof(ipaddr); + rc = orte_dss.unpack(buffer, &ipaddr, &count, ORTE_BYTE); + if(rc != ORTE_SUCCESS) { + OBJ_RELEASE(addr); + return NULL; + } + addr->addr_inet[i].sin_addr.s_addr = ipaddr; } } return addr; diff --git a/orte/mca/oob/tcp/oob_tcp_addr.h b/orte/mca/oob/tcp/oob_tcp_addr.h index 3c53846454..9ed9293ca8 100644 --- a/orte/mca/oob/tcp/oob_tcp_addr.h +++ b/orte/mca/oob/tcp/oob_tcp_addr.h @@ -53,6 +53,8 @@ typedef struct mca_oob_tcp_addr_t mca_oob_tcp_addr_t; OBJ_CLASS_DECLARATION(mca_oob_tcp_addr_t); +#define MCA_OOB_TCP_ADDR_TYPE_AFINET 0x01 + /** * Unpack the contact information posted by the peer. */