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 (c) 2001 by Sun Microsystems, Inc. 26 * All rights reserved. 27 * 28 */ 29 30 // SCCS Status: %W% %G% 31 // SLPV1Manager.java: Manages V1 Compatibility 32 // Author: James Kempf 33 // Created On: Wed Sep 9 09:51:40 1998 34 // Last Modified By: James Kempf 35 // Last Modified On: Thu Mar 4 10:39:11 1999 36 // Update Count: 46 37 // 38 39 package com.sun.slp; 40 41 import java.io.*; 42 import java.util.*; 43 import java.net.*; 44 45 46 /** 47 * The SLPV1Manager manages access between the DA and the V1 compatibility 48 * framework. The DA calls into the SLPV1Manager to initialize 49 * active and passive DA advertising, and to decode an incoming V1 50 * message. However, the ServiceTable does *not* call into SLPV1Manager 51 * to handle an outgoing message, since each individual message type is 52 * handled separately. SLPV1Manager also handles V1 defaults. 53 * 54 * @version %R%.%L% %D% 55 * @author James Kempf 56 */ 57 58 abstract class SLPV1Manager extends Object { 59 60 // V1 Header class. 61 62 static final String V1_HEADER_CLASS = "com.sun.slp.SLPHeaderV1"; 63 64 // V1 multicast addresses. 65 66 static final String sGeneralSLPMCAddress = "224.0.1.22"; 67 static final String sDADiscSLPMCAddress = "224.0.1.35"; 68 69 static InetAddress v1SLPGSAddr = null; 70 static InetAddress v1SLPDAAddr = null; 71 72 /** 73 * The SLPV1Advertiser implements the SLPv1 DAAdvert xid incrementing 74 * algorithm. In SLPv1, the xid of an unsolicited DAAdvert is only 75 * 0 if it came up stateless. If it comes up with preexisting state, 76 * it sets the counter to 0x100. Also, when the xid counter wraps, 77 * it must wrap to 0x100 and not 0x0. 78 */ 79 80 static class SLPV1Advertiser extends DAAdvertiser { 81 82 // For implementing the V1 xid algorithm. 83 84 private short xid = 0; 85 86 private static final short STATEFUL_XID = 0x100; 87 88 private static final long STATEFUL_TIME_BOUND = 300L; 89 90 // Service table. 91 92 private ServiceTable table = null; 93 94 // Scopes to use. We need to map from V2, so default corresponds to 95 // the empty scope. 96 97 Vector useScopes = new Vector(); 98 99 // Create an SLPv1 Advertiser and start it running. 100 101 SLPV1Advertiser(InetAddress interfac, 102 InetAddress maddr, 103 ServiceTable table) 104 throws ServiceLocationException { 105 super(); 106 107 this.table = table; 108 109 initialize(); 110 111 // There will be NO listener on this multicast address, 112 // so the superclass will simply create a scoket for it. 113 // We don't want to create a new Listener 114 // because we are not interested in multicast requests since 115 // only SAs answer multicast requests. 116 117 initializeNetworking(interfac, maddr); 118 } 119 120 // Initialize the xid for passive advertising. We need to determine 121 // whether we came up stateless or not. We do this by asking the 122 // the service store for the stateless reboot time. If the 123 // stateless reboot time is within the last 5 minutes, we 124 // assume we came up stateless. Otherwise, we're stateful. 125 // We also initialize the URL and scopes. 126 127 private void initialize() throws ServiceLocationException { 128 129 // Initialize the xid. 130 131 ServiceStore store = ServiceTable.getServiceTable().store; 132 long timestamp = store.getStateTimestamp(); 133 long currentTime = SLPConfig.currentSLPTime(); 134 135 if ((currentTime - timestamp) > STATEFUL_TIME_BOUND) { 136 xid = STATEFUL_XID; 137 138 } 139 140 // Initialize the scopes. 141 142 useScopes = config.getSAConfiguredScopes(); 143 144 } 145 146 // Return the output buffer for a passive advert. We need to create 147 // the advert, rolling over the xid if necessary for the next one. 148 149 protected byte[] getOutbuf() { 150 151 SDAAdvert daadvert = null; 152 153 try { 154 155 SLPHeaderV1 hdr = new SLPHeaderV1(); 156 hdr.functionCode = SrvLocHeader.DAAdvert; 157 hdr.locale = config.getLocale(); 158 159 daadvert = (SDAAdvert)table.makeDAAdvert(hdr, 160 interfac, 161 xid, 162 useScopes, 163 config); 164 hdr = (SLPHeaderV1)daadvert.getHeader(); 165 166 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 167 168 hdr.externalize(baos, true, false); 169 byte[] outbuf = baos.toByteArray(); 170 171 bumpXid(); 172 173 return outbuf; 174 175 } catch (ServiceLocationException ex) { 176 Assert.slpassert(false, 177 "v1_advert_error", 178 new Object[0]); 179 180 } 181 182 return null; 183 } 184 185 private void bumpXid() { 186 187 int newXID = (int)xid + 1; 188 189 if (newXID > Short.MAX_VALUE) { 190 xid = STATEFUL_XID; 191 192 } else { 193 xid = (short)newXID; 194 195 } 196 } 197 } 198 199 200 // Start up listener, active and passive listeners for SLPv1. 201 202 static public void 203 start(SLPConfig config, ServerDATable table, ServiceTable stable) { 204 205 // We do not handle SLPv1 if security is enabled, because SLPv1 206 // security is not implemented. 207 208 if (config.getHasSecurity()) { 209 210 if (config.regTest() || 211 config.traceMsg() || 212 config.traceDrop() || 213 config.traceDATraffic()) { 214 215 config.writeLog("v1_security_enabled", 216 new Object[0]); 217 } 218 219 return; 220 221 } 222 223 Vector interfaces = config.getInterfaces(); 224 int i = 0, n = interfaces.size(); 225 Vector advs = new Vector(); 226 227 try { 228 229 InetAddress v1SLPDAAddr = null; 230 231 // Get address for DA discovery multicast. 232 233 v1SLPDAAddr = InetAddress.getByName(sDADiscSLPMCAddress); 234 v1SLPGSAddr = InetAddress.getByName(sGeneralSLPMCAddress); 235 236 // Add all listeners onto the SLPv1 DA multicast address and 237 // create a DAAdvertiser on all network interfaces for the 238 // general multicast group. 239 240 for (i = 0; i < n; i++) { 241 InetAddress interfac = (InetAddress)interfaces.elementAt(i); 242 243 // Listen for SLPv1 multicast DA service requests. Only DA 244 // service requests are multicast on this address. 245 246 Listener.addListenerToMulticastGroup(interfac, v1SLPDAAddr); 247 248 // We don't need to listen to the SLPv1 general multicast 249 // address because we never want any multicast service 250 // requests. But we do need to advertise as an SLPv1 DA. 251 // So we have a special DAAdvertiser subclass to do it. 252 253 DAAdvertiser ad = 254 new SLPV1Advertiser(interfac, v1SLPGSAddr, stable); 255 ad.start(); 256 257 advs.addElement(ad); 258 259 } 260 261 // Let admin know we are running in SLPv1 compatibility mode 262 // if tracing is on 263 264 if (config.regTest() || 265 config.traceMsg() || 266 config.traceDrop() || 267 config.traceDATraffic()) { 268 269 config.writeLog("v1_hello", 270 new Object[] {config.getSAConfiguredScopes()}); 271 } 272 273 return; 274 275 } catch (ServiceLocationException ex) { 276 277 config.writeLog("v1_init_error", 278 new Object[] {ex.getMessage()}); 279 280 } catch (UnknownHostException ex) { 281 282 config.writeLog("v1_init_error", 283 new Object[] {ex.getMessage()}); 284 285 } 286 287 // Remove Listeners from multicast group, stop DAAdvertisers. 288 // An error occured. 289 290 int j; 291 292 for (j = 0; j < i; i++) { 293 InetAddress interfac = (InetAddress)interfaces.elementAt(i); 294 DatagramSocket dss = 295 Listener.returnListenerSocketOnInterface(interfac); 296 297 if (dss instanceof MulticastSocket) { 298 MulticastSocket mss = (MulticastSocket)dss; 299 300 try { 301 mss.leaveGroup(v1SLPDAAddr); 302 303 } catch (IOException ex) { 304 305 // Ignore it. 306 307 } 308 309 DAAdvertiser ad = (DAAdvertiser)advs.elementAt(j); 310 311 ad.stopThread(); 312 } 313 } 314 } 315 316 // Initialize CSrvReg, CSrvDereg, CSrvMsg, and SDAAdvert classes for SLPv1, 317 // also V1 header class. 318 319 static { 320 321 SrvLocHeader.addHeaderClass(V1_HEADER_CLASS, SLPHeaderV1.VERSION); 322 323 } 324 } 325