2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 1999 by Sun Microsystems, Inc.
2N/A * All rights reserved.
2N/A *
2N/A */
2N/A
2N/A// DAAdvertiser.java: Advertise a DA, also handle incoming DAAdverts.
2N/A// Author: James Kempf
2N/A// Created On: Tue May 19 15:22:04 1998
2N/A// Last Modified By: James Kempf
2N/A// Last Modified On: Thu Mar 4 10:39:06 1999
2N/A// Update Count: 44
2N/A//
2N/A
2N/Apackage com.sun.slp;
2N/A
2N/Aimport java.net.*;
2N/Aimport java.util.*;
2N/Aimport java.io.*;
2N/A
2N/A/**
2N/A * This class supplies a regular interval 'heartbeat' DAAdvertisement.
2N/A * Implementation specific subclasses handle incoming DAAdverts and
2N/A * forwarding of registrations and deregistrations to other DAs. The
2N/A * implementation specific subclasses depend on how the server is
2N/A * representing DA information internally.
2N/A *
2N/A * @author James Kempf, Erik Guttman
2N/A */
2N/A
2N/Aclass DAAdvertiser extends Thread {
2N/A
2N/A protected DatagramSocket dss = null;
2N/A protected InetAddress castAddr = null;
2N/A protected InetAddress interfac = null;
2N/A
2N/A // V2 advertising has the same DAAdvert every time.
2N/A
2N/A static private byte[] outbuf = null;
2N/A
2N/A static protected SLPConfig config = null; // Config object.
2N/A static protected Hashtable daadv =
2N/A new Hashtable(); // Existing advertisers
2N/A
2N/A private Boolean done = new Boolean(false);
2N/A
2N/A // Initialize the DAAdvertiser on the designated interface.
2N/A
2N/A static void initializeDAAdvertiserOnInterface(InetAddress interfac)
2N/A throws ServiceLocationException {
2N/A
2N/A // If we've got it, return.
2N/A
2N/A if (daadv.get(interfac) != null) {
2N/A return;
2N/A
2N/A }
2N/A
2N/A // Get the config object.
2N/A
2N/A if (config == null) {
2N/A config = SLPConfig.getSLPConfig();
2N/A
2N/A }
2N/A
2N/A // Get the SLPv2 DAADvert to send
2N/A
2N/A ServiceTable table = ServiceTable.getServiceTable();
2N/A
2N/A SLPServerHeaderV2 hdr =
2N/A new SLPServerHeaderV2(SrvLocHeader.DAAdvert,
2N/A false,
2N/A config.getLocale());
2N/A
2N/A SDAAdvert msg =
2N/A (SDAAdvert)table.makeDAAdvert(hdr,
2N/A interfac,
2N/A (short)0x0,
2N/A config.getSAConfiguredScopes(),
2N/A config);
2N/A
2N/A // Create a new DAAdvertiser for this interface, with SLPv2
2N/A // message to send.
2N/A
2N/A DAAdvertiser daadv = new DAAdvertiser(interfac, msg.getHeader());
2N/A
2N/A // Start thread running.
2N/A
2N/A daadv.start();
2N/A
2N/A }
2N/A
2N/A // Used by V1 subclass constructor.
2N/A
2N/A DAAdvertiser() {
2N/A
2N/A if (config == null) {
2N/A config = SLPConfig.getSLPConfig();
2N/A
2N/A }
2N/A
2N/A }
2N/A
2N/A // Create a new DAAdvertiser for the interface for default multicast
2N/A // address. Externalize the message and set the instance variable.
2N/A
2N/A DAAdvertiser(InetAddress interfac, SrvLocHeader hdr)
2N/A throws ServiceLocationException {
2N/A
2N/A // Config may not be initialized if this was called directly from
2N/A // slpd.
2N/A
2N/A if (config == null) {
2N/A config = SLPConfig.getSLPConfig();
2N/A
2N/A }
2N/A
2N/A // Externalize the DAAdvert.
2N/A
2N/A ByteArrayOutputStream baos = new ByteArrayOutputStream();
2N/A
2N/A hdr.externalize(baos, true, false);
2N/A outbuf = baos.toByteArray();
2N/A
2N/A // Initialize the networking for default multicast address.
2N/A
2N/A initializeNetworking(interfac, config.getMulticastAddress());
2N/A
2N/A }
2N/A
2N/A
2N/A // Convert advert to bytes, initialize networking.
2N/A
2N/A protected void
2N/A initializeNetworking(InetAddress interfac,
2N/A InetAddress maddr)
2N/A throws ServiceLocationException {
2N/A
2N/A // Set the interface and multicast address on this advertiser.
2N/A
2N/A this.interfac = interfac;
2N/A this.castAddr = maddr;
2N/A
2N/A // Get the socket from the listener object corresponding to this
2N/A // interface. The listener will always be started before the
2N/A // DAAdvertiser, otherwise, SAs may start sending registrations
2N/A // before anybody is listening.
2N/A
2N/A dss = Listener.returnListenerSocketOnInterface(interfac);
2N/A
2N/A // If the socket is null, then there is no listener. Open a
2N/A // new socket. Note that any listener opened *afterwards* will
2N/A // not get this socket.
2N/A
2N/A if (dss == null) {
2N/A dss = config.getMulticastSocketOnInterface(interfac, true);
2N/A
2N/A }
2N/A }
2N/A
2N/A public void run() {
2N/A
2N/A // Set the thread name.
2N/A
2N/A setName("SLP DA Advertisement");
2N/A
2N/A long heartbeat = config.getAdvertHeartbeatTime() * 1000;
2N/A
2N/A while (true) {
2N/A
2N/A // Send an advert.
2N/A
2N/A sendAdvert();
2N/A
2N/A // Sleep until next time.
2N/A
2N/A try {
2N/A sleep(heartbeat);
2N/A
2N/A } catch (InterruptedException ie) {
2N/A
2N/A // Somebody interrupted us. If we are to exit, then do so.
2N/A
2N/A synchronized (done) {
2N/A
2N/A if (done.booleanValue()) {
2N/A return;
2N/A
2N/A }
2N/A }
2N/A
2N/A }
2N/A
2N/A }
2N/A }
2N/A
2N/A // Send an unsolicited DAAdvert.
2N/A
2N/A void sendAdvert() {
2N/A
2N/A byte[] buf = getOutbuf();
2N/A
2N/A DatagramPacket dp =
2N/A new DatagramPacket(buf,
2N/A buf.length,
2N/A castAddr,
2N/A Defaults.iSLPPort);
2N/A try {
2N/A
2N/A dss.send(dp);
2N/A
2N/A } catch (IOException ex) {
2N/A config.writeLog("passive_advert_exception",
2N/A new Object[] {ex.getMessage()});
2N/A
2N/A // Tell the listener to refresh the socket.
2N/A
2N/A dss = Listener.refreshSocketOnInterface(interfac);
2N/A
2N/A }
2N/A }
2N/A
2N/A // Return the buffer for transmission.
2N/A
2N/A protected byte[] getOutbuf() {
2N/A return outbuf;
2N/A
2N/A }
2N/A
2N/A // Stop the thread from executing.
2N/A
2N/A void stopThread() {
2N/A
2N/A synchronized (done) {
2N/A done = new Boolean(true);
2N/A
2N/A }
2N/A
2N/A this.interrupt();
2N/A
2N/A }
2N/A}