xref: /onnv-gate/usr/src/lib/libslp/javalib/com/sun/slp/SLPV1Manager.java (revision 7298:b69e27387f74)
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