Example #1
0
bool
Sinful::addressPointsToMe( Sinful const &addr ) const
{
	bool addr_matches = false;

	// Confirm that ports match. Don't even bother checking the addresses if ports don't match.
	if ( getHost() && getPort() && addr.getPort() && !strcmp(getPort(),addr.getPort()) )
	{
		// Check if host addresses match
		if( addr.getHost() && !strcmp(getHost(),addr.getHost()) )
		{
			addr_matches = true;
		}

		// We may have failed to match host addresses above, but we now need
		// to cover the case of the loopback interface (aka 127.0.0.1).  A common
		// usage pattern for this method is for "this" object to represent our daemonCore 
		// command socket.  If this is the case, and the addr passed in is a loopback
		// address, consider the addresses to match.  Note we convert to a condor_sockaddr
		// so we can use method is_loopback(), which correctly handles both IPv4 and IPv6.
		Sinful oursinful( global_dc_sinful() );
		condor_sockaddr addrsock;
		if( !addr_matches && oursinful.getHost() && !strcmp(getHost(),oursinful.getHost()) &&
			addr.getSinful() && addrsock.from_sinful(addr.getSinful()) && addrsock.is_loopback() )
		{
			addr_matches = true;
		}
	}

	// The addrs and ports match, but if shared_port is in use, we need to confirm the
	// shared port id also matches.
	if (addr_matches)
	{
		char const *spid = getSharedPortID();
		char const *addr_spid = addr.getSharedPortID();
		if( (spid == NULL && addr_spid == NULL) ||			// case without shared port
			(spid && addr_spid && !strcmp(spid,addr_spid)) 	// case with shared port
		  )
		{
			return true;
		}
	}

	// Public address failed to match, but now need to do it all over again checking
	// the private address.
	if( getPrivateAddr() ) {
		Sinful private_addr( getPrivateAddr() );
		return private_addr.addressPointsToMe( addr );
	}

	return false;
}
char const *
SharedPortEndpoint::GetMyLocalAddress()
{
	if( !m_listening ) {
		return NULL;
	}
	if( m_local_addr.IsEmpty() ) {
		Sinful sinful;
			// port 0 is used as an indicator that no SharedPortServer
			// address is included in this address.  This address should
			// never be shared with anybody except for local commands
			// and daemons who can then form a connection to us via
			// direct access to our named socket.
		sinful.setPort("0");
		sinful.setHost(my_ip_string());
		sinful.setSharedPortID( m_local_id.Value() );
		std::string alias;
		if( param(alias,"HOST_ALIAS") ) {
			sinful.setAlias(alias.c_str());
		}
		m_local_addr = sinful.getSinful();
	}
	return m_local_addr.Value();
}
Example #3
0
int main( int, char ** ) {
	Sinful s;
	Sinful t;

	//
	// Test, for 0, 1, 2, and 3 condor_sockaddrs: that the vector is not NULL,
	// that the vector has the correct number of elements, that the vector's
	// elements values are correct (and in the correct order); and that the
	// string form of the sinful is correct; and that the parser correctly
	// handles the sinful string (by repeating the vector tests); and that
	// the string->sinful->string loop also works (by repeating the string
	// test).  Then repeat the 0 test after clearing the Sinful of addrs.
	//
	// We then also test adding three condor_sockaddrs in a row, just in
	// case one-at-a-time testing somehow hides a problem; this also tests
	// that adding condor_sockaddrs after clearing the Sinful works.
	//


	std::vector< condor_sockaddr > * v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 0 );
	delete v; v = NULL;

	char const * sinfulString = NULL;
	sinfulString = s.getSinful();
	REQUIRE( sinfulString == NULL );

	REQUIRE( ! s.hasAddrs() );


	condor_sockaddr sa;
	bool ok = sa.from_ip_and_port_string( "1.2.3.4:5" );
	REQUIRE( ok );
	s.addAddrToAddrs( sa );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 1 );
	REQUIRE( (*v)[0] == sa );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 1 );
	REQUIRE( (*v)[0] == sa );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	condor_sockaddr sa2;
	ok = sa2.from_ip_and_port_string( "5.6.7.8:9" );
	REQUIRE( ok );
	s.addAddrToAddrs( sa2 );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 2 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 2 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	condor_sockaddr sa3;
	ok = sa3.from_ip_and_port_string( "[1:3:5:7::a]:13" );
	REQUIRE( ok );
	s.addAddrToAddrs( sa3 );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	s.clearAddrs();
	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 0 );

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 0 );

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<>" ) == 0 );

	REQUIRE( ! s.hasAddrs() );


	s.addAddrToAddrs( sa );
	s.addAddrToAddrs( sa2 );
	s.addAddrToAddrs( sa3 );

	v = s.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = s.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	t = Sinful( sinfulString );
	v = t.getAddrs();
	REQUIRE( v != NULL );
	REQUIRE( v->size() == 3 );
	REQUIRE( (*v)[0] == sa );
	REQUIRE( (*v)[1] == sa2 );
	REQUIRE( (*v)[2] == sa3 );
	delete v; v = NULL;

	sinfulString = t.getSinful();
	REQUIRE( sinfulString != NULL );
	REQUIRE( strcmp( sinfulString, "<?addrs=1.2.3.4-5+5.6.7.8-9+[1-3-5-7--a]-13>" ) == 0 );

	REQUIRE( s.hasAddrs() );


	// In practice, all C++03 implementations are stable with respect
	// to insertion order; the  C++11 standard requires that they are.
	// This is the unit test for the former.
	std::multimap< int, condor_sockaddr > sortedByDesire;

	sortedByDesire.insert(std::make_pair( 0, sa ));
	sortedByDesire.insert(std::make_pair( 0, sa2 ));
	sortedByDesire.insert(std::make_pair( 0, sa3 ));
	int i = 0;
	std::multimap< int, condor_sockaddr >::const_iterator iter;
	for( iter = sortedByDesire.begin(); iter != sortedByDesire.end(); ++iter, ++i ) {
		switch( i ) {
			case 0:
				REQUIRE( (* iter).second == sa );
				break;
			case 1:
				REQUIRE( (* iter).second == sa2 );
				break;
			case 2:
				REQUIRE( (* iter).second == sa3 );
				break;
			default:
				REQUIRE( false );
				break;
		}
	}

	sortedByDesire.clear();
	REQUIRE( sortedByDesire.size() == 0 );
	sortedByDesire.insert(std::make_pair( 1, sa ));
	sortedByDesire.insert(std::make_pair( 0, sa2 ));
	sortedByDesire.insert(std::make_pair( 0, sa3 ));
	i = 0;
	for( iter = sortedByDesire.begin(); iter != sortedByDesire.end(); ++iter, ++i ) {
		switch( i ) {
			case 0:
				REQUIRE( (* iter).second == sa2 );
				break;
			case 1:
				REQUIRE( (* iter).second == sa3 );
				break;
			case 2:
				REQUIRE( (* iter).second == sa );
				break;
			default:
				REQUIRE( false );
				break;
		}
	}

	sortedByDesire.clear();
	REQUIRE( sortedByDesire.size() == 0 );
	sortedByDesire.insert(std::make_pair( 0, sa2 ));
	sortedByDesire.insert(std::make_pair( 1, sa ));
	sortedByDesire.insert(std::make_pair( 0, sa3 ));
	i = 0;
	for( iter = sortedByDesire.begin(); iter != sortedByDesire.end(); ++iter, ++i ) {
		switch( i ) {
			case 0:
				REQUIRE( (* iter).second == sa2 );
				break;
			case 1:
				REQUIRE( (* iter).second == sa3 );
				break;
			case 2:
				REQUIRE( (* iter).second == sa );
				break;
			default:
				REQUIRE( false );
				break;
		}
	}

	return 0;
}