From 959bdace3c1e60248ead1f8ac9b83f4af7212306 Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Wed, 30 Jul 2014 21:03:56 +0000 Subject: [PATCH] usnic: check that connectivity pings came from where they said they came from Ensure that incoming "ping" messages came from the IP address that they think they came from. If they don't, drop them (because it is probably routing error), which will likely eventually cause the connectivity checker to timeout, and therefore cause the job to abort. This commit was SVN r32368. --- opal/mca/btl/usnic/btl_usnic_cagent.c | 28 ++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/opal/mca/btl/usnic/btl_usnic_cagent.c b/opal/mca/btl/usnic/btl_usnic_cagent.c index 4c8210d57c..7550a02424 100644 --- a/opal/mca/btl/usnic/btl_usnic_cagent.c +++ b/opal/mca/btl/usnic/btl_usnic_cagent.c @@ -332,9 +332,9 @@ static void agent_thread_handle_ping(agent_udp_port_listener_t *listener, /* If the size we received isn't equal to what the sender says it sent, do the simple thing: just don't send an ACK */ agent_udp_message_t *msg = (agent_udp_message_t*) listener->buffer; + struct sockaddr_in *src_addr_in = (struct sockaddr_in*) from; if (msg->size != numbytes) { char str[INET_ADDRSTRLEN]; - struct sockaddr_in *src_addr_in = (struct sockaddr_in*) from; inet_ntop(AF_INET, &src_addr_in->sin_addr, str, sizeof(str)); opal_output_verbose(20, USNIC_OUT, @@ -343,13 +343,31 @@ static void agent_thread_handle_ping(agent_udp_port_listener_t *listener, return; } - char src_ipv4_addr_str[IPV4STRADDRLEN]; - opal_btl_usnic_snprintf_ipv4_addr(src_ipv4_addr_str, - sizeof(src_ipv4_addr_str), + /* Ensure that the sender sent the ping from the IP address that + they think they sent it from. If they didn't, then drop it + (i.e., it's a bad ping because the sender sent it from an + unexpected interface). This should probably never happen, but + it's a good failsafe for unexpected scenarios. */ + char msg_ipv4_addr_str[IPV4STRADDRLEN]; + char real_ipv4_addr_str[IPV4STRADDRLEN]; + + opal_btl_usnic_snprintf_ipv4_addr(msg_ipv4_addr_str, + sizeof(msg_ipv4_addr_str), msg->src_ipv4_addr, 0); + opal_btl_usnic_snprintf_ipv4_addr(real_ipv4_addr_str, + sizeof(real_ipv4_addr_str), + src_addr_in->sin_addr.s_addr, 0); + + if (msg->src_ipv4_addr != src_addr_in->sin_addr.s_addr) { + opal_output_verbose(20, USNIC_OUT, + "usNIC connectivity got bad ping (from unexpected address: %s != %s, discarded)", + msg_ipv4_addr_str, real_ipv4_addr_str); + return; + } + opal_output_verbose(20, USNIC_OUT, "usNIC connectivity got PING (size=%ld) from %s; sending ACK", - numbytes, src_ipv4_addr_str); + numbytes, msg_ipv4_addr_str); /* Send back an ACK. No need to allocate a new buffer; just re-use the same buffer we just got. Note that msg->size is