1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * Copyright (c) 1999 by Sun Microsystems, Inc. 26 * All rights reserved. 27 * 28 */ 29 30 // SCCS Status: %W% %G% 31 // CDAAdvert.java: Message class for SLP CDAAdvert message 32 // Author: James Kempf 33 // Created On: Fri Oct 10 10:48:05 1997 34 // Last Modified By: James Kempf 35 // Last Modified On: Fri Jan 29 09:24:50 1999 36 // Update Count: 134 37 // 38 39 package com.sun.slp; 40 41 import java.util.*; 42 import java.io.*; 43 44 45 /** 46 * The CDAAdvert class models the SLP DAAdvert message, client side. 47 * We need to accommodate SLPv1 by using an initialize() method. 48 * 49 * @version %R%.%L% %D% 50 * @author James Kempf 51 */ 52 53 54 class CDAAdvert extends SrvLocMsgImpl { 55 56 ServiceURL URL = null; // The DA's service URL 57 long timestamp = 0; // timestamp. 58 Vector attrs = new Vector(); // Attributes 59 Hashtable authBlock = null; // Scope auth blocks. 60 String spis = null; // Supported SPIs 61 62 // Construct a CDAAdvert from the input stream. 63 64 CDAAdvert(SrvLocHeader hdr, DataInputStream dis) 65 throws ServiceLocationException, IOException { 66 super(hdr, SrvLocHeader.DAAdvert); 67 68 this.initialize(dis); 69 70 } 71 72 // Initialize the object from the input stream. 73 74 protected void initialize(DataInputStream dis) 75 throws ServiceLocationException, IOException { 76 77 SLPHeaderV2 hdr = (SLPHeaderV2)getHeader(); 78 79 // Parse in the timestamp. Save bytes for auth block. 80 81 byte[] tsBytes = new byte[4]; 82 83 timestamp = getInt32(hdr, dis, tsBytes); 84 85 // Parse in DA's service URL. 86 87 StringBuffer buf = new StringBuffer(); 88 89 byte[] urlBytes = hdr.getString(buf, dis); 90 91 int lifetime = getDAURLLifetime(); 92 93 String surl = buf.toString(); 94 95 // Parse in the scope list. 96 97 byte[] scopeBytes = hdr.getString(buf, dis); 98 99 hdr.scopes = hdr.parseCommaSeparatedListIn(buf.toString(), true); 100 101 // Unescape scope strigns. 102 103 hdr.unescapeScopeStrings(hdr.scopes); 104 105 // Validate scope list. 106 107 DATable.validateScopes(hdr.scopes, hdr.locale); 108 109 // Parse in attribute list. 110 111 byte[] attrBytes = hdr.parseAttributeVectorIn(attrs, dis, false); 112 113 // Parse in the SPI list 114 byte[] spiBytes = hdr.getString(buf, dis); 115 spis = buf.toString(); 116 117 // Construct bytes for auth. 118 Object[] message = new Object[9]; 119 120 message[0] = tsBytes; 121 122 // None of the strings have leading length fields, so add them here 123 ByteArrayOutputStream abaos = new ByteArrayOutputStream(); 124 hdr.putInteger(urlBytes.length, abaos); 125 message[1] = abaos.toByteArray(); 126 message[2] = urlBytes; 127 128 abaos = new ByteArrayOutputStream(); 129 hdr.putInteger(attrBytes.length, abaos); 130 message[3] = abaos.toByteArray(); 131 message[4] = attrBytes; 132 133 abaos = new ByteArrayOutputStream(); 134 hdr.putInteger(scopeBytes.length, abaos); 135 message[5] = abaos.toByteArray(); 136 message[6] = scopeBytes; 137 138 abaos = new ByteArrayOutputStream(); 139 hdr.putInteger(spiBytes.length, abaos); 140 message[7] = abaos.toByteArray(); 141 message[8] = spiBytes; 142 143 // Parse in an auth block, if there. 144 145 authBlock = hdr.parseSignatureIn(message, dis); 146 147 if (authBlock != null) { 148 lifetime = AuthBlock.getShortestLifetime(authBlock); 149 150 } 151 152 // Create URL. 153 154 try { 155 156 URL = new ServiceURL(surl, lifetime); 157 158 } catch (IllegalArgumentException ex) { 159 160 throw 161 new ServiceLocationException( 162 ServiceLocationException.PARSE_ERROR, 163 "malformed_url", 164 new Object[] {ex.getMessage()}); 165 166 } 167 168 // Validate the service URL. 169 170 ServiceType serviceType = URL.getServiceType(); 171 172 if (!serviceType.equals(Defaults.DA_SERVICE_TYPE)) { 173 throw 174 new ServiceLocationException( 175 ServiceLocationException.PARSE_ERROR, 176 "not_right_url", 177 new Object[] {URL, "DA"}); 178 179 } 180 181 // Set number of replies to one. 182 183 hdr.iNumReplies = 1; 184 } 185 186 187 // Get the timestamp. 188 189 static private long getInt32(SrvLocHeader hdr, 190 DataInputStream dis, 191 byte[] bytes) 192 throws ServiceLocationException, IOException { 193 194 bytes[0] = (byte)dis.read(); 195 bytes[1] = (byte)dis.read(); 196 bytes[2] = (byte)dis.read(); 197 bytes[3] = (byte)dis.read(); 198 199 long a = (long)((char)bytes[0] & 0xFF); 200 long b = (long)((char)bytes[1] & 0xFF); 201 long c = (long)((char)bytes[2] & 0xFF); 202 long d = (long)((char)bytes[3] & 0xFF); 203 204 long i = a << 24; 205 i += b << 16; 206 i += c << 8; 207 i += d; 208 209 hdr.nbytes += 4; 210 211 return i; 212 } 213 214 // Return true if the advert indicates that the DA is going down. 215 216 boolean isGoingDown() { 217 return (timestamp == 0); 218 219 } 220 221 // Return true if the advert was unsolicited. 222 223 boolean isUnsolicited() { 224 return (hdr.xid == 0); 225 226 } 227 228 // Set is solicited. No-op for V2, since messages already know. 229 230 void setIsUnsolicited(boolean flag) { 231 232 } 233 234 // Calcualte DA URL lifetime, based on active discovery interval and 235 // granularity. 236 237 private int getDAURLLifetime() { 238 239 // Calculate lifetime based on maximum length of time between 240 // active discoveries. We add a fudge factor to avoid problems 241 // with scheduler granularity. 242 243 SLPConfig config = SLPConfig.getSLPConfig(); 244 245 int disInt = config.getActiveDiscoveryInterval(); 246 int granInt = config.getActiveDiscoveryGranularity(); 247 248 // If the discovery interval is zero, then the granularity will be 249 // also, and active discovery is off. In principle, it doesn't 250 // matter what the DA URL interval is because active discovery 251 // won't find any, because its off. 252 253 if (disInt <= 0) { 254 return ServiceURL.LIFETIME_MAXIMUM; 255 256 } else { 257 int lifetime = disInt + granInt; 258 259 return 260 (lifetime > ServiceURL.LIFETIME_MAXIMUM ? 261 ServiceURL.LIFETIME_MAXIMUM:lifetime); 262 263 } 264 } 265 } 266