usr/src/lib/libslp/javalib/com/sun/slp/DAAdvertiser.java
author Mark J. Nelson <Mark.J.Nelson@Sun.COM>
Wed, 06 Aug 2008 16:29:39 -0600
changeset 7298 b69e27387f74
parent 0 68f95e015346
permissions -rw-r--r--
6733918 Teamware has retired, please welcome your new manager, Mercurial 4758439 some files use "current date" sccs keywords 6560843 asm sources should not rely on .file "%M%" for naming STT_FILE symbols 6560958 Solaris:: perl modules should not use SCCS keywords in version information 6729074 webrev doesn't deal well with remote ssh hg parents

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1999 by Sun Microsystems, Inc.
 * All rights reserved.
 *
 */

//  DAAdvertiser.java: Advertise a DA, also handle incoming DAAdverts.
//  Author:           James Kempf
//  Created On:       Tue May 19 15:22:04 1998
//  Last Modified By: James Kempf
//  Last Modified On: Thu Mar  4 10:39:06 1999
//  Update Count:     44
//

package com.sun.slp;

import java.net.*;
import java.util.*;
import java.io.*;

/**
 * This class supplies a regular interval 'heartbeat' DAAdvertisement.
 * Implementation specific subclasses handle incoming DAAdverts and
 * forwarding of registrations and deregistrations to other DAs. The
 * implementation specific subclasses depend on how the server is
 * representing DA information internally.
 *
 * @author James Kempf, Erik Guttman
 */

class DAAdvertiser extends Thread {

    protected DatagramSocket dss = null;
    protected InetAddress castAddr = null;
    protected InetAddress interfac = null;

    // V2 advertising has the same DAAdvert every time.

    static private byte[]	 outbuf = null;

    static protected SLPConfig config = null;    // Config object.
    static protected Hashtable daadv =
	new Hashtable();	// Existing advertisers

    private Boolean done = new Boolean(false);

    // Initialize the DAAdvertiser on the designated interface.

    static void initializeDAAdvertiserOnInterface(InetAddress interfac)
	throws ServiceLocationException {

	// If we've got it, return.

	if (daadv.get(interfac) != null) {
	    return;

	}

	// Get the config object.

	if (config == null) {
	    config = SLPConfig.getSLPConfig();

	}

	// Get the SLPv2 DAADvert to send

	ServiceTable table = ServiceTable.getServiceTable();

	SLPServerHeaderV2 hdr =
	    new SLPServerHeaderV2(SrvLocHeader.DAAdvert,
				  false,
				  config.getLocale());

	SDAAdvert msg =
	    (SDAAdvert)table.makeDAAdvert(hdr,
					  interfac,
					  (short)0x0,
					  config.getSAConfiguredScopes(),
					  config);

	// Create a new DAAdvertiser for this interface, with SLPv2
	//  message to send.

	DAAdvertiser daadv = new DAAdvertiser(interfac, msg.getHeader());

	// Start thread running.

	daadv.start();

    }

    // Used by V1 subclass constructor.

    DAAdvertiser() {

	if (config == null) {
	    config = SLPConfig.getSLPConfig();

	}

    }

    // Create a new DAAdvertiser for the interface for default multicast
    //  address. Externalize the message and set the instance variable.

    DAAdvertiser(InetAddress interfac, SrvLocHeader hdr)
	throws ServiceLocationException {

	// Config may not be initialized if this was called directly from
	//  slpd.

	if (config == null) {
	    config = SLPConfig.getSLPConfig();

	}

	// Externalize the DAAdvert.

	ByteArrayOutputStream baos = new ByteArrayOutputStream();

	hdr.externalize(baos, true, false);
	outbuf = baos.toByteArray();

	// Initialize the networking for default multicast address.

	initializeNetworking(interfac, config.getMulticastAddress());

    }


    // Convert advert to bytes, initialize networking.

    protected void
	initializeNetworking(InetAddress interfac,
			     InetAddress maddr)
	throws ServiceLocationException {

	// Set the interface and multicast address on this advertiser.

	this.interfac = interfac;
	this.castAddr = maddr;

	// Get the socket from the listener object corresponding to this
	//  interface. The listener will always be started before the
	//  DAAdvertiser, otherwise, SAs may start sending registrations
	//  before anybody is listening.

	dss = Listener.returnListenerSocketOnInterface(interfac);

	// If the socket is null, then there is no listener. Open a
	//  new socket. Note that any listener opened *afterwards* will
	//  not get this socket.

	if (dss == null) {
	    dss = config.getMulticastSocketOnInterface(interfac, true);

	}
    }

    public void run() {

	// Set the thread name.

	setName("SLP DA Advertisement");

	long heartbeat = config.getAdvertHeartbeatTime() * 1000;

	while (true) {

	    // Send an advert.

	    sendAdvert();

	    // Sleep until next time.

	    try {
		sleep(heartbeat);

	    } catch (InterruptedException ie) {

		// Somebody interrupted us. If we are to exit, then do so.

		synchronized (done) {

		    if (done.booleanValue()) {
			return;

		    }
		}

	    }

	}
    }

    // Send an unsolicited DAAdvert.

    void sendAdvert() {

	byte[] buf = getOutbuf();

	DatagramPacket dp =
	    new DatagramPacket(buf,
			       buf.length,
			       castAddr,
			       Defaults.iSLPPort);
	try {

	    dss.send(dp);

	} catch (IOException ex) {
	    config.writeLog("passive_advert_exception",
			    new Object[] {ex.getMessage()});

	    // Tell the listener to refresh the socket.

	    dss = Listener.refreshSocketOnInterface(interfac);

	}
    }

    // Return the buffer for transmission.

    protected byte[] getOutbuf() {
	return outbuf;

    }

    // Stop the thread from executing.

    void stopThread() {

	synchronized (done) {
	    done = new Boolean(true);

	}

	this.interrupt();

    }
}