xref: /illumos-gate/usr/src/lib/libslp/javalib/com/sun/slp/ActiveDiscoverer.java (revision 45ede40b2394db7967e59f19288fae9b62efd4aa)
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