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