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