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) 1999 by Sun Microsystems, Inc. 26 * All rights reserved. 27 * 28 */ 29 30 // SCCS Status: %W% %G% 31 // DAAdvertiser.java: Advertise a DA, also handle incoming DAAdverts. 32 // Author: James Kempf 33 // Created On: Tue May 19 15:22:04 1998 34 // Last Modified By: James Kempf 35 // Last Modified On: Thu Mar 4 10:39:06 1999 36 // Update Count: 44 37 // 38 39 package com.sun.slp; 40 41 import java.net.*; 42 import java.util.*; 43 import java.io.*; 44 45 /** 46 * This class supplies a regular interval 'heartbeat' DAAdvertisement. 47 * Implementation specific subclasses handle incoming DAAdverts and 48 * forwarding of registrations and deregistrations to other DAs. The 49 * implementation specific subclasses depend on how the server is 50 * representing DA information internally. 51 * 52 * @version %R%.%L% %D% 53 * @author James Kempf, Erik Guttman 54 */ 55 56 class DAAdvertiser extends Thread { 57 58 protected DatagramSocket dss = null; 59 protected InetAddress castAddr = null; 60 protected InetAddress interfac = null; 61 62 // V2 advertising has the same DAAdvert every time. 63 64 static private byte[] outbuf = null; 65 66 static protected SLPConfig config = null; // Config object. 67 static protected Hashtable daadv = 68 new Hashtable(); // Existing advertisers 69 70 private Boolean done = new Boolean(false); 71 72 // Initialize the DAAdvertiser on the designated interface. 73 74 static void initializeDAAdvertiserOnInterface(InetAddress interfac) 75 throws ServiceLocationException { 76 77 // If we've got it, return. 78 79 if (daadv.get(interfac) != null) { 80 return; 81 82 } 83 84 // Get the config object. 85 86 if (config == null) { 87 config = SLPConfig.getSLPConfig(); 88 89 } 90 91 // Get the SLPv2 DAADvert to send 92 93 ServiceTable table = ServiceTable.getServiceTable(); 94 95 SLPServerHeaderV2 hdr = 96 new SLPServerHeaderV2(SrvLocHeader.DAAdvert, 97 false, 98 config.getLocale()); 99 100 SDAAdvert msg = 101 (SDAAdvert)table.makeDAAdvert(hdr, 102 interfac, 103 (short)0x0, 104 config.getSAConfiguredScopes(), 105 config); 106 107 // Create a new DAAdvertiser for this interface, with SLPv2 108 // message to send. 109 110 DAAdvertiser daadv = new DAAdvertiser(interfac, msg.getHeader()); 111 112 // Start thread running. 113 114 daadv.start(); 115 116 } 117 118 // Used by V1 subclass constructor. 119 120 DAAdvertiser() { 121 122 if (config == null) { 123 config = SLPConfig.getSLPConfig(); 124 125 } 126 127 } 128 129 // Create a new DAAdvertiser for the interface for default multicast 130 // address. Externalize the message and set the instance variable. 131 132 DAAdvertiser(InetAddress interfac, SrvLocHeader hdr) 133 throws ServiceLocationException { 134 135 // Config may not be initialized if this was called directly from 136 // slpd. 137 138 if (config == null) { 139 config = SLPConfig.getSLPConfig(); 140 141 } 142 143 // Externalize the DAAdvert. 144 145 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 146 147 hdr.externalize(baos, true, false); 148 outbuf = baos.toByteArray(); 149 150 // Initialize the networking for default multicast address. 151 152 initializeNetworking(interfac, config.getMulticastAddress()); 153 154 } 155 156 157 // Convert advert to bytes, initialize networking. 158 159 protected void 160 initializeNetworking(InetAddress interfac, 161 InetAddress maddr) 162 throws ServiceLocationException { 163 164 // Set the interface and multicast address on this advertiser. 165 166 this.interfac = interfac; 167 this.castAddr = maddr; 168 169 // Get the socket from the listener object corresponding to this 170 // interface. The listener will always be started before the 171 // DAAdvertiser, otherwise, SAs may start sending registrations 172 // before anybody is listening. 173 174 dss = Listener.returnListenerSocketOnInterface(interfac); 175 176 // If the socket is null, then there is no listener. Open a 177 // new socket. Note that any listener opened *afterwards* will 178 // not get this socket. 179 180 if (dss == null) { 181 dss = config.getMulticastSocketOnInterface(interfac, true); 182 183 } 184 } 185 186 public void run() { 187 188 // Set the thread name. 189 190 setName("SLP DA Advertisement"); 191 192 long heartbeat = config.getAdvertHeartbeatTime() * 1000; 193 194 while (true) { 195 196 // Send an advert. 197 198 sendAdvert(); 199 200 // Sleep until next time. 201 202 try { 203 sleep(heartbeat); 204 205 } catch (InterruptedException ie) { 206 207 // Somebody interrupted us. If we are to exit, then do so. 208 209 synchronized (done) { 210 211 if (done.booleanValue()) { 212 return; 213 214 } 215 } 216 217 } 218 219 } 220 } 221 222 // Send an unsolicited DAAdvert. 223 224 void sendAdvert() { 225 226 byte[] buf = getOutbuf(); 227 228 DatagramPacket dp = 229 new DatagramPacket(buf, 230 buf.length, 231 castAddr, 232 Defaults.iSLPPort); 233 try { 234 235 dss.send(dp); 236 237 } catch (IOException ex) { 238 config.writeLog("passive_advert_exception", 239 new Object[] {ex.getMessage()}); 240 241 // Tell the listener to refresh the socket. 242 243 dss = Listener.refreshSocketOnInterface(interfac); 244 245 } 246 } 247 248 // Return the buffer for transmission. 249 250 protected byte[] getOutbuf() { 251 return outbuf; 252 253 } 254 255 // Stop the thread from executing. 256 257 void stopThread() { 258 259 synchronized (done) { 260 done = new Boolean(true); 261 262 } 263 264 this.interrupt(); 265 266 } 267 } 268