bool
SharedPortEndpoint::InitRemoteAddress()
{
		// Why do we read SharedPortServer's address from a file rather
		// than getting it passed down to us via the environment or
		// having a (configurable) fixed port?  Because the
		// SharedPortServer daemon may be listening via CCB, and its CCB
		// contact info may not be known as soon as it is started up
		// or may even change over time.

		// Why don't we just use a daemon client object to find the
		// address of the SharedPortServer daemon?  Because daemon
		// client assumes we want the best address for _us_ to connect
		// to.  That's not necessarily the public address that we want
		// to advertise for others to connect to.

	MyString shared_port_server_ad_file;
	if( !param(shared_port_server_ad_file,"SHARED_PORT_DAEMON_AD_FILE") ) {
		EXCEPT("SHARED_PORT_DAEMON_AD_FILE must be defined");
	}

	FILE *fp = safe_fopen_wrapper_follow(shared_port_server_ad_file.Value(),"r");
	if( !fp ) {
		dprintf(D_ALWAYS,"SharedPortEndpoint: failed to open %s: %s\n",
				shared_port_server_ad_file.Value(), strerror(errno));
		return false;
	}

	int adIsEOF = 0, errorReadingAd = 0, adEmpty = 0;
	ClassAd *ad = new ClassAd(fp, "[classad-delimiter]", adIsEOF, errorReadingAd, adEmpty);
	ASSERT(ad);
	fclose( fp );

		// avoid leaking ad when returning from this function
	counted_ptr<ClassAd> smart_ad_ptr(ad);

	if( errorReadingAd ) {
		dprintf(D_ALWAYS,"SharedPortEndpoint: failed to read ad from %s.\n",
				shared_port_server_ad_file.Value());
		return false;
	}

	MyString public_addr;
	if( !ad->LookupString(ATTR_MY_ADDRESS,public_addr) ) {
		dprintf(D_ALWAYS,
				"SharedPortEndpoint: failed to find %s in ad from %s.\n",
				ATTR_MY_ADDRESS, shared_port_server_ad_file.Value());
		return false;
	}

	Sinful sinful(public_addr.Value());
	sinful.setSharedPortID( m_local_id.Value() );

		// if there is a private address, set the shared port id on that too
	char const *private_addr = sinful.getPrivateAddr();
	if( private_addr ) {
		Sinful private_sinful( private_addr );
		private_sinful.setSharedPortID( m_local_id.Value() );
		sinful.setPrivateAddr( private_sinful.getSinful() );
	}

	// Next, look for alternate command strings
	std::string commandStrings;
	if (ad->EvaluateAttrString(ATTR_SHARED_PORT_COMMAND_SINFULS, commandStrings))
	{
		m_remote_addrs.clear();
		StringList sl(commandStrings.c_str());
		sl.rewind();
		const char *commandSinfulStr;
		while ((commandSinfulStr = sl.next()))
		{
			Sinful altsinful(commandSinfulStr);
			altsinful.setSharedPortID(m_local_id.Value());
			char const *private_addr = sinful.getPrivateAddr();
			if (private_addr)
			{
				Sinful private_sinful(private_addr);
				private_sinful.setSharedPortID(m_local_id.Value());
				altsinful.setPrivateAddr(private_sinful.getSinful());
			}
			m_remote_addrs.push_back(altsinful);
		}
	}

	m_remote_addr = sinful.getSinful();

	return true;
}
예제 #2
0
void
CCBServer::InitAndReconfig()
{
		// construct the CCB address to be advertised by CCB listeners
	Sinful sinful(daemonCore->publicNetworkIpAddr());
		// strip out <>'s, private address, and CCB listener info
	sinful.setPrivateAddr(NULL);
	sinful.setCCBContact(NULL);
	ASSERT( sinful.getSinful() && sinful.getSinful()[0] == '<' );
	m_address.formatstr("%s",sinful.getSinful()+1);
	if( m_address[m_address.Length()-1] == '>' ) {
		m_address.setChar(m_address.Length()-1,'\0');
	}

	m_read_buffer_size = param_integer("CCB_SERVER_READ_BUFFER",2*1024);
	m_write_buffer_size = param_integer("CCB_SERVER_WRITE_BUFFER",2*1024);

	m_last_reconnect_info_sweep = time(NULL);

	m_reconnect_info_sweep_interval = param_integer("CCB_SWEEP_INTERVAL",1200);

	CloseReconnectFile();

	MyString old_reconnect_fname = m_reconnect_fname;
	char *fname = param("CCB_RECONNECT_FILE");
	if( fname ) {
		m_reconnect_fname = fname;
		if( m_reconnect_fname.find(".ccb_reconnect") == -1 ) {
			// required for preen to ignore this file
			m_reconnect_fname += ".ccb_reconnect";
		}
		free( fname );
	}
	else {
		char *spool = param("SPOOL");
		ASSERT( spool );
		Sinful my_addr( daemonCore->publicNetworkIpAddr() );
		m_reconnect_fname.formatstr("%s%c%s-%s.ccb_reconnect",
			spool,
			DIR_DELIM_CHAR,
			my_addr.getHost() ? my_addr.getHost() : "localhost",
			my_addr.getPort() ? my_addr.getPort() : "0");
		free( spool );
	}

	if( old_reconnect_fname != m_reconnect_fname &&
		!old_reconnect_fname.IsEmpty() &&
		!m_reconnect_fname.IsEmpty() )
	{
		// reconnect filename changed
		// not worth freaking out on error here
		remove( m_reconnect_fname.Value() );
		rename( old_reconnect_fname.Value(), m_reconnect_fname.Value() );
	}
	if( old_reconnect_fname.IsEmpty() &&
		!m_reconnect_fname.IsEmpty() &&
		m_reconnect_info.getNumElements() == 0 )
	{
		// we are starting up from scratch, so load saved info
		LoadReconnectInfo();
	}

	Timeslice poll_slice;
	poll_slice.setTimeslice( // do not run more than this fraction of the time
		param_double("CCB_POLLING_TIMESLICE",0.05) );

	poll_slice.setDefaultInterval( // try to run this often
		param_integer("CCB_POLLING_INTERVAL",20,0) );

	poll_slice.setMaxInterval( // run at least this often
		param_integer("CCB_POLLING_MAX_INTERVAL",600) );

	if( m_polling_timer != -1 ) {
		daemonCore->Cancel_Timer(m_polling_timer);
	}

	m_polling_timer = daemonCore->Register_Timer(
		poll_slice,
		(TimerHandlercpp)&CCBServer::PollSockets,
		"CCBServer::PollSockets",
		this);

	RegisterHandlers();
}
예제 #3
0
UdpWakeOnLanWaker::UdpWakeOnLanWaker (
    ClassAd *ad ) throw ()
	: WakerBase ()
{

    int     found   = 0;

    /* make sure we are only capable of sending the WOL
    magic packet if all of the initialization succeds */
    m_can_wake = false;

    /* retrieve the hardware address from the ad */
    found = ad->LookupString (
        ATTR_HARDWARE_ADDRESS,
        m_mac,
        STRING_MAC_ADDRESS_LENGTH );

    if ( !found ) {

        dprintf (
            D_ALWAYS,
            "UdpWakeOnLanWaker: no hardware address "
            "(MAC) defined\n" );

        return;

    }

    /* retrieve the IP from the ad */
	Daemon d(ad,DT_STARTD,NULL);
	char const *addr = d.addr();
	Sinful sinful( addr );
	if( !addr || !sinful.getHost() ) {
        dprintf (
            D_ALWAYS,
            "UdpWakeOnLanWaker: no IP address defined\n" );

        return;
	}
	strncpy( m_public_ip, sinful.getHost(), MAX_IP_ADDRESS_LENGTH-1);
	m_public_ip[MAX_IP_ADDRESS_LENGTH-1] = '\0';

    /* retrieve the subnet from the ad */
    found = ad->LookupString (
        ATTR_SUBNET_MASK,
        m_subnet,
        MAX_IP_ADDRESS_LENGTH );

    if ( !found ) {

        dprintf (
            D_ALWAYS,
            "UdpWakeOnLanWaker: no subnet defined\n" );

        return;

    }

	/* retrieve the port number from the ad */
	found = ad->LookupInteger (
		ATTR_WOL_PORT,
		m_port );

	if ( !found ) {

		/* no error, just auto-detect the port number */
		m_port = detect_port;

	}

    /* initialize the internal structures */
    if ( !initialize () ) {

        dprintf (
            D_ALWAYS,
            "UdpWakeOnLanWaker: failed to initialize\n" );

        return;

    }

    /* if we made it here, then initialization succeeded */
    m_can_wake = true;

}