Skip to content

Commit

Permalink
[XrdCl] Don't use sort to partition IP addresses.
Browse files Browse the repository at this point in the history
At BNL the Caching Proxy is frequently crashing due to a segv in the
std::sort.
  • Loading branch information
simonmichal committed Mar 6, 2018
1 parent 8092aa9 commit 38add6f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 16 deletions.
10 changes: 0 additions & 10 deletions src/XrdCl/XrdClStream.cc
Expand Up @@ -259,16 +259,6 @@ namespace XrdCl
Utils::LogHostAddresses( log, PostMasterMsg, pUrl->GetHostId(),
pAddresses );

//--------------------------------------------------------------------------
// Initiate the connection process to the first one on the list.
// It's more efficient to remove addresses from the back of a vector
// so we reverse the it.
//--------------------------------------------------------------------------
int preferIPv4 = DefaultPreferIPv4;
DefaultEnv::GetEnv()->GetInt( "PreferIPv4", preferIPv4 );
if( !preferIPv4 )
std::reverse( pAddresses.begin(), pAddresses.end() );

while( !pAddresses.empty() )
{
pSubStreams[0]->socket->SetAddress( pAddresses.back() );
Expand Down
42 changes: 36 additions & 6 deletions src/XrdCl/XrdClUtils.cc
Expand Up @@ -163,16 +163,46 @@ namespace XrdCl
return Status( stError, errInvalidAddr );
}

addresses.clear();
//--------------------------------------------------------------------------
// Check what are the preferences IPv6 or IPv4
//--------------------------------------------------------------------------
int preferIPv4 = DefaultPreferIPv4;
DefaultEnv::GetEnv()->GetInt( "PreferIPv4", preferIPv4 );

//--------------------------------------------------------------------------
// Partition the addresses according to the preferences
//
// The preferred IP family goes to the back as it is easier to remove
// items from the back of the vector
//--------------------------------------------------------------------------
std::vector<XrdNetAddr> result( nAddrs );
auto itr = result.begin();
auto ritr = result.end() - 1;

for( int i = 0; i < nAddrs; ++i )
addresses.push_back( addrs[i] );
delete [] addrs;
{
bool isIPv4 = addrs[i].isIPType( XrdNetAddrInfo::IPv4 ) ||
( addrs[i].isIPType( XrdNetAddrInfo::IPv6 ) && addrs[i].isMapped() );

auto store = preferIPv4 ?
( isIPv4 ? ritr-- : itr++ ) :
( isIPv4 ? itr++ : ritr-- );

*store = addrs[i];
}

//--------------------------------------------------------------------------
// Shuffle each partition
//--------------------------------------------------------------------------
// Sort and shuffle them
std::random_shuffle( result.begin(), itr );
std::random_shuffle( itr, result.end() );

//--------------------------------------------------------------------------
// Return result through output parameter
//--------------------------------------------------------------------------
std::random_shuffle( addresses.begin(), addresses.end() );
std::sort( addresses.begin(), addresses.end(), PreferIPv6() );
addresses.swap( result );
delete [] addrs;

return Status();
}

Expand Down

0 comments on commit 38add6f

Please sign in to comment.