xref: /onnv-gate/usr/src/lib/libslp/javalib/com/sun/slp/DAAdvertiser.java (revision 7298:b69e27387f74)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7298SMark.J.Nelson@Sun.COM  * Common Development and Distribution License (the "License").
6*7298SMark.J.Nelson@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
220Sstevel@tonic-gate  * Copyright (c) 1999 by Sun Microsystems, Inc.
230Sstevel@tonic-gate  * All rights reserved.
240Sstevel@tonic-gate  *
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate //  DAAdvertiser.java: Advertise a DA, also handle incoming DAAdverts.
280Sstevel@tonic-gate //  Author:           James Kempf
290Sstevel@tonic-gate //  Created On:       Tue May 19 15:22:04 1998
300Sstevel@tonic-gate //  Last Modified By: James Kempf
310Sstevel@tonic-gate //  Last Modified On: Thu Mar  4 10:39:06 1999
320Sstevel@tonic-gate //  Update Count:     44
330Sstevel@tonic-gate //
340Sstevel@tonic-gate 
350Sstevel@tonic-gate package com.sun.slp;
360Sstevel@tonic-gate 
370Sstevel@tonic-gate import java.net.*;
380Sstevel@tonic-gate import java.util.*;
390Sstevel@tonic-gate import java.io.*;
400Sstevel@tonic-gate 
410Sstevel@tonic-gate /**
420Sstevel@tonic-gate  * This class supplies a regular interval 'heartbeat' DAAdvertisement.
430Sstevel@tonic-gate  * Implementation specific subclasses handle incoming DAAdverts and
440Sstevel@tonic-gate  * forwarding of registrations and deregistrations to other DAs. The
450Sstevel@tonic-gate  * implementation specific subclasses depend on how the server is
460Sstevel@tonic-gate  * representing DA information internally.
470Sstevel@tonic-gate  *
480Sstevel@tonic-gate  * @author James Kempf, Erik Guttman
490Sstevel@tonic-gate  */
500Sstevel@tonic-gate 
510Sstevel@tonic-gate class DAAdvertiser extends Thread {
520Sstevel@tonic-gate 
530Sstevel@tonic-gate     protected DatagramSocket dss = null;
540Sstevel@tonic-gate     protected InetAddress castAddr = null;
550Sstevel@tonic-gate     protected InetAddress interfac = null;
560Sstevel@tonic-gate 
570Sstevel@tonic-gate     // V2 advertising has the same DAAdvert every time.
580Sstevel@tonic-gate 
590Sstevel@tonic-gate     static private byte[]	 outbuf = null;
600Sstevel@tonic-gate 
610Sstevel@tonic-gate     static protected SLPConfig config = null;    // Config object.
620Sstevel@tonic-gate     static protected Hashtable daadv =
630Sstevel@tonic-gate 	new Hashtable();	// Existing advertisers
640Sstevel@tonic-gate 
650Sstevel@tonic-gate     private Boolean done = new Boolean(false);
660Sstevel@tonic-gate 
670Sstevel@tonic-gate     // Initialize the DAAdvertiser on the designated interface.
680Sstevel@tonic-gate 
initializeDAAdvertiserOnInterface(InetAddress interfac)690Sstevel@tonic-gate     static void initializeDAAdvertiserOnInterface(InetAddress interfac)
700Sstevel@tonic-gate 	throws ServiceLocationException {
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	// If we've got it, return.
730Sstevel@tonic-gate 
740Sstevel@tonic-gate 	if (daadv.get(interfac) != null) {
750Sstevel@tonic-gate 	    return;
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	}
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 	// Get the config object.
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	if (config == null) {
820Sstevel@tonic-gate 	    config = SLPConfig.getSLPConfig();
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	}
850Sstevel@tonic-gate 
860Sstevel@tonic-gate 	// Get the SLPv2 DAADvert to send
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	ServiceTable table = ServiceTable.getServiceTable();
890Sstevel@tonic-gate 
900Sstevel@tonic-gate 	SLPServerHeaderV2 hdr =
910Sstevel@tonic-gate 	    new SLPServerHeaderV2(SrvLocHeader.DAAdvert,
920Sstevel@tonic-gate 				  false,
930Sstevel@tonic-gate 				  config.getLocale());
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	SDAAdvert msg =
960Sstevel@tonic-gate 	    (SDAAdvert)table.makeDAAdvert(hdr,
970Sstevel@tonic-gate 					  interfac,
980Sstevel@tonic-gate 					  (short)0x0,
990Sstevel@tonic-gate 					  config.getSAConfiguredScopes(),
1000Sstevel@tonic-gate 					  config);
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	// Create a new DAAdvertiser for this interface, with SLPv2
1030Sstevel@tonic-gate 	//  message to send.
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate 	DAAdvertiser daadv = new DAAdvertiser(interfac, msg.getHeader());
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 	// Start thread running.
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	daadv.start();
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate     }
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate     // Used by V1 subclass constructor.
1140Sstevel@tonic-gate 
DAAdvertiser()1150Sstevel@tonic-gate     DAAdvertiser() {
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	if (config == null) {
1180Sstevel@tonic-gate 	    config = SLPConfig.getSLPConfig();
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	}
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate     }
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate     // Create a new DAAdvertiser for the interface for default multicast
1250Sstevel@tonic-gate     //  address. Externalize the message and set the instance variable.
1260Sstevel@tonic-gate 
DAAdvertiser(InetAddress interfac, SrvLocHeader hdr)1270Sstevel@tonic-gate     DAAdvertiser(InetAddress interfac, SrvLocHeader hdr)
1280Sstevel@tonic-gate 	throws ServiceLocationException {
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	// Config may not be initialized if this was called directly from
1310Sstevel@tonic-gate 	//  slpd.
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 	if (config == null) {
1340Sstevel@tonic-gate 	    config = SLPConfig.getSLPConfig();
1350Sstevel@tonic-gate 
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	// Externalize the DAAdvert.
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	ByteArrayOutputStream baos = new ByteArrayOutputStream();
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 	hdr.externalize(baos, true, false);
1430Sstevel@tonic-gate 	outbuf = baos.toByteArray();
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	// Initialize the networking for default multicast address.
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	initializeNetworking(interfac, config.getMulticastAddress());
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate     }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate     // Convert advert to bytes, initialize networking.
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate     protected void
initializeNetworking(InetAddress interfac, InetAddress maddr)1550Sstevel@tonic-gate 	initializeNetworking(InetAddress interfac,
1560Sstevel@tonic-gate 			     InetAddress maddr)
1570Sstevel@tonic-gate 	throws ServiceLocationException {
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	// Set the interface and multicast address on this advertiser.
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	this.interfac = interfac;
1620Sstevel@tonic-gate 	this.castAddr = maddr;
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	// Get the socket from the listener object corresponding to this
1650Sstevel@tonic-gate 	//  interface. The listener will always be started before the
1660Sstevel@tonic-gate 	//  DAAdvertiser, otherwise, SAs may start sending registrations
1670Sstevel@tonic-gate 	//  before anybody is listening.
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	dss = Listener.returnListenerSocketOnInterface(interfac);
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 	// If the socket is null, then there is no listener. Open a
1720Sstevel@tonic-gate 	//  new socket. Note that any listener opened *afterwards* will
1730Sstevel@tonic-gate 	//  not get this socket.
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	if (dss == null) {
1760Sstevel@tonic-gate 	    dss = config.getMulticastSocketOnInterface(interfac, true);
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 	}
1790Sstevel@tonic-gate     }
1800Sstevel@tonic-gate 
run()1810Sstevel@tonic-gate     public void run() {
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 	// Set the thread name.
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	setName("SLP DA Advertisement");
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	long heartbeat = config.getAdvertHeartbeatTime() * 1000;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 	while (true) {
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	    // Send an advert.
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 	    sendAdvert();
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	    // Sleep until next time.
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	    try {
1980Sstevel@tonic-gate 		sleep(heartbeat);
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 	    } catch (InterruptedException ie) {
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate 		// Somebody interrupted us. If we are to exit, then do so.
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 		synchronized (done) {
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 		    if (done.booleanValue()) {
2070Sstevel@tonic-gate 			return;
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 		    }
2100Sstevel@tonic-gate 		}
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 	    }
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	}
2150Sstevel@tonic-gate     }
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate     // Send an unsolicited DAAdvert.
2180Sstevel@tonic-gate 
sendAdvert()2190Sstevel@tonic-gate     void sendAdvert() {
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate 	byte[] buf = getOutbuf();
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	DatagramPacket dp =
2240Sstevel@tonic-gate 	    new DatagramPacket(buf,
2250Sstevel@tonic-gate 			       buf.length,
2260Sstevel@tonic-gate 			       castAddr,
2270Sstevel@tonic-gate 			       Defaults.iSLPPort);
2280Sstevel@tonic-gate 	try {
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 	    dss.send(dp);
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 	} catch (IOException ex) {
2330Sstevel@tonic-gate 	    config.writeLog("passive_advert_exception",
2340Sstevel@tonic-gate 			    new Object[] {ex.getMessage()});
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	    // Tell the listener to refresh the socket.
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate 	    dss = Listener.refreshSocketOnInterface(interfac);
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 	}
2410Sstevel@tonic-gate     }
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate     // Return the buffer for transmission.
2440Sstevel@tonic-gate 
getOutbuf()2450Sstevel@tonic-gate     protected byte[] getOutbuf() {
2460Sstevel@tonic-gate 	return outbuf;
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate     }
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate     // Stop the thread from executing.
2510Sstevel@tonic-gate 
stopThread()2520Sstevel@tonic-gate     void stopThread() {
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	synchronized (done) {
2550Sstevel@tonic-gate 	    done = new Boolean(true);
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	}
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate 	this.interrupt();
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate     }
2620Sstevel@tonic-gate }
263