/*
* 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();
}
}