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 2001-2002 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate * 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate // SLPServerHeaderV2.java: SLPv2 Header Class for Server Side 280Sstevel@tonic-gate // Author: James Kempf 290Sstevel@tonic-gate // Created On: Wed Sep 16 08:44:31 1998 300Sstevel@tonic-gate // Last Modified By: James Kempf 310Sstevel@tonic-gate // Last Modified On: Mon Jan 4 15:26:33 1999 320Sstevel@tonic-gate // Update Count: 30 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 390Sstevel@tonic-gate import java.net.*; 400Sstevel@tonic-gate import java.io.*; 410Sstevel@tonic-gate import java.security.*; 420Sstevel@tonic-gate 430Sstevel@tonic-gate /** 440Sstevel@tonic-gate * The SLPServerHeaderV2 class serves as the header class for all server side 450Sstevel@tonic-gate * SLPv2 messages. 460Sstevel@tonic-gate * 470Sstevel@tonic-gate * @author James Kempf 480Sstevel@tonic-gate */ 490Sstevel@tonic-gate 500Sstevel@tonic-gate class SLPServerHeaderV2 extends SLPHeaderV2 implements Cloneable { 510Sstevel@tonic-gate 520Sstevel@tonic-gate // Function code for message reply. 530Sstevel@tonic-gate 540Sstevel@tonic-gate int replyFunctionCode = SrvLocHeader.SrvAck; 550Sstevel@tonic-gate 560Sstevel@tonic-gate // For SrvLocHeader.newInstance(). 570Sstevel@tonic-gate SLPServerHeaderV2()580Sstevel@tonic-gate SLPServerHeaderV2() { 590Sstevel@tonic-gate super(); 600Sstevel@tonic-gate 610Sstevel@tonic-gate } 620Sstevel@tonic-gate 630Sstevel@tonic-gate // Construct a header for output. Used by the client side code to 640Sstevel@tonic-gate // construct an initial request and the server side code to construct 650Sstevel@tonic-gate // a reply. 660Sstevel@tonic-gate SLPServerHeaderV2(int functionCode, boolean fresh, Locale locale)670Sstevel@tonic-gate SLPServerHeaderV2(int functionCode, boolean fresh, Locale locale) 680Sstevel@tonic-gate throws ServiceLocationException { 690Sstevel@tonic-gate super(functionCode, fresh, locale); 700Sstevel@tonic-gate 710Sstevel@tonic-gate } 720Sstevel@tonic-gate 730Sstevel@tonic-gate // Assign reply code based on function code type, then use superclass 740Sstevel@tonic-gate // method to parse header. 750Sstevel@tonic-gate parseHeader(int functionCode, DataInputStream dis)760Sstevel@tonic-gate void parseHeader(int functionCode, DataInputStream dis) 770Sstevel@tonic-gate throws ServiceLocationException, IOException { 780Sstevel@tonic-gate 790Sstevel@tonic-gate // We ignore the error case here. 800Sstevel@tonic-gate 810Sstevel@tonic-gate switch (functionCode) { 820Sstevel@tonic-gate 830Sstevel@tonic-gate case SrvLocHeader.SrvReq: 840Sstevel@tonic-gate replyFunctionCode = SrvLocHeader.SrvRply; 850Sstevel@tonic-gate break; 860Sstevel@tonic-gate 870Sstevel@tonic-gate case SrvLocHeader.AttrRqst: 880Sstevel@tonic-gate replyFunctionCode = SrvLocHeader.AttrRply; 890Sstevel@tonic-gate break; 900Sstevel@tonic-gate 910Sstevel@tonic-gate case SrvLocHeader.SrvTypeRqst: 920Sstevel@tonic-gate replyFunctionCode = SrvLocHeader.SrvTypeRply; 930Sstevel@tonic-gate break; 940Sstevel@tonic-gate 950Sstevel@tonic-gate case SrvLocHeader.SrvReg: case SrvLocHeader.SrvDereg: 960Sstevel@tonic-gate replyFunctionCode = SrvLocHeader.SrvAck; 970Sstevel@tonic-gate break; 980Sstevel@tonic-gate 990Sstevel@tonic-gate // If we get an error during creating of the DAAdvert to 1000Sstevel@tonic-gate // reply, we need to continue and reply with DAAdvert. 1010Sstevel@tonic-gate // This is only true for a unicast DAAdvert, though. 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate case SrvLocHeader.DAAdvert: 1040Sstevel@tonic-gate replyFunctionCode = SrvLocHeader.DAAdvert; 1050Sstevel@tonic-gate break; 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate // We ignore the header error code for SAAdvert because 1080Sstevel@tonic-gate // it is always multicast. 1090Sstevel@tonic-gate 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate // We are now set up to handle any errors that may come flying out 1130Sstevel@tonic-gate // of here. 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate super.parseHeader(functionCode, dis); 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate } 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate // Replace the superclass method with a method that parses the server 1200Sstevel@tonic-gate // side. 1210Sstevel@tonic-gate parseMsg(DataInputStream dis)1220Sstevel@tonic-gate SrvLocMsg parseMsg(DataInputStream dis) 1230Sstevel@tonic-gate throws ServiceLocationException, 1240Sstevel@tonic-gate IOException, 1250Sstevel@tonic-gate IllegalArgumentException { 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate SrvLocMsg msg = null; 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate // DAAdvert needs to get it's error code parsed here because 1300Sstevel@tonic-gate // error codes are always handled in parseMsg() and it is 1310Sstevel@tonic-gate // the only server side message that has one. 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate if (functionCode == SrvLocHeader.DAAdvert) { 1340Sstevel@tonic-gate errCode = (short)getInt(dis); 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate } 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate // Switch and convert according to function code. 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate switch (functionCode) { 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate case SrvLocHeader.SrvReg: 1430Sstevel@tonic-gate msg = new SSrvReg(this, dis); 1440Sstevel@tonic-gate break; 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate case SrvLocHeader.SrvDereg: 1470Sstevel@tonic-gate msg = new SSrvDereg(this, dis); 1480Sstevel@tonic-gate break; 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate case SrvLocHeader.SrvReq: 1510Sstevel@tonic-gate msg = new SSrvMsg(this, dis); 1520Sstevel@tonic-gate break; 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate case SrvLocHeader.AttrRqst: 1550Sstevel@tonic-gate msg = new SAttrMsg(this, dis); 1560Sstevel@tonic-gate break; 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate case SrvLocHeader.SrvAck: 1590Sstevel@tonic-gate 1600Sstevel@tonic-gate // We function as our own message. 1610Sstevel@tonic-gate 1620Sstevel@tonic-gate msg = this; 1630Sstevel@tonic-gate iNumReplies = 1; 1640Sstevel@tonic-gate break; 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate case SrvLocHeader.SrvTypeRqst: 1670Sstevel@tonic-gate msg = new SSrvTypeMsg(this, dis); 1680Sstevel@tonic-gate break; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate case SrvLocHeader.DAAdvert: 1710Sstevel@tonic-gate msg = new CDAAdvert(this, dis); 1720Sstevel@tonic-gate break; 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate case SrvLocHeader.SAAdvert: 1750Sstevel@tonic-gate msg = new CSAAdvert(this, dis); 1760Sstevel@tonic-gate break; 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate default: 1790Sstevel@tonic-gate throw 1800Sstevel@tonic-gate new ServiceLocationException( 1810Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 1820Sstevel@tonic-gate "function_code_error", 1830Sstevel@tonic-gate new Object[] { 1840Sstevel@tonic-gate new Integer(functionCode)}); 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate // Check for size overflow. 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate if (nbytes > length) { 1910Sstevel@tonic-gate throw 1920Sstevel@tonic-gate new ServiceLocationException( 1930Sstevel@tonic-gate ServiceLocationException.PARSE_ERROR, 1940Sstevel@tonic-gate "length_overflow", 1950Sstevel@tonic-gate new Object[] { 1960Sstevel@tonic-gate new Integer(nbytes), new Integer(length)}); 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate return msg; 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate } 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate // Create an error reply using the reply code. Calculate the 2050Sstevel@tonic-gate // error code using the exception. 2060Sstevel@tonic-gate makeErrorReply(Exception ex)2070Sstevel@tonic-gate SrvLocMsg makeErrorReply(Exception ex) { 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate SrvLocHeader hdr = null; 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate // Clone the header to make sure that everything else is the same. 2120Sstevel@tonic-gate // We don't want to use the same header because it may be tested 2130Sstevel@tonic-gate // elsewhere. 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate try { 2160Sstevel@tonic-gate hdr = (SrvLocHeader)this.clone(); 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate } catch (CloneNotSupportedException exx) { 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate // We support it, so no-op. 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate // Re-initialize flags but not multicast, since we need to filter on it 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate hdr.fresh = false; 2270Sstevel@tonic-gate hdr.overflow = false; 2280Sstevel@tonic-gate hdr.functionCode = replyFunctionCode; 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate // We should *not* be getting a null exception down this path! 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate Assert.slpassert(ex != null, 2330Sstevel@tonic-gate "null_parameter", 2340Sstevel@tonic-gate new Object[] {ex}); 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate if (ex instanceof ServiceLocationException) { 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate hdr.errCode = ((ServiceLocationException)ex).getErrorCode(); 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate if (!ServiceLocationException.validWireErrorCode(hdr.errCode)) { 2410Sstevel@tonic-gate hdr.errCode = ServiceLocationException.INTERNAL_ERROR; 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate } else if (ex instanceof IllegalArgumentException || 2460Sstevel@tonic-gate ex instanceof IOException) { 2470Sstevel@tonic-gate hdr.errCode = ServiceLocationException.PARSE_ERROR; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate } else { 2500Sstevel@tonic-gate hdr.errCode = ServiceLocationException.INTERNAL_ERROR; 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate } 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate // Construct header description. 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate constructDescription("SrvLocMsg", ""); 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate return hdr; 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate // Return a reply header with flags properly set. 2620Sstevel@tonic-gate makeReplyHeader()2630Sstevel@tonic-gate SLPServerHeaderV2 makeReplyHeader() { 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate SLPServerHeaderV2 hdr = null; 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate try { 2680Sstevel@tonic-gate hdr = (SLPServerHeaderV2)this.clone(); 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate } catch (CloneNotSupportedException ex) { 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate // No-op, since we support it. 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate } 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate hdr.functionCode = replyFunctionCode; 2770Sstevel@tonic-gate hdr.length = 0; 2780Sstevel@tonic-gate hdr.previousResponders = null; 2790Sstevel@tonic-gate hdr.scopes = null; 2800Sstevel@tonic-gate hdr.overflow = false; 2810Sstevel@tonic-gate hdr.fresh = false; 2820Sstevel@tonic-gate hdr.mcast = false; 2830Sstevel@tonic-gate hdr.nbytes = 0; 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate return hdr; 2860Sstevel@tonic-gate } 2870Sstevel@tonic-gate 2880Sstevel@tonic-gate // Return display string. 2890Sstevel@tonic-gate toString()2900Sstevel@tonic-gate public String toString() { 2910Sstevel@tonic-gate return 2920Sstevel@tonic-gate getMsgType() + ":version=``" + version + "''\n" + 2930Sstevel@tonic-gate " functionCode=``" + functionCode + "''\n" + 2940Sstevel@tonic-gate " length=``" + length + "''" + "''\n" + 2950Sstevel@tonic-gate " overflow=``" + overflow + "''\n" + 2960Sstevel@tonic-gate " mcast = ``" + mcast + "''\n" + 2970Sstevel@tonic-gate " fresh=``" + fresh + "''\n" + 2980Sstevel@tonic-gate " locale = ``" + locale + "''\n" + 2990Sstevel@tonic-gate " xid=``0x" + Integer.toHexString(xid) + "''\n" + 3000Sstevel@tonic-gate " errCode=``" + errCode + "''\n" + 3010Sstevel@tonic-gate " previousResponders=``" + previousResponders + "''\n" + 3020Sstevel@tonic-gate " scopes=``" + scopes + "''\n" + 3030Sstevel@tonic-gate getMsgDescription(); 3040Sstevel@tonic-gate } 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate // 3070Sstevel@tonic-gate // Parsing Utilities. 3080Sstevel@tonic-gate // 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate // Parse in the scope list. 3110Sstevel@tonic-gate parseScopesIn(DataInputStream dis)3120Sstevel@tonic-gate void parseScopesIn(DataInputStream dis) 3130Sstevel@tonic-gate throws ServiceLocationException, IOException { 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate getString(buf, dis); 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate scopes = parseCommaSeparatedListIn(buf.toString(), true); 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate // Unescape scope strings. 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate unescapeScopeStrings(scopes); 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate // Validate. 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate DATable.validateScopes(scopes, locale); 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate parsePreviousRespondersIn(DataInputStream dis)3310Sstevel@tonic-gate void parsePreviousRespondersIn(DataInputStream dis) 3320Sstevel@tonic-gate throws ServiceLocationException, IOException { 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate getString(buf, dis); 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate previousResponders = 3390Sstevel@tonic-gate parseCommaSeparatedListIn(buf.toString(), true); 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate } 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate // Return an SLPv2 DAAdvert. 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate SDAAdvert getDAAdvert(short xid, long timestamp, ServiceURL url, Vector scopes, Vector attrs)3460Sstevel@tonic-gate getDAAdvert(short xid, 3470Sstevel@tonic-gate long timestamp, 3480Sstevel@tonic-gate ServiceURL url, 3490Sstevel@tonic-gate Vector scopes, 3500Sstevel@tonic-gate Vector attrs) 3510Sstevel@tonic-gate throws ServiceLocationException { 3520Sstevel@tonic-gate 3530Sstevel@tonic-gate // If scopes vector is null, then return all scopes for this 3540Sstevel@tonic-gate // DA. 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate if (scopes.size() <= 0) { 3570Sstevel@tonic-gate scopes = SLPConfig.getSLPConfig().getSAConfiguredScopes(); 3580Sstevel@tonic-gate 3590Sstevel@tonic-gate } 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate return new SDAAdvert(this, xid, timestamp, url, scopes, attrs); 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate } 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate } 366