2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 1999 by Sun Microsystems, Inc.
2N/A * All rights reserved.
2N/A *
2N/A */
2N/A
2N/A// CDAAdvert.java: Message class for SLP CDAAdvert message
2N/A// Author: James Kempf
2N/A// Created On: Fri Oct 10 10:48:05 1997
2N/A// Last Modified By: James Kempf
2N/A// Last Modified On: Fri Jan 29 09:24:50 1999
2N/A// Update Count: 134
2N/A//
2N/A
2N/Apackage com.sun.slp;
2N/A
2N/Aimport java.util.*;
2N/Aimport java.io.*;
2N/A
2N/A
2N/A/**
2N/A * The CDAAdvert class models the SLP DAAdvert message, client side.
2N/A * We need to accommodate SLPv1 by using an initialize() method.
2N/A *
2N/A * @author James Kempf
2N/A */
2N/A
2N/A
2N/Aclass CDAAdvert extends SrvLocMsgImpl {
2N/A
2N/A ServiceURL URL = null; // The DA's service URL
2N/A long timestamp = 0; // timestamp.
2N/A Vector attrs = new Vector(); // Attributes
2N/A Hashtable authBlock = null; // Scope auth blocks.
2N/A String spis = null; // Supported SPIs
2N/A
2N/A // Construct a CDAAdvert from the input stream.
2N/A
2N/A CDAAdvert(SrvLocHeader hdr, DataInputStream dis)
2N/A throws ServiceLocationException, IOException {
2N/A super(hdr, SrvLocHeader.DAAdvert);
2N/A
2N/A this.initialize(dis);
2N/A
2N/A }
2N/A
2N/A // Initialize the object from the input stream.
2N/A
2N/A protected void initialize(DataInputStream dis)
2N/A throws ServiceLocationException, IOException {
2N/A
2N/A SLPHeaderV2 hdr = (SLPHeaderV2)getHeader();
2N/A
2N/A // Parse in the timestamp. Save bytes for auth block.
2N/A
2N/A byte[] tsBytes = new byte[4];
2N/A
2N/A timestamp = getInt32(hdr, dis, tsBytes);
2N/A
2N/A // Parse in DA's service URL.
2N/A
2N/A StringBuffer buf = new StringBuffer();
2N/A
2N/A byte[] urlBytes = hdr.getString(buf, dis);
2N/A
2N/A int lifetime = getDAURLLifetime();
2N/A
2N/A String surl = buf.toString();
2N/A
2N/A // Parse in the scope list.
2N/A
2N/A byte[] scopeBytes = hdr.getString(buf, dis);
2N/A
2N/A hdr.scopes = hdr.parseCommaSeparatedListIn(buf.toString(), true);
2N/A
2N/A // Unescape scope strigns.
2N/A
2N/A hdr.unescapeScopeStrings(hdr.scopes);
2N/A
2N/A // Validate scope list.
2N/A
2N/A DATable.validateScopes(hdr.scopes, hdr.locale);
2N/A
2N/A // Parse in attribute list.
2N/A
2N/A byte[] attrBytes = hdr.parseAttributeVectorIn(attrs, dis, false);
2N/A
2N/A // Parse in the SPI list
2N/A byte[] spiBytes = hdr.getString(buf, dis);
2N/A spis = buf.toString();
2N/A
2N/A // Construct bytes for auth.
2N/A Object[] message = new Object[9];
2N/A
2N/A message[0] = tsBytes;
2N/A
2N/A // None of the strings have leading length fields, so add them here
2N/A ByteArrayOutputStream abaos = new ByteArrayOutputStream();
2N/A hdr.putInteger(urlBytes.length, abaos);
2N/A message[1] = abaos.toByteArray();
2N/A message[2] = urlBytes;
2N/A
2N/A abaos = new ByteArrayOutputStream();
2N/A hdr.putInteger(attrBytes.length, abaos);
2N/A message[3] = abaos.toByteArray();
2N/A message[4] = attrBytes;
2N/A
2N/A abaos = new ByteArrayOutputStream();
2N/A hdr.putInteger(scopeBytes.length, abaos);
2N/A message[5] = abaos.toByteArray();
2N/A message[6] = scopeBytes;
2N/A
2N/A abaos = new ByteArrayOutputStream();
2N/A hdr.putInteger(spiBytes.length, abaos);
2N/A message[7] = abaos.toByteArray();
2N/A message[8] = spiBytes;
2N/A
2N/A // Parse in an auth block, if there.
2N/A
2N/A authBlock = hdr.parseSignatureIn(message, dis);
2N/A
2N/A if (authBlock != null) {
2N/A lifetime = AuthBlock.getShortestLifetime(authBlock);
2N/A
2N/A }
2N/A
2N/A // Create URL.
2N/A
2N/A try {
2N/A
2N/A URL = new ServiceURL(surl, lifetime);
2N/A
2N/A } catch (IllegalArgumentException ex) {
2N/A
2N/A throw
2N/A new ServiceLocationException(
2N/A ServiceLocationException.PARSE_ERROR,
2N/A "malformed_url",
2N/A new Object[] {ex.getMessage()});
2N/A
2N/A }
2N/A
2N/A // Validate the service URL.
2N/A
2N/A ServiceType serviceType = URL.getServiceType();
2N/A
2N/A if (!serviceType.equals(Defaults.DA_SERVICE_TYPE)) {
2N/A throw
2N/A new ServiceLocationException(
2N/A ServiceLocationException.PARSE_ERROR,
2N/A "not_right_url",
2N/A new Object[] {URL, "DA"});
2N/A
2N/A }
2N/A
2N/A // Set number of replies to one.
2N/A
2N/A hdr.iNumReplies = 1;
2N/A }
2N/A
2N/A
2N/A // Get the timestamp.
2N/A
2N/A static private long getInt32(SrvLocHeader hdr,
2N/A DataInputStream dis,
2N/A byte[] bytes)
2N/A throws ServiceLocationException, IOException {
2N/A
2N/A bytes[0] = (byte)dis.read();
2N/A bytes[1] = (byte)dis.read();
2N/A bytes[2] = (byte)dis.read();
2N/A bytes[3] = (byte)dis.read();
2N/A
2N/A long a = (long)((char)bytes[0] & 0xFF);
2N/A long b = (long)((char)bytes[1] & 0xFF);
2N/A long c = (long)((char)bytes[2] & 0xFF);
2N/A long d = (long)((char)bytes[3] & 0xFF);
2N/A
2N/A long i = a << 24;
2N/A i += b << 16;
2N/A i += c << 8;
2N/A i += d;
2N/A
2N/A hdr.nbytes += 4;
2N/A
2N/A return i;
2N/A }
2N/A
2N/A // Return true if the advert indicates that the DA is going down.
2N/A
2N/A boolean isGoingDown() {
2N/A return (timestamp == 0);
2N/A
2N/A }
2N/A
2N/A // Return true if the advert was unsolicited.
2N/A
2N/A boolean isUnsolicited() {
2N/A return (hdr.xid == 0);
2N/A
2N/A }
2N/A
2N/A // Set is solicited. No-op for V2, since messages already know.
2N/A
2N/A void setIsUnsolicited(boolean flag) {
2N/A
2N/A }
2N/A
2N/A // Calcualte DA URL lifetime, based on active discovery interval and
2N/A // granularity.
2N/A
2N/A private int getDAURLLifetime() {
2N/A
2N/A // Calculate lifetime based on maximum length of time between
2N/A // active discoveries. We add a fudge factor to avoid problems
2N/A // with scheduler granularity.
2N/A
2N/A SLPConfig config = SLPConfig.getSLPConfig();
2N/A
2N/A int disInt = config.getActiveDiscoveryInterval();
2N/A int granInt = config.getActiveDiscoveryGranularity();
2N/A
2N/A // If the discovery interval is zero, then the granularity will be
2N/A // also, and active discovery is off. In principle, it doesn't
2N/A // matter what the DA URL interval is because active discovery
2N/A // won't find any, because its off.
2N/A
2N/A if (disInt <= 0) {
2N/A return ServiceURL.LIFETIME_MAXIMUM;
2N/A
2N/A } else {
2N/A int lifetime = disInt + granInt;
2N/A
2N/A return
2N/A (lifetime > ServiceURL.LIFETIME_MAXIMUM ?
2N/A ServiceURL.LIFETIME_MAXIMUM:lifetime);
2N/A
2N/A }
2N/A }
2N/A}