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 (c) 1999 by Sun Microsystems, Inc. 237c478bd9Sstevel@tonic-gate * All rights reserved. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate // CDAAdvert.java: Message class for SLP CDAAdvert message 287c478bd9Sstevel@tonic-gate // Author: James Kempf 297c478bd9Sstevel@tonic-gate // Created On: Fri Oct 10 10:48:05 1997 307c478bd9Sstevel@tonic-gate // Last Modified By: James Kempf 317c478bd9Sstevel@tonic-gate // Last Modified On: Fri Jan 29 09:24:50 1999 327c478bd9Sstevel@tonic-gate // Update Count: 134 337c478bd9Sstevel@tonic-gate // 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate package com.sun.slp; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate import java.util.*; 387c478bd9Sstevel@tonic-gate import java.io.*; 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /** 427c478bd9Sstevel@tonic-gate * The CDAAdvert class models the SLP DAAdvert message, client side. 437c478bd9Sstevel@tonic-gate * We need to accommodate SLPv1 by using an initialize() method. 447c478bd9Sstevel@tonic-gate * 457c478bd9Sstevel@tonic-gate * @author James Kempf 467c478bd9Sstevel@tonic-gate */ 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate class CDAAdvert extends SrvLocMsgImpl { 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate ServiceURL URL = null; // The DA's service URL 527c478bd9Sstevel@tonic-gate long timestamp = 0; // timestamp. 537c478bd9Sstevel@tonic-gate Vector attrs = new Vector(); // Attributes 547c478bd9Sstevel@tonic-gate Hashtable authBlock = null; // Scope auth blocks. 557c478bd9Sstevel@tonic-gate String spis = null; // Supported SPIs 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate // Construct a CDAAdvert from the input stream. 587c478bd9Sstevel@tonic-gate CDAAdvert(SrvLocHeader hdr, DataInputStream dis)59*55fea89dSDan Cross CDAAdvert(SrvLocHeader hdr, DataInputStream dis) 607c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 617c478bd9Sstevel@tonic-gate super(hdr, SrvLocHeader.DAAdvert); 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate this.initialize(dis); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate } 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate // Initialize the object from the input stream. 687c478bd9Sstevel@tonic-gate initialize(DataInputStream dis)697c478bd9Sstevel@tonic-gate protected void initialize(DataInputStream dis) 707c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate SLPHeaderV2 hdr = (SLPHeaderV2)getHeader(); 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate // Parse in the timestamp. Save bytes for auth block. 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate byte[] tsBytes = new byte[4]; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate timestamp = getInt32(hdr, dis, tsBytes); 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate // Parse in DA's service URL. 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate byte[] urlBytes = hdr.getString(buf, dis); 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate int lifetime = getDAURLLifetime(); 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate String surl = buf.toString(); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate // Parse in the scope list. 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate byte[] scopeBytes = hdr.getString(buf, dis); 93*55fea89dSDan Cross 947c478bd9Sstevel@tonic-gate hdr.scopes = hdr.parseCommaSeparatedListIn(buf.toString(), true); 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate // Unescape scope strigns. 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate hdr.unescapeScopeStrings(hdr.scopes); 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate // Validate scope list. 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate DATable.validateScopes(hdr.scopes, hdr.locale); 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate // Parse in attribute list. 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate byte[] attrBytes = hdr.parseAttributeVectorIn(attrs, dis, false); 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate // Parse in the SPI list 1097c478bd9Sstevel@tonic-gate byte[] spiBytes = hdr.getString(buf, dis); 1107c478bd9Sstevel@tonic-gate spis = buf.toString(); 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate // Construct bytes for auth. 1137c478bd9Sstevel@tonic-gate Object[] message = new Object[9]; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate message[0] = tsBytes; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate // None of the strings have leading length fields, so add them here 1187c478bd9Sstevel@tonic-gate ByteArrayOutputStream abaos = new ByteArrayOutputStream(); 1197c478bd9Sstevel@tonic-gate hdr.putInteger(urlBytes.length, abaos); 1207c478bd9Sstevel@tonic-gate message[1] = abaos.toByteArray(); 1217c478bd9Sstevel@tonic-gate message[2] = urlBytes; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate abaos = new ByteArrayOutputStream(); 1247c478bd9Sstevel@tonic-gate hdr.putInteger(attrBytes.length, abaos); 1257c478bd9Sstevel@tonic-gate message[3] = abaos.toByteArray(); 1267c478bd9Sstevel@tonic-gate message[4] = attrBytes; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate abaos = new ByteArrayOutputStream(); 1297c478bd9Sstevel@tonic-gate hdr.putInteger(scopeBytes.length, abaos); 1307c478bd9Sstevel@tonic-gate message[5] = abaos.toByteArray(); 1317c478bd9Sstevel@tonic-gate message[6] = scopeBytes; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate abaos = new ByteArrayOutputStream(); 1347c478bd9Sstevel@tonic-gate hdr.putInteger(spiBytes.length, abaos); 1357c478bd9Sstevel@tonic-gate message[7] = abaos.toByteArray(); 1367c478bd9Sstevel@tonic-gate message[8] = spiBytes; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate // Parse in an auth block, if there. 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate authBlock = hdr.parseSignatureIn(message, dis); 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate if (authBlock != null) { 1437c478bd9Sstevel@tonic-gate lifetime = AuthBlock.getShortestLifetime(authBlock); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate // Create URL. 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate try { 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate URL = new ServiceURL(surl, lifetime); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate } catch (IllegalArgumentException ex) { 1547c478bd9Sstevel@tonic-gate 155*55fea89dSDan Cross throw 1567c478bd9Sstevel@tonic-gate new ServiceLocationException( 1577c478bd9Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 1587c478bd9Sstevel@tonic-gate "malformed_url", 1597c478bd9Sstevel@tonic-gate new Object[] {ex.getMessage()}); 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate // Validate the service URL. 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate ServiceType serviceType = URL.getServiceType(); 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate if (!serviceType.equals(Defaults.DA_SERVICE_TYPE)) { 168*55fea89dSDan Cross throw 1697c478bd9Sstevel@tonic-gate new ServiceLocationException( 170*55fea89dSDan Cross ServiceLocationException.PARSE_ERROR, 1717c478bd9Sstevel@tonic-gate "not_right_url", 1727c478bd9Sstevel@tonic-gate new Object[] {URL, "DA"}); 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate // Set number of replies to one. 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate hdr.iNumReplies = 1; 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 181*55fea89dSDan Cross 1827c478bd9Sstevel@tonic-gate // Get the timestamp. 1837c478bd9Sstevel@tonic-gate getInt32(SrvLocHeader hdr, DataInputStream dis, byte[] bytes)1847c478bd9Sstevel@tonic-gate static private long getInt32(SrvLocHeader hdr, 1857c478bd9Sstevel@tonic-gate DataInputStream dis, 1867c478bd9Sstevel@tonic-gate byte[] bytes) 1877c478bd9Sstevel@tonic-gate throws ServiceLocationException, IOException { 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate bytes[0] = (byte)dis.read(); 1907c478bd9Sstevel@tonic-gate bytes[1] = (byte)dis.read(); 1917c478bd9Sstevel@tonic-gate bytes[2] = (byte)dis.read(); 1927c478bd9Sstevel@tonic-gate bytes[3] = (byte)dis.read(); 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate long a = (long)((char)bytes[0] & 0xFF); 1957c478bd9Sstevel@tonic-gate long b = (long)((char)bytes[1] & 0xFF); 1967c478bd9Sstevel@tonic-gate long c = (long)((char)bytes[2] & 0xFF); 1977c478bd9Sstevel@tonic-gate long d = (long)((char)bytes[3] & 0xFF); 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate long i = a << 24; 2007c478bd9Sstevel@tonic-gate i += b << 16; 2017c478bd9Sstevel@tonic-gate i += c << 8; 2027c478bd9Sstevel@tonic-gate i += d; 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate hdr.nbytes += 4; 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate return i; 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate // Return true if the advert indicates that the DA is going down. 2107c478bd9Sstevel@tonic-gate isGoingDown()2117c478bd9Sstevel@tonic-gate boolean isGoingDown() { 2127c478bd9Sstevel@tonic-gate return (timestamp == 0); 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate // Return true if the advert was unsolicited. 2177c478bd9Sstevel@tonic-gate isUnsolicited()2187c478bd9Sstevel@tonic-gate boolean isUnsolicited() { 2197c478bd9Sstevel@tonic-gate return (hdr.xid == 0); 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate // Set is solicited. No-op for V2, since messages already know. 2247c478bd9Sstevel@tonic-gate setIsUnsolicited(boolean flag)2257c478bd9Sstevel@tonic-gate void setIsUnsolicited(boolean flag) { 2267c478bd9Sstevel@tonic-gate 227*55fea89dSDan Cross } 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate // Calcualte DA URL lifetime, based on active discovery interval and 2307c478bd9Sstevel@tonic-gate // granularity. 2317c478bd9Sstevel@tonic-gate getDAURLLifetime()2327c478bd9Sstevel@tonic-gate private int getDAURLLifetime() { 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate // Calculate lifetime based on maximum length of time between 2357c478bd9Sstevel@tonic-gate // active discoveries. We add a fudge factor to avoid problems 2367c478bd9Sstevel@tonic-gate // with scheduler granularity. 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate SLPConfig config = SLPConfig.getSLPConfig(); 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate int disInt = config.getActiveDiscoveryInterval(); 2417c478bd9Sstevel@tonic-gate int granInt = config.getActiveDiscoveryGranularity(); 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate // If the discovery interval is zero, then the granularity will be 2447c478bd9Sstevel@tonic-gate // also, and active discovery is off. In principle, it doesn't 2457c478bd9Sstevel@tonic-gate // matter what the DA URL interval is because active discovery 2467c478bd9Sstevel@tonic-gate // won't find any, because its off. 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate if (disInt <= 0) { 2497c478bd9Sstevel@tonic-gate return ServiceURL.LIFETIME_MAXIMUM; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate } else { 2527c478bd9Sstevel@tonic-gate int lifetime = disInt + granInt; 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate return 255*55fea89dSDan Cross (lifetime > ServiceURL.LIFETIME_MAXIMUM ? 2567c478bd9Sstevel@tonic-gate ServiceURL.LIFETIME_MAXIMUM:lifetime); 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate } 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate } 261