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 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 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 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 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 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 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 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 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 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 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