slpd.java revision 9a70fc3be3b1e966bf78825cdb8d509963a6f0a1
/*
* 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
* 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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
// sldp.java : The service location daemon.
// Author: Erik Guttman
//
/**
* The slpd class is the main class for the slpd directory agent/
* service agent server of SLP. Slpd can run in two possible modes,
* depending on the configuration of the classes with which it was shipped
* and information read from the optional configuration file argument:
*
* <ol>
* <li> <b> Service Agent server </b>
* In this mode, slpd functions as a service agent server only.
* Directory agent functionality is disabled. Service agent
* clients on the local machine register and deregister services
* with slpd, and slpd responds to multicast requests for
* services. It passively and actively listens for directory agent
* advertisements, caches them, and forwards them to both
* user agent and service agent clients. A file of serialized
* proxy registrations can be read at startup.
* This mode is normally default.
*
* In this mode, slpd functions as a directory agent
* for port 427 on the local machine. The directory agent
* caches service advertisements, makes directory agent
* advertisements of its services, and responds to requests
* for TCP connections with service agents and user agents.
* In addition, slpd functions in the first mode, as a
* service agent server, for SAs and UAs on the local host.
*
* </ol>
*
* The slpd is invoked as follows:<br>
*<blockquote>
*
* java com.sun.slpd [monitor] [stop] [-f <config file name>]
*
*</blockquote>
*
* The optional monitor argument specifies that a GUI monitor should be
* brought up. The optional stop argument indicates that slpd should
* signal a running slpd to stop. The optional <config file name> argument
* specifies that the named file should be used as the configuration file.
* <p>
* See <a href="slpd.conf.html">slpd.conf</a> for more information on
* configuration file syntax and <a href="slpd.reg.html">slpd.reg</a>
* for more information on proxy registration file syntax.
*
* @author Erik Guttman, James Kempf
*/
// Note that the inheritance is *only* so slpd can initialize the
// internals of SLP config.
// Server bundle. Set the parent.
static class ServerBundle extends ResourceBundle {
static ResourceBundle
throws MissingResourceException {
}
throws MissingResourceException {
}
try {
bundle =
} catch (MalformedURLException e) {
// fallthru to default location
} // No locales in slpd.jar, so propagate the
// MissingResourceException
bundle :
}
throws MissingResourceException {
try {
} catch (MissingResourceException ex) {
}
return ret;
}
public Enumeration getKeys() {
}
}
/**
* Log object for SLP to write to GUI. This class follows the
* semantics of the other SLP logging classes:
*
* This class does not actually write anything until the flush() method
* in invoked; this will write the concatenation of all messages
* passed to the write() method since the last invocation of flush().
*
* The actual logging class used can be controlled via the
* sun.net.slp.loggerClass property.
*
* See also the StderrLog and Syslog classes.
*/
private StringBuffer buf;
buf = new StringBuffer();
}
// Write to the StringBuffer
throws IOException {
}
// Write to the Frame.
public void flush() throws IOException {
"********" +
date + "\n" +
"********\n");
buf = new StringBuffer();
}
// These is a no-op
public void close() throws IOException {}
}
//
// slpd definition.
//
// Called by the slpd and subclasses only.
protected slpd() {
super();
}
private static void usage() {
new Object[0],
bundle));
}
/**
* Usage: slpd [monitor] [stop] [-f config-file name]<br>
* <br>
* String arguments are:
* <br>
* <b> monitor </b> Puts up a rudimentary GUI for the slpd.<br>
* <b>stop <b> Bring down a running slpd and exit.
* <b> config-file name </b> Reads the specified configuration file.<br>
*
* The default running mode is to have no GUI and to use SLP
* defined configuration.
*/
boolean bMon = false;
boolean bStop = false;
configFile = null;
// Process args.
usage();
}
for (i = 0; i < n; i++) {
// Argument is a config file.
if (configFile != null) {
usage();
}
// Make sure we can open it.
try {
configFile = args[i];
usage();
}
bMon = true;
bStop = true;
} else {
usage();
}
}
// Read message bundle file, load config file into properties.
try {
if (configFile != null) {
"file:" + configFile);
}
// Create a new SLP Config object from the config file.
// Create a GUI if the user asked for one.
if (bMon) {
try {
synchronized (config) {
}
slpdgui.setVisible(true);
new Object[0],
bundle));
}
}
// Either start or stop the server, depending on what was
// requested.
if (!bStop) {
start();
} else {
stop();
}
} catch (ServiceLocationException ex) {
}
}
/**
* Start the slpd.
*
* @param bMon True if initializing with GUI monitor.
* @exception ServiceLocationException Internal error or network
* initialization error or
* internal networking error.
*
*/
static void start() throws ServiceLocationException {
// Initialize the service table.
// Initialize the class name for the DA table to the Sun-specific
// DA table.
// If there is a request on stdin, process it now
try {
}
} catch (IOException e) {}
// Start a StreamListener on loopback to start accepting locals regs
config.getLoopback());
// Create a ServerDATable from the class. This will initialize
// active discovery. Note that we need to record our own presence
// in the DA table because we are not yet listening for requests.
// We do this after deserialization so that if we discover any
// DAs, we can perform registrations of the serialized advertisements.
// Deserialize any serialized advertisements and do them now.
// Waiting until here allows any error messages to appear in
// the GUI log, if any, and at this point the DA table is ready.
// Need to create datagram and stream listeners, and a
// DAAdvertiser on all network interfaces.
int i, n = interfaces.size();
for (i = 0; i < n; i++) {
// interface. This includes a datagram listener, a DAAdvertiser
// (which shares the same socket as the datagram listener), and
// a stream listener.
}
// If we've been configured as a DA, then create a DA advertiser to
// periodically advertise our presence on this interface. This
// is only done on the default interface.
config.getLocalHost());
}
// Report scopes and whether DA or SA.
// Report that we are running if tracing is on
config.traceDATraffic()) {
new Object[] {interfaces,
}
// If V1 is supported, crank up V1 support as well.
if (config.isV1Supported()) {
}
}
// Stop a running server by sending a DAAdvert or SAAdvert.
static void stop() throws ServiceLocationException {
if (daemonIsDA()) {
stopDA();
} else {
stopSA();
}
}
// Determine whether the daemon running on this machine is a DA
// or not.
static boolean daemonIsDA() throws ServiceLocationException {
// Get a DA table with available DAs.
// Get DAs.
// If no DAs, then simply return.
return false;
}
// Find our address in the list, if it exists.
for (i = 0; i < n; i++) {
int j, m = interfaces.size();
for (j = 0; j < m; j++) {
return true;
}
}
}
return false;
}
// Stop a DA by multicasting the DAAdvert with boot timestamp 0.
private static void stopDA() throws ServiceLocationException {
// Make the DA URL and the DAAdvert. Note that we only need signal
// on the default local host interface because that is the only
// one on which the server is listening.
"://" +
new SDAAdvert(new SLPServerHeaderV2(),
(short)0x0, // sez we're unsolicited...
0L, // sez we're going down...
url,
new Vector()); // no attributes needed to go down...
// Make the DAAdvertiser.
// Send out unsolicted "going down" message.
daadv.sendAdvert();
// That's it! No need for any messages here.
}
// Stop an SA server by unicasting an SA advert with xid 0.
private static void stopSA() throws ServiceLocationException {
// We signal for stop on the local host, which is guaranteed
// to have an SA listener.
(short)0x0, // sez we're going down...
url,
new Vector());
// don't care about attrs..,
// Send it TCP. We ignore NETWORK_ERROR because it only means
// that the daemon didn't send us a reply, which is expected.
try {
new Object[] {
}
} catch (ServiceLocationException ex) {
}
}
// That's it!
}
// Print error message, exit.
switch (ex.getErrorCode()) {
new Object[] {
ex.getMessage()},
bundle));
break;
new Object[] {
ex.getMessage()},
bundle));
break;
new Object[] {
ex.getMessage()},
bundle));
break;
default:
new Object[] {
ex.getMessage()},
bundle));
}
new Object[0],
bundle));
}
// Make a new SLPConfig object of the right class type.
private static SLPConfig initializeSLPConfig() {
// The server *always* runs as an SA. It may also run as a DA.
// set default logging class for slpd to syslog
}
// slpd is the server side config.
theSLPConfig = new slpd();
return theSLPConfig;
}
//
// Extensions to sldp for server side only.
//
boolean isDA() {
}
// Determine whether V1 is supported. Default is no.
boolean isV1Supported() {
if (!isDA() || super.getSLPv1NotSupported()) {
return false;
}
boolean v1Supported = false;
try {
v1Supported = true;
} catch (ClassNotFoundException ex) {
// Not there.
}
return v1Supported;
}
// Load server message bundle.
// Get the parent bundle first.
}
// We need this in case we get an error before the config object is
// created.
static private ResourceBundle getMessageBundleInternal(
// Now create a server subclass.
try {
// We can't print out to the log, because we may be in the
// process of trying to.
"'' for locale ``"+
"''");
// Hosed if the default locale is missing.
}
// Otherwise, return the default locale.
}
return msgBundle;
}
}