1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2001 by Sun Microsystems, Inc. 23 * All rights reserved. 24 * 25 */ 26 27 // ActiveDiscoverer.java: Object to perform active DA discovery. 28 // Author: James Kempf 29 // Created On: Thu Sep 3 08:45:21 1998 30 // Last Modified By: James Kempf 31 // Last Modified On: Thu Jan 28 15:45:45 1999 32 // Update Count: 32 33 // 34 35 package com.sun.slp; 36 37 import java.util.*; 38 import java.net.*; 39 40 /* 41 * The ActiveDiscover does active discovery DA discovery by periodically 42 * sending out a SrvRqst for "service:directory-agent". Replies are 43 * entered into the DA table. 44 * 45 * @author James Kempf 46 */ 47 48 class ActiveDiscoverer extends Thread { 49 50 // Config object. 51 52 static private SLPConfig config = null; 53 54 // Message for active DA discovery. 55 56 private CSrvMsg activeMsg = null; 57 58 // Version of protocol to use for advertisements. 59 60 private int version = 0; 61 62 // DATable where discovered DAs are recorded. 63 64 private ServerDATable table = null; 65 66 // Scopes to advertise for. 67 68 private Vector useScopes = null; 69 70 // Address on which to advertise. 71 72 private InetAddress address = null; 73 74 // Create an active discoverer. 75 76 ActiveDiscoverer(int version, 77 ServerDATable table, 78 Vector useScopes, 79 InetAddress address) { 80 81 this.version = version; 82 83 this.table = table; 84 85 this.useScopes = useScopes; 86 87 this.address = address; 88 89 if (config == null) { 90 config = SLPConfig.getSLPConfig(); 91 92 } 93 94 } 95 96 // Do an initial active discovery then start a thread to 97 // do one periodically. 98 99 public void start() { 100 101 // Initial sleepy time. 102 103 long sleepyTime = config.getRandomWait(); 104 105 // Create a message for active discovery. 106 107 try { 108 109 activeMsg = new CSrvMsg(config.getLocale(), 110 Defaults.DA_SERVICE_TYPE, 111 useScopes, 112 ""); 113 114 } catch (ServiceLocationException ex) { 115 Assert.slpassert(false, 116 "sdat_active_err", 117 new Object[] { 118 new Integer(ex.getErrorCode()), 119 ex.getMessage()}); 120 121 } 122 123 // Initialize preconfigured DAs. 124 125 addPreconfiguredDAs(); 126 127 // Do an initial round of active discovery, waiting for 128 // a random period first. Only do it if active 129 // discovery is on. 130 131 if (config.getActiveDiscoveryInterval() > 0) { 132 try { 133 Thread.currentThread().sleep(sleepyTime); 134 135 } catch (InterruptedException ex) { 136 137 } 138 139 activeDiscovery(); 140 141 } else { 142 143 // Report that active discovery is off. 144 145 config.writeLog("ad_active_off", 146 new Object[0]); 147 148 } 149 150 // Start the active discovery thread. 151 152 super.start(); 153 } 154 155 156 157 // Implement the Runnable interface for a thread to start. 158 159 public void run() { 160 161 // Set the Thread name. 162 163 Thread.currentThread().setName("SLP Active DA Discovery"); 164 165 // Sleepy time until discovery. 166 167 long sleepyTime = config.getActiveDiscoveryInterval() * 1000; 168 169 // If the sleep time is zero, then active discovery is turned off. 170 // Use the service URL maximum lifetime. 171 172 if (sleepyTime <= 0) { 173 sleepyTime = (ServiceURL.LIFETIME_MAXIMUM / 2) * 1000; 174 175 } 176 177 // Register ourselves at startup if we are a DA. We may not be 178 // listening for the active discovery message at startup 179 // because the listener thread goes on-line last of all. 180 181 if (config.isDA()) { 182 Vector interfaces = config.getInterfaces(); 183 int i, n = interfaces.size(); 184 185 for (i = 0; i < n; i++) { 186 InetAddress interfac = (InetAddress)interfaces.elementAt(i); 187 ServiceURL url = new ServiceURL(Defaults.DA_SERVICE_TYPE + 188 "://" + 189 interfac.getHostAddress(), 190 ServiceURL.LIFETIME_MAXIMUM); 191 Vector scopes = config.getSAConfiguredScopes(); 192 long timestamp = 0; // later adverts will cause replacement, 193 // but noforwarding because it is to us... 194 195 String mySPIs = System.getProperty("sun.net.slp.SPIs"); 196 mySPIs = mySPIs == null ? "" : mySPIs; 197 198 table.recordNewDA(url, 199 scopes, 200 timestamp, 201 version, 202 config.getDAAttributes(), 203 mySPIs); 204 } 205 } 206 207 // Sleep, then perform active discovery or polling of preconfigured 208 // DAs when we awake. 209 210 do { 211 212 try { 213 214 sleep(sleepyTime); 215 216 if (config.getActiveDiscoveryInterval() > 0) { 217 activeDiscovery(); 218 219 } else { 220 addPreconfiguredDAs(); 221 222 } 223 224 } catch (InterruptedException ex) { 225 226 } 227 228 } while (true); 229 230 } 231 232 // Perform active DA discovery. 233 234 synchronized private void activeDiscovery() { 235 236 // Set the previous responders list to null. Otherwise, 237 // the previous responders from the last time we did 238 // this may interfere. 239 240 SrvLocHeader hdr = activeMsg.getHeader(); 241 242 hdr.previousResponders.removeAllElements(); 243 244 245 // Perform the active discovery message transaction. 246 247 try { 248 Transact.transactActiveAdvertRequest(Defaults.DA_SERVICE_TYPE, 249 activeMsg, 250 table); 251 252 } catch (ServiceLocationException ex) { 253 254 config.writeLog("ad_multi_error", 255 new Object[] { new Integer(ex.getErrorCode()), 256 ex.getMessage() }); 257 258 } 259 260 } 261 262 // Add preconfigured DAs to the DA table. Note that we poll the 263 // preconfigured DAs once every 9 hours to make sure they are still around. 264 265 synchronized private void addPreconfiguredDAs() { 266 267 Vector daAddrs = config.getPreconfiguredDAs(); 268 int i, n = daAddrs.size(); 269 270 // Go through the DA addresses, contacting them for their 271 // information. Better not be any SLPv1 DAs there. 272 273 for (i = 0; i < n; i++) { 274 InetAddress daAddr = (InetAddress)daAddrs.elementAt(i); 275 276 // Use a TCP connection. DAs must support TCP so why not? 277 278 SrvLocMsg reply = null; 279 280 try { 281 reply = Transact.transactTCPMsg(daAddr, activeMsg, false); 282 283 } catch (ServiceLocationException ex) { 284 285 if (config.traceDrop()) { 286 config.writeLog("ad_trans_error", new Object[] { 287 new Integer(ex.getErrorCode()), 288 daAddr, 289 ex.getMessage() }); 290 } 291 292 continue; 293 } 294 295 // Report if there's an error in configuration. 296 297 if (!(reply instanceof CDAAdvert)) { 298 if (config.traceDrop()) { 299 config.writeLog("ad_preconfig_not_advert", 300 new Object[] { daAddr, reply }); 301 302 } 303 304 continue; 305 } 306 307 308 CDAAdvert advert = (CDAAdvert)reply; 309 SrvLocHeader hdr = advert.getHeader(); 310 311 // We need to make the URL long lived if active 312 // discovery is off. Otherwise, we let the DA time out like all the 313 // rest. 314 315 if (config.getActiveDiscoveryInterval() <= 0) { 316 advert.URL = 317 new ServiceURL(advert.URL.toString(), 318 ServiceURL.LIFETIME_MAXIMUM); 319 320 } 321 322 // Add the scopes to the configured scopes. Scopes from configured 323 // DAs count as configured scopes. 324 325 config.addPreconfiguredDAScopes(hdr.scopes); 326 327 // Record it. Note that we don't have to forward here 328 // because it's the very beginning. 329 330 table.recordNewDA(advert.URL, 331 hdr.scopes, 332 advert.timestamp, 333 hdr.version, 334 advert.attrs, 335 advert.spis); 336 337 } 338 } 339 340 } 341