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 59a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License"). 69a70fc3bSMark 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 1999-2003 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate // SLPConfig.java 287c478bd9Sstevel@tonic-gate // 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /** 317c478bd9Sstevel@tonic-gate * This class is a singleton - it has the configuration which 327c478bd9Sstevel@tonic-gate * is the default. It reads from a configuration file and 337c478bd9Sstevel@tonic-gate * this overrides the default. If the config file does not 347c478bd9Sstevel@tonic-gate * expressly forbid it, the ServiceLocationManager interface 357c478bd9Sstevel@tonic-gate * allows some of these configuration options to be modified. 367c478bd9Sstevel@tonic-gate * This configuration is refered to by many points of the 377c478bd9Sstevel@tonic-gate * implementation. Note that the class itself is abstract, 387c478bd9Sstevel@tonic-gate * and is extended by two classes, one that allows slpd to 397c478bd9Sstevel@tonic-gate * run as an SA server only, the other allows it to run 407c478bd9Sstevel@tonic-gate * as a DA as well. 417c478bd9Sstevel@tonic-gate * 427c478bd9Sstevel@tonic-gate * @see com.sun.slp.ServiceLocationManager 437c478bd9Sstevel@tonic-gate */ 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate package com.sun.slp; 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate import java.net.*; 487c478bd9Sstevel@tonic-gate import java.util.*; 497c478bd9Sstevel@tonic-gate import java.text.*; 507c478bd9Sstevel@tonic-gate import java.io.*; 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* 537c478bd9Sstevel@tonic-gate * This class contains all configuration information. It 547c478bd9Sstevel@tonic-gate * is hard coded to know the defaults, and will read a config 557c478bd9Sstevel@tonic-gate * file if it is present. The config file will override the 567c478bd9Sstevel@tonic-gate * default values and policy. If the config file allows it 577c478bd9Sstevel@tonic-gate * the user may reset some of these values using the 587c478bd9Sstevel@tonic-gate * ServiceLocationManager interface. 597c478bd9Sstevel@tonic-gate * 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate class SLPConfig { 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /** 647c478bd9Sstevel@tonic-gate * A Java properties file defines `\' as an escape character, which 657c478bd9Sstevel@tonic-gate * conflicts with the SLP API escape convention. Therefore, we need 667c478bd9Sstevel@tonic-gate * to subclass properties so we can parse in the file ourselves. 677c478bd9Sstevel@tonic-gate */ 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate public static class SLPProperties extends Properties { 707c478bd9Sstevel@tonic-gate SLPProperties(Properties p)717c478bd9Sstevel@tonic-gate SLPProperties(Properties p) { 727c478bd9Sstevel@tonic-gate super(p); 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate } 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate // Parse the SLP properties file ourselves. Groan! We don't recognize 777c478bd9Sstevel@tonic-gate // backslash as an escape. 787c478bd9Sstevel@tonic-gate load(InputStream in)797c478bd9Sstevel@tonic-gate public synchronized void load(InputStream in) throws IOException { 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate BufferedReader rd = new BufferedReader(new InputStreamReader(in)); 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate while (rd.ready()) { 847c478bd9Sstevel@tonic-gate String ln = rd.readLine(); 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate // Throw out anything that begins with '#' or ';'. 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate if (ln.startsWith("#") || 897c478bd9Sstevel@tonic-gate ln.startsWith(";") || 907c478bd9Sstevel@tonic-gate ln.length() <= 0) { 917c478bd9Sstevel@tonic-gate continue; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate // Parse out equals sign, if any. Note that we trim any 96*55fea89dSDan Cross // white space preceding or following data strings. 97*55fea89dSDan Cross // Although the grammar doesn't allow it, users may 987c478bd9Sstevel@tonic-gate // enter blanks in their configuration files. 997c478bd9Sstevel@tonic-gate // NOTE: White space is not allowed in the data of 1007c478bd9Sstevel@tonic-gate // property tag or values. If included, according 101*55fea89dSDan Cross // to RFC 2614, Section 2.1 these MUST be escaped, 102*55fea89dSDan Cross // ie. space would be represented with '\20'. 103*55fea89dSDan Cross // Therefore, it is *completely* safe to perform 104*55fea89dSDan Cross // these trim()s. They will catch errors resulting 105*55fea89dSDan Cross // from sloppy data entry in slp.conf files and 106*55fea89dSDan Cross // never corrupt or alter correctly formatted 1077c478bd9Sstevel@tonic-gate // properties. 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate SLPTokenizer tk = new SLPTokenizer(ln, "="); 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate if (!tk.hasMoreTokens()) {// empty line... 1127c478bd9Sstevel@tonic-gate continue; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate String prop = tk.nextToken().trim(); 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate if (prop.trim().length() <= 0) {// line has just spaces... 1197c478bd9Sstevel@tonic-gate continue; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate if (!tk.hasMoreTokens()) {// line has no definition... 1247c478bd9Sstevel@tonic-gate continue; 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate // Register the property. 1297c478bd9Sstevel@tonic-gate String def = tk.nextToken().trim(); 1307c478bd9Sstevel@tonic-gate this.setProperty(prop, def); 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate SLPConfig()1367c478bd9Sstevel@tonic-gate protected SLPConfig() { 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate // Create a temporary, default log to report any errors during 1397c478bd9Sstevel@tonic-gate // configuration. 1407c478bd9Sstevel@tonic-gate log = new StderrLog(); 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate // Initialize properties. Properties on command line override config 1437c478bd9Sstevel@tonic-gate // file properties, and both override defaults. 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate Properties sysProps = (Properties)(System.getProperties().clone()); 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate // Load Defalts. 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate try { 1507c478bd9Sstevel@tonic-gate Class.forName("com.sun.slp.Defaults"); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate } catch (ClassNotFoundException ex) { 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate Assert.printMessageAndDie(this, 1557c478bd9Sstevel@tonic-gate "no_class", 1567c478bd9Sstevel@tonic-gate new Object[] {"com.sun.slp.Defaults"}); 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate // System properties now contain Defaults 1607c478bd9Sstevel@tonic-gate Properties defaultProps = System.getProperties(); 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate // Load config file. 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate SLPProperties slpProps = new SLPProperties(new Properties()); 1657c478bd9Sstevel@tonic-gate try { 1667c478bd9Sstevel@tonic-gate InputStream fis = getConfigURLStream(); 1677c478bd9Sstevel@tonic-gate if (fis != null) { 1687c478bd9Sstevel@tonic-gate slpProps.load(fis); 1697c478bd9Sstevel@tonic-gate System.setProperties(slpProps); 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate } catch (IOException ex) { 1737c478bd9Sstevel@tonic-gate writeLog("unparsable_config_file", 1747c478bd9Sstevel@tonic-gate new Object[] {ex.getMessage()}); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate // Add config properties to Defaults, overwritting any pre-existing 1787c478bd9Sstevel@tonic-gate // entries 1797c478bd9Sstevel@tonic-gate defaultProps.putAll(slpProps); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate // Now add in system props, overwritting any pre-existing entries 1827c478bd9Sstevel@tonic-gate defaultProps.putAll(sysProps); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate System.setProperties(defaultProps); 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate // Initialize useScopes property. This is read-only after the file 1887c478bd9Sstevel@tonic-gate // has been loaded. 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate configuredScopes = initializeScopes("net.slp.useScopes"); 1917c478bd9Sstevel@tonic-gate saConfiguredScopes = (Vector)configuredScopes.clone(); 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate // Add default scope to scopes for SA. 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate if (saConfiguredScopes.size() <= 0) { 1967c478bd9Sstevel@tonic-gate saConfiguredScopes.addElement(Defaults.DEFAULT_SCOPE); 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate // Initialize SA scopes. This uses a Sun specific property for 2017c478bd9Sstevel@tonic-gate // scopes only used by the SA and adds in the DA scopes. 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate saOnlyScopes = initializeScopes(DATable.SA_ONLY_SCOPES_PROP); 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate // Initialized preconfigured DAs. 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate preconfiguredDAs = initializePreconfiguredDAs(); 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate // Initialize broadcast flag. 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate broadcastOnly = Boolean.getBoolean("net.slp.isBroadcastOnly"); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate // Initialize logging. Default is stderr, first check for alternate. 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate String failed = null; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate try { 2187c478bd9Sstevel@tonic-gate String loggerClassName = 2197c478bd9Sstevel@tonic-gate System.getProperty("sun.net.slp.loggerClass"); 2207c478bd9Sstevel@tonic-gate if (loggerClassName != null) { 2217c478bd9Sstevel@tonic-gate Class loggerClass = Class.forName(loggerClassName); 2227c478bd9Sstevel@tonic-gate // Protect against disastrous pilot error, such as trying 2237c478bd9Sstevel@tonic-gate // to use com.sun.slp.SLPConfig as the log class 2247c478bd9Sstevel@tonic-gate // (causes stack recursion) 2257c478bd9Sstevel@tonic-gate if (Class.forName("java.io.Writer").isAssignableFrom( 2267c478bd9Sstevel@tonic-gate loggerClass)) { 2277c478bd9Sstevel@tonic-gate Object logger = loggerClass.newInstance(); 2287c478bd9Sstevel@tonic-gate log = (Writer) logger; 2297c478bd9Sstevel@tonic-gate } else { 2307c478bd9Sstevel@tonic-gate failed = formatMessage( 2317c478bd9Sstevel@tonic-gate "bad_log_class", 2327c478bd9Sstevel@tonic-gate new Object[] { 2337c478bd9Sstevel@tonic-gate loggerClass.toString()}) + "\n"; 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate } catch (Throwable ex) { 2387c478bd9Sstevel@tonic-gate log = null; 2397c478bd9Sstevel@tonic-gate failed = formatMessage( 2407c478bd9Sstevel@tonic-gate "bad_log", 2417c478bd9Sstevel@tonic-gate new Object[] { 2427c478bd9Sstevel@tonic-gate ex.toString()}) + "\n"; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate // If no alternate log, revert to minimal default 2467c478bd9Sstevel@tonic-gate if (log == null) { 2477c478bd9Sstevel@tonic-gate log = new StderrLog(); 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate // If the alternate log failed, log it through the default log 2507c478bd9Sstevel@tonic-gate if (failed != null) { 2517c478bd9Sstevel@tonic-gate try { 2527c478bd9Sstevel@tonic-gate synchronized (log) { 2537c478bd9Sstevel@tonic-gate log.write(failed); 2547c478bd9Sstevel@tonic-gate log.flush(); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate } catch (IOException giveUp) {} 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate getConfigURLStream()2627c478bd9Sstevel@tonic-gate private InputStream getConfigURLStream() { 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate // Open a URL onto the configuration file. 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate String conf = System.getProperty("sun.net.slp.configURL"); 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate if (conf == null) { 2697c478bd9Sstevel@tonic-gate conf = Defaults.SOLARIS_CONF; 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate InputStream str = null; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate try { 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate URL confURL = new URL(conf); 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate str = confURL.openStream(); 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate } catch (MalformedURLException ex) { 2827c478bd9Sstevel@tonic-gate writeLog("url_malformed", 2837c478bd9Sstevel@tonic-gate new Object[] {conf}); 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate } catch (IOException ex) { 2867c478bd9Sstevel@tonic-gate if (conf != Defaults.SOLARIS_CONF) { 2877c478bd9Sstevel@tonic-gate // don't complain if we can't find our own default 2887c478bd9Sstevel@tonic-gate writeLog("unparsable_config_file", 2897c478bd9Sstevel@tonic-gate new Object[] {ex.getMessage()}); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate return str; 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 2987c478bd9Sstevel@tonic-gate // Property manipulation functions 2997c478bd9Sstevel@tonic-gate // 3007c478bd9Sstevel@tonic-gate OKBound(int i, int lb, int ub)3017c478bd9Sstevel@tonic-gate private boolean OKBound(int i, int lb, int ub) { 3027c478bd9Sstevel@tonic-gate if (i < lb || i > ub) 3037c478bd9Sstevel@tonic-gate return false; 3047c478bd9Sstevel@tonic-gate else 3057c478bd9Sstevel@tonic-gate return true; 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate getIntProperty(String prop, int df, int lb, int ub)3087c478bd9Sstevel@tonic-gate int getIntProperty(String prop, int df, int lb, int ub) { 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate int i = Integer.getInteger(prop, df).intValue(); 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate if (OKBound(i, lb, ub)) { 3137c478bd9Sstevel@tonic-gate return i; 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate } else { 3167c478bd9Sstevel@tonic-gate writeLog("bad_prop_tag", new Object[] {prop}); 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate return df; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 3237c478bd9Sstevel@tonic-gate // Multicast radius 3247c478bd9Sstevel@tonic-gate // 3257c478bd9Sstevel@tonic-gate private int iMinMCRadius = 1; // link local scope 3267c478bd9Sstevel@tonic-gate private int iMaxMCRadius = 255; // universal scope 3277c478bd9Sstevel@tonic-gate getMCRadius()3287c478bd9Sstevel@tonic-gate int getMCRadius() { 3297c478bd9Sstevel@tonic-gate return getIntProperty("net.slp.multicastTTL", 3307c478bd9Sstevel@tonic-gate Defaults.iMulticastRadius, 3317c478bd9Sstevel@tonic-gate iMinMCRadius, 3327c478bd9Sstevel@tonic-gate iMaxMCRadius); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 3367c478bd9Sstevel@tonic-gate // Heartbeat interval, seconds. 3377c478bd9Sstevel@tonic-gate // 3387c478bd9Sstevel@tonic-gate private final int iMinHeart = 2000; // 10 minutes 3397c478bd9Sstevel@tonic-gate private final int iMaxHeart = 259200000; // 3 days 3407c478bd9Sstevel@tonic-gate getAdvertHeartbeatTime()3417c478bd9Sstevel@tonic-gate int getAdvertHeartbeatTime() { 3427c478bd9Sstevel@tonic-gate return getIntProperty("net.slp.DAHeartBeat", 3437c478bd9Sstevel@tonic-gate Defaults.iHeartbeat, 3447c478bd9Sstevel@tonic-gate iMinHeart, 3457c478bd9Sstevel@tonic-gate iMaxHeart); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 3497c478bd9Sstevel@tonic-gate // Active discovery interval, seconds. 3507c478bd9Sstevel@tonic-gate // 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate private final int iMinDisc = 300; // 5 minutes 3537c478bd9Sstevel@tonic-gate private final int iMaxDisc = 10800; // 3 hours 3547c478bd9Sstevel@tonic-gate getActiveDiscoveryInterval()3557c478bd9Sstevel@tonic-gate int getActiveDiscoveryInterval() { 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate // We allow zero in order to turn active discovery off, but 3587c478bd9Sstevel@tonic-gate // if 5 minutes is the smallest actual time. 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate int prop = getIntProperty("net.slp.DAActiveDiscoveryInterval", 3617c478bd9Sstevel@tonic-gate Defaults.iActiveDiscoveryInterval, 3627c478bd9Sstevel@tonic-gate 0, 3637c478bd9Sstevel@tonic-gate iMaxDisc); 3647c478bd9Sstevel@tonic-gate if (prop > 0 && prop < iMinDisc) { 3657c478bd9Sstevel@tonic-gate writeLog("bad_prop_tag", 3667c478bd9Sstevel@tonic-gate new Object[] {"net.slp.DAActiveDiscoveryInterval"}); 3677c478bd9Sstevel@tonic-gate return iMinDisc; 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate return prop; 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 3767c478bd9Sstevel@tonic-gate // Active discovery granularity, seconds. 3777c478bd9Sstevel@tonic-gate // 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate private int iMaxDiscGran = iMaxDisc * 2; 3807c478bd9Sstevel@tonic-gate getActiveDiscoveryGranularity()3817c478bd9Sstevel@tonic-gate int getActiveDiscoveryGranularity() { 3827c478bd9Sstevel@tonic-gate return getIntProperty("sun.net.slp.DAActiveDiscoveryGranularity", 3837c478bd9Sstevel@tonic-gate Defaults.iActiveDiscoveryGranularity, 3847c478bd9Sstevel@tonic-gate 0, 3857c478bd9Sstevel@tonic-gate iMaxDiscGran); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 3897c478bd9Sstevel@tonic-gate // Bound for random wait, milliseconds. 3907c478bd9Sstevel@tonic-gate // 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate private final int iMinWait = 1000; // 1 sec. 3937c478bd9Sstevel@tonic-gate private final int iMaxWait = 3000; // 3 sec. 3947c478bd9Sstevel@tonic-gate getRandomWaitBound()3957c478bd9Sstevel@tonic-gate int getRandomWaitBound() { 3967c478bd9Sstevel@tonic-gate return getIntProperty("net.slp.randomWaitBound", 3977c478bd9Sstevel@tonic-gate Defaults.iRandomWaitBound, 3987c478bd9Sstevel@tonic-gate iMinWait, 3997c478bd9Sstevel@tonic-gate iMaxWait); 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate private static Random randomWait = null; 4037c478bd9Sstevel@tonic-gate getRandomWait()4047c478bd9Sstevel@tonic-gate long getRandomWait() { 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate if (randomWait == null) { 4077c478bd9Sstevel@tonic-gate randomWait = new Random(); 4087c478bd9Sstevel@tonic-gate } 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate double r = randomWait.nextDouble(); 4117c478bd9Sstevel@tonic-gate double max = (double)getRandomWaitBound(); 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate return (long)(max * r); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 4177c478bd9Sstevel@tonic-gate // TCP timeout, milliseconds. 4187c478bd9Sstevel@tonic-gate // 4197c478bd9Sstevel@tonic-gate final static private int iMinTimeout = 100; 4207c478bd9Sstevel@tonic-gate final static private int iMaxTimeout = 360000; 4217c478bd9Sstevel@tonic-gate getTCPTimeout()4227c478bd9Sstevel@tonic-gate int getTCPTimeout() { 4237c478bd9Sstevel@tonic-gate return getIntProperty("sun.net.slp.TCPTimeout", 4247c478bd9Sstevel@tonic-gate Defaults.iTCPTimeout, 4257c478bd9Sstevel@tonic-gate iMinTimeout, 4267c478bd9Sstevel@tonic-gate iMaxTimeout); 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 4307c478bd9Sstevel@tonic-gate // Path MTU 4317c478bd9Sstevel@tonic-gate // 4327c478bd9Sstevel@tonic-gate private final int iMinMTU = 128; // used for some ppp connections 4337c478bd9Sstevel@tonic-gate private final int iMaxMTU = 8192; // used on some LANs 4347c478bd9Sstevel@tonic-gate getMTU()4357c478bd9Sstevel@tonic-gate int getMTU() { 4367c478bd9Sstevel@tonic-gate return getIntProperty("net.slp.MTU", 4377c478bd9Sstevel@tonic-gate Defaults.iMTU, 4387c478bd9Sstevel@tonic-gate iMinMTU, 4397c478bd9Sstevel@tonic-gate iMaxMTU); 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 4447c478bd9Sstevel@tonic-gate // Serialized registrations. 4457c478bd9Sstevel@tonic-gate // 4467c478bd9Sstevel@tonic-gate getSerializedRegURL()4477c478bd9Sstevel@tonic-gate String getSerializedRegURL() { 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate return System.getProperty("net.slp.serializedRegURL", null); 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 4547c478bd9Sstevel@tonic-gate // Are we running as a DA or SA server? 4557c478bd9Sstevel@tonic-gate // 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate protected static boolean isSA = false; 4587c478bd9Sstevel@tonic-gate isDA()4597c478bd9Sstevel@tonic-gate boolean isDA() { 4607c478bd9Sstevel@tonic-gate return false; 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate isSA()4637c478bd9Sstevel@tonic-gate boolean isSA() { 4647c478bd9Sstevel@tonic-gate return isSA; 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 4687c478bd9Sstevel@tonic-gate // DA and SA attributes 4697c478bd9Sstevel@tonic-gate // 4707c478bd9Sstevel@tonic-gate getDAAttributes()4717c478bd9Sstevel@tonic-gate Vector getDAAttributes() { 4727c478bd9Sstevel@tonic-gate return getAttributes("net.slp.DAAttributes", 4737c478bd9Sstevel@tonic-gate Defaults.defaultDAAttributes, 4747c478bd9Sstevel@tonic-gate true); 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate getSAAttributes()4777c478bd9Sstevel@tonic-gate Vector getSAAttributes() { 4787c478bd9Sstevel@tonic-gate return getAttributes("net.slp.SAAttributes", 4797c478bd9Sstevel@tonic-gate Defaults.defaultSAAttributes, 4807c478bd9Sstevel@tonic-gate false); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate getAttributes(String prop, Vector defaults, boolean daAttrs)4837c478bd9Sstevel@tonic-gate private Vector getAttributes(String prop, 4847c478bd9Sstevel@tonic-gate Vector defaults, 4857c478bd9Sstevel@tonic-gate boolean daAttrs) { 4867c478bd9Sstevel@tonic-gate String attrList = 4877c478bd9Sstevel@tonic-gate System.getProperty(prop); 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate if (attrList == null || attrList.length() <= 0) { 4907c478bd9Sstevel@tonic-gate return (Vector)defaults.clone(); 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate 4947c478bd9Sstevel@tonic-gate try { 4957c478bd9Sstevel@tonic-gate Vector sAttrs = 4967c478bd9Sstevel@tonic-gate SrvLocHeader.parseCommaSeparatedListIn(attrList, false); 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate Vector attrs = new Vector(); 4997c478bd9Sstevel@tonic-gate int i, n = sAttrs.size(); 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate // Create attribute objects. 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 5047c478bd9Sstevel@tonic-gate String attrExp = (String)sAttrs.elementAt(i); 5057c478bd9Sstevel@tonic-gate ServiceLocationAttribute attr = 5067c478bd9Sstevel@tonic-gate new ServiceLocationAttribute(attrExp, false); 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate // If this is the min-refresh-interval, then check the value. 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate if (daAttrs && 5117c478bd9Sstevel@tonic-gate attr.getId().equals( 5127c478bd9Sstevel@tonic-gate Defaults.MIN_REFRESH_INTERVAL_ATTR_ID)) { 5137c478bd9Sstevel@tonic-gate Vector values = attr.getValues(); 5147c478bd9Sstevel@tonic-gate boolean errorp = true; 515*55fea89dSDan Cross 5167c478bd9Sstevel@tonic-gate if (values != null && values.size() == 1) { 5177c478bd9Sstevel@tonic-gate Object val = values.elementAt(0); 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate if (val instanceof Integer) { 5207c478bd9Sstevel@tonic-gate int ival = ((Integer)val).intValue(); 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate if (ival >= 0 && 5237c478bd9Sstevel@tonic-gate ival <= ServiceURL.LIFETIME_MAXIMUM) { 5247c478bd9Sstevel@tonic-gate errorp = false; 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate // Throw exception if it didn't work. 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate if (errorp) { 5337c478bd9Sstevel@tonic-gate throw new ServiceLocationException( 5347c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 5357c478bd9Sstevel@tonic-gate "syntax_error_prop", 5367c478bd9Sstevel@tonic-gate new Object[] {prop, attrs}); 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate } 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate // Add attribute to vector. 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate attrs.addElement(attr); 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate } 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate return attrs; 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate } catch (Exception ex) { 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate writeLog("syntax_error_prop", 5527c478bd9Sstevel@tonic-gate new Object[] {prop, attrList}); 5537c478bd9Sstevel@tonic-gate return (Vector)defaults.clone(); 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate // ------------------------------------------------------------- 5597c478bd9Sstevel@tonic-gate // Do we support V1? 5607c478bd9Sstevel@tonic-gate // 5617c478bd9Sstevel@tonic-gate isV1Supported()5627c478bd9Sstevel@tonic-gate boolean isV1Supported() { 5637c478bd9Sstevel@tonic-gate return false; 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate // ------------------------------------------------------------- 5677c478bd9Sstevel@tonic-gate // Queue length for server socket. 5687c478bd9Sstevel@tonic-gate // 5697c478bd9Sstevel@tonic-gate getServerSocketQueueLength()5707c478bd9Sstevel@tonic-gate int getServerSocketQueueLength() { 5717c478bd9Sstevel@tonic-gate return getIntProperty("sun.net.slp.serverSocketQueueLength", 5727c478bd9Sstevel@tonic-gate Defaults.iSocketQueueLength, 5737c478bd9Sstevel@tonic-gate 0, 5747c478bd9Sstevel@tonic-gate Integer.MAX_VALUE); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 5787c478bd9Sstevel@tonic-gate // Testing options 5797c478bd9Sstevel@tonic-gate // 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate traceAll()5827c478bd9Sstevel@tonic-gate boolean traceAll() {// not official! 5837c478bd9Sstevel@tonic-gate return Boolean.getBoolean("sun.net.slp.traceALL"); 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate regTest()5867c478bd9Sstevel@tonic-gate boolean regTest() { 5877c478bd9Sstevel@tonic-gate if (Boolean.getBoolean("sun.net.slp.traceALL") || 5887c478bd9Sstevel@tonic-gate Boolean.getBoolean("net.slp.traceReg")) 5897c478bd9Sstevel@tonic-gate return true; 5907c478bd9Sstevel@tonic-gate else 5917c478bd9Sstevel@tonic-gate return false; 5927c478bd9Sstevel@tonic-gate } 5937c478bd9Sstevel@tonic-gate traceMsg()5947c478bd9Sstevel@tonic-gate boolean traceMsg() { 5957c478bd9Sstevel@tonic-gate if (Boolean.getBoolean("sun.net.slp.traceALL") || 5967c478bd9Sstevel@tonic-gate Boolean.getBoolean("net.slp.traceMsg")) 5977c478bd9Sstevel@tonic-gate return true; 5987c478bd9Sstevel@tonic-gate else 5997c478bd9Sstevel@tonic-gate return false; 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate traceDrop()6027c478bd9Sstevel@tonic-gate boolean traceDrop() { 6037c478bd9Sstevel@tonic-gate if (Boolean.getBoolean("sun.net.slp.traceALL") || 6047c478bd9Sstevel@tonic-gate Boolean.getBoolean("net.slp.traceDrop")) 6057c478bd9Sstevel@tonic-gate return true; 6067c478bd9Sstevel@tonic-gate else 6077c478bd9Sstevel@tonic-gate return false; 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate traceDATraffic()6107c478bd9Sstevel@tonic-gate boolean traceDATraffic() { 6117c478bd9Sstevel@tonic-gate if (Boolean.getBoolean("sun.net.slp.traceALL") || 6127c478bd9Sstevel@tonic-gate Boolean.getBoolean("net.slp.traceDATraffic")) 6137c478bd9Sstevel@tonic-gate return true; 6147c478bd9Sstevel@tonic-gate else 6157c478bd9Sstevel@tonic-gate return false; 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate // cannot use Boolean.getBoolean as the default is 'true' 6197c478bd9Sstevel@tonic-gate // using that mechanism, absense would be considered 'false' 6207c478bd9Sstevel@tonic-gate passiveDADetection()6217c478bd9Sstevel@tonic-gate boolean passiveDADetection() { 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate String sPassive = 6247c478bd9Sstevel@tonic-gate System.getProperty("net.slp.passiveDADetection", "true"); 6257c478bd9Sstevel@tonic-gate if (sPassive.equalsIgnoreCase("true")) 6267c478bd9Sstevel@tonic-gate return true; 6277c478bd9Sstevel@tonic-gate else 6287c478bd9Sstevel@tonic-gate return false; 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate } 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate // Initialized when the SLPConfig object is created to avoid changing 6337c478bd9Sstevel@tonic-gate // during the program. 6347c478bd9Sstevel@tonic-gate private boolean broadcastOnly = false; 6357c478bd9Sstevel@tonic-gate isBroadcastOnly()6367c478bd9Sstevel@tonic-gate boolean isBroadcastOnly() { 6377c478bd9Sstevel@tonic-gate return broadcastOnly; 6387c478bd9Sstevel@tonic-gate } 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 6427c478bd9Sstevel@tonic-gate // Multicast/broadcast socket mangement. 6437c478bd9Sstevel@tonic-gate // 6447c478bd9Sstevel@tonic-gate DatagramSocket broadSocket = null; // cached broadcast socket. 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate 6477c478bd9Sstevel@tonic-gate // Reopen the multicast/broadcast socket bound to the 6487c478bd9Sstevel@tonic-gate // interface. If groups is not null, then join all 6497c478bd9Sstevel@tonic-gate // the groups. Otherwise, this is send only. 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate DatagramSocket refreshMulticastSocketOnInterface(InetAddress interfac, Vector groups)6527c478bd9Sstevel@tonic-gate refreshMulticastSocketOnInterface(InetAddress interfac, 6537c478bd9Sstevel@tonic-gate Vector groups) { 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate try { 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate // Reopen it. 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate DatagramSocket dss = 6607c478bd9Sstevel@tonic-gate getMulticastSocketOnInterface(interfac, 6617c478bd9Sstevel@tonic-gate (groups == null ? true:false)); 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate if ((groups != null) && (dss instanceof MulticastSocket)) { 6647c478bd9Sstevel@tonic-gate int i, n = groups.size(); 6657c478bd9Sstevel@tonic-gate MulticastSocket mss = (MulticastSocket)dss; 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 6687c478bd9Sstevel@tonic-gate InetAddress maddr = (InetAddress)groups.elementAt(i); 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate mss.joinGroup(maddr); 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate return dss; 6767c478bd9Sstevel@tonic-gate 6777c478bd9Sstevel@tonic-gate } catch (Exception ex) { 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate // Any exception in error recovery causes program to die. 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate Assert.slpassert(false, 6827c478bd9Sstevel@tonic-gate "cast_socket_failure", 6837c478bd9Sstevel@tonic-gate new Object[] {ex, ex.getMessage()}); 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate } 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate return null; 6887c478bd9Sstevel@tonic-gate } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate // Open a multicast/broadcast socket on the interface. Note that if 6917c478bd9Sstevel@tonic-gate // the socket is broadcast, the network interface is not specified in the 6927c478bd9Sstevel@tonic-gate // creation message. Is it bound to all interfaces? The isSend parameter 6937c478bd9Sstevel@tonic-gate // specifies whether the socket is for send only. 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate DatagramSocket getMulticastSocketOnInterface(InetAddress interfac, boolean isSend)6967c478bd9Sstevel@tonic-gate getMulticastSocketOnInterface(InetAddress interfac, boolean isSend) 6977c478bd9Sstevel@tonic-gate throws ServiceLocationException { 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate DatagramSocket castSocket = null; 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate // Substitute broadcast if we are configured for it. 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate if (isBroadcastOnly()) { 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate try { 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate // If transmit, then simply return a new socket. 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate if (isSend) { 7107c478bd9Sstevel@tonic-gate castSocket = new DatagramSocket(); 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate } else { 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate // Return cached socket if there. 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate if (broadSocket != null) { 7177c478bd9Sstevel@tonic-gate castSocket = broadSocket; 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate } else { 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate // Make a new broadcast socket. 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate castSocket = 7247c478bd9Sstevel@tonic-gate new DatagramSocket(Defaults.iSLPPort, 7257c478bd9Sstevel@tonic-gate getBroadcastAddress()); 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate // Cache for future reference. 7307c478bd9Sstevel@tonic-gate 7317c478bd9Sstevel@tonic-gate broadSocket = castSocket; 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate } catch (SocketException ex) { 734*55fea89dSDan Cross throw 7357c478bd9Sstevel@tonic-gate new ServiceLocationException( 7367c478bd9Sstevel@tonic-gate ServiceLocationException.NETWORK_INIT_FAILED, 7377c478bd9Sstevel@tonic-gate "socket_creation_failure", 7387c478bd9Sstevel@tonic-gate new Object[] { 7397c478bd9Sstevel@tonic-gate getBroadcastAddress(), ex.getMessage()}); 7407c478bd9Sstevel@tonic-gate } 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate } else { 7437c478bd9Sstevel@tonic-gate 7447c478bd9Sstevel@tonic-gate // Create a multicast socket. 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate MulticastSocket ms; 7477c478bd9Sstevel@tonic-gate 7487c478bd9Sstevel@tonic-gate try { 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate if (isSend) { 7517c478bd9Sstevel@tonic-gate ms = new MulticastSocket(); 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate } else { 7547c478bd9Sstevel@tonic-gate ms = new MulticastSocket(Defaults.iSLPPort); 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate } catch (IOException ex) { 7597c478bd9Sstevel@tonic-gate throw 7607c478bd9Sstevel@tonic-gate new ServiceLocationException( 7617c478bd9Sstevel@tonic-gate ServiceLocationException.NETWORK_INIT_FAILED, 7627c478bd9Sstevel@tonic-gate "socket_creation_failure", 7637c478bd9Sstevel@tonic-gate new Object[] {interfac, ex.getMessage()}); 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate try { 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate // Set the TTL and the interface on the multicast socket. 7707c478bd9Sstevel@tonic-gate // Client is responsible for joining group. 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate ms.setTimeToLive(getMCRadius()); 7737c478bd9Sstevel@tonic-gate ms.setInterface(interfac); 7747c478bd9Sstevel@tonic-gate 7757c478bd9Sstevel@tonic-gate } catch (IOException ex) { 7767c478bd9Sstevel@tonic-gate throw 7777c478bd9Sstevel@tonic-gate new ServiceLocationException( 7787c478bd9Sstevel@tonic-gate ServiceLocationException.NETWORK_INIT_FAILED, 7797c478bd9Sstevel@tonic-gate "socket_initializtion_failure", 7807c478bd9Sstevel@tonic-gate new Object[] {interfac, ex.getMessage()}); 7817c478bd9Sstevel@tonic-gate } 7827c478bd9Sstevel@tonic-gate 7837c478bd9Sstevel@tonic-gate castSocket = ms; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate } 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate return castSocket; 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 7917c478bd9Sstevel@tonic-gate // Type hint 7927c478bd9Sstevel@tonic-gate // 7937c478bd9Sstevel@tonic-gate 7947c478bd9Sstevel@tonic-gate // Return a vector of ServiceType objects for the type hint. 7957c478bd9Sstevel@tonic-gate getTypeHint()7967c478bd9Sstevel@tonic-gate Vector getTypeHint() { 7977c478bd9Sstevel@tonic-gate Vector hint = new Vector(); 7987c478bd9Sstevel@tonic-gate String sTypeList = System.getProperty("net.slp.typeHint", ""); 7997c478bd9Sstevel@tonic-gate 8007c478bd9Sstevel@tonic-gate if (sTypeList.length() <= 0) { 8017c478bd9Sstevel@tonic-gate return hint; 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate } 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate // Create a vector of ServiceType objects for the type hint. 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate try { 8087c478bd9Sstevel@tonic-gate 8097c478bd9Sstevel@tonic-gate hint = SrvLocHeader.parseCommaSeparatedListIn(sTypeList, true); 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate int i, n = hint.size(); 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 8147c478bd9Sstevel@tonic-gate String type = (String)hint.elementAt(i); 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate hint.setElementAt(new ServiceType(type), i); 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate } 8197c478bd9Sstevel@tonic-gate } catch (ServiceLocationException ex) { 8207c478bd9Sstevel@tonic-gate 8217c478bd9Sstevel@tonic-gate writeLog("syntax_error_prop", 8227c478bd9Sstevel@tonic-gate new Object[] {"net.slp.typeHint", sTypeList}); 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate hint.removeAllElements(); 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate return hint; 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate } 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 8337c478bd9Sstevel@tonic-gate // Configured scope handling 8347c478bd9Sstevel@tonic-gate // 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate // Vector of configured scopes. 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate private Vector configuredScopes = null; 8397c478bd9Sstevel@tonic-gate 8407c478bd9Sstevel@tonic-gate // Vector of configures scopes for SA. 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate private Vector saConfiguredScopes = null; 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate // Vector of scopes only in the sa server. 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate private Vector saOnlyScopes = null; 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate // Return the configured scopes. 8497c478bd9Sstevel@tonic-gate getConfiguredScopes()8507c478bd9Sstevel@tonic-gate Vector getConfiguredScopes() { 8517c478bd9Sstevel@tonic-gate return (Vector)configuredScopes.clone(); 8527c478bd9Sstevel@tonic-gate } 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate // Return SA scopes. 8557c478bd9Sstevel@tonic-gate getSAOnlyScopes()8567c478bd9Sstevel@tonic-gate Vector getSAOnlyScopes() { 8577c478bd9Sstevel@tonic-gate return (Vector)saOnlyScopes.clone(); 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate } 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate // Return the configured scopes for the SA. 8627c478bd9Sstevel@tonic-gate getSAConfiguredScopes()8637c478bd9Sstevel@tonic-gate Vector getSAConfiguredScopes() { 8647c478bd9Sstevel@tonic-gate return (Vector)saConfiguredScopes.clone(); 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate } 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate // Add scopes discovered during preconfigured DA contact. 8697c478bd9Sstevel@tonic-gate // These count as configured scopes. 8707c478bd9Sstevel@tonic-gate addPreconfiguredDAScopes(Vector scopes)8717c478bd9Sstevel@tonic-gate void addPreconfiguredDAScopes(Vector scopes) { 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate int i, n = scopes.size(); 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 8767c478bd9Sstevel@tonic-gate Object scope = scopes.elementAt(i); 8777c478bd9Sstevel@tonic-gate 8787c478bd9Sstevel@tonic-gate if (!configuredScopes.contains(scope)) { 8797c478bd9Sstevel@tonic-gate configuredScopes.addElement(scope); 8807c478bd9Sstevel@tonic-gate 8817c478bd9Sstevel@tonic-gate } 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate // There better be none extra here for the SA server/DA. 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate if (isSA() || isDA()) { 8867c478bd9Sstevel@tonic-gate Assert.slpassert(saConfiguredScopes.contains(scope), 8877c478bd9Sstevel@tonic-gate "sa_new_scope", 8887c478bd9Sstevel@tonic-gate new Object[] {scope, saConfiguredScopes}); 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate } 8917c478bd9Sstevel@tonic-gate } 8927c478bd9Sstevel@tonic-gate } 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate // Initialize the scopes list on property. 8957c478bd9Sstevel@tonic-gate initializeScopes(String prop)8967c478bd9Sstevel@tonic-gate private Vector initializeScopes(String prop) { 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate String sScopes = System.getProperty(prop); 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate if (sScopes == null || sScopes.length() <= 0) { 9017c478bd9Sstevel@tonic-gate return new Vector(); 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate try { 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate Vector vv = 9077c478bd9Sstevel@tonic-gate SrvLocHeader.parseCommaSeparatedListIn(sScopes, true); 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate // Unescape scope strings. 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate SLPHeaderV2.unescapeScopeStrings(vv); 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate // Validate, lower case scope names. 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate DATable.validateScopes(vv, getLocale()); 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate if (vv.size() > 0) { 9187c478bd9Sstevel@tonic-gate return vv; 9197c478bd9Sstevel@tonic-gate } 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate } catch (ServiceLocationException ex) { 9227c478bd9Sstevel@tonic-gate writeLog("syntax_error_prop", 9237c478bd9Sstevel@tonic-gate new Object[] { 9247c478bd9Sstevel@tonic-gate prop, 9257c478bd9Sstevel@tonic-gate sScopes}); 926*55fea89dSDan Cross 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate 9307c478bd9Sstevel@tonic-gate return new Vector(); 9317c478bd9Sstevel@tonic-gate } 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate // Vector of preconfigured DAs. Read only after initialized. 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate private Vector preconfiguredDAs = null; 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate // Return a vector of DA addresses. 9387c478bd9Sstevel@tonic-gate getPreconfiguredDAs()9397c478bd9Sstevel@tonic-gate Vector getPreconfiguredDAs() { 9407c478bd9Sstevel@tonic-gate return (Vector)preconfiguredDAs.clone(); 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate } 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate // Initialize preconfigured DA list. 9457c478bd9Sstevel@tonic-gate initializePreconfiguredDAs()9467c478bd9Sstevel@tonic-gate private Vector initializePreconfiguredDAs() { 9477c478bd9Sstevel@tonic-gate String sDAList = System.getProperty("net.slp.DAAddresses", ""); 9487c478bd9Sstevel@tonic-gate Vector ret = new Vector(); 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate sDAList.trim(); 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate if (sDAList.length() <= 0) { 9537c478bd9Sstevel@tonic-gate return ret; 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate } 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate try { 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate ret = SrvLocHeader.parseCommaSeparatedListIn(sDAList, true); 9607c478bd9Sstevel@tonic-gate 9617c478bd9Sstevel@tonic-gate } catch (ServiceLocationException ex) { 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate writeLog("syntax_error_prop", 9647c478bd9Sstevel@tonic-gate new Object[] {"net.slp.DAAddress", sDAList}); 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate return ret; 9677c478bd9Sstevel@tonic-gate 9687c478bd9Sstevel@tonic-gate } 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate // Convert to InetAddress objects. 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate int i; 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate for (i = 0; i < ret.size(); i++) { 9757c478bd9Sstevel@tonic-gate String da = ""; 9767c478bd9Sstevel@tonic-gate 9777c478bd9Sstevel@tonic-gate try { 9787c478bd9Sstevel@tonic-gate da = ((String)ret.elementAt(i)).trim(); 9797c478bd9Sstevel@tonic-gate InetAddress daAddr = InetAddress.getByName(da); 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate ret.setElementAt(daAddr, i); 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate } catch (UnknownHostException ex) { 9847c478bd9Sstevel@tonic-gate 9857c478bd9Sstevel@tonic-gate writeLog("resolve_failed", 9867c478bd9Sstevel@tonic-gate new Object[] {da}); 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate /* 9897c478bd9Sstevel@tonic-gate * Must decrement the index 'i' otherwise the next iteration 9907c478bd9Sstevel@tonic-gate * around the loop will miss the element immediately after 9917c478bd9Sstevel@tonic-gate * the element removed. 9927c478bd9Sstevel@tonic-gate * 9937c478bd9Sstevel@tonic-gate * WARNING: Do not use 'i' again until the loop has 9947c478bd9Sstevel@tonic-gate * iterated as it may, after decrementing, 9957c478bd9Sstevel@tonic-gate * be negative. 9967c478bd9Sstevel@tonic-gate */ 9977c478bd9Sstevel@tonic-gate ret.removeElementAt(i); 9987c478bd9Sstevel@tonic-gate i--; 9997c478bd9Sstevel@tonic-gate continue; 10007c478bd9Sstevel@tonic-gate } 10017c478bd9Sstevel@tonic-gate } 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate 10047c478bd9Sstevel@tonic-gate return ret; 10057c478bd9Sstevel@tonic-gate } 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 10087c478bd9Sstevel@tonic-gate // SLPv1 Support Switches 10097c478bd9Sstevel@tonic-gate // 10107c478bd9Sstevel@tonic-gate getSLPv1NotSupported()10117c478bd9Sstevel@tonic-gate boolean getSLPv1NotSupported() {// not official! 10127c478bd9Sstevel@tonic-gate return Boolean.getBoolean("sun.net.slp.SLPv1NotSupported"); 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate getAcceptSLPv1UnscopedRegs()10167c478bd9Sstevel@tonic-gate boolean getAcceptSLPv1UnscopedRegs() {// not official! 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate if (!getSLPv1NotSupported()) { 10197c478bd9Sstevel@tonic-gate return Boolean.getBoolean("sun.net.slp.acceptSLPv1UnscopedRegs"); 10207c478bd9Sstevel@tonic-gate 10217c478bd9Sstevel@tonic-gate } 10227c478bd9Sstevel@tonic-gate 10237c478bd9Sstevel@tonic-gate return false; 10247c478bd9Sstevel@tonic-gate } 10257c478bd9Sstevel@tonic-gate 10267c478bd9Sstevel@tonic-gate // ------------------------------------------------------------ 10277c478bd9Sstevel@tonic-gate // Accessor for SLPConfig object 10287c478bd9Sstevel@tonic-gate // 10297c478bd9Sstevel@tonic-gate 10307c478bd9Sstevel@tonic-gate protected static SLPConfig theSLPConfig = null; 10317c478bd9Sstevel@tonic-gate getSLPConfig()10327c478bd9Sstevel@tonic-gate static SLPConfig getSLPConfig() { 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate if (theSLPConfig == null) { 10357c478bd9Sstevel@tonic-gate theSLPConfig = new SLPConfig(); 10367c478bd9Sstevel@tonic-gate } 10377c478bd9Sstevel@tonic-gate 10387c478bd9Sstevel@tonic-gate return theSLPConfig; 10397c478bd9Sstevel@tonic-gate 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate /** 10437c478bd9Sstevel@tonic-gate * @return Maximum number of messages/objects to return. 10447c478bd9Sstevel@tonic-gate */ 10457c478bd9Sstevel@tonic-gate getMaximumResults()10467c478bd9Sstevel@tonic-gate int getMaximumResults() { 10477c478bd9Sstevel@tonic-gate int i = Integer.getInteger("net.slp.maxResults", 10487c478bd9Sstevel@tonic-gate Defaults.iMaximumResults).intValue(); 10497c478bd9Sstevel@tonic-gate if (i == -1) { 10507c478bd9Sstevel@tonic-gate i = Integer.MAX_VALUE; 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate } 10537c478bd9Sstevel@tonic-gate 10547c478bd9Sstevel@tonic-gate if (OKBound(i, 1, Integer.MAX_VALUE)) { 10557c478bd9Sstevel@tonic-gate return i; 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate } else { 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate writeLog("bad_prop_tag", 10607c478bd9Sstevel@tonic-gate new Object[] { 10617c478bd9Sstevel@tonic-gate "net.slp.maxResults"}); 10627c478bd9Sstevel@tonic-gate 10637c478bd9Sstevel@tonic-gate return Defaults.iMaximumResults; 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate } 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate /** 10697c478bd9Sstevel@tonic-gate * Convert a language tag into a locale. 10707c478bd9Sstevel@tonic-gate */ 10717c478bd9Sstevel@tonic-gate langTagToLocale(String ltag)10727c478bd9Sstevel@tonic-gate static Locale langTagToLocale(String ltag) { 10737c478bd9Sstevel@tonic-gate 10747c478bd9Sstevel@tonic-gate // We treat the first part as the ISO 639 language and the 10757c478bd9Sstevel@tonic-gate // second part as the ISO 3166 country tag, even though RFC 10767c478bd9Sstevel@tonic-gate // 1766 doesn't necessarily require that. We should probably 10777c478bd9Sstevel@tonic-gate // use a lookup table here to determine if they are correct. 10787c478bd9Sstevel@tonic-gate 10797c478bd9Sstevel@tonic-gate StringTokenizer tk = new StringTokenizer(ltag, "-"); 10807c478bd9Sstevel@tonic-gate String lang = ""; 10817c478bd9Sstevel@tonic-gate String country = ""; 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate if (tk.hasMoreTokens()) { 10847c478bd9Sstevel@tonic-gate lang = tk.nextToken(); 10857c478bd9Sstevel@tonic-gate 10867c478bd9Sstevel@tonic-gate if (tk.hasMoreTokens()) { 10877c478bd9Sstevel@tonic-gate country = tk.nextToken(""); 10887c478bd9Sstevel@tonic-gate // country name may have "-" in it... 10897c478bd9Sstevel@tonic-gate 10907c478bd9Sstevel@tonic-gate } 10917c478bd9Sstevel@tonic-gate } 10927c478bd9Sstevel@tonic-gate 10937c478bd9Sstevel@tonic-gate return new Locale(lang, country); 10947c478bd9Sstevel@tonic-gate } 10957c478bd9Sstevel@tonic-gate 10967c478bd9Sstevel@tonic-gate /** 10977c478bd9Sstevel@tonic-gate * Convert a Locale object into a language tag for output. 10987c478bd9Sstevel@tonic-gate * 10997c478bd9Sstevel@tonic-gate * @param locale The Locale. 11007c478bd9Sstevel@tonic-gate * @return String with the language tag encoded. 11017c478bd9Sstevel@tonic-gate */ 11027c478bd9Sstevel@tonic-gate localeToLangTag(Locale locale)11037c478bd9Sstevel@tonic-gate static String localeToLangTag(Locale locale) { 11047c478bd9Sstevel@tonic-gate 11057c478bd9Sstevel@tonic-gate // Construct the language tag. 11067c478bd9Sstevel@tonic-gate 11077c478bd9Sstevel@tonic-gate String ltag = locale.getCountry(); 11087c478bd9Sstevel@tonic-gate ltag = locale.getLanguage() + (ltag.length() <= 0 ? "" : ("-" + ltag)); 11097c478bd9Sstevel@tonic-gate 11107c478bd9Sstevel@tonic-gate return ltag; 11117c478bd9Sstevel@tonic-gate 11127c478bd9Sstevel@tonic-gate } 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate /** 11157c478bd9Sstevel@tonic-gate * @return the language requests will be made in. 11167c478bd9Sstevel@tonic-gate */ getLocale()11177c478bd9Sstevel@tonic-gate static Locale getLocale() { 11187c478bd9Sstevel@tonic-gate String s = System.getProperty("net.slp.locale"); 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate if (s != null && s.length() > 0) { 11217c478bd9Sstevel@tonic-gate return langTagToLocale(s); 11227c478bd9Sstevel@tonic-gate 11237c478bd9Sstevel@tonic-gate } else { 11247c478bd9Sstevel@tonic-gate 11257c478bd9Sstevel@tonic-gate // Return the Java default if the SLP property is not set. 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate return Locale.getDefault(); 11287c478bd9Sstevel@tonic-gate 11297c478bd9Sstevel@tonic-gate } 11307c478bd9Sstevel@tonic-gate } 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate /** 11337c478bd9Sstevel@tonic-gate * @return the InetAddress of the broadcast interface. 11347c478bd9Sstevel@tonic-gate */ 11357c478bd9Sstevel@tonic-gate 11367c478bd9Sstevel@tonic-gate static private InetAddress broadcastAddress; 11377c478bd9Sstevel@tonic-gate getBroadcastAddress()11387c478bd9Sstevel@tonic-gate static InetAddress getBroadcastAddress() { 11397c478bd9Sstevel@tonic-gate if (broadcastAddress == null) { 11407c478bd9Sstevel@tonic-gate 11417c478bd9Sstevel@tonic-gate try { 11427c478bd9Sstevel@tonic-gate broadcastAddress = 11437c478bd9Sstevel@tonic-gate InetAddress.getByName(Defaults.sBroadcast); 11447c478bd9Sstevel@tonic-gate } catch (UnknownHostException uhe) { 11457c478bd9Sstevel@tonic-gate 11467c478bd9Sstevel@tonic-gate Assert.slpassert(false, 11477c478bd9Sstevel@tonic-gate "cast_address_failure", 11487c478bd9Sstevel@tonic-gate new Object[] {Defaults.sBroadcast}); 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate } 11527c478bd9Sstevel@tonic-gate return broadcastAddress; 11537c478bd9Sstevel@tonic-gate } 11547c478bd9Sstevel@tonic-gate 11557c478bd9Sstevel@tonic-gate 11567c478bd9Sstevel@tonic-gate /** 11577c478bd9Sstevel@tonic-gate * @return the InetAddress of the multicast group. 11587c478bd9Sstevel@tonic-gate */ 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate static private InetAddress multicastAddress; 11617c478bd9Sstevel@tonic-gate getMulticastAddress()11627c478bd9Sstevel@tonic-gate static InetAddress getMulticastAddress() { 11637c478bd9Sstevel@tonic-gate if (multicastAddress == null) { 11647c478bd9Sstevel@tonic-gate 11657c478bd9Sstevel@tonic-gate try { 11667c478bd9Sstevel@tonic-gate multicastAddress = 11677c478bd9Sstevel@tonic-gate InetAddress.getByName(Defaults.sGeneralSLPMCAddress); 11687c478bd9Sstevel@tonic-gate } catch (UnknownHostException uhe) { 11697c478bd9Sstevel@tonic-gate Assert.slpassert(false, 11707c478bd9Sstevel@tonic-gate "cast_address_failure", 11717c478bd9Sstevel@tonic-gate new Object[] {Defaults.sGeneralSLPMCAddress}); 11727c478bd9Sstevel@tonic-gate 11737c478bd9Sstevel@tonic-gate } 11747c478bd9Sstevel@tonic-gate } 11757c478bd9Sstevel@tonic-gate return multicastAddress; 11767c478bd9Sstevel@tonic-gate } 11777c478bd9Sstevel@tonic-gate 11787c478bd9Sstevel@tonic-gate /** 11797c478bd9Sstevel@tonic-gate * @return the interfaces on which SLP should listen and transmit. 11807c478bd9Sstevel@tonic-gate */ 11817c478bd9Sstevel@tonic-gate 11827c478bd9Sstevel@tonic-gate private static Vector interfaces = null; 11837c478bd9Sstevel@tonic-gate getInterfaces()11847c478bd9Sstevel@tonic-gate Vector getInterfaces() { 11857c478bd9Sstevel@tonic-gate 11867c478bd9Sstevel@tonic-gate if (interfaces == null) { 11877c478bd9Sstevel@tonic-gate InetAddress iaLocal = null; 11887c478bd9Sstevel@tonic-gate 11897c478bd9Sstevel@tonic-gate // Get local host. 11907c478bd9Sstevel@tonic-gate 11917c478bd9Sstevel@tonic-gate try { 11927c478bd9Sstevel@tonic-gate iaLocal = InetAddress.getLocalHost(); 11937c478bd9Sstevel@tonic-gate 11947c478bd9Sstevel@tonic-gate } catch (UnknownHostException ex) { 11957c478bd9Sstevel@tonic-gate Assert.slpassert(false, 11967c478bd9Sstevel@tonic-gate "resolve_failed", 11977c478bd9Sstevel@tonic-gate new Object[] {"localhost"}); 11987c478bd9Sstevel@tonic-gate } 11997c478bd9Sstevel@tonic-gate 12007c478bd9Sstevel@tonic-gate String mcastI = System.getProperty("net.slp.interfaces"); 12017c478bd9Sstevel@tonic-gate interfaces = new Vector(); 12027c478bd9Sstevel@tonic-gate 12037c478bd9Sstevel@tonic-gate // Only add local host if nothing else is given. 12047c478bd9Sstevel@tonic-gate 12057c478bd9Sstevel@tonic-gate if (mcastI == null || mcastI.length() <= 0) { 12067c478bd9Sstevel@tonic-gate interfaces.addElement(iaLocal); 12077c478bd9Sstevel@tonic-gate return interfaces; 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate } 12107c478bd9Sstevel@tonic-gate 12117c478bd9Sstevel@tonic-gate Vector nintr; 12127c478bd9Sstevel@tonic-gate 12137c478bd9Sstevel@tonic-gate try { 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate nintr = SrvLocHeader.parseCommaSeparatedListIn(mcastI, true); 12167c478bd9Sstevel@tonic-gate 12177c478bd9Sstevel@tonic-gate } catch (ServiceLocationException ex) { 12187c478bd9Sstevel@tonic-gate writeLog("syntax_error_prop", 12197c478bd9Sstevel@tonic-gate new Object[] { 12207c478bd9Sstevel@tonic-gate "net.slp.multicastInterfaces", 12217c478bd9Sstevel@tonic-gate mcastI}); 12227c478bd9Sstevel@tonic-gate 12237c478bd9Sstevel@tonic-gate // Add local host. 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate interfaces.addElement(iaLocal); 1226*55fea89dSDan Cross 12277c478bd9Sstevel@tonic-gate return interfaces; 12287c478bd9Sstevel@tonic-gate 12297c478bd9Sstevel@tonic-gate } 12307c478bd9Sstevel@tonic-gate 12317c478bd9Sstevel@tonic-gate // See if they are really there. 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate int i, n = nintr.size(); 12347c478bd9Sstevel@tonic-gate 12357c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 12367c478bd9Sstevel@tonic-gate InetAddress ia; 12377c478bd9Sstevel@tonic-gate String host = (String)nintr.elementAt(i); 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate try { 12407c478bd9Sstevel@tonic-gate 12417c478bd9Sstevel@tonic-gate ia = InetAddress.getByName(host); 12427c478bd9Sstevel@tonic-gate 12437c478bd9Sstevel@tonic-gate } catch (UnknownHostException ex) { 12447c478bd9Sstevel@tonic-gate writeLog("unknown_interface", 12457c478bd9Sstevel@tonic-gate new Object[] {host, 12467c478bd9Sstevel@tonic-gate "net.slp.multicastInterfaces"}); 12477c478bd9Sstevel@tonic-gate continue; 12487c478bd9Sstevel@tonic-gate 12497c478bd9Sstevel@tonic-gate } 12507c478bd9Sstevel@tonic-gate 12517c478bd9Sstevel@tonic-gate if (!interfaces.contains(ia)) { 12527c478bd9Sstevel@tonic-gate 12537c478bd9Sstevel@tonic-gate // Add default at beginning. 12547c478bd9Sstevel@tonic-gate 12557c478bd9Sstevel@tonic-gate if (ia.equals(iaLocal)) { 12567c478bd9Sstevel@tonic-gate interfaces.insertElementAt(ia, 0); 12577c478bd9Sstevel@tonic-gate 12587c478bd9Sstevel@tonic-gate } else { 12597c478bd9Sstevel@tonic-gate interfaces.addElement(ia); 12607c478bd9Sstevel@tonic-gate 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate } 12637c478bd9Sstevel@tonic-gate } 12647c478bd9Sstevel@tonic-gate } 12657c478bd9Sstevel@tonic-gate 12667c478bd9Sstevel@tonic-gate return interfaces; 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gate } 12697c478bd9Sstevel@tonic-gate 12707c478bd9Sstevel@tonic-gate /** 12717c478bd9Sstevel@tonic-gate * @return An InetAddress object representing 127.0.0.1 12727c478bd9Sstevel@tonic-gate */ getLoopback()12737c478bd9Sstevel@tonic-gate InetAddress getLoopback() { 12747c478bd9Sstevel@tonic-gate InetAddress iaLoopback = null; 12757c478bd9Sstevel@tonic-gate 12767c478bd9Sstevel@tonic-gate try { 12777c478bd9Sstevel@tonic-gate iaLoopback = InetAddress.getByName(Defaults.LOOPBACK_ADDRESS); 12787c478bd9Sstevel@tonic-gate 12797c478bd9Sstevel@tonic-gate } catch (UnknownHostException ex) { 12807c478bd9Sstevel@tonic-gate Assert.slpassert(false, 12817c478bd9Sstevel@tonic-gate "resolve_failed", 12827c478bd9Sstevel@tonic-gate new Object[] {"localhost loopback"}); 12837c478bd9Sstevel@tonic-gate } 12847c478bd9Sstevel@tonic-gate 12857c478bd9Sstevel@tonic-gate return iaLoopback; 12867c478bd9Sstevel@tonic-gate } 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate /** 12897c478bd9Sstevel@tonic-gate * @return The default interface, which should be the first in the 12907c478bd9Sstevel@tonic-gate * interfaces vector Vector. 12917c478bd9Sstevel@tonic-gate */ 12927c478bd9Sstevel@tonic-gate getLocalHost()12937c478bd9Sstevel@tonic-gate InetAddress getLocalHost() { 12947c478bd9Sstevel@tonic-gate Vector inter = getInterfaces(); 12957c478bd9Sstevel@tonic-gate return (InetAddress)inter.elementAt(0); 12967c478bd9Sstevel@tonic-gate 12977c478bd9Sstevel@tonic-gate } 12987c478bd9Sstevel@tonic-gate 12997c478bd9Sstevel@tonic-gate // Return true if the address is one of the local interfaces. 13007c478bd9Sstevel@tonic-gate isLocalHostSource(InetAddress addr)13017c478bd9Sstevel@tonic-gate boolean isLocalHostSource(InetAddress addr) { 13027c478bd9Sstevel@tonic-gate 13037c478bd9Sstevel@tonic-gate // First check loopback 13047c478bd9Sstevel@tonic-gate 13057c478bd9Sstevel@tonic-gate if (addr.equals(getLoopback())) { 13067c478bd9Sstevel@tonic-gate return true; 13077c478bd9Sstevel@tonic-gate 13087c478bd9Sstevel@tonic-gate } 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gate return interfaces.contains(addr); 13117c478bd9Sstevel@tonic-gate 13127c478bd9Sstevel@tonic-gate } 13137c478bd9Sstevel@tonic-gate 13147c478bd9Sstevel@tonic-gate // ----------------- 13157c478bd9Sstevel@tonic-gate // Timeouts 13167c478bd9Sstevel@tonic-gate // 13177c478bd9Sstevel@tonic-gate 13187c478bd9Sstevel@tonic-gate // Return the maximum wait for multicast convergence. 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate final static private int iMultiMin = 1000; // one second 13217c478bd9Sstevel@tonic-gate final static private int iMultiMax = 60000; // one minute 13227c478bd9Sstevel@tonic-gate getMulticastMaximumWait()13237c478bd9Sstevel@tonic-gate int getMulticastMaximumWait() { 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate return getIntProperty("net.slp.multicastMaximumWait", 13267c478bd9Sstevel@tonic-gate Defaults.iMulticastMaxWait, 13277c478bd9Sstevel@tonic-gate iMultiMin, 13287c478bd9Sstevel@tonic-gate iMultiMax); 13297c478bd9Sstevel@tonic-gate } 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate /* 13327c478bd9Sstevel@tonic-gate * @return Vector of timeouts for multicast convergence. 13337c478bd9Sstevel@tonic-gate */ 13347c478bd9Sstevel@tonic-gate getMulticastTimeouts()13357c478bd9Sstevel@tonic-gate int[] getMulticastTimeouts() { 13367c478bd9Sstevel@tonic-gate int[] timeouts = parseTimeouts("net.slp.multicastTimeouts", 13377c478bd9Sstevel@tonic-gate Defaults.a_iConvergeTimeout); 13387c478bd9Sstevel@tonic-gate 13397c478bd9Sstevel@tonic-gate timeouts = capTimeouts("net.slp.multicastTimeouts", 13407c478bd9Sstevel@tonic-gate timeouts, 13417c478bd9Sstevel@tonic-gate false, 13427c478bd9Sstevel@tonic-gate 0, 13437c478bd9Sstevel@tonic-gate 0); 13447c478bd9Sstevel@tonic-gate 13457c478bd9Sstevel@tonic-gate return timeouts; 13467c478bd9Sstevel@tonic-gate } 13477c478bd9Sstevel@tonic-gate 13487c478bd9Sstevel@tonic-gate /** 13497c478bd9Sstevel@tonic-gate * @return Vector of timeouts to try for datagram transmission. 13507c478bd9Sstevel@tonic-gate */ 13517c478bd9Sstevel@tonic-gate getDatagramTimeouts()13527c478bd9Sstevel@tonic-gate int[] getDatagramTimeouts() { 13537c478bd9Sstevel@tonic-gate int[] timeouts = parseTimeouts("net.slp.datagramTimeouts", 13547c478bd9Sstevel@tonic-gate Defaults.a_iDatagramTimeout); 13557c478bd9Sstevel@tonic-gate 13567c478bd9Sstevel@tonic-gate timeouts = capTimeouts("net.slp.datagramTimeouts", 13577c478bd9Sstevel@tonic-gate timeouts, 13587c478bd9Sstevel@tonic-gate true, 13597c478bd9Sstevel@tonic-gate iMultiMin, 13607c478bd9Sstevel@tonic-gate iMultiMax); 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate return timeouts; 13637c478bd9Sstevel@tonic-gate } 13647c478bd9Sstevel@tonic-gate 13657c478bd9Sstevel@tonic-gate /** 13667c478bd9Sstevel@tonic-gate * @return Vector of timeouts for DA discovery multicast. 13677c478bd9Sstevel@tonic-gate */ 13687c478bd9Sstevel@tonic-gate getDADiscoveryTimeouts()13697c478bd9Sstevel@tonic-gate int[] getDADiscoveryTimeouts() { 13707c478bd9Sstevel@tonic-gate int[] timeouts = parseTimeouts("net.slp.DADiscoveryTimeouts", 13717c478bd9Sstevel@tonic-gate Defaults.a_iDADiscoveryTimeout); 13727c478bd9Sstevel@tonic-gate 13737c478bd9Sstevel@tonic-gate timeouts = capTimeouts("net.slp.DADiscoveryTimeouts", 13747c478bd9Sstevel@tonic-gate timeouts, 13757c478bd9Sstevel@tonic-gate false, 13767c478bd9Sstevel@tonic-gate 0, 13777c478bd9Sstevel@tonic-gate 0); 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate return timeouts; 13807c478bd9Sstevel@tonic-gate } 13817c478bd9Sstevel@tonic-gate 13827c478bd9Sstevel@tonic-gate /** 13837c478bd9Sstevel@tonic-gate * This method ensures that all the timeouts are within valid ranges. 13847c478bd9Sstevel@tonic-gate * The sum of all timeouts for the given property name must not 13857c478bd9Sstevel@tonic-gate * exceed the value returned by <i>getMulticastMaximumWait()</i>. If 13867c478bd9Sstevel@tonic-gate * the sum of all timeouts does exceed the maximum wait period the 13877c478bd9Sstevel@tonic-gate * timeouts are averaged out so that the sum equals the maximum wait 13887c478bd9Sstevel@tonic-gate * period. 13897c478bd9Sstevel@tonic-gate * <br> 13907c478bd9Sstevel@tonic-gate * Additional range checking is also performed when <i>rangeCheck</i> 13917c478bd9Sstevel@tonic-gate * is true. Then the sum of all timeouts must also be between <i>min</i> 13927c478bd9Sstevel@tonic-gate * and <i>max</i>. If the sum of all timeouts is not within the range 13937c478bd9Sstevel@tonic-gate * the average is taken from the closest range boundary. 13947c478bd9Sstevel@tonic-gate * 13957c478bd9Sstevel@tonic-gate * @param property 13967c478bd9Sstevel@tonic-gate * Name of timeout property being capped. This is only present for 13977c478bd9Sstevel@tonic-gate * reporting purposes and no actual manipulation of the property 13987c478bd9Sstevel@tonic-gate * is made within this method. 13997c478bd9Sstevel@tonic-gate * @param timeouts 14007c478bd9Sstevel@tonic-gate * Array of timeout values. 14017c478bd9Sstevel@tonic-gate * @param rangeCheck 14027c478bd9Sstevel@tonic-gate * Indicator of whether additional range checking is required. When 14037c478bd9Sstevel@tonic-gate * false <i>min</i> and <i>max</i> are ignored. 14047c478bd9Sstevel@tonic-gate * @param min 14057c478bd9Sstevel@tonic-gate * Additional range checking lower boundary. 14067c478bd9Sstevel@tonic-gate * @param max 14077c478bd9Sstevel@tonic-gate * Additional range checking upper boundary. 14087c478bd9Sstevel@tonic-gate * @return 14097c478bd9Sstevel@tonic-gate * Array of capped timeouts. Note this may be the same array as 14107c478bd9Sstevel@tonic-gate * passed in (<i>timeouts</i>). 14117c478bd9Sstevel@tonic-gate */ capTimeouts(String property, int[] timeouts, boolean rangeCheck, int min, int max)14127c478bd9Sstevel@tonic-gate private int[] capTimeouts(String property, 14137c478bd9Sstevel@tonic-gate int[] timeouts, 14147c478bd9Sstevel@tonic-gate boolean rangeCheck, 14157c478bd9Sstevel@tonic-gate int min, 14167c478bd9Sstevel@tonic-gate int max) { 14177c478bd9Sstevel@tonic-gate 14187c478bd9Sstevel@tonic-gate int averagedTimeout; 14197c478bd9Sstevel@tonic-gate int totalWait = 0; 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate for (int index = 0; index < timeouts.length; index++) { 14227c478bd9Sstevel@tonic-gate totalWait += timeouts[index]; 14237c478bd9Sstevel@tonic-gate } 14247c478bd9Sstevel@tonic-gate 14257c478bd9Sstevel@tonic-gate if (rangeCheck) { 14267c478bd9Sstevel@tonic-gate // If sum of timeouts within limits then finished. 14277c478bd9Sstevel@tonic-gate if (totalWait >= min && totalWait <= max) { 14287c478bd9Sstevel@tonic-gate return timeouts; 14297c478bd9Sstevel@tonic-gate } 14307c478bd9Sstevel@tonic-gate 14317c478bd9Sstevel@tonic-gate // Average out the timeouts so the sum is equal to the closest 14327c478bd9Sstevel@tonic-gate // range boundary. 14337c478bd9Sstevel@tonic-gate if (totalWait < min) { 14347c478bd9Sstevel@tonic-gate averagedTimeout = min / timeouts.length; 14357c478bd9Sstevel@tonic-gate } else { 14367c478bd9Sstevel@tonic-gate averagedTimeout = max / timeouts.length; 14377c478bd9Sstevel@tonic-gate } 14387c478bd9Sstevel@tonic-gate 14397c478bd9Sstevel@tonic-gate writeLog("capped_range_timeout_prop", 14407c478bd9Sstevel@tonic-gate new Object[] {property, 14417c478bd9Sstevel@tonic-gate String.valueOf(totalWait), 14427c478bd9Sstevel@tonic-gate String.valueOf(min), 14437c478bd9Sstevel@tonic-gate String.valueOf(max), 14447c478bd9Sstevel@tonic-gate String.valueOf(timeouts.length), 14457c478bd9Sstevel@tonic-gate String.valueOf(averagedTimeout)}); 14467c478bd9Sstevel@tonic-gate } else { 14477c478bd9Sstevel@tonic-gate // Sum of all timeouts must not exceed this value. 14487c478bd9Sstevel@tonic-gate int maximumWait = getMulticastMaximumWait(); 14497c478bd9Sstevel@tonic-gate 14507c478bd9Sstevel@tonic-gate // If sum of timeouts within limits then finished. 14517c478bd9Sstevel@tonic-gate if (totalWait <= maximumWait) { 14527c478bd9Sstevel@tonic-gate return timeouts; 14537c478bd9Sstevel@tonic-gate } 14547c478bd9Sstevel@tonic-gate 14557c478bd9Sstevel@tonic-gate // Average out the timeouts so the sum is equal to the maximum 14567c478bd9Sstevel@tonic-gate // timeout. 14577c478bd9Sstevel@tonic-gate averagedTimeout = maximumWait / timeouts.length; 14587c478bd9Sstevel@tonic-gate 14597c478bd9Sstevel@tonic-gate writeLog("capped_timeout_prop", 14607c478bd9Sstevel@tonic-gate new Object[] {property, 14617c478bd9Sstevel@tonic-gate String.valueOf(totalWait), 14627c478bd9Sstevel@tonic-gate String.valueOf(maximumWait), 14637c478bd9Sstevel@tonic-gate String.valueOf(timeouts.length), 14647c478bd9Sstevel@tonic-gate String.valueOf(averagedTimeout)}); 14657c478bd9Sstevel@tonic-gate } 14667c478bd9Sstevel@tonic-gate 14677c478bd9Sstevel@tonic-gate for (int index = 0; index < timeouts.length; index++) { 14687c478bd9Sstevel@tonic-gate timeouts[index] = averagedTimeout; 14697c478bd9Sstevel@tonic-gate } 14707c478bd9Sstevel@tonic-gate 14717c478bd9Sstevel@tonic-gate return timeouts; 14727c478bd9Sstevel@tonic-gate } 14737c478bd9Sstevel@tonic-gate parseTimeouts(String property, int[] defaults)14747c478bd9Sstevel@tonic-gate private int[] parseTimeouts(String property, int[] defaults) { 14757c478bd9Sstevel@tonic-gate 14767c478bd9Sstevel@tonic-gate String sTimeouts = System.getProperty(property); 14777c478bd9Sstevel@tonic-gate 14787c478bd9Sstevel@tonic-gate if (sTimeouts == null || sTimeouts.length() <= 0) { 14797c478bd9Sstevel@tonic-gate return defaults; 14807c478bd9Sstevel@tonic-gate 14817c478bd9Sstevel@tonic-gate } 14827c478bd9Sstevel@tonic-gate 14837c478bd9Sstevel@tonic-gate Vector timeouts = null; 14847c478bd9Sstevel@tonic-gate 14857c478bd9Sstevel@tonic-gate try { 14867c478bd9Sstevel@tonic-gate timeouts = SrvLocHeader.parseCommaSeparatedListIn(sTimeouts, true); 14877c478bd9Sstevel@tonic-gate 14887c478bd9Sstevel@tonic-gate } catch (ServiceLocationException ex) { 14897c478bd9Sstevel@tonic-gate writeLog("syntax_error_prop", 14907c478bd9Sstevel@tonic-gate new Object[] {property, sTimeouts}); 14917c478bd9Sstevel@tonic-gate return defaults; 14927c478bd9Sstevel@tonic-gate 14937c478bd9Sstevel@tonic-gate } 14947c478bd9Sstevel@tonic-gate 14957c478bd9Sstevel@tonic-gate int iCount = 0; 14967c478bd9Sstevel@tonic-gate int[] iTOs = new int[timeouts.size()]; 14977c478bd9Sstevel@tonic-gate 14987c478bd9Sstevel@tonic-gate for (Enumeration en = timeouts.elements(); en.hasMoreElements(); ) { 14997c478bd9Sstevel@tonic-gate String s1 = (String)en.nextElement(); 15007c478bd9Sstevel@tonic-gate 15017c478bd9Sstevel@tonic-gate try { 15027c478bd9Sstevel@tonic-gate iTOs[iCount] = Integer.parseInt(s1); 15037c478bd9Sstevel@tonic-gate 15047c478bd9Sstevel@tonic-gate } catch (NumberFormatException nfe) { 15057c478bd9Sstevel@tonic-gate writeLog("syntax_error_prop", 15067c478bd9Sstevel@tonic-gate new Object[] {property, sTimeouts}); 15077c478bd9Sstevel@tonic-gate return defaults; 15087c478bd9Sstevel@tonic-gate 15097c478bd9Sstevel@tonic-gate } 15107c478bd9Sstevel@tonic-gate 15117c478bd9Sstevel@tonic-gate if (iTOs[iCount] < 0) { 15127c478bd9Sstevel@tonic-gate writeLog("invalid_timeout_prop", 15137c478bd9Sstevel@tonic-gate new Object[] {property, String.valueOf(iTOs[iCount])}); 15147c478bd9Sstevel@tonic-gate return defaults; 15157c478bd9Sstevel@tonic-gate } 15167c478bd9Sstevel@tonic-gate 15177c478bd9Sstevel@tonic-gate iCount++; 15187c478bd9Sstevel@tonic-gate } 15197c478bd9Sstevel@tonic-gate 15207c478bd9Sstevel@tonic-gate return iTOs; 15217c478bd9Sstevel@tonic-gate } 15227c478bd9Sstevel@tonic-gate 15237c478bd9Sstevel@tonic-gate // ----------------------------- 15247c478bd9Sstevel@tonic-gate // SLP Time Calculation 15257c478bd9Sstevel@tonic-gate // 15267c478bd9Sstevel@tonic-gate 15277c478bd9Sstevel@tonic-gate /** 15287c478bd9Sstevel@tonic-gate * Returns the number of seconds since 00:00 Universal Coordinated 15297c478bd9Sstevel@tonic-gate * Time, January 1, 1970. 15307c478bd9Sstevel@tonic-gate * 15317c478bd9Sstevel@tonic-gate * Java returns the number of milliseconds, so all the method does is 15327c478bd9Sstevel@tonic-gate * divide by 1000. 15337c478bd9Sstevel@tonic-gate * 15347c478bd9Sstevel@tonic-gate * This implementation still will have a problem when the Java time 15357c478bd9Sstevel@tonic-gate * values wraps, but there isn't much we can do now. 15367c478bd9Sstevel@tonic-gate */ currentSLPTime()15377c478bd9Sstevel@tonic-gate static long currentSLPTime() { 15387c478bd9Sstevel@tonic-gate return (System.currentTimeMillis() / 1000); 15397c478bd9Sstevel@tonic-gate } 15407c478bd9Sstevel@tonic-gate 15417c478bd9Sstevel@tonic-gate /* security */ 15427c478bd9Sstevel@tonic-gate 15437c478bd9Sstevel@tonic-gate // Indicates whether security class is available. 15447c478bd9Sstevel@tonic-gate getSecurityEnabled()15457c478bd9Sstevel@tonic-gate boolean getSecurityEnabled() { 15467c478bd9Sstevel@tonic-gate return securityEnabled; 15477c478bd9Sstevel@tonic-gate 15487c478bd9Sstevel@tonic-gate } 15497c478bd9Sstevel@tonic-gate 15507c478bd9Sstevel@tonic-gate private static boolean securityEnabled; 15517c478bd9Sstevel@tonic-gate 15527c478bd9Sstevel@tonic-gate // Indicates whether the securityEnabled property is true 15537c478bd9Sstevel@tonic-gate getHasSecurity()15547c478bd9Sstevel@tonic-gate boolean getHasSecurity() { 15557c478bd9Sstevel@tonic-gate return securityEnabled && 15567c478bd9Sstevel@tonic-gate (new Boolean(System.getProperty("net.slp.securityEnabled", 15577c478bd9Sstevel@tonic-gate "false")).booleanValue()); 15587c478bd9Sstevel@tonic-gate } 15597c478bd9Sstevel@tonic-gate 15607c478bd9Sstevel@tonic-gate // I18N Support. 15617c478bd9Sstevel@tonic-gate 15627c478bd9Sstevel@tonic-gate private static final String BASE_BUNDLE_NAME = "com/sun/slp/ClientLib"; 15637c478bd9Sstevel@tonic-gate getMessageBundle(Locale locale)15647c478bd9Sstevel@tonic-gate ResourceBundle getMessageBundle(Locale locale) { 15657c478bd9Sstevel@tonic-gate 15667c478bd9Sstevel@tonic-gate ResourceBundle msgBundle = null; 15677c478bd9Sstevel@tonic-gate 15687c478bd9Sstevel@tonic-gate // First try the Solaris Java locale area 15697c478bd9Sstevel@tonic-gate 15707c478bd9Sstevel@tonic-gate try { 15717c478bd9Sstevel@tonic-gate URL[] urls = new URL[] {new URL("file:/usr/share/lib/locale/")}; 15727c478bd9Sstevel@tonic-gate 15737c478bd9Sstevel@tonic-gate URLClassLoader ld = new URLClassLoader(urls); 15747c478bd9Sstevel@tonic-gate 15757c478bd9Sstevel@tonic-gate msgBundle = ResourceBundle.getBundle(BASE_BUNDLE_NAME, locale, ld); 15767c478bd9Sstevel@tonic-gate 15777c478bd9Sstevel@tonic-gate return msgBundle; 15787c478bd9Sstevel@tonic-gate } catch (MalformedURLException e) { // shouldn't get here 15797c478bd9Sstevel@tonic-gate } catch (MissingResourceException ex) { 15807c478bd9Sstevel@tonic-gate System.err.println("Missing resource bundle ``"+ 15817c478bd9Sstevel@tonic-gate "/usr/share/lib/locale/" + BASE_BUNDLE_NAME + 15827c478bd9Sstevel@tonic-gate "'' for locale ``" + 15837c478bd9Sstevel@tonic-gate locale + "''; trying default..."); 15847c478bd9Sstevel@tonic-gate } 15857c478bd9Sstevel@tonic-gate 15867c478bd9Sstevel@tonic-gate try { 15877c478bd9Sstevel@tonic-gate msgBundle = ResourceBundle.getBundle(BASE_BUNDLE_NAME, locale); 15887c478bd9Sstevel@tonic-gate 15897c478bd9Sstevel@tonic-gate } catch (MissingResourceException ex) { // can't localize this one! 15907c478bd9Sstevel@tonic-gate 15917c478bd9Sstevel@tonic-gate // We can't print out to the log, because we may be in the 15927c478bd9Sstevel@tonic-gate // process of trying to. 15937c478bd9Sstevel@tonic-gate 15947c478bd9Sstevel@tonic-gate System.err.println("Missing resource bundle ``"+ 15957c478bd9Sstevel@tonic-gate BASE_BUNDLE_NAME+ 15967c478bd9Sstevel@tonic-gate "'' for locale ``"+ 15977c478bd9Sstevel@tonic-gate locale+ 15987c478bd9Sstevel@tonic-gate "''"); 15997c478bd9Sstevel@tonic-gate // Hosed if the default locale is missing. 16007c478bd9Sstevel@tonic-gate 16017c478bd9Sstevel@tonic-gate if (locale.equals(Defaults.locale)) { 16027c478bd9Sstevel@tonic-gate 16037c478bd9Sstevel@tonic-gate System.err.println("Exiting..."); 16047c478bd9Sstevel@tonic-gate System.exit(1); 16057c478bd9Sstevel@tonic-gate } 16067c478bd9Sstevel@tonic-gate 16077c478bd9Sstevel@tonic-gate // Otherwise, return the default locale. 16087c478bd9Sstevel@tonic-gate 16097c478bd9Sstevel@tonic-gate System.err.println("Using SLP default locale ``" + 16107c478bd9Sstevel@tonic-gate Defaults.locale + 16117c478bd9Sstevel@tonic-gate "''"); 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate msgBundle = getMessageBundle(Defaults.locale); 16147c478bd9Sstevel@tonic-gate 16157c478bd9Sstevel@tonic-gate } 16167c478bd9Sstevel@tonic-gate 16177c478bd9Sstevel@tonic-gate return msgBundle; 16187c478bd9Sstevel@tonic-gate } 16197c478bd9Sstevel@tonic-gate formatMessage(String msgTag, Object[] params)16207c478bd9Sstevel@tonic-gate String formatMessage(String msgTag, Object[] params) { 16217c478bd9Sstevel@tonic-gate ResourceBundle bundle = getMessageBundle(getLocale()); 16227c478bd9Sstevel@tonic-gate return formatMessageInternal(msgTag, params, bundle); 16237c478bd9Sstevel@tonic-gate 16247c478bd9Sstevel@tonic-gate } 16257c478bd9Sstevel@tonic-gate 16267c478bd9Sstevel@tonic-gate // MessageFormat is picky about types. Convert the params into strings. 16277c478bd9Sstevel@tonic-gate convertToString(Object[] params)16287c478bd9Sstevel@tonic-gate static void convertToString(Object[] params) { 16297c478bd9Sstevel@tonic-gate int i, n = params.length; 16307c478bd9Sstevel@tonic-gate 16317c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 16327c478bd9Sstevel@tonic-gate 16337c478bd9Sstevel@tonic-gate if (params[i] != null) { 16347c478bd9Sstevel@tonic-gate params[i] = params[i].toString(); 16357c478bd9Sstevel@tonic-gate 16367c478bd9Sstevel@tonic-gate } else { 16377c478bd9Sstevel@tonic-gate params[i] = "<null>"; 16387c478bd9Sstevel@tonic-gate 16397c478bd9Sstevel@tonic-gate } 16407c478bd9Sstevel@tonic-gate } 16417c478bd9Sstevel@tonic-gate } 16427c478bd9Sstevel@tonic-gate 16437c478bd9Sstevel@tonic-gate static String formatMessageInternal(String msgTag, Object[] params, ResourceBundle bundle)16447c478bd9Sstevel@tonic-gate formatMessageInternal(String msgTag, 16457c478bd9Sstevel@tonic-gate Object[] params, 16467c478bd9Sstevel@tonic-gate ResourceBundle bundle) { 16477c478bd9Sstevel@tonic-gate String pattern = ""; 16487c478bd9Sstevel@tonic-gate 16497c478bd9Sstevel@tonic-gate try { 16507c478bd9Sstevel@tonic-gate pattern = bundle.getString(msgTag); 16517c478bd9Sstevel@tonic-gate 16527c478bd9Sstevel@tonic-gate } catch (MissingResourceException ex) { 16537c478bd9Sstevel@tonic-gate 16547c478bd9Sstevel@tonic-gate // Attempt to report error. Can't use Assert here because it 16557c478bd9Sstevel@tonic-gate // calls back into SLPConfig. 16567c478bd9Sstevel@tonic-gate String msg = "Can''t find message ``{0}''''."; 16577c478bd9Sstevel@tonic-gate 16587c478bd9Sstevel@tonic-gate try { 16597c478bd9Sstevel@tonic-gate pattern = bundle.getString("cant_find_resource"); 16607c478bd9Sstevel@tonic-gate msg = MessageFormat.format(pattern, new Object[] {msgTag}); 1661*55fea89dSDan Cross 16627c478bd9Sstevel@tonic-gate } catch (MissingResourceException exx) { 16637c478bd9Sstevel@tonic-gate 16647c478bd9Sstevel@tonic-gate } 16657c478bd9Sstevel@tonic-gate 16667c478bd9Sstevel@tonic-gate System.err.println(msg); 16677c478bd9Sstevel@tonic-gate System.exit(-1); 16687c478bd9Sstevel@tonic-gate } 16697c478bd9Sstevel@tonic-gate 16707c478bd9Sstevel@tonic-gate convertToString(params); 16717c478bd9Sstevel@tonic-gate 16727c478bd9Sstevel@tonic-gate return MessageFormat.format(pattern, params); 16737c478bd9Sstevel@tonic-gate } 16747c478bd9Sstevel@tonic-gate 16757c478bd9Sstevel@tonic-gate // logging. 16767c478bd9Sstevel@tonic-gate 16777c478bd9Sstevel@tonic-gate // Protected so slpd can replace it. 16787c478bd9Sstevel@tonic-gate 16797c478bd9Sstevel@tonic-gate protected Writer log; 16807c478bd9Sstevel@tonic-gate 16817c478bd9Sstevel@tonic-gate // Synchronized so writes from multiple threads don't get interleaved. 16827c478bd9Sstevel@tonic-gate writeLog(String msgTag, Object[] params)16837c478bd9Sstevel@tonic-gate void writeLog(String msgTag, Object[] params) { 16847c478bd9Sstevel@tonic-gate 16857c478bd9Sstevel@tonic-gate // MessageFormat is picky about types. Convert the params into strings. 16867c478bd9Sstevel@tonic-gate 16877c478bd9Sstevel@tonic-gate convertToString(params); 16887c478bd9Sstevel@tonic-gate 16897c478bd9Sstevel@tonic-gate try { 16907c478bd9Sstevel@tonic-gate synchronized (log) { 16917c478bd9Sstevel@tonic-gate log.write(formatMessage(msgTag, params)); 16927c478bd9Sstevel@tonic-gate log.flush(); 16937c478bd9Sstevel@tonic-gate } 16947c478bd9Sstevel@tonic-gate } catch (IOException ex) {} 16957c478bd9Sstevel@tonic-gate } 16967c478bd9Sstevel@tonic-gate writeLogLine(String msgTag, Object[] params)16977c478bd9Sstevel@tonic-gate void writeLogLine(String msgTag, Object[] params) { 16987c478bd9Sstevel@tonic-gate 16997c478bd9Sstevel@tonic-gate try { 17007c478bd9Sstevel@tonic-gate String pattern = getMessageBundle(getLocale()).getString(msgTag); 17017c478bd9Sstevel@tonic-gate 17027c478bd9Sstevel@tonic-gate synchronized (log) { 17037c478bd9Sstevel@tonic-gate log.write(formatMessage(msgTag, params)); 17047c478bd9Sstevel@tonic-gate log.write("\n"); 17057c478bd9Sstevel@tonic-gate log.flush(); 17067c478bd9Sstevel@tonic-gate } 17077c478bd9Sstevel@tonic-gate } catch (IOException ex) {} 17087c478bd9Sstevel@tonic-gate 17097c478bd9Sstevel@tonic-gate } 17107c478bd9Sstevel@tonic-gate getDateString()17117c478bd9Sstevel@tonic-gate static String getDateString() { 17127c478bd9Sstevel@tonic-gate 17137c478bd9Sstevel@tonic-gate DateFormat df = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, 17147c478bd9Sstevel@tonic-gate DateFormat.DEFAULT, 17157c478bd9Sstevel@tonic-gate getLocale()); 17167c478bd9Sstevel@tonic-gate Calendar calendar = Calendar.getInstance(getLocale()); 17177c478bd9Sstevel@tonic-gate return df.format(calendar.getTime()); 17187c478bd9Sstevel@tonic-gate 17197c478bd9Sstevel@tonic-gate } 17207c478bd9Sstevel@tonic-gate 17217c478bd9Sstevel@tonic-gate 17227c478bd9Sstevel@tonic-gate // On load, check whether the signature class is available, and turn 17237c478bd9Sstevel@tonic-gate // security off if not. 17247c478bd9Sstevel@tonic-gate 17257c478bd9Sstevel@tonic-gate static { 17267c478bd9Sstevel@tonic-gate 17277c478bd9Sstevel@tonic-gate securityEnabled = true; 17287c478bd9Sstevel@tonic-gate try { 17297c478bd9Sstevel@tonic-gate Class c = Class.forName("com.sun.slp.AuthBlock"); 17307c478bd9Sstevel@tonic-gate 17317c478bd9Sstevel@tonic-gate } catch (ClassNotFoundException e) { 17327c478bd9Sstevel@tonic-gate securityEnabled = false; 17337c478bd9Sstevel@tonic-gate } 17347c478bd9Sstevel@tonic-gate } 17357c478bd9Sstevel@tonic-gate 17367c478bd9Sstevel@tonic-gate } 1737