xref: /illumos-gate/usr/src/lib/libslp/javalib/com/sun/slp/ActiveDiscoverer.java (revision 55fea89dcaa64928bed4327112404dcb3e07b79f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*9a70fc3bSMark J. Nelson  * Common Development and Distribution License (the "License").
6*9a70fc3bSMark J. Nelson  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate  * Copyright (c) 2001 by Sun Microsystems, Inc.
237c478bd9Sstevel@tonic-gate  * All rights reserved.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate //  ActiveDiscoverer.java: Object to perform active DA discovery.
287c478bd9Sstevel@tonic-gate //  Author:           James Kempf
297c478bd9Sstevel@tonic-gate //  Created On:       Thu Sep  3 08:45:21 1998
307c478bd9Sstevel@tonic-gate //  Last Modified By: James Kempf
317c478bd9Sstevel@tonic-gate //  Last Modified On: Thu Jan 28 15:45:45 1999
327c478bd9Sstevel@tonic-gate //  Update Count:     32
337c478bd9Sstevel@tonic-gate //
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate package com.sun.slp;
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate import java.util.*;
387c478bd9Sstevel@tonic-gate import java.net.*;
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * The ActiveDiscover does active discovery DA discovery by periodically
427c478bd9Sstevel@tonic-gate  * sending out a SrvRqst for "service:directory-agent". Replies are
437c478bd9Sstevel@tonic-gate  * entered into the DA table.
447c478bd9Sstevel@tonic-gate  *
457c478bd9Sstevel@tonic-gate  * @author James Kempf
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate class ActiveDiscoverer extends Thread {
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate     // Config object.
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate     static private SLPConfig config = null;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate     // Message for active DA discovery.
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate     private CSrvMsg activeMsg = null;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate     // Version of protocol to use for advertisements.
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate     private int version = 0;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate     // DATable where discovered DAs are recorded.
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate     private ServerDATable table = null;
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate     // Scopes to advertise for.
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate     private Vector useScopes = null;
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate     // Address on which to advertise.
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate     private InetAddress address = null;
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate     // Create an active discoverer.
757c478bd9Sstevel@tonic-gate 
ActiveDiscoverer(int version, ServerDATable table, Vector useScopes, InetAddress address)767c478bd9Sstevel@tonic-gate     ActiveDiscoverer(int version,
777c478bd9Sstevel@tonic-gate 		     ServerDATable table,
787c478bd9Sstevel@tonic-gate 		     Vector useScopes,
797c478bd9Sstevel@tonic-gate 		     InetAddress address) {
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	this.version = version;
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 	this.table = table;
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	this.useScopes = useScopes;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	this.address = address;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	if (config == null) {
907c478bd9Sstevel@tonic-gate 	    config = SLPConfig.getSLPConfig();
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	}
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate     }
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate     // Do an initial active discovery then start a thread to
977c478bd9Sstevel@tonic-gate     //  do one periodically.
987c478bd9Sstevel@tonic-gate 
start()997c478bd9Sstevel@tonic-gate     public void start() {
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	// Initial sleepy time.
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	long sleepyTime = config.getRandomWait();
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	// Create a message for active discovery.
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	try {
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate 	    activeMsg = new CSrvMsg(config.getLocale(),
1107c478bd9Sstevel@tonic-gate 				    Defaults.DA_SERVICE_TYPE,
1117c478bd9Sstevel@tonic-gate 				    useScopes,
1127c478bd9Sstevel@tonic-gate 				    "");
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
1157c478bd9Sstevel@tonic-gate 	    Assert.slpassert(false,
1167c478bd9Sstevel@tonic-gate 			  "sdat_active_err",
1177c478bd9Sstevel@tonic-gate 			  new Object[] {
1187c478bd9Sstevel@tonic-gate 		new Integer(ex.getErrorCode()),
1197c478bd9Sstevel@tonic-gate 		    ex.getMessage()});
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	}
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	// Initialize preconfigured DAs.
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	addPreconfiguredDAs();
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 	// Do an initial round of active discovery, waiting for
1287c478bd9Sstevel@tonic-gate 	//  a random period first. Only do it if active
1297c478bd9Sstevel@tonic-gate 	//  discovery is on.
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	if (config.getActiveDiscoveryInterval() > 0) {
1327c478bd9Sstevel@tonic-gate 	    try {
1337c478bd9Sstevel@tonic-gate 		Thread.currentThread().sleep(sleepyTime);
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	    } catch (InterruptedException ex) {
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	    }
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	    activeDiscovery();
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	} else {
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	    // Report that active discovery is off.
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	    config.writeLog("ad_active_off",
1467c478bd9Sstevel@tonic-gate 			    new Object[0]);
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	}
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	// Start the active discovery thread.
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	super.start();
1537c478bd9Sstevel@tonic-gate     }
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate     // Implement the Runnable interface for a thread to start.
1587c478bd9Sstevel@tonic-gate 
run()1597c478bd9Sstevel@tonic-gate     public void run() {
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	// Set the Thread name.
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	Thread.currentThread().setName("SLP Active DA Discovery");
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	// Sleepy time until discovery.
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	long sleepyTime = config.getActiveDiscoveryInterval() * 1000;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	// If the sleep time is zero, then active discovery is turned off.
1707c478bd9Sstevel@tonic-gate 	//  Use the service URL maximum lifetime.
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 	if (sleepyTime <= 0) {
1737c478bd9Sstevel@tonic-gate 	    sleepyTime = (ServiceURL.LIFETIME_MAXIMUM / 2) * 1000;
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	// Register ourselves at startup if we are a DA. We may not be
1787c478bd9Sstevel@tonic-gate 	//  listening for the active discovery message at startup
1797c478bd9Sstevel@tonic-gate 	//  because the listener thread goes on-line last of all.
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	if (config.isDA()) {
1827c478bd9Sstevel@tonic-gate 	    Vector interfaces = config.getInterfaces();
1837c478bd9Sstevel@tonic-gate 	    int i, n = interfaces.size();
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 	    for (i = 0; i < n; i++) {
1867c478bd9Sstevel@tonic-gate 		InetAddress interfac = (InetAddress)interfaces.elementAt(i);
1877c478bd9Sstevel@tonic-gate 		ServiceURL url = new ServiceURL(Defaults.DA_SERVICE_TYPE +
1887c478bd9Sstevel@tonic-gate 						"://" +
1897c478bd9Sstevel@tonic-gate 						interfac.getHostAddress(),
1907c478bd9Sstevel@tonic-gate 						ServiceURL.LIFETIME_MAXIMUM);
1917c478bd9Sstevel@tonic-gate 		Vector scopes = config.getSAConfiguredScopes();
1927c478bd9Sstevel@tonic-gate 		long timestamp = 0; // later adverts will cause replacement,
1937c478bd9Sstevel@tonic-gate 				    // but noforwarding because it is to us...
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 		String mySPIs = System.getProperty("sun.net.slp.SPIs");
1967c478bd9Sstevel@tonic-gate 		mySPIs = mySPIs == null ? "" : mySPIs;
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 		table.recordNewDA(url,
1997c478bd9Sstevel@tonic-gate 				  scopes,
2007c478bd9Sstevel@tonic-gate 				  timestamp,
2017c478bd9Sstevel@tonic-gate 				  version,
2027c478bd9Sstevel@tonic-gate 				  config.getDAAttributes(),
2037c478bd9Sstevel@tonic-gate 				  mySPIs);
2047c478bd9Sstevel@tonic-gate 	    }
2057c478bd9Sstevel@tonic-gate 	}
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	// Sleep, then perform active discovery or polling of preconfigured
2087c478bd9Sstevel@tonic-gate 	//  DAs when we awake.
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	do {
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	    try {
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 		sleep(sleepyTime);
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 		if (config.getActiveDiscoveryInterval() > 0) {
2177c478bd9Sstevel@tonic-gate 		    activeDiscovery();
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 		} else {
2207c478bd9Sstevel@tonic-gate 		    addPreconfiguredDAs();
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 		}
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	    } catch (InterruptedException ex) {
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 	    }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 	} while (true);
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate     }
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate     // Perform active DA discovery.
2337c478bd9Sstevel@tonic-gate 
activeDiscovery()2347c478bd9Sstevel@tonic-gate     synchronized private void activeDiscovery() {
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate 	// Set the previous responders list to null. Otherwise,
2377c478bd9Sstevel@tonic-gate 	//  the previous responders from the last time we did
2387c478bd9Sstevel@tonic-gate 	//  this may interfere.
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = activeMsg.getHeader();
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	hdr.previousResponders.removeAllElements();
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	// Perform the active discovery message transaction.
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	try {
2487c478bd9Sstevel@tonic-gate 	    Transact.transactActiveAdvertRequest(Defaults.DA_SERVICE_TYPE,
2497c478bd9Sstevel@tonic-gate 						 activeMsg,
2507c478bd9Sstevel@tonic-gate 						 table);
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	    config.writeLog("ad_multi_error",
2557c478bd9Sstevel@tonic-gate 			    new Object[] { new Integer(ex.getErrorCode()),
2567c478bd9Sstevel@tonic-gate 					       ex.getMessage() });
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	}
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate     }
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate     // Add preconfigured DAs to the DA table. Note that we poll the
2637c478bd9Sstevel@tonic-gate     // preconfigured DAs once every 9 hours to make sure they are still around.
2647c478bd9Sstevel@tonic-gate 
addPreconfiguredDAs()2657c478bd9Sstevel@tonic-gate     synchronized private void addPreconfiguredDAs() {
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	Vector daAddrs = config.getPreconfiguredDAs();
2687c478bd9Sstevel@tonic-gate 	int i, n = daAddrs.size();
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	// Go through the DA addresses, contacting them for their
2717c478bd9Sstevel@tonic-gate 	// information. Better not be any SLPv1 DAs there.
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; i++) {
2747c478bd9Sstevel@tonic-gate 	    InetAddress daAddr = (InetAddress)daAddrs.elementAt(i);
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 	    // Use a TCP connection. DAs must support TCP so why not?
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 	    SrvLocMsg reply = null;
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	    try {
2817c478bd9Sstevel@tonic-gate 		reply = Transact.transactTCPMsg(daAddr, activeMsg, false);
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 	    } catch (ServiceLocationException ex) {
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 		if (config.traceDrop()) {
2867c478bd9Sstevel@tonic-gate 		    config.writeLog("ad_trans_error", new Object[] {
2877c478bd9Sstevel@tonic-gate 			new Integer(ex.getErrorCode()),
2887c478bd9Sstevel@tonic-gate 			    daAddr,
2897c478bd9Sstevel@tonic-gate 			    ex.getMessage() });
2907c478bd9Sstevel@tonic-gate 		}
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 		continue;
2937c478bd9Sstevel@tonic-gate 	    }
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	    // Report if there's an error in configuration.
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	    if (!(reply instanceof CDAAdvert)) {
2987c478bd9Sstevel@tonic-gate 		if (config.traceDrop()) {
2997c478bd9Sstevel@tonic-gate 		    config.writeLog("ad_preconfig_not_advert",
3007c478bd9Sstevel@tonic-gate 				    new Object[] { daAddr, reply });
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 		}
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 		continue;
3057c478bd9Sstevel@tonic-gate 	    }
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	    CDAAdvert advert = (CDAAdvert)reply;
3097c478bd9Sstevel@tonic-gate 	    SrvLocHeader hdr = advert.getHeader();
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	    // We need to make the URL long lived if active
3127c478bd9Sstevel@tonic-gate 	    // discovery is off. Otherwise, we let the DA time out like all the
3137c478bd9Sstevel@tonic-gate 	    // rest.
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	    if (config.getActiveDiscoveryInterval() <= 0) {
3167c478bd9Sstevel@tonic-gate 		advert.URL =
3177c478bd9Sstevel@tonic-gate 		    new ServiceURL(advert.URL.toString(),
3187c478bd9Sstevel@tonic-gate 				   ServiceURL.LIFETIME_MAXIMUM);
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 	    }
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	    // Add the scopes to the configured scopes. Scopes from configured
3237c478bd9Sstevel@tonic-gate 	    //  DAs count as configured scopes.
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	    config.addPreconfiguredDAScopes(hdr.scopes);
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	    // Record it. Note that we don't have to forward here
3287c478bd9Sstevel@tonic-gate 	    //  because it's the very beginning.
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	    table.recordNewDA(advert.URL,
3317c478bd9Sstevel@tonic-gate 			      hdr.scopes,
3327c478bd9Sstevel@tonic-gate 			      advert.timestamp,
3337c478bd9Sstevel@tonic-gate 			      hdr.version,
3347c478bd9Sstevel@tonic-gate 			      advert.attrs,
3357c478bd9Sstevel@tonic-gate 			      advert.spis);
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	}
3387c478bd9Sstevel@tonic-gate     }
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate }
341