/* * 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) 2001 by Sun Microsystems, Inc. * All rights reserved. * */ // ActiveDiscoverer.java: Object to perform active DA discovery. // Author: James Kempf // Created On: Thu Sep 3 08:45:21 1998 // Last Modified By: James Kempf // Last Modified On: Thu Jan 28 15:45:45 1999 // Update Count: 32 // package com.sun.slp; import java.util.*; import java.net.*; /* * The ActiveDiscover does active discovery DA discovery by periodically * sending out a SrvRqst for "service:directory-agent". Replies are * entered into the DA table. * * @author James Kempf */ class ActiveDiscoverer extends Thread { // Config object. static private SLPConfig config = null; // Message for active DA discovery. private CSrvMsg activeMsg = null; // Version of protocol to use for advertisements. private int version = 0; // DATable where discovered DAs are recorded. private ServerDATable table = null; // Scopes to advertise for. private Vector useScopes = null; // Address on which to advertise. private InetAddress address = null; // Create an active discoverer. ActiveDiscoverer(int version, ServerDATable table, Vector useScopes, InetAddress address) { this.version = version; this.table = table; this.useScopes = useScopes; this.address = address; if (config == null) { config = SLPConfig.getSLPConfig(); } } // Do an initial active discovery then start a thread to // do one periodically. public void start() { // Initial sleepy time. long sleepyTime = config.getRandomWait(); // Create a message for active discovery. try { activeMsg = new CSrvMsg(config.getLocale(), Defaults.DA_SERVICE_TYPE, useScopes, ""); } catch (ServiceLocationException ex) { Assert.slpassert(false, "sdat_active_err", new Object[] { new Integer(ex.getErrorCode()), ex.getMessage()}); } // Initialize preconfigured DAs. addPreconfiguredDAs(); // Do an initial round of active discovery, waiting for // a random period first. Only do it if active // discovery is on. if (config.getActiveDiscoveryInterval() > 0) { try { Thread.currentThread().sleep(sleepyTime); } catch (InterruptedException ex) { } activeDiscovery(); } else { // Report that active discovery is off. config.writeLog("ad_active_off", new Object[0]); } // Start the active discovery thread. super.start(); } // Implement the Runnable interface for a thread to start. public void run() { // Set the Thread name. Thread.currentThread().setName("SLP Active DA Discovery"); // Sleepy time until discovery. long sleepyTime = config.getActiveDiscoveryInterval() * 1000; // If the sleep time is zero, then active discovery is turned off. // Use the service URL maximum lifetime. if (sleepyTime <= 0) { sleepyTime = (ServiceURL.LIFETIME_MAXIMUM / 2) * 1000; } // Register ourselves at startup if we are a DA. We may not be // listening for the active discovery message at startup // because the listener thread goes on-line last of all. if (config.isDA()) { Vector interfaces = config.getInterfaces(); int i, n = interfaces.size(); for (i = 0; i < n; i++) { InetAddress interfac = (InetAddress)interfaces.elementAt(i); ServiceURL url = new ServiceURL(Defaults.DA_SERVICE_TYPE + "://" + interfac.getHostAddress(), ServiceURL.LIFETIME_MAXIMUM); Vector scopes = config.getSAConfiguredScopes(); long timestamp = 0; // later adverts will cause replacement, // but noforwarding because it is to us... String mySPIs = System.getProperty("sun.net.slp.SPIs"); mySPIs = mySPIs == null ? "" : mySPIs; table.recordNewDA(url, scopes, timestamp, version, config.getDAAttributes(), mySPIs); } } // Sleep, then perform active discovery or polling of preconfigured // DAs when we awake. do { try { sleep(sleepyTime); if (config.getActiveDiscoveryInterval() > 0) { activeDiscovery(); } else { addPreconfiguredDAs(); } } catch (InterruptedException ex) { } } while (true); } // Perform active DA discovery. synchronized private void activeDiscovery() { // Set the previous responders list to null. Otherwise, // the previous responders from the last time we did // this may interfere. SrvLocHeader hdr = activeMsg.getHeader(); hdr.previousResponders.removeAllElements(); // Perform the active discovery message transaction. try { Transact.transactActiveAdvertRequest(Defaults.DA_SERVICE_TYPE, activeMsg, table); } catch (ServiceLocationException ex) { config.writeLog("ad_multi_error", new Object[] { new Integer(ex.getErrorCode()), ex.getMessage() }); } } // Add preconfigured DAs to the DA table. Note that we poll the // preconfigured DAs once every 9 hours to make sure they are still around. synchronized private void addPreconfiguredDAs() { Vector daAddrs = config.getPreconfiguredDAs(); int i, n = daAddrs.size(); // Go through the DA addresses, contacting them for their // information. Better not be any SLPv1 DAs there. for (i = 0; i < n; i++) { InetAddress daAddr = (InetAddress)daAddrs.elementAt(i); // Use a TCP connection. DAs must support TCP so why not? SrvLocMsg reply = null; try { reply = Transact.transactTCPMsg(daAddr, activeMsg, false); } catch (ServiceLocationException ex) { if (config.traceDrop()) { config.writeLog("ad_trans_error", new Object[] { new Integer(ex.getErrorCode()), daAddr, ex.getMessage() }); } continue; } // Report if there's an error in configuration. if (!(reply instanceof CDAAdvert)) { if (config.traceDrop()) { config.writeLog("ad_preconfig_not_advert", new Object[] { daAddr, reply }); } continue; } CDAAdvert advert = (CDAAdvert)reply; SrvLocHeader hdr = advert.getHeader(); // We need to make the URL long lived if active // discovery is off. Otherwise, we let the DA time out like all the // rest. if (config.getActiveDiscoveryInterval() <= 0) { advert.URL = new ServiceURL(advert.URL.toString(), ServiceURL.LIFETIME_MAXIMUM); } // Add the scopes to the configured scopes. Scopes from configured // DAs count as configured scopes. config.addPreconfiguredDAScopes(hdr.scopes); // Record it. Note that we don't have to forward here // because it's the very beginning. table.recordNewDA(advert.URL, hdr.scopes, advert.timestamp, hdr.version, advert.attrs, advert.spis); } } }