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