17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 59a70fc3bSMark J. Nelson * Common Development and Distribution License (the "License"). 69a70fc3bSMark J. Nelson * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 227c478bd9Sstevel@tonic-gate * Copyright (c) 2001 by Sun Microsystems, Inc. 237c478bd9Sstevel@tonic-gate * All rights reserved. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate // SLPV1Manager.java: Manages V1 Compatibility 287c478bd9Sstevel@tonic-gate // Author: James Kempf 297c478bd9Sstevel@tonic-gate // Created On: Wed Sep 9 09:51:40 1998 307c478bd9Sstevel@tonic-gate // Last Modified By: James Kempf 317c478bd9Sstevel@tonic-gate // Last Modified On: Thu Mar 4 10:39:11 1999 327c478bd9Sstevel@tonic-gate // Update Count: 46 337c478bd9Sstevel@tonic-gate // 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate package com.sun.slp; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate import java.io.*; 387c478bd9Sstevel@tonic-gate import java.util.*; 397c478bd9Sstevel@tonic-gate import java.net.*; 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate /** 437c478bd9Sstevel@tonic-gate * The SLPV1Manager manages access between the DA and the V1 compatibility 447c478bd9Sstevel@tonic-gate * framework. The DA calls into the SLPV1Manager to initialize 457c478bd9Sstevel@tonic-gate * active and passive DA advertising, and to decode an incoming V1 467c478bd9Sstevel@tonic-gate * message. However, the ServiceTable does *not* call into SLPV1Manager 477c478bd9Sstevel@tonic-gate * to handle an outgoing message, since each individual message type is 487c478bd9Sstevel@tonic-gate * handled separately. SLPV1Manager also handles V1 defaults. 497c478bd9Sstevel@tonic-gate * 507c478bd9Sstevel@tonic-gate * @author James Kempf 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate abstract class SLPV1Manager extends Object { 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate // V1 Header class. 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate static final String V1_HEADER_CLASS = "com.sun.slp.SLPHeaderV1"; 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate // V1 multicast addresses. 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static final String sGeneralSLPMCAddress = "224.0.1.22"; 627c478bd9Sstevel@tonic-gate static final String sDADiscSLPMCAddress = "224.0.1.35"; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate static InetAddress v1SLPGSAddr = null; 657c478bd9Sstevel@tonic-gate static InetAddress v1SLPDAAddr = null; 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /** 687c478bd9Sstevel@tonic-gate * The SLPV1Advertiser implements the SLPv1 DAAdvert xid incrementing 697c478bd9Sstevel@tonic-gate * algorithm. In SLPv1, the xid of an unsolicited DAAdvert is only 707c478bd9Sstevel@tonic-gate * 0 if it came up stateless. If it comes up with preexisting state, 717c478bd9Sstevel@tonic-gate * it sets the counter to 0x100. Also, when the xid counter wraps, 727c478bd9Sstevel@tonic-gate * it must wrap to 0x100 and not 0x0. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate static class SLPV1Advertiser extends DAAdvertiser { 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate // For implementing the V1 xid algorithm. 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate private short xid = 0; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate private static final short STATEFUL_XID = 0x100; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate private static final long STATEFUL_TIME_BOUND = 300L; 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate // Service table. 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate private ServiceTable table = null; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate // Scopes to use. We need to map from V2, so default corresponds to 907c478bd9Sstevel@tonic-gate // the empty scope. 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate Vector useScopes = new Vector(); 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate // Create an SLPv1 Advertiser and start it running. 957c478bd9Sstevel@tonic-gate SLPV1Advertiser(InetAddress interfac, InetAddress maddr, ServiceTable table)967c478bd9Sstevel@tonic-gate SLPV1Advertiser(InetAddress interfac, 977c478bd9Sstevel@tonic-gate InetAddress maddr, 987c478bd9Sstevel@tonic-gate ServiceTable table) 997c478bd9Sstevel@tonic-gate throws ServiceLocationException { 1007c478bd9Sstevel@tonic-gate super(); 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate this.table = table; 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate initialize(); 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate // There will be NO listener on this multicast address, 1077c478bd9Sstevel@tonic-gate // so the superclass will simply create a scoket for it. 1087c478bd9Sstevel@tonic-gate // We don't want to create a new Listener 1097c478bd9Sstevel@tonic-gate // because we are not interested in multicast requests since 1107c478bd9Sstevel@tonic-gate // only SAs answer multicast requests. 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate initializeNetworking(interfac, maddr); 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate // Initialize the xid for passive advertising. We need to determine 1167c478bd9Sstevel@tonic-gate // whether we came up stateless or not. We do this by asking the 1177c478bd9Sstevel@tonic-gate // the service store for the stateless reboot time. If the 1187c478bd9Sstevel@tonic-gate // stateless reboot time is within the last 5 minutes, we 1197c478bd9Sstevel@tonic-gate // assume we came up stateless. Otherwise, we're stateful. 1207c478bd9Sstevel@tonic-gate // We also initialize the URL and scopes. 1217c478bd9Sstevel@tonic-gate initialize()1227c478bd9Sstevel@tonic-gate private void initialize() throws ServiceLocationException { 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate // Initialize the xid. 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate ServiceStore store = ServiceTable.getServiceTable().store; 1277c478bd9Sstevel@tonic-gate long timestamp = store.getStateTimestamp(); 1287c478bd9Sstevel@tonic-gate long currentTime = SLPConfig.currentSLPTime(); 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate if ((currentTime - timestamp) > STATEFUL_TIME_BOUND) { 1317c478bd9Sstevel@tonic-gate xid = STATEFUL_XID; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate // Initialize the scopes. 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate useScopes = config.getSAConfiguredScopes(); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate // Return the output buffer for a passive advert. We need to create 1427c478bd9Sstevel@tonic-gate // the advert, rolling over the xid if necessary for the next one. 1437c478bd9Sstevel@tonic-gate getOutbuf()1447c478bd9Sstevel@tonic-gate protected byte[] getOutbuf() { 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate SDAAdvert daadvert = null; 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate try { 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate SLPHeaderV1 hdr = new SLPHeaderV1(); 1517c478bd9Sstevel@tonic-gate hdr.functionCode = SrvLocHeader.DAAdvert; 1527c478bd9Sstevel@tonic-gate hdr.locale = config.getLocale(); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate daadvert = (SDAAdvert)table.makeDAAdvert(hdr, 1557c478bd9Sstevel@tonic-gate interfac, 1567c478bd9Sstevel@tonic-gate xid, 1577c478bd9Sstevel@tonic-gate useScopes, 1587c478bd9Sstevel@tonic-gate config); 1597c478bd9Sstevel@tonic-gate hdr = (SLPHeaderV1)daadvert.getHeader(); 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate ByteArrayOutputStream baos = new ByteArrayOutputStream(); 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate hdr.externalize(baos, true, false); 1647c478bd9Sstevel@tonic-gate byte[] outbuf = baos.toByteArray(); 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate bumpXid(); 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate return outbuf; 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate } catch (ServiceLocationException ex) { 1717c478bd9Sstevel@tonic-gate Assert.slpassert(false, 1727c478bd9Sstevel@tonic-gate "v1_advert_error", 1737c478bd9Sstevel@tonic-gate new Object[0]); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate return null; 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate bumpXid()1807c478bd9Sstevel@tonic-gate private void bumpXid() { 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate int newXID = (int)xid + 1; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate if (newXID > Short.MAX_VALUE) { 1857c478bd9Sstevel@tonic-gate xid = STATEFUL_XID; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate } else { 1887c478bd9Sstevel@tonic-gate xid = (short)newXID; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate // Start up listener, active and passive listeners for SLPv1. 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate static public void start(SLPConfig config, ServerDATable table, ServiceTable stable)1987c478bd9Sstevel@tonic-gate start(SLPConfig config, ServerDATable table, ServiceTable stable) { 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate // We do not handle SLPv1 if security is enabled, because SLPv1 2017c478bd9Sstevel@tonic-gate // security is not implemented. 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate if (config.getHasSecurity()) { 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if (config.regTest() || 2067c478bd9Sstevel@tonic-gate config.traceMsg() || 2077c478bd9Sstevel@tonic-gate config.traceDrop() || 2087c478bd9Sstevel@tonic-gate config.traceDATraffic()) { 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate config.writeLog("v1_security_enabled", 2117c478bd9Sstevel@tonic-gate new Object[0]); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate return; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate Vector interfaces = config.getInterfaces(); 2197c478bd9Sstevel@tonic-gate int i = 0, n = interfaces.size(); 2207c478bd9Sstevel@tonic-gate Vector advs = new Vector(); 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate try { 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate InetAddress v1SLPDAAddr = null; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate // Get address for DA discovery multicast. 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate v1SLPDAAddr = InetAddress.getByName(sDADiscSLPMCAddress); 2297c478bd9Sstevel@tonic-gate v1SLPGSAddr = InetAddress.getByName(sGeneralSLPMCAddress); 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate // Add all listeners onto the SLPv1 DA multicast address and 2327c478bd9Sstevel@tonic-gate // create a DAAdvertiser on all network interfaces for the 2337c478bd9Sstevel@tonic-gate // general multicast group. 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 2367c478bd9Sstevel@tonic-gate InetAddress interfac = (InetAddress)interfaces.elementAt(i); 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate // Listen for SLPv1 multicast DA service requests. Only DA 2397c478bd9Sstevel@tonic-gate // service requests are multicast on this address. 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate Listener.addListenerToMulticastGroup(interfac, v1SLPDAAddr); 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate // We don't need to listen to the SLPv1 general multicast 2447c478bd9Sstevel@tonic-gate // address because we never want any multicast service 2457c478bd9Sstevel@tonic-gate // requests. But we do need to advertise as an SLPv1 DA. 2467c478bd9Sstevel@tonic-gate // So we have a special DAAdvertiser subclass to do it. 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate DAAdvertiser ad = 2497c478bd9Sstevel@tonic-gate new SLPV1Advertiser(interfac, v1SLPGSAddr, stable); 2507c478bd9Sstevel@tonic-gate ad.start(); 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate advs.addElement(ad); 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate // Let admin know we are running in SLPv1 compatibility mode 2577c478bd9Sstevel@tonic-gate // if tracing is on 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate if (config.regTest() || 2607c478bd9Sstevel@tonic-gate config.traceMsg() || 2617c478bd9Sstevel@tonic-gate config.traceDrop() || 2627c478bd9Sstevel@tonic-gate config.traceDATraffic()) { 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate config.writeLog("v1_hello", 2657c478bd9Sstevel@tonic-gate new Object[] {config.getSAConfiguredScopes()}); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate return; 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate } catch (ServiceLocationException ex) { 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate config.writeLog("v1_init_error", 2737c478bd9Sstevel@tonic-gate new Object[] {ex.getMessage()}); 274*55fea89dSDan Cross 2757c478bd9Sstevel@tonic-gate } catch (UnknownHostException ex) { 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate config.writeLog("v1_init_error", 2787c478bd9Sstevel@tonic-gate new Object[] {ex.getMessage()}); 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate // Remove Listeners from multicast group, stop DAAdvertisers. 2837c478bd9Sstevel@tonic-gate // An error occured. 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate int j; 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate for (j = 0; j < i; i++) { 2887c478bd9Sstevel@tonic-gate InetAddress interfac = (InetAddress)interfaces.elementAt(i); 2897c478bd9Sstevel@tonic-gate DatagramSocket dss = 2907c478bd9Sstevel@tonic-gate Listener.returnListenerSocketOnInterface(interfac); 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate if (dss instanceof MulticastSocket) { 2937c478bd9Sstevel@tonic-gate MulticastSocket mss = (MulticastSocket)dss; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate try { 2967c478bd9Sstevel@tonic-gate mss.leaveGroup(v1SLPDAAddr); 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate } catch (IOException ex) { 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate // Ignore it. 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate DAAdvertiser ad = (DAAdvertiser)advs.elementAt(j); 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate ad.stopThread(); 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate // Initialize CSrvReg, CSrvDereg, CSrvMsg, and SDAAdvert classes for SLPv1, 3127c478bd9Sstevel@tonic-gate // also V1 header class. 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate static { 3157c478bd9Sstevel@tonic-gate SrvLocHeader.addHeaderClass(V1_HEADER_CLASS, SLPHeaderV1.VERSION)3167c478bd9Sstevel@tonic-gate SrvLocHeader.addHeaderClass(V1_HEADER_CLASS, SLPHeaderV1.VERSION); 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate } 320