10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7298SMark.J.Nelson@Sun.COM * Common Development and Distribution License (the "License"). 6*7298SMark.J.Nelson@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 220Sstevel@tonic-gate * Copyright (c) 2001 by Sun Microsystems, Inc. 230Sstevel@tonic-gate * All rights reserved. 240Sstevel@tonic-gate * 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate // SLPV1Manager.java: Manages V1 Compatibility 280Sstevel@tonic-gate // Author: James Kempf 290Sstevel@tonic-gate // Created On: Wed Sep 9 09:51:40 1998 300Sstevel@tonic-gate // Last Modified By: James Kempf 310Sstevel@tonic-gate // Last Modified On: Thu Mar 4 10:39:11 1999 320Sstevel@tonic-gate // Update Count: 46 330Sstevel@tonic-gate // 340Sstevel@tonic-gate 350Sstevel@tonic-gate package com.sun.slp; 360Sstevel@tonic-gate 370Sstevel@tonic-gate import java.io.*; 380Sstevel@tonic-gate import java.util.*; 390Sstevel@tonic-gate import java.net.*; 400Sstevel@tonic-gate 410Sstevel@tonic-gate 420Sstevel@tonic-gate /** 430Sstevel@tonic-gate * The SLPV1Manager manages access between the DA and the V1 compatibility 440Sstevel@tonic-gate * framework. The DA calls into the SLPV1Manager to initialize 450Sstevel@tonic-gate * active and passive DA advertising, and to decode an incoming V1 460Sstevel@tonic-gate * message. However, the ServiceTable does *not* call into SLPV1Manager 470Sstevel@tonic-gate * to handle an outgoing message, since each individual message type is 480Sstevel@tonic-gate * handled separately. SLPV1Manager also handles V1 defaults. 490Sstevel@tonic-gate * 500Sstevel@tonic-gate * @author James Kempf 510Sstevel@tonic-gate */ 520Sstevel@tonic-gate 530Sstevel@tonic-gate abstract class SLPV1Manager extends Object { 540Sstevel@tonic-gate 550Sstevel@tonic-gate // V1 Header class. 560Sstevel@tonic-gate 570Sstevel@tonic-gate static final String V1_HEADER_CLASS = "com.sun.slp.SLPHeaderV1"; 580Sstevel@tonic-gate 590Sstevel@tonic-gate // V1 multicast addresses. 600Sstevel@tonic-gate 610Sstevel@tonic-gate static final String sGeneralSLPMCAddress = "224.0.1.22"; 620Sstevel@tonic-gate static final String sDADiscSLPMCAddress = "224.0.1.35"; 630Sstevel@tonic-gate 640Sstevel@tonic-gate static InetAddress v1SLPGSAddr = null; 650Sstevel@tonic-gate static InetAddress v1SLPDAAddr = null; 660Sstevel@tonic-gate 670Sstevel@tonic-gate /** 680Sstevel@tonic-gate * The SLPV1Advertiser implements the SLPv1 DAAdvert xid incrementing 690Sstevel@tonic-gate * algorithm. In SLPv1, the xid of an unsolicited DAAdvert is only 700Sstevel@tonic-gate * 0 if it came up stateless. If it comes up with preexisting state, 710Sstevel@tonic-gate * it sets the counter to 0x100. Also, when the xid counter wraps, 720Sstevel@tonic-gate * it must wrap to 0x100 and not 0x0. 730Sstevel@tonic-gate */ 740Sstevel@tonic-gate 750Sstevel@tonic-gate static class SLPV1Advertiser extends DAAdvertiser { 760Sstevel@tonic-gate 770Sstevel@tonic-gate // For implementing the V1 xid algorithm. 780Sstevel@tonic-gate 790Sstevel@tonic-gate private short xid = 0; 800Sstevel@tonic-gate 810Sstevel@tonic-gate private static final short STATEFUL_XID = 0x100; 820Sstevel@tonic-gate 830Sstevel@tonic-gate private static final long STATEFUL_TIME_BOUND = 300L; 840Sstevel@tonic-gate 850Sstevel@tonic-gate // Service table. 860Sstevel@tonic-gate 870Sstevel@tonic-gate private ServiceTable table = null; 880Sstevel@tonic-gate 890Sstevel@tonic-gate // Scopes to use. We need to map from V2, so default corresponds to 900Sstevel@tonic-gate // the empty scope. 910Sstevel@tonic-gate 920Sstevel@tonic-gate Vector useScopes = new Vector(); 930Sstevel@tonic-gate 940Sstevel@tonic-gate // Create an SLPv1 Advertiser and start it running. 950Sstevel@tonic-gate SLPV1Advertiser(InetAddress interfac, InetAddress maddr, ServiceTable table)960Sstevel@tonic-gate SLPV1Advertiser(InetAddress interfac, 970Sstevel@tonic-gate InetAddress maddr, 980Sstevel@tonic-gate ServiceTable table) 990Sstevel@tonic-gate throws ServiceLocationException { 1000Sstevel@tonic-gate super(); 1010Sstevel@tonic-gate 1020Sstevel@tonic-gate this.table = table; 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate initialize(); 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate // There will be NO listener on this multicast address, 1070Sstevel@tonic-gate // so the superclass will simply create a scoket for it. 1080Sstevel@tonic-gate // We don't want to create a new Listener 1090Sstevel@tonic-gate // because we are not interested in multicast requests since 1100Sstevel@tonic-gate // only SAs answer multicast requests. 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate initializeNetworking(interfac, maddr); 1130Sstevel@tonic-gate } 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate // Initialize the xid for passive advertising. We need to determine 1160Sstevel@tonic-gate // whether we came up stateless or not. We do this by asking the 1170Sstevel@tonic-gate // the service store for the stateless reboot time. If the 1180Sstevel@tonic-gate // stateless reboot time is within the last 5 minutes, we 1190Sstevel@tonic-gate // assume we came up stateless. Otherwise, we're stateful. 1200Sstevel@tonic-gate // We also initialize the URL and scopes. 1210Sstevel@tonic-gate initialize()1220Sstevel@tonic-gate private void initialize() throws ServiceLocationException { 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate // Initialize the xid. 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate ServiceStore store = ServiceTable.getServiceTable().store; 1270Sstevel@tonic-gate long timestamp = store.getStateTimestamp(); 1280Sstevel@tonic-gate long currentTime = SLPConfig.currentSLPTime(); 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate if ((currentTime - timestamp) > STATEFUL_TIME_BOUND) { 1310Sstevel@tonic-gate xid = STATEFUL_XID; 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate } 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate // Initialize the scopes. 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate useScopes = config.getSAConfiguredScopes(); 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 1410Sstevel@tonic-gate // Return the output buffer for a passive advert. We need to create 1420Sstevel@tonic-gate // the advert, rolling over the xid if necessary for the next one. 1430Sstevel@tonic-gate getOutbuf()1440Sstevel@tonic-gate protected byte[] getOutbuf() { 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate SDAAdvert daadvert = null; 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate try { 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate SLPHeaderV1 hdr = new SLPHeaderV1(); 1510Sstevel@tonic-gate hdr.functionCode = SrvLocHeader.DAAdvert; 1520Sstevel@tonic-gate hdr.locale = config.getLocale(); 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate daadvert = (SDAAdvert)table.makeDAAdvert(hdr, 1550Sstevel@tonic-gate interfac, 1560Sstevel@tonic-gate xid, 1570Sstevel@tonic-gate useScopes, 1580Sstevel@tonic-gate config); 1590Sstevel@tonic-gate hdr = (SLPHeaderV1)daadvert.getHeader(); 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate hdr.externalize(baos, true, false); 1640Sstevel@tonic-gate byte[] outbuf = baos.toByteArray(); 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate bumpXid(); 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate return outbuf; 1690Sstevel@tonic-gate 1700Sstevel@tonic-gate } catch (ServiceLocationException ex) { 1710Sstevel@tonic-gate Assert.slpassert(false, 1720Sstevel@tonic-gate "v1_advert_error", 1730Sstevel@tonic-gate new Object[0]); 1740Sstevel@tonic-gate 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate return null; 1780Sstevel@tonic-gate } 1790Sstevel@tonic-gate bumpXid()1800Sstevel@tonic-gate private void bumpXid() { 1810Sstevel@tonic-gate 1820Sstevel@tonic-gate int newXID = (int)xid + 1; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate if (newXID > Short.MAX_VALUE) { 1850Sstevel@tonic-gate xid = STATEFUL_XID; 1860Sstevel@tonic-gate 1870Sstevel@tonic-gate } else { 1880Sstevel@tonic-gate xid = (short)newXID; 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate } 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate // Start up listener, active and passive listeners for SLPv1. 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate static public void start(SLPConfig config, ServerDATable table, ServiceTable stable)1980Sstevel@tonic-gate start(SLPConfig config, ServerDATable table, ServiceTable stable) { 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate // We do not handle SLPv1 if security is enabled, because SLPv1 2010Sstevel@tonic-gate // security is not implemented. 2020Sstevel@tonic-gate 2030Sstevel@tonic-gate if (config.getHasSecurity()) { 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate if (config.regTest() || 2060Sstevel@tonic-gate config.traceMsg() || 2070Sstevel@tonic-gate config.traceDrop() || 2080Sstevel@tonic-gate config.traceDATraffic()) { 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate config.writeLog("v1_security_enabled", 2110Sstevel@tonic-gate new Object[0]); 2120Sstevel@tonic-gate } 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate return; 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate } 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate Vector interfaces = config.getInterfaces(); 2190Sstevel@tonic-gate int i = 0, n = interfaces.size(); 2200Sstevel@tonic-gate Vector advs = new Vector(); 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate try { 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate InetAddress v1SLPDAAddr = null; 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate // Get address for DA discovery multicast. 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate v1SLPDAAddr = InetAddress.getByName(sDADiscSLPMCAddress); 2290Sstevel@tonic-gate v1SLPGSAddr = InetAddress.getByName(sGeneralSLPMCAddress); 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate // Add all listeners onto the SLPv1 DA multicast address and 2320Sstevel@tonic-gate // create a DAAdvertiser on all network interfaces for the 2330Sstevel@tonic-gate // general multicast group. 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate for (i = 0; i < n; i++) { 2360Sstevel@tonic-gate InetAddress interfac = (InetAddress)interfaces.elementAt(i); 2370Sstevel@tonic-gate 2380Sstevel@tonic-gate // Listen for SLPv1 multicast DA service requests. Only DA 2390Sstevel@tonic-gate // service requests are multicast on this address. 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate Listener.addListenerToMulticastGroup(interfac, v1SLPDAAddr); 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate // We don't need to listen to the SLPv1 general multicast 2440Sstevel@tonic-gate // address because we never want any multicast service 2450Sstevel@tonic-gate // requests. But we do need to advertise as an SLPv1 DA. 2460Sstevel@tonic-gate // So we have a special DAAdvertiser subclass to do it. 2470Sstevel@tonic-gate 2480Sstevel@tonic-gate DAAdvertiser ad = 2490Sstevel@tonic-gate new SLPV1Advertiser(interfac, v1SLPGSAddr, stable); 2500Sstevel@tonic-gate ad.start(); 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate advs.addElement(ad); 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate } 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate // Let admin know we are running in SLPv1 compatibility mode 2570Sstevel@tonic-gate // if tracing is on 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate if (config.regTest() || 2600Sstevel@tonic-gate config.traceMsg() || 2610Sstevel@tonic-gate config.traceDrop() || 2620Sstevel@tonic-gate config.traceDATraffic()) { 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate config.writeLog("v1_hello", 2650Sstevel@tonic-gate new Object[] {config.getSAConfiguredScopes()}); 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate return; 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate } catch (ServiceLocationException ex) { 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate config.writeLog("v1_init_error", 2730Sstevel@tonic-gate new Object[] {ex.getMessage()}); 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate } catch (UnknownHostException ex) { 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate config.writeLog("v1_init_error", 2780Sstevel@tonic-gate new Object[] {ex.getMessage()}); 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate } 2810Sstevel@tonic-gate 2820Sstevel@tonic-gate // Remove Listeners from multicast group, stop DAAdvertisers. 2830Sstevel@tonic-gate // An error occured. 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate int j; 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate for (j = 0; j < i; i++) { 2880Sstevel@tonic-gate InetAddress interfac = (InetAddress)interfaces.elementAt(i); 2890Sstevel@tonic-gate DatagramSocket dss = 2900Sstevel@tonic-gate Listener.returnListenerSocketOnInterface(interfac); 2910Sstevel@tonic-gate 2920Sstevel@tonic-gate if (dss instanceof MulticastSocket) { 2930Sstevel@tonic-gate MulticastSocket mss = (MulticastSocket)dss; 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate try { 2960Sstevel@tonic-gate mss.leaveGroup(v1SLPDAAddr); 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate } catch (IOException ex) { 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate // Ignore it. 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate } 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate DAAdvertiser ad = (DAAdvertiser)advs.elementAt(j); 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate ad.stopThread(); 3070Sstevel@tonic-gate } 3080Sstevel@tonic-gate } 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate // Initialize CSrvReg, CSrvDereg, CSrvMsg, and SDAAdvert classes for SLPv1, 3120Sstevel@tonic-gate // also V1 header class. 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate static { 3150Sstevel@tonic-gate SrvLocHeader.addHeaderClass(V1_HEADER_CLASS, SLPHeaderV1.VERSION)3160Sstevel@tonic-gate SrvLocHeader.addHeaderClass(V1_HEADER_CLASS, SLPHeaderV1.VERSION); 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate } 320