10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7298SMark.J.Nelson@Sun.COM * Common Development and Distribution License (the "License"). 6*7298SMark.J.Nelson@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 220Sstevel@tonic-gate * Copyright (c) 1999 by Sun Microsystems, Inc. 230Sstevel@tonic-gate * All rights reserved. 240Sstevel@tonic-gate * 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate // CDAAdvert.java: Message class for SLP CDAAdvert message 280Sstevel@tonic-gate // Author: James Kempf 290Sstevel@tonic-gate // Created On: Fri Oct 10 10:48:05 1997 300Sstevel@tonic-gate // Last Modified By: James Kempf 310Sstevel@tonic-gate // Last Modified On: Fri Jan 29 09:24:50 1999 320Sstevel@tonic-gate // Update Count: 134 330Sstevel@tonic-gate // 340Sstevel@tonic-gate 350Sstevel@tonic-gate package com.sun.slp; 360Sstevel@tonic-gate 370Sstevel@tonic-gate import java.util.*; 380Sstevel@tonic-gate import java.io.*; 390Sstevel@tonic-gate 400Sstevel@tonic-gate 410Sstevel@tonic-gate /** 420Sstevel@tonic-gate * The CDAAdvert class models the SLP DAAdvert message, client side. 430Sstevel@tonic-gate * We need to accommodate SLPv1 by using an initialize() method. 440Sstevel@tonic-gate * 450Sstevel@tonic-gate * @author James Kempf 460Sstevel@tonic-gate */ 470Sstevel@tonic-gate 480Sstevel@tonic-gate 490Sstevel@tonic-gate class CDAAdvert extends SrvLocMsgImpl { 500Sstevel@tonic-gate 510Sstevel@tonic-gate ServiceURL URL = null; // The DA's service URL 520Sstevel@tonic-gate long timestamp = 0; // timestamp. 530Sstevel@tonic-gate Vector attrs = new Vector(); // Attributes 540Sstevel@tonic-gate Hashtable authBlock = null; // Scope auth blocks. 550Sstevel@tonic-gate String spis = null; // Supported SPIs 560Sstevel@tonic-gate 570Sstevel@tonic-gate // Construct a CDAAdvert from the input stream. 580Sstevel@tonic-gate CDAAdvert(SrvLocHeader hdr, DataInputStream dis)590Sstevel@tonic-gate CDAAdvert(SrvLocHeader hdr, DataInputStream dis) 600Sstevel@tonic-gate throws ServiceLocationException, IOException { 610Sstevel@tonic-gate super(hdr, SrvLocHeader.DAAdvert); 620Sstevel@tonic-gate 630Sstevel@tonic-gate this.initialize(dis); 640Sstevel@tonic-gate 650Sstevel@tonic-gate } 660Sstevel@tonic-gate 670Sstevel@tonic-gate // Initialize the object from the input stream. 680Sstevel@tonic-gate initialize(DataInputStream dis)690Sstevel@tonic-gate protected void initialize(DataInputStream dis) 700Sstevel@tonic-gate throws ServiceLocationException, IOException { 710Sstevel@tonic-gate 720Sstevel@tonic-gate SLPHeaderV2 hdr = (SLPHeaderV2)getHeader(); 730Sstevel@tonic-gate 740Sstevel@tonic-gate // Parse in the timestamp. Save bytes for auth block. 750Sstevel@tonic-gate 760Sstevel@tonic-gate byte[] tsBytes = new byte[4]; 770Sstevel@tonic-gate 780Sstevel@tonic-gate timestamp = getInt32(hdr, dis, tsBytes); 790Sstevel@tonic-gate 800Sstevel@tonic-gate // Parse in DA's service URL. 810Sstevel@tonic-gate 820Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 830Sstevel@tonic-gate 840Sstevel@tonic-gate byte[] urlBytes = hdr.getString(buf, dis); 850Sstevel@tonic-gate 860Sstevel@tonic-gate int lifetime = getDAURLLifetime(); 870Sstevel@tonic-gate 880Sstevel@tonic-gate String surl = buf.toString(); 890Sstevel@tonic-gate 900Sstevel@tonic-gate // Parse in the scope list. 910Sstevel@tonic-gate 920Sstevel@tonic-gate byte[] scopeBytes = hdr.getString(buf, dis); 930Sstevel@tonic-gate 940Sstevel@tonic-gate hdr.scopes = hdr.parseCommaSeparatedListIn(buf.toString(), true); 950Sstevel@tonic-gate 960Sstevel@tonic-gate // Unescape scope strigns. 970Sstevel@tonic-gate 980Sstevel@tonic-gate hdr.unescapeScopeStrings(hdr.scopes); 990Sstevel@tonic-gate 1000Sstevel@tonic-gate // Validate scope list. 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate DATable.validateScopes(hdr.scopes, hdr.locale); 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate // Parse in attribute list. 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate byte[] attrBytes = hdr.parseAttributeVectorIn(attrs, dis, false); 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate // Parse in the SPI list 1090Sstevel@tonic-gate byte[] spiBytes = hdr.getString(buf, dis); 1100Sstevel@tonic-gate spis = buf.toString(); 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate // Construct bytes for auth. 1130Sstevel@tonic-gate Object[] message = new Object[9]; 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate message[0] = tsBytes; 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate // None of the strings have leading length fields, so add them here 1180Sstevel@tonic-gate ByteArrayOutputStream abaos = new ByteArrayOutputStream(); 1190Sstevel@tonic-gate hdr.putInteger(urlBytes.length, abaos); 1200Sstevel@tonic-gate message[1] = abaos.toByteArray(); 1210Sstevel@tonic-gate message[2] = urlBytes; 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate abaos = new ByteArrayOutputStream(); 1240Sstevel@tonic-gate hdr.putInteger(attrBytes.length, abaos); 1250Sstevel@tonic-gate message[3] = abaos.toByteArray(); 1260Sstevel@tonic-gate message[4] = attrBytes; 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate abaos = new ByteArrayOutputStream(); 1290Sstevel@tonic-gate hdr.putInteger(scopeBytes.length, abaos); 1300Sstevel@tonic-gate message[5] = abaos.toByteArray(); 1310Sstevel@tonic-gate message[6] = scopeBytes; 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate abaos = new ByteArrayOutputStream(); 1340Sstevel@tonic-gate hdr.putInteger(spiBytes.length, abaos); 1350Sstevel@tonic-gate message[7] = abaos.toByteArray(); 1360Sstevel@tonic-gate message[8] = spiBytes; 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate // Parse in an auth block, if there. 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate authBlock = hdr.parseSignatureIn(message, dis); 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate if (authBlock != null) { 1430Sstevel@tonic-gate lifetime = AuthBlock.getShortestLifetime(authBlock); 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate } 1460Sstevel@tonic-gate 1470Sstevel@tonic-gate // Create URL. 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate try { 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate URL = new ServiceURL(surl, lifetime); 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate } catch (IllegalArgumentException ex) { 1540Sstevel@tonic-gate 1550Sstevel@tonic-gate throw 1560Sstevel@tonic-gate new ServiceLocationException( 1570Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 1580Sstevel@tonic-gate "malformed_url", 1590Sstevel@tonic-gate new Object[] {ex.getMessage()}); 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate } 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate // Validate the service URL. 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate ServiceType serviceType = URL.getServiceType(); 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate if (!serviceType.equals(Defaults.DA_SERVICE_TYPE)) { 1680Sstevel@tonic-gate throw 1690Sstevel@tonic-gate new ServiceLocationException( 1700Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 1710Sstevel@tonic-gate "not_right_url", 1720Sstevel@tonic-gate new Object[] {URL, "DA"}); 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate } 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate // Set number of replies to one. 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate hdr.iNumReplies = 1; 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate // Get the timestamp. 1830Sstevel@tonic-gate getInt32(SrvLocHeader hdr, DataInputStream dis, byte[] bytes)1840Sstevel@tonic-gate static private long getInt32(SrvLocHeader hdr, 1850Sstevel@tonic-gate DataInputStream dis, 1860Sstevel@tonic-gate byte[] bytes) 1870Sstevel@tonic-gate throws ServiceLocationException, IOException { 1880Sstevel@tonic-gate 1890Sstevel@tonic-gate bytes[0] = (byte)dis.read(); 1900Sstevel@tonic-gate bytes[1] = (byte)dis.read(); 1910Sstevel@tonic-gate bytes[2] = (byte)dis.read(); 1920Sstevel@tonic-gate bytes[3] = (byte)dis.read(); 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate long a = (long)((char)bytes[0] & 0xFF); 1950Sstevel@tonic-gate long b = (long)((char)bytes[1] & 0xFF); 1960Sstevel@tonic-gate long c = (long)((char)bytes[2] & 0xFF); 1970Sstevel@tonic-gate long d = (long)((char)bytes[3] & 0xFF); 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate long i = a << 24; 2000Sstevel@tonic-gate i += b << 16; 2010Sstevel@tonic-gate i += c << 8; 2020Sstevel@tonic-gate i += d; 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate hdr.nbytes += 4; 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate return i; 2070Sstevel@tonic-gate } 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate // Return true if the advert indicates that the DA is going down. 2100Sstevel@tonic-gate isGoingDown()2110Sstevel@tonic-gate boolean isGoingDown() { 2120Sstevel@tonic-gate return (timestamp == 0); 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate // Return true if the advert was unsolicited. 2170Sstevel@tonic-gate isUnsolicited()2180Sstevel@tonic-gate boolean isUnsolicited() { 2190Sstevel@tonic-gate return (hdr.xid == 0); 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate } 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate // Set is solicited. No-op for V2, since messages already know. 2240Sstevel@tonic-gate setIsUnsolicited(boolean flag)2250Sstevel@tonic-gate void setIsUnsolicited(boolean flag) { 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate 2290Sstevel@tonic-gate // Calcualte DA URL lifetime, based on active discovery interval and 2300Sstevel@tonic-gate // granularity. 2310Sstevel@tonic-gate getDAURLLifetime()2320Sstevel@tonic-gate private int getDAURLLifetime() { 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate // Calculate lifetime based on maximum length of time between 2350Sstevel@tonic-gate // active discoveries. We add a fudge factor to avoid problems 2360Sstevel@tonic-gate // with scheduler granularity. 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate SLPConfig config = SLPConfig.getSLPConfig(); 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate int disInt = config.getActiveDiscoveryInterval(); 2410Sstevel@tonic-gate int granInt = config.getActiveDiscoveryGranularity(); 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate // If the discovery interval is zero, then the granularity will be 2440Sstevel@tonic-gate // also, and active discovery is off. In principle, it doesn't 2450Sstevel@tonic-gate // matter what the DA URL interval is because active discovery 2460Sstevel@tonic-gate // won't find any, because its off. 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate if (disInt <= 0) { 2490Sstevel@tonic-gate return ServiceURL.LIFETIME_MAXIMUM; 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate } else { 2520Sstevel@tonic-gate int lifetime = disInt + granInt; 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate return 2550Sstevel@tonic-gate (lifetime > ServiceURL.LIFETIME_MAXIMUM ? 2560Sstevel@tonic-gate ServiceURL.LIFETIME_MAXIMUM:lifetime); 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate } 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate } 261