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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 */ 26 27 // SLPServerHeaderV2.java: SLPv2 Header Class for Server Side 28 // Author: James Kempf 29 // Created On: Wed Sep 16 08:44:31 1998 30 // Last Modified By: James Kempf 31 // Last Modified On: Mon Jan 4 15:26:33 1999 32 // Update Count: 30 33 // 34 35 package com.sun.slp; 36 37 import java.util.*; 38 39 import java.net.*; 40 import java.io.*; 41 import java.security.*; 42 43 /** 44 * The SLPServerHeaderV2 class serves as the header class for all server side 45 * SLPv2 messages. 46 * 47 * @author James Kempf 48 */ 49 50 class SLPServerHeaderV2 extends SLPHeaderV2 implements Cloneable { 51 52 // Function code for message reply. 53 54 int replyFunctionCode = SrvLocHeader.SrvAck; 55 56 // For SrvLocHeader.newInstance(). 57 SLPServerHeaderV2()58 SLPServerHeaderV2() { 59 super(); 60 61 } 62 63 // Construct a header for output. Used by the client side code to 64 // construct an initial request and the server side code to construct 65 // a reply. 66 SLPServerHeaderV2(int functionCode, boolean fresh, Locale locale)67 SLPServerHeaderV2(int functionCode, boolean fresh, Locale locale) 68 throws ServiceLocationException { 69 super(functionCode, fresh, locale); 70 71 } 72 73 // Assign reply code based on function code type, then use superclass 74 // method to parse header. 75 parseHeader(int functionCode, DataInputStream dis)76 void parseHeader(int functionCode, DataInputStream dis) 77 throws ServiceLocationException, IOException { 78 79 // We ignore the error case here. 80 81 switch (functionCode) { 82 83 case SrvLocHeader.SrvReq: 84 replyFunctionCode = SrvLocHeader.SrvRply; 85 break; 86 87 case SrvLocHeader.AttrRqst: 88 replyFunctionCode = SrvLocHeader.AttrRply; 89 break; 90 91 case SrvLocHeader.SrvTypeRqst: 92 replyFunctionCode = SrvLocHeader.SrvTypeRply; 93 break; 94 95 case SrvLocHeader.SrvReg: case SrvLocHeader.SrvDereg: 96 replyFunctionCode = SrvLocHeader.SrvAck; 97 break; 98 99 // If we get an error during creating of the DAAdvert to 100 // reply, we need to continue and reply with DAAdvert. 101 // This is only true for a unicast DAAdvert, though. 102 103 case SrvLocHeader.DAAdvert: 104 replyFunctionCode = SrvLocHeader.DAAdvert; 105 break; 106 107 // We ignore the header error code for SAAdvert because 108 // it is always multicast. 109 110 } 111 112 // We are now set up to handle any errors that may come flying out 113 // of here. 114 115 super.parseHeader(functionCode, dis); 116 117 } 118 119 // Replace the superclass method with a method that parses the server 120 // side. 121 parseMsg(DataInputStream dis)122 SrvLocMsg parseMsg(DataInputStream dis) 123 throws ServiceLocationException, 124 IOException, 125 IllegalArgumentException { 126 127 SrvLocMsg msg = null; 128 129 // DAAdvert needs to get it's error code parsed here because 130 // error codes are always handled in parseMsg() and it is 131 // the only server side message that has one. 132 133 if (functionCode == SrvLocHeader.DAAdvert) { 134 errCode = (short)getInt(dis); 135 136 } 137 138 // Switch and convert according to function code. 139 140 switch (functionCode) { 141 142 case SrvLocHeader.SrvReg: 143 msg = new SSrvReg(this, dis); 144 break; 145 146 case SrvLocHeader.SrvDereg: 147 msg = new SSrvDereg(this, dis); 148 break; 149 150 case SrvLocHeader.SrvReq: 151 msg = new SSrvMsg(this, dis); 152 break; 153 154 case SrvLocHeader.AttrRqst: 155 msg = new SAttrMsg(this, dis); 156 break; 157 158 case SrvLocHeader.SrvAck: 159 160 // We function as our own message. 161 162 msg = this; 163 iNumReplies = 1; 164 break; 165 166 case SrvLocHeader.SrvTypeRqst: 167 msg = new SSrvTypeMsg(this, dis); 168 break; 169 170 case SrvLocHeader.DAAdvert: 171 msg = new CDAAdvert(this, dis); 172 break; 173 174 case SrvLocHeader.SAAdvert: 175 msg = new CSAAdvert(this, dis); 176 break; 177 178 default: 179 throw 180 new ServiceLocationException( 181 ServiceLocationException.PARSE_ERROR, 182 "function_code_error", 183 new Object[] { 184 new Integer(functionCode)}); 185 186 } 187 188 // Check for size overflow. 189 190 if (nbytes > length) { 191 throw 192 new ServiceLocationException( 193 ServiceLocationException.PARSE_ERROR, 194 "length_overflow", 195 new Object[] { 196 new Integer(nbytes), new Integer(length)}); 197 198 } 199 200 return msg; 201 202 } 203 204 // Create an error reply using the reply code. Calculate the 205 // error code using the exception. 206 makeErrorReply(Exception ex)207 SrvLocMsg makeErrorReply(Exception ex) { 208 209 SrvLocHeader hdr = null; 210 211 // Clone the header to make sure that everything else is the same. 212 // We don't want to use the same header because it may be tested 213 // elsewhere. 214 215 try { 216 hdr = (SrvLocHeader)this.clone(); 217 218 } catch (CloneNotSupportedException exx) { 219 220 // We support it, so no-op. 221 222 } 223 224 // Re-initialize flags but not multicast, since we need to filter on it 225 226 hdr.fresh = false; 227 hdr.overflow = false; 228 hdr.functionCode = replyFunctionCode; 229 230 // We should *not* be getting a null exception down this path! 231 232 Assert.slpassert(ex != null, 233 "null_parameter", 234 new Object[] {ex}); 235 236 if (ex instanceof ServiceLocationException) { 237 238 hdr.errCode = ((ServiceLocationException)ex).getErrorCode(); 239 240 if (!ServiceLocationException.validWireErrorCode(hdr.errCode)) { 241 hdr.errCode = ServiceLocationException.INTERNAL_ERROR; 242 243 } 244 245 } else if (ex instanceof IllegalArgumentException || 246 ex instanceof IOException) { 247 hdr.errCode = ServiceLocationException.PARSE_ERROR; 248 249 } else { 250 hdr.errCode = ServiceLocationException.INTERNAL_ERROR; 251 252 } 253 254 // Construct header description. 255 256 constructDescription("SrvLocMsg", ""); 257 258 return hdr; 259 } 260 261 // Return a reply header with flags properly set. 262 makeReplyHeader()263 SLPServerHeaderV2 makeReplyHeader() { 264 265 SLPServerHeaderV2 hdr = null; 266 267 try { 268 hdr = (SLPServerHeaderV2)this.clone(); 269 270 } catch (CloneNotSupportedException ex) { 271 272 // No-op, since we support it. 273 274 } 275 276 hdr.functionCode = replyFunctionCode; 277 hdr.length = 0; 278 hdr.previousResponders = null; 279 hdr.scopes = null; 280 hdr.overflow = false; 281 hdr.fresh = false; 282 hdr.mcast = false; 283 hdr.nbytes = 0; 284 285 return hdr; 286 } 287 288 // Return display string. 289 toString()290 public String toString() { 291 return 292 getMsgType() + ":version=``" + version + "''\n" + 293 " functionCode=``" + functionCode + "''\n" + 294 " length=``" + length + "''" + "''\n" + 295 " overflow=``" + overflow + "''\n" + 296 " mcast = ``" + mcast + "''\n" + 297 " fresh=``" + fresh + "''\n" + 298 " locale = ``" + locale + "''\n" + 299 " xid=``0x" + Integer.toHexString(xid) + "''\n" + 300 " errCode=``" + errCode + "''\n" + 301 " previousResponders=``" + previousResponders + "''\n" + 302 " scopes=``" + scopes + "''\n" + 303 getMsgDescription(); 304 } 305 306 // 307 // Parsing Utilities. 308 // 309 310 // Parse in the scope list. 311 parseScopesIn(DataInputStream dis)312 void parseScopesIn(DataInputStream dis) 313 throws ServiceLocationException, IOException { 314 315 StringBuffer buf = new StringBuffer(); 316 317 getString(buf, dis); 318 319 scopes = parseCommaSeparatedListIn(buf.toString(), true); 320 321 // Unescape scope strings. 322 323 unescapeScopeStrings(scopes); 324 325 // Validate. 326 327 DATable.validateScopes(scopes, locale); 328 329 } 330 parsePreviousRespondersIn(DataInputStream dis)331 void parsePreviousRespondersIn(DataInputStream dis) 332 throws ServiceLocationException, IOException { 333 334 StringBuffer buf = new StringBuffer(); 335 336 getString(buf, dis); 337 338 previousResponders = 339 parseCommaSeparatedListIn(buf.toString(), true); 340 341 } 342 343 // Return an SLPv2 DAAdvert. 344 345 SDAAdvert getDAAdvert(short xid, long timestamp, ServiceURL url, Vector scopes, Vector attrs)346 getDAAdvert(short xid, 347 long timestamp, 348 ServiceURL url, 349 Vector scopes, 350 Vector attrs) 351 throws ServiceLocationException { 352 353 // If scopes vector is null, then return all scopes for this 354 // DA. 355 356 if (scopes.size() <= 0) { 357 scopes = SLPConfig.getSLPConfig().getSAConfiguredScopes(); 358 359 } 360 361 return new SDAAdvert(this, xid, timestamp, url, scopes, attrs); 362 363 } 364 365 } 366