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 2001-2002 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate * 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate // RequestHandler.java: Handle an incoming request in a separate thread. 280Sstevel@tonic-gate // Author: James Kempf 290Sstevel@tonic-gate // Created On: Mon May 18 14:00:27 1998 300Sstevel@tonic-gate // Last Modified By: James Kempf 310Sstevel@tonic-gate // Last Modified On: Mon Mar 8 16:12:13 1999 320Sstevel@tonic-gate // Update Count: 173 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.net.*; 390Sstevel@tonic-gate import java.util.*; 400Sstevel@tonic-gate 410Sstevel@tonic-gate /** 420Sstevel@tonic-gate * Handle an incoming request in a separate thread. The request 430Sstevel@tonic-gate * may have arrived via datagram, or it may have arrived via 440Sstevel@tonic-gate * stream. 450Sstevel@tonic-gate * 460Sstevel@tonic-gate * @author James Kempf, Erik Guttman 470Sstevel@tonic-gate */ 480Sstevel@tonic-gate 490Sstevel@tonic-gate 500Sstevel@tonic-gate class RequestHandler extends Thread { 510Sstevel@tonic-gate 520Sstevel@tonic-gate private SLPConfig config; // Config for system properties. 530Sstevel@tonic-gate private ServerDATable daTable; // DA table in server for reg and dereg 540Sstevel@tonic-gate private InetAddress interfac = null; // Interface on which request came in. 550Sstevel@tonic-gate private Socket sock = null; // Socket for incoming stream request. 560Sstevel@tonic-gate private DatagramPacket packet = null; // Packet for datagram requests. 570Sstevel@tonic-gate private InetAddress clientAddr = null; // Internet address of the client. 580Sstevel@tonic-gate private int port = 0; // Port to use. 590Sstevel@tonic-gate private ServiceTable serviceTable = null; 600Sstevel@tonic-gate private SrvLocMsg toForward = null; // Reg or dereg to forward. 610Sstevel@tonic-gate private InputStream inStream = null; 620Sstevel@tonic-gate private OutputStream outStream = null; 630Sstevel@tonic-gate 640Sstevel@tonic-gate static private Hashtable inProgress = new Hashtable(); 650Sstevel@tonic-gate // Keeps track of in progress requests 660Sstevel@tonic-gate 670Sstevel@tonic-gate // When a request handler gets GC'd, make sure it's open socket is closed. 680Sstevel@tonic-gate // We simply let the exception propagate, because it is ignored. 690Sstevel@tonic-gate finalize()700Sstevel@tonic-gate protected void finalize() throws IOException { 710Sstevel@tonic-gate if (sock != null) sock.close(); 720Sstevel@tonic-gate 730Sstevel@tonic-gate } 740Sstevel@tonic-gate RequestHandler(InputStream in, OutputStream out, SLPConfig config_in)750Sstevel@tonic-gate RequestHandler(InputStream in, OutputStream out, SLPConfig config_in) { 760Sstevel@tonic-gate config = config_in; 770Sstevel@tonic-gate sock = null; 780Sstevel@tonic-gate inStream = in; 790Sstevel@tonic-gate outStream = out; 800Sstevel@tonic-gate clientAddr = config.getLoopback(); 810Sstevel@tonic-gate port = 427; 820Sstevel@tonic-gate interfac = clientAddr; 830Sstevel@tonic-gate 840Sstevel@tonic-gate try { 850Sstevel@tonic-gate serviceTable = ServiceTable.getServiceTable(); 860Sstevel@tonic-gate 870Sstevel@tonic-gate } catch (ServiceLocationException ex) { 880Sstevel@tonic-gate 890Sstevel@tonic-gate // Taken care of in initialization code. 900Sstevel@tonic-gate 910Sstevel@tonic-gate } 920Sstevel@tonic-gate } 930Sstevel@tonic-gate 940Sstevel@tonic-gate // Request arrived via stream. Set the incoming socket, spawn 950Sstevel@tonic-gate // a separate thread in which to run. 960Sstevel@tonic-gate RequestHandler(Socket sock_in, InetAddress interfac, SLPConfig config_in)970Sstevel@tonic-gate RequestHandler(Socket sock_in, InetAddress interfac, SLPConfig config_in) { 980Sstevel@tonic-gate 990Sstevel@tonic-gate Assert.slpassert((sock_in != null), 1000Sstevel@tonic-gate "rh_null_sock", 1010Sstevel@tonic-gate new Object[0]); 1020Sstevel@tonic-gate Assert.slpassert((config_in != null), 1030Sstevel@tonic-gate "ls_null_config", 1040Sstevel@tonic-gate new Object[0]); 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate config = config_in; 1070Sstevel@tonic-gate sock = sock_in; 1080Sstevel@tonic-gate clientAddr = sock.getInetAddress(); 1090Sstevel@tonic-gate port = sock.getPort(); 1100Sstevel@tonic-gate this.interfac = interfac; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate try { 1130Sstevel@tonic-gate serviceTable = ServiceTable.getServiceTable(); 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate } catch (ServiceLocationException ex) { 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate // Taken care of in initialization code. 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate } 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate // Request arrived via datagram. Set the incoming packet, spawn 1230Sstevel@tonic-gate // a separate thread in which to run. 1240Sstevel@tonic-gate RequestHandler(DatagramPacket packet_in, InetAddress interfac, SLPConfig config_in)1250Sstevel@tonic-gate RequestHandler(DatagramPacket packet_in, 1260Sstevel@tonic-gate InetAddress interfac, 1270Sstevel@tonic-gate SLPConfig config_in) { 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate Assert.slpassert((packet_in != null), 1300Sstevel@tonic-gate "rh_null_packy", 1310Sstevel@tonic-gate new Object[0]); 1320Sstevel@tonic-gate Assert.slpassert((config_in != null), 1330Sstevel@tonic-gate "ls_null_config", 1340Sstevel@tonic-gate new Object[0]); 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate config = config_in; 1370Sstevel@tonic-gate packet = packet_in; 1380Sstevel@tonic-gate clientAddr = packet.getAddress(); 1390Sstevel@tonic-gate port = packet.getPort(); 1400Sstevel@tonic-gate this.interfac = interfac; 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate try { 1430Sstevel@tonic-gate serviceTable = ServiceTable.getServiceTable(); 1440Sstevel@tonic-gate daTable = ServerDATable.getServerDATable(); 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate } catch (ServiceLocationException ex) { 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate // Taken care of in initialziation code. 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate } 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate } 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate /** 1550Sstevel@tonic-gate * Return a stringified buffer, suitable for printing, for 1560Sstevel@tonic-gate * debugging. 1570Sstevel@tonic-gate * 1580Sstevel@tonic-gate * @param bytes The byte buffer. 1590Sstevel@tonic-gate * @return A string with the ASCII characters as characters, otherwise 1600Sstevel@tonic-gate * convert to escape notation. 1610Sstevel@tonic-gate */ 1620Sstevel@tonic-gate stringifyBuffer(byte[] bytes)1630Sstevel@tonic-gate static String stringifyBuffer(byte[] bytes) { 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 1660Sstevel@tonic-gate int i, n = bytes.length; 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate for (i = 0; i < n; i++) { 1690Sstevel@tonic-gate byte b = bytes[i]; 1700Sstevel@tonic-gate 1710Sstevel@tonic-gate if ((b >= 0x21) && (b < 0x7e)) { 1720Sstevel@tonic-gate buf.append((char)b); 1730Sstevel@tonic-gate } else { 1740Sstevel@tonic-gate buf.append("\\"+Integer.toHexString(((int)b) & 0xFF)); 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate } 1770Sstevel@tonic-gate 1780Sstevel@tonic-gate return buf.toString(); 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate // If a stream thread, then get the request first. Process the 1820Sstevel@tonic-gate // request and reply to client. 1830Sstevel@tonic-gate run()1840Sstevel@tonic-gate public void run() { 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate // Is this a stream or datagram thread? 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate if (sock != null || inStream != null) { 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate // Label appropriately. 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate setName("Stream Request Handler "+clientAddr+":"+port); 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate if (sock != null) { 1950Sstevel@tonic-gate // Set the socket to block until there are bytes to read. 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate try { 1980Sstevel@tonic-gate sock.setSoTimeout(0); 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate } catch (SocketException ex) { 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate } 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate // get DA Table 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate try { 2090Sstevel@tonic-gate daTable = ServerDATable.getServerDATable(); 2100Sstevel@tonic-gate } catch (ServiceLocationException e) { 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate // Taken care of in initialziation code. 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate // Stream needs to loop through until requests are completed. 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate handleStream(); 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate if (sock != null) { 2210Sstevel@tonic-gate try { 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate sock.close(); 2240Sstevel@tonic-gate sock = null; 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate } catch (IOException ex) { 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate } 2290Sstevel@tonic-gate } 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate } else { 2320Sstevel@tonic-gate 2330Sstevel@tonic-gate // Label appropriately. 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate setName("Datagram Request Handler "+clientAddr+":"+port); 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate byte[] inbuf = packet.getData(); 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate // Copy xid for use in hash key. 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate byte[] xidBuf = new byte[2]; 2420Sstevel@tonic-gate System.arraycopy(inbuf, SrvLocHeader.XID_OFFSET, xidBuf, 0, 2); 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate // If this request is already in progress, drop new request. 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate int xid = 0; 2470Sstevel@tonic-gate xid = (int)((char)xidBuf[0] & 0xFF) << 8; 2480Sstevel@tonic-gate xid += (int)((char)xidBuf[1] & 0xFF); 2490Sstevel@tonic-gate String syncTableKey = 2500Sstevel@tonic-gate (new Integer(xid)).toString() + clientAddr.getHostAddress(); 2510Sstevel@tonic-gate boolean there = false; 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate synchronized (inProgress) { 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate there = (inProgress.get(syncTableKey) != null); 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate if (!there) { 2580Sstevel@tonic-gate inProgress.put(syncTableKey, this); 2590Sstevel@tonic-gate 2600Sstevel@tonic-gate } 2610Sstevel@tonic-gate } 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate // Drop if we are processing it already. 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate if (there) { 2660Sstevel@tonic-gate if (config.traceDrop()) { 2670Sstevel@tonic-gate config.writeLog("rh_rqst_in_progress", 2680Sstevel@tonic-gate new Object[] {clientAddr, 2690Sstevel@tonic-gate new Integer(port), 2700Sstevel@tonic-gate interfac}); 2710Sstevel@tonic-gate } 2720Sstevel@tonic-gate return; 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate } 2750Sstevel@tonic-gate 2760Sstevel@tonic-gate // We can simply cut to the chase and process the datagram 2770Sstevel@tonic-gate // request. 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate DataInputStream dis = 2800Sstevel@tonic-gate new DataInputStream(new ByteArrayInputStream(inbuf)); 2810Sstevel@tonic-gate ByteArrayOutputStream baos = new ByteArrayOutputStream(); 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate try { 2840Sstevel@tonic-gate 2850Sstevel@tonic-gate handleRequest(dis, baos, false); 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate byte[] outbuf = baos.toByteArray(); 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate // Open a data output stream for the outgoing request. There 2900Sstevel@tonic-gate // is no buffer for reply or it is empty, the request was 2910Sstevel@tonic-gate // multicast and nothing was sent back. 2920Sstevel@tonic-gate 2930Sstevel@tonic-gate if (outbuf != null && outbuf.length > 0) { 2940Sstevel@tonic-gate sendDatagramReply(outbuf); 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate } 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate } catch (IOException ex) { 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate // No excuse for an EOF exception here. 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate if (config.traceDrop()) { 3030Sstevel@tonic-gate config.writeLog("rh_datagram_ioe", 3040Sstevel@tonic-gate new Object[] {clientAddr, 3050Sstevel@tonic-gate new Integer(port), 3060Sstevel@tonic-gate interfac, 3070Sstevel@tonic-gate ex.getMessage()}); 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate } 3110Sstevel@tonic-gate 3120Sstevel@tonic-gate // Remove the lock for this request. We do this just before the 3130Sstevel@tonic-gate // run() method exits and the thread expires to reduce the 3140Sstevel@tonic-gate // window in which a new copy of the request could come in. 3150Sstevel@tonic-gate // We need to be sure that we only remove if it is this 3160Sstevel@tonic-gate // request handler. 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate synchronized (inProgress) { 3190Sstevel@tonic-gate RequestHandler rh = 3200Sstevel@tonic-gate (RequestHandler)inProgress.get(syncTableKey); 3210Sstevel@tonic-gate 3220Sstevel@tonic-gate if (rh == this) { 3230Sstevel@tonic-gate inProgress.remove(syncTableKey); 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate } 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate } 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate // Handle an incoming stream. 3340Sstevel@tonic-gate handleStream()3350Sstevel@tonic-gate private void handleStream() { 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate try { 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate DataInputStream dis = null; 3400Sstevel@tonic-gate DataOutputStream dos = null; 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate if (inStream != null) { 3430Sstevel@tonic-gate dis = new DataInputStream(inStream); 3440Sstevel@tonic-gate dos = new DataOutputStream(outStream); 3450Sstevel@tonic-gate } else { 3460Sstevel@tonic-gate // use the socket 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate dis = new DataInputStream(sock.getInputStream()); 3490Sstevel@tonic-gate dos = new DataOutputStream(sock.getOutputStream()); 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate // Loop while the client still wants to send something. But we 3530Sstevel@tonic-gate // only read one SLP message at a time on the connection, 3540Sstevel@tonic-gate // returning if it there are no more bytes to read. Note that 3550Sstevel@tonic-gate // we have to use a do/while loop here so that the read hangs 3560Sstevel@tonic-gate // until something shows up. 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate do { 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate // Handle the new request. 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate ByteArrayOutputStream baos = new ByteArrayOutputStream(); 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate boolean parseError = handleRequest(dis, baos, true); 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate dos.write(baos.toByteArray(), 0, baos.size()); 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate // Forward reg or dereg to foreign DAs that need to know 3690Sstevel@tonic-gate // about it. 3700Sstevel@tonic-gate 3710Sstevel@tonic-gate if (toForward != null) { 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate try { 3740Sstevel@tonic-gate daTable.forwardSAMessage(toForward, clientAddr); 3750Sstevel@tonic-gate toForward = null; 3760Sstevel@tonic-gate 3770Sstevel@tonic-gate } catch (ServiceLocationException ex) { 3780Sstevel@tonic-gate config.writeLog("sa_forwarding_exception", 3790Sstevel@tonic-gate new Object[] { 3800Sstevel@tonic-gate new Short(ex.getErrorCode()), 3810Sstevel@tonic-gate Integer.toHexString(toForward.getHeader().xid), 3820Sstevel@tonic-gate ex.getMessage()}); 3830Sstevel@tonic-gate } 3840Sstevel@tonic-gate } 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate // If there was a parse error, then break out and close the 3870Sstevel@tonic-gate // stream, because it may have lingering bytes. 3880Sstevel@tonic-gate 3890Sstevel@tonic-gate if (parseError && config.traceMsg()) { 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate config.writeLog("rh_tcp_error", 3920Sstevel@tonic-gate new Object[] {clientAddr, 3930Sstevel@tonic-gate new Integer(port), 3940Sstevel@tonic-gate interfac}); 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate break; 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate } while (true); 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate } catch (EOFException ex) { 4030Sstevel@tonic-gate 4040Sstevel@tonic-gate if (config.traceMsg()) { 4050Sstevel@tonic-gate config.writeLog("rh_socket_closed", 4060Sstevel@tonic-gate new Object[] {clientAddr, 4070Sstevel@tonic-gate new Integer(port), 4080Sstevel@tonic-gate interfac}); 4090Sstevel@tonic-gate } 4100Sstevel@tonic-gate 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate } catch (IOException ex) { 4130Sstevel@tonic-gate 4140Sstevel@tonic-gate // An error occured during input. 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate if (config.traceDrop()) { 4170Sstevel@tonic-gate config.writeLog("ioexception_server_stream", 4180Sstevel@tonic-gate new Object[] {clientAddr, 4190Sstevel@tonic-gate new Integer(port), 4200Sstevel@tonic-gate interfac, 4210Sstevel@tonic-gate ex.getMessage()}); 4220Sstevel@tonic-gate } 4230Sstevel@tonic-gate 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate // Send a byte buffer reply through a datagram socket. 4280Sstevel@tonic-gate sendDatagramReply(byte[] outbuf)4290Sstevel@tonic-gate private void sendDatagramReply(byte[] outbuf) { 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate DatagramSocket ds = null; 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate try { 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate // Open the socket. 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate ds = new DatagramSocket(); 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate // Format the outgoing packet. 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate DatagramPacket dpOut = 4420Sstevel@tonic-gate new DatagramPacket(outbuf, outbuf.length, clientAddr, port); 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate // Send the reply. 4450Sstevel@tonic-gate 4460Sstevel@tonic-gate ds.send(dpOut); 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate // Forward reg or dereg to foreign DAs that need to know about it. 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate if (toForward != null) { 4510Sstevel@tonic-gate 4520Sstevel@tonic-gate try { 4530Sstevel@tonic-gate daTable.forwardSAMessage(toForward, clientAddr); 4540Sstevel@tonic-gate toForward = null; 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate } catch (ServiceLocationException ex) { 4570Sstevel@tonic-gate config.writeLog("sle_forward_error", 4580Sstevel@tonic-gate new Object[] { 4590Sstevel@tonic-gate new Integer(ex.getErrorCode()), 4600Sstevel@tonic-gate Integer.toHexString(toForward.getHeader().xid), 4610Sstevel@tonic-gate ex.getMessage()}); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate } 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate } catch (SocketException ex) { 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate // Failure in reply. 4680Sstevel@tonic-gate 4690Sstevel@tonic-gate if (config.traceDrop()) { 4700Sstevel@tonic-gate config.writeLog("rh_socket_error", 4710Sstevel@tonic-gate new Object[] {clientAddr, 4720Sstevel@tonic-gate new Integer(port), 4730Sstevel@tonic-gate interfac, 4740Sstevel@tonic-gate ex.getMessage()}); 4750Sstevel@tonic-gate } 4760Sstevel@tonic-gate } catch (IOException ex) { 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate // Failure in reply. 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate if (config.traceDrop()) { 4810Sstevel@tonic-gate config.writeLog( 4820Sstevel@tonic-gate "rh_ioexception_reply", 4830Sstevel@tonic-gate new Object[] {clientAddr, 4840Sstevel@tonic-gate new Integer(port), 4850Sstevel@tonic-gate interfac, 4860Sstevel@tonic-gate ex.getMessage()}); 4870Sstevel@tonic-gate } 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate } finally { 4900Sstevel@tonic-gate 4910Sstevel@tonic-gate if (ds != null) { 4920Sstevel@tonic-gate ds.close(); 4930Sstevel@tonic-gate 4940Sstevel@tonic-gate } 4950Sstevel@tonic-gate 4960Sstevel@tonic-gate } 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate } 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate // Handle an incoming stream containing an SLP request. 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate private boolean handleRequest(DataInputStream dis, ByteArrayOutputStream baos, boolean isTCP)5030Sstevel@tonic-gate handleRequest(DataInputStream dis, 5040Sstevel@tonic-gate ByteArrayOutputStream baos, 5050Sstevel@tonic-gate boolean isTCP) 5060Sstevel@tonic-gate throws IOException { 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate boolean parseError = false; 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate // Decode the message. 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate SrvLocMsg msg = internalize(dis, isTCP); 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate // If there was an error converting the request, then don't 5150Sstevel@tonic-gate // process further. 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate SrvLocMsg rply = msg; 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate if (msg != null) { 5200Sstevel@tonic-gate SrvLocHeader hdr = msg.getHeader(); 5210Sstevel@tonic-gate 5220Sstevel@tonic-gate if (hdr.errCode == ServiceLocationException.OK) { 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate if (config.traceMsg()) { 5250Sstevel@tonic-gate config.writeLog("rh_rqst_in", 5260Sstevel@tonic-gate new Object[] {Integer.toHexString(hdr.xid), 5270Sstevel@tonic-gate clientAddr, 5280Sstevel@tonic-gate new Integer(port), 5290Sstevel@tonic-gate interfac, 5300Sstevel@tonic-gate msg.getHeader()}); 5310Sstevel@tonic-gate } 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate // Dispatch the message to the service table. 5350Sstevel@tonic-gate 5360Sstevel@tonic-gate rply = dispatch(msg); 5370Sstevel@tonic-gate 5380Sstevel@tonic-gate // If no reply, then simply return. 5390Sstevel@tonic-gate 5400Sstevel@tonic-gate if (rply == null) { 5410Sstevel@tonic-gate 5420Sstevel@tonic-gate if (config.traceMsg()) { 5430Sstevel@tonic-gate config.writeLog("rh_rply_null", 5440Sstevel@tonic-gate new Object[] { 5450Sstevel@tonic-gate Integer.toHexString(hdr.xid), 5460Sstevel@tonic-gate clientAddr, 5470Sstevel@tonic-gate new Integer(port), 5480Sstevel@tonic-gate interfac}); 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate } 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate return parseError; 5530Sstevel@tonic-gate 5540Sstevel@tonic-gate } 5550Sstevel@tonic-gate } else { 5560Sstevel@tonic-gate 5570Sstevel@tonic-gate // Drop if multicast. 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate if (msg.getHeader().mcast) { 5600Sstevel@tonic-gate rply = null; 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate if (config.traceDrop()) { 5630Sstevel@tonic-gate config.writeLog("rh_multi_error", 5640Sstevel@tonic-gate new Object[] { 5650Sstevel@tonic-gate msg.getClass().getName(), 5660Sstevel@tonic-gate Integer.toHexString(hdr.xid), 5670Sstevel@tonic-gate clientAddr, 5680Sstevel@tonic-gate new Integer(port), 5690Sstevel@tonic-gate interfac}); 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate } else if (isTCP) { 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate // Set the parse error flag so that the stream gets closed. 5760Sstevel@tonic-gate // It's easier than trying to keep track of the number of 5770Sstevel@tonic-gate // bytes read. Otherwise, the remnents of the message 5780Sstevel@tonic-gate // hang around. 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate parseError = true; 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate } 5830Sstevel@tonic-gate } 5840Sstevel@tonic-gate } 5850Sstevel@tonic-gate 5860Sstevel@tonic-gate // Reply to the client if necessary. Note that if the reply is null 5870Sstevel@tonic-gate // here, there was a problem parsing the message in and so formulating 5880Sstevel@tonic-gate // a reply may be impossible (for example, the message may not 5890Sstevel@tonic-gate // be parsable beyond the function code. 5900Sstevel@tonic-gate 5910Sstevel@tonic-gate if (rply != null) { 5920Sstevel@tonic-gate SrvLocHeader hdr = rply.getHeader(); 5930Sstevel@tonic-gate ServiceLocationException ex = null; 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate // Parse out the message. 5960Sstevel@tonic-gate 5970Sstevel@tonic-gate try { 5980Sstevel@tonic-gate hdr.externalize(baos, false, isTCP); 5990Sstevel@tonic-gate } catch (ServiceLocationException sle) { 6000Sstevel@tonic-gate ex = sle; 6010Sstevel@tonic-gate } 6020Sstevel@tonic-gate 6030Sstevel@tonic-gate if (config.traceMsg()) { 6040Sstevel@tonic-gate config.writeLog("rh_rply_out", 6050Sstevel@tonic-gate new Object[] {Integer.toHexString(hdr.xid), 6060Sstevel@tonic-gate clientAddr, 6070Sstevel@tonic-gate new Integer(port), 6080Sstevel@tonic-gate interfac, 6090Sstevel@tonic-gate rply.getHeader()}); 6100Sstevel@tonic-gate } 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate if (ex != null) { 6130Sstevel@tonic-gate baos.reset(); 6140Sstevel@tonic-gate rply = hdr.makeErrorReply(ex); 6150Sstevel@tonic-gate 6160Sstevel@tonic-gate Assert.slpassert(msg != null, 6170Sstevel@tonic-gate "rh_header_class_error", 6180Sstevel@tonic-gate new Object[] {ex.getMessage()}); 6190Sstevel@tonic-gate 6200Sstevel@tonic-gate hdr = rply.getHeader(); 6210Sstevel@tonic-gate 6220Sstevel@tonic-gate try { 6230Sstevel@tonic-gate hdr.externalize(baos, false, isTCP); 6240Sstevel@tonic-gate 6250Sstevel@tonic-gate } catch (ServiceLocationException exx) { 6260Sstevel@tonic-gate 6270Sstevel@tonic-gate } 6280Sstevel@tonic-gate } 6290Sstevel@tonic-gate } else if (config.traceMsg()) { 6300Sstevel@tonic-gate 6310Sstevel@tonic-gate // Print error message. 6320Sstevel@tonic-gate 6330Sstevel@tonic-gate String xidStr = "<null message>"; 6340Sstevel@tonic-gate 6350Sstevel@tonic-gate if (msg != null) { 6360Sstevel@tonic-gate SrvLocHeader hdr = msg.getHeader(); 6370Sstevel@tonic-gate xidStr = Integer.toHexString(hdr.xid); 6380Sstevel@tonic-gate 6390Sstevel@tonic-gate } 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate config.writeLog("rh_rply_null", 6420Sstevel@tonic-gate new Object[] {xidStr, 6430Sstevel@tonic-gate clientAddr, 6440Sstevel@tonic-gate new Integer(port), 6450Sstevel@tonic-gate interfac}); 6460Sstevel@tonic-gate } 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate return parseError; 6490Sstevel@tonic-gate } 6500Sstevel@tonic-gate 6510Sstevel@tonic-gate /** 6520Sstevel@tonic-gate * Internalize the byte array in the input stream into a SrvLocMsg 6530Sstevel@tonic-gate * subclass. It will be an appropriate subclass for the SA/DA. 6540Sstevel@tonic-gate * 6550Sstevel@tonic-gate * @param dis The input stream containing the packet. 6560Sstevel@tonic-gate * @param viaTCP True if the outgoing stream is via TCP. 6570Sstevel@tonic-gate * @return The right SrvLocMsg subclass appropriate for the SA/DA. 6580Sstevel@tonic-gate * If null is returned, it means that the function code was 6590Sstevel@tonic-gate * not recognized. 6600Sstevel@tonic-gate * If any error occurs during creation, an error request is 6610Sstevel@tonic-gate * returned with the error code set. 6620Sstevel@tonic-gate */ 6630Sstevel@tonic-gate 6640Sstevel@tonic-gate private SrvLocMsg internalize(DataInputStream dis, boolean viaTCP)6650Sstevel@tonic-gate internalize(DataInputStream dis, boolean viaTCP) throws IOException { 6660Sstevel@tonic-gate 6670Sstevel@tonic-gate int ver = 0, fun = 0; 6680Sstevel@tonic-gate 6690Sstevel@tonic-gate Assert.slpassert((dis != null), 6700Sstevel@tonic-gate "rh_null_bais", 6710Sstevel@tonic-gate new Object[0]); 6720Sstevel@tonic-gate 6730Sstevel@tonic-gate try { 6740Sstevel@tonic-gate 6750Sstevel@tonic-gate // Pull off the version number and function code. 6760Sstevel@tonic-gate 6770Sstevel@tonic-gate byte[] b = new byte[2]; 6780Sstevel@tonic-gate 6790Sstevel@tonic-gate dis.readFully(b, 0, 2); 6800Sstevel@tonic-gate 6810Sstevel@tonic-gate ver = (int) ((char)b[0] & 0XFF); 6820Sstevel@tonic-gate fun = (int) ((char)b[1] & 0XFF); 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate } catch (IOException ex) { 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate // Print an error message, but only if not EOF. 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate if (!(ex instanceof EOFException)) { 6890Sstevel@tonic-gate printInternalizeErrorMessage(ver, fun, ex); 6900Sstevel@tonic-gate 6910Sstevel@tonic-gate } 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate // Throw the exception, so streams can terminate. 6940Sstevel@tonic-gate 6950Sstevel@tonic-gate throw ex; 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate } 6980Sstevel@tonic-gate 6990Sstevel@tonic-gate SrvLocMsg msg = null; 7000Sstevel@tonic-gate SrvLocHeader hdr = null; 7010Sstevel@tonic-gate 7020Sstevel@tonic-gate try { 7030Sstevel@tonic-gate 7040Sstevel@tonic-gate hdr = SrvLocHeader.newInstance(ver); 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate // Unrecognized version number if header not returned. 7070Sstevel@tonic-gate // We only throw an exception if the version number 7080Sstevel@tonic-gate // is greater than the current default version number. 7090Sstevel@tonic-gate // otherwise, the packet is from an earlier version 7100Sstevel@tonic-gate // of the protocol and should be ignored if we are 7110Sstevel@tonic-gate // not operating in compatibility mode. 7120Sstevel@tonic-gate 7130Sstevel@tonic-gate if (hdr == null) { 7140Sstevel@tonic-gate 7150Sstevel@tonic-gate if (ver > Defaults.version || 7160Sstevel@tonic-gate (config.isV1Supported() && config.isDA())) { 7170Sstevel@tonic-gate // code problem... 7180Sstevel@tonic-gate throw 7190Sstevel@tonic-gate new ServiceLocationException( 7200Sstevel@tonic-gate ServiceLocationException.VERSION_NOT_SUPPORTED, 7210Sstevel@tonic-gate "rh_version_number_error", 7220Sstevel@tonic-gate new Object[] {new Integer(ver), 7230Sstevel@tonic-gate clientAddr, 7240Sstevel@tonic-gate new Integer(port), 7250Sstevel@tonic-gate interfac}); 7260Sstevel@tonic-gate } else { 7270Sstevel@tonic-gate return null; 7280Sstevel@tonic-gate 7290Sstevel@tonic-gate } 7300Sstevel@tonic-gate } 7310Sstevel@tonic-gate 7320Sstevel@tonic-gate // If we've come via TCP, clear the packet length so the 7330Sstevel@tonic-gate // eventual reply won't be checked for overflow. 7340Sstevel@tonic-gate 7350Sstevel@tonic-gate if (viaTCP) { 7360Sstevel@tonic-gate hdr.setPacketLength(Integer.MAX_VALUE); 7370Sstevel@tonic-gate 7380Sstevel@tonic-gate } 7390Sstevel@tonic-gate 7400Sstevel@tonic-gate // Parse the header. 7410Sstevel@tonic-gate 7420Sstevel@tonic-gate hdr.parseHeader(fun, dis); 7430Sstevel@tonic-gate 7440Sstevel@tonic-gate // Parse body. 7450Sstevel@tonic-gate 7460Sstevel@tonic-gate if ((msg = hdr.parseMsg(dis)) != null) { 7470Sstevel@tonic-gate 7480Sstevel@tonic-gate // Parse options, if any. 7490Sstevel@tonic-gate 7500Sstevel@tonic-gate hdr.parseOptions(dis); 7510Sstevel@tonic-gate 7520Sstevel@tonic-gate } 7530Sstevel@tonic-gate 7540Sstevel@tonic-gate } catch (Exception ex) { 7550Sstevel@tonic-gate 7560Sstevel@tonic-gate printInternalizeErrorMessage(ver, fun, ex); 7570Sstevel@tonic-gate 7580Sstevel@tonic-gate msg = null; 7590Sstevel@tonic-gate 7600Sstevel@tonic-gate // If this is a DAAdvert or an SAAdvert, or there's no header, 7610Sstevel@tonic-gate // return null cause we don't need to return anything or 7620Sstevel@tonic-gate // can't. 7630Sstevel@tonic-gate 7640Sstevel@tonic-gate if (fun != SrvLocHeader.DAAdvert && 7650Sstevel@tonic-gate fun != SrvLocHeader.SAAdvert && 7660Sstevel@tonic-gate hdr != null) { 7670Sstevel@tonic-gate 7680Sstevel@tonic-gate // Let header create message. 7690Sstevel@tonic-gate 7700Sstevel@tonic-gate msg = hdr.makeErrorReply(ex); 7710Sstevel@tonic-gate 7720Sstevel@tonic-gate } 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate } 7750Sstevel@tonic-gate 7760Sstevel@tonic-gate return msg; 7770Sstevel@tonic-gate } 7780Sstevel@tonic-gate 7790Sstevel@tonic-gate // Print an error message for errors during internalization. 7800Sstevel@tonic-gate printInternalizeErrorMessage(int ver, int fun, Exception ex)7810Sstevel@tonic-gate private void printInternalizeErrorMessage(int ver, int fun, Exception ex) { 7820Sstevel@tonic-gate 7830Sstevel@tonic-gate if (config.traceDrop()) { 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate StringWriter sw = new StringWriter(); 7860Sstevel@tonic-gate PrintWriter pw = new PrintWriter(sw); 7870Sstevel@tonic-gate 7880Sstevel@tonic-gate ex.printStackTrace(pw); 7890Sstevel@tonic-gate 7900Sstevel@tonic-gate short errCode = ServiceLocationException.INTERNAL_SYSTEM_ERROR; 7910Sstevel@tonic-gate 7920Sstevel@tonic-gate if (ex instanceof ServiceLocationException) { 7930Sstevel@tonic-gate errCode = ((ServiceLocationException)ex).getErrorCode(); 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate } else if (ex instanceof IllegalArgumentException) { 7960Sstevel@tonic-gate errCode = ServiceLocationException.PARSE_ERROR; 7970Sstevel@tonic-gate 7980Sstevel@tonic-gate } 7990Sstevel@tonic-gate 8000Sstevel@tonic-gate String exMsg = "(" + errCode + "):" + ex.getMessage(); 8010Sstevel@tonic-gate 8020Sstevel@tonic-gate config.writeLog("rh_unparse_exception", 8030Sstevel@tonic-gate new Object[] {clientAddr, 8040Sstevel@tonic-gate new Integer(port), 8050Sstevel@tonic-gate interfac, 8060Sstevel@tonic-gate new Integer(ver), 8070Sstevel@tonic-gate new Integer(fun), 8080Sstevel@tonic-gate exMsg, 8090Sstevel@tonic-gate sw.toString()}); 8100Sstevel@tonic-gate } 8110Sstevel@tonic-gate } 8120Sstevel@tonic-gate 8130Sstevel@tonic-gate /** 8140Sstevel@tonic-gate * Dispatch the service request object to the service table. 8150Sstevel@tonic-gate * The SA table is used for the following: 8160Sstevel@tonic-gate * 8170Sstevel@tonic-gate * @param rqst Service request object. 8180Sstevel@tonic-gate * @return A SrvLocMsg object to reply with, or null if no reply. 8190Sstevel@tonic-gate */ 8200Sstevel@tonic-gate dispatch(SrvLocMsg rqst)8210Sstevel@tonic-gate SrvLocMsg dispatch(SrvLocMsg rqst) { 8220Sstevel@tonic-gate 8230Sstevel@tonic-gate SrvLocHeader hdr = rqst.getHeader(); 8240Sstevel@tonic-gate boolean mcast = hdr.mcast; 8250Sstevel@tonic-gate 8260Sstevel@tonic-gate // Check CDAAdvert and CSAAdvert before we check the previous 8270Sstevel@tonic-gate // responders list, because they don't have any. 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate if (rqst instanceof CDAAdvert) { // DA advert... 8300Sstevel@tonic-gate CDAAdvert msg = (CDAAdvert)rqst; 8310Sstevel@tonic-gate 8320Sstevel@tonic-gate // For V1, V2 messages know. 8330Sstevel@tonic-gate 8340Sstevel@tonic-gate msg.setIsUnsolicited(true); 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate // If passive detection is off, ignore it, but only if it wasn't 8370Sstevel@tonic-gate // a signal to stop. 8380Sstevel@tonic-gate 8390Sstevel@tonic-gate if (!config.passiveDADetection() && 8400Sstevel@tonic-gate msg.isUnsolicited() && 8410Sstevel@tonic-gate !msg.isGoingDown()) { 8420Sstevel@tonic-gate if (config.traceDrop()) { 8430Sstevel@tonic-gate config.writeLog("rh_passive_drop", 8440Sstevel@tonic-gate new Object[] {msg.URL, 8450Sstevel@tonic-gate hdr.scopes}); 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate } 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate } else if (msg.isGoingDown() && msg.isUnsolicited() && 8500Sstevel@tonic-gate isLocalHostURL(msg.URL) && config.isDA()) { 8510Sstevel@tonic-gate 8520Sstevel@tonic-gate // We've been asked to terminate. 8530Sstevel@tonic-gate 8540Sstevel@tonic-gate // Check scopes. 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate Vector scopes = (Vector)hdr.scopes.clone(); 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate DATable.filterScopes(scopes, 8590Sstevel@tonic-gate config.getSAConfiguredScopes(), true); 8600Sstevel@tonic-gate 8610Sstevel@tonic-gate // If all scopes not equal, it isn't a shutdown message for us. 8620Sstevel@tonic-gate 8630Sstevel@tonic-gate if (scopes.size() > 0) { 8640Sstevel@tonic-gate daTable.handleAdvertIn(msg); 8650Sstevel@tonic-gate 8660Sstevel@tonic-gate } else { 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate Vector discoveredScopes = new Vector(); 8690Sstevel@tonic-gate 8700Sstevel@tonic-gate try { 8710Sstevel@tonic-gate discoveredScopes = daTable.findScopes(); 8720Sstevel@tonic-gate 8730Sstevel@tonic-gate } catch (ServiceLocationException ex) { 8740Sstevel@tonic-gate 8750Sstevel@tonic-gate // Ignore, we're going down anyway and it's 8760Sstevel@tonic-gate // just a report. 8770Sstevel@tonic-gate 8780Sstevel@tonic-gate } 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate // It is a shutdown message for us. 8810Sstevel@tonic-gate 8820Sstevel@tonic-gate Vector serverScopes = config.getSAConfiguredScopes(); 8830Sstevel@tonic-gate Vector interfaces = config.getInterfaces(); 8840Sstevel@tonic-gate Vector daAttributes = config.getDAAttributes(); 8850Sstevel@tonic-gate 8860Sstevel@tonic-gate if (config.traceAll() || 8870Sstevel@tonic-gate config.traceMsg() || 8880Sstevel@tonic-gate config.traceDrop() || 8890Sstevel@tonic-gate config.traceDATraffic()) { 8900Sstevel@tonic-gate 8910Sstevel@tonic-gate config.writeLog("goodby_da", 8920Sstevel@tonic-gate new Object[] {interfaces, 8930Sstevel@tonic-gate serverScopes, 8940Sstevel@tonic-gate discoveredScopes, 8950Sstevel@tonic-gate daAttributes}); 8960Sstevel@tonic-gate } 8970Sstevel@tonic-gate 8980Sstevel@tonic-gate 8990Sstevel@tonic-gate // We don't reply, which means that the client will 9000Sstevel@tonic-gate // time out. 9010Sstevel@tonic-gate 9020Sstevel@tonic-gate System.exit(0); 9030Sstevel@tonic-gate 9040Sstevel@tonic-gate } 9050Sstevel@tonic-gate } else { 9060Sstevel@tonic-gate 9070Sstevel@tonic-gate // The implementation specific DA table handles this. 9080Sstevel@tonic-gate 9090Sstevel@tonic-gate daTable.handleAdvertIn(msg); 9100Sstevel@tonic-gate 9110Sstevel@tonic-gate } 9120Sstevel@tonic-gate 9130Sstevel@tonic-gate return null; 9140Sstevel@tonic-gate 9150Sstevel@tonic-gate } else if (rqst instanceof CSAAdvert) {// SA advert... 9160Sstevel@tonic-gate CSAAdvert msg = (CSAAdvert)rqst; 9170Sstevel@tonic-gate 9180Sstevel@tonic-gate // We are only interested in it if we may be going down. 9190Sstevel@tonic-gate 9200Sstevel@tonic-gate if ((hdr.xid == 0) && isLocalHostURL(msg.URL) && !config.isDA()) { 9210Sstevel@tonic-gate 9220Sstevel@tonic-gate // Check scopes. 9230Sstevel@tonic-gate 9240Sstevel@tonic-gate Vector scopes = (Vector)hdr.scopes.clone(); 9250Sstevel@tonic-gate 9260Sstevel@tonic-gate DATable.filterScopes(scopes, 9270Sstevel@tonic-gate config.getSAConfiguredScopes(), true); 9280Sstevel@tonic-gate 9290Sstevel@tonic-gate // If all scopes not equal, it isn't a shutdown message for us. 9300Sstevel@tonic-gate 9310Sstevel@tonic-gate if (scopes.size() <= 0) { 9320Sstevel@tonic-gate 9330Sstevel@tonic-gate Vector discoveredScopes = new Vector(); 9340Sstevel@tonic-gate 9350Sstevel@tonic-gate try { 9360Sstevel@tonic-gate discoveredScopes = daTable.findScopes(); 9370Sstevel@tonic-gate 9380Sstevel@tonic-gate } catch (ServiceLocationException ex) { 9390Sstevel@tonic-gate 9400Sstevel@tonic-gate // Ignore, we're going down anyway and it's just a 9410Sstevel@tonic-gate // report. 9420Sstevel@tonic-gate 9430Sstevel@tonic-gate } 9440Sstevel@tonic-gate 9450Sstevel@tonic-gate // It is a shutdown message for us. 9460Sstevel@tonic-gate 9470Sstevel@tonic-gate Vector serverScopes = config.getSAConfiguredScopes(); 9480Sstevel@tonic-gate Vector interfaces = config.getInterfaces(); 9490Sstevel@tonic-gate Vector saAttributes = config.getSAAttributes(); 9500Sstevel@tonic-gate 9510Sstevel@tonic-gate if (config.traceAll() || 9520Sstevel@tonic-gate config.traceMsg() || 9530Sstevel@tonic-gate config.traceDrop() || 9540Sstevel@tonic-gate config.traceDATraffic()) { 9550Sstevel@tonic-gate 9560Sstevel@tonic-gate config.writeLog("goodby", 9570Sstevel@tonic-gate new Object[] {interfaces, 9580Sstevel@tonic-gate serverScopes, 9590Sstevel@tonic-gate discoveredScopes, 9600Sstevel@tonic-gate saAttributes}); 9610Sstevel@tonic-gate } 9620Sstevel@tonic-gate 9630Sstevel@tonic-gate System.exit(0); 9640Sstevel@tonic-gate } 9650Sstevel@tonic-gate } 9660Sstevel@tonic-gate 9670Sstevel@tonic-gate // Otherwise, drop it for now. 9680Sstevel@tonic-gate 9690Sstevel@tonic-gate if (config.traceDrop()) { 9700Sstevel@tonic-gate config.writeLog("rh_client_sa_advert_drop", 9710Sstevel@tonic-gate new Object[] {Integer.toHexString(hdr.xid), 9720Sstevel@tonic-gate clientAddr, 9730Sstevel@tonic-gate new Integer(port), 9740Sstevel@tonic-gate interfac}); 9750Sstevel@tonic-gate } 9760Sstevel@tonic-gate 9770Sstevel@tonic-gate return null; 9780Sstevel@tonic-gate 9790Sstevel@tonic-gate } 9800Sstevel@tonic-gate 9810Sstevel@tonic-gate if (rqst instanceof SSrvReg) { // registration... 9820Sstevel@tonic-gate 9830Sstevel@tonic-gate return dispatchReg((SSrvReg)rqst, 9840Sstevel@tonic-gate serviceTable); 9850Sstevel@tonic-gate 9860Sstevel@tonic-gate } else if (rqst instanceof SSrvDereg) { // deregistration... 9870Sstevel@tonic-gate 9880Sstevel@tonic-gate return dispatchDereg((SSrvDereg)rqst, 9890Sstevel@tonic-gate serviceTable); 9900Sstevel@tonic-gate 9910Sstevel@tonic-gate } 9920Sstevel@tonic-gate 9930Sstevel@tonic-gate 9940Sstevel@tonic-gate // If we are on the previous responder list, then ignore this 9950Sstevel@tonic-gate // request. 9960Sstevel@tonic-gate 9970Sstevel@tonic-gate if (isPreviousResponder(hdr)) { 9980Sstevel@tonic-gate 9990Sstevel@tonic-gate if (config.traceDrop()) { 10000Sstevel@tonic-gate config.writeLog("rh_prev_resp", 10010Sstevel@tonic-gate new Object[] {Integer.toHexString(hdr.xid), 10020Sstevel@tonic-gate clientAddr, 10030Sstevel@tonic-gate new Integer(port), 10040Sstevel@tonic-gate interfac}); 10050Sstevel@tonic-gate } 10060Sstevel@tonic-gate 10070Sstevel@tonic-gate return null; 10080Sstevel@tonic-gate 10090Sstevel@tonic-gate } 10100Sstevel@tonic-gate 10110Sstevel@tonic-gate // Now check requests with previous responders. 10120Sstevel@tonic-gate 10130Sstevel@tonic-gate if (rqst instanceof SSrvTypeMsg) { // service types... 10140Sstevel@tonic-gate 10150Sstevel@tonic-gate return dispatchSrvType((SSrvTypeMsg)rqst, 10160Sstevel@tonic-gate serviceTable); 10170Sstevel@tonic-gate 10180Sstevel@tonic-gate } else if (rqst instanceof SAttrMsg) { // attributes... 10190Sstevel@tonic-gate 10200Sstevel@tonic-gate return dispatchAttr((SAttrMsg)rqst, 10210Sstevel@tonic-gate serviceTable); 10220Sstevel@tonic-gate 10230Sstevel@tonic-gate } else if (rqst instanceof SSrvMsg) { // services... 10240Sstevel@tonic-gate 10250Sstevel@tonic-gate return dispatchSrv((SSrvMsg)rqst, 10260Sstevel@tonic-gate serviceTable); 10270Sstevel@tonic-gate 10280Sstevel@tonic-gate } else { // error... 10290Sstevel@tonic-gate 10300Sstevel@tonic-gate Assert.slpassert(false, 10310Sstevel@tonic-gate "rh_rqst_type_err", 10320Sstevel@tonic-gate new Object[] {rqst}); 10330Sstevel@tonic-gate 10340Sstevel@tonic-gate } 10350Sstevel@tonic-gate 10360Sstevel@tonic-gate return null; 10370Sstevel@tonic-gate 10380Sstevel@tonic-gate } 10390Sstevel@tonic-gate 10400Sstevel@tonic-gate 10410Sstevel@tonic-gate // Dispatch a service registration. 10420Sstevel@tonic-gate dispatchReg(SSrvReg rqst, ServiceTable serviceTable)10430Sstevel@tonic-gate private SrvLocMsg dispatchReg(SSrvReg rqst, 10440Sstevel@tonic-gate ServiceTable serviceTable) { 10450Sstevel@tonic-gate 10460Sstevel@tonic-gate SrvLocHeader hdr = rqst.getHeader(); 10470Sstevel@tonic-gate 10480Sstevel@tonic-gate // Report error if the message was multicast. 10490Sstevel@tonic-gate 10500Sstevel@tonic-gate if (hdr.mcast && config.traceDrop()) { 10510Sstevel@tonic-gate 10520Sstevel@tonic-gate if (config.traceDrop()) { 10530Sstevel@tonic-gate config.writeLog("rh_no_multi", 10540Sstevel@tonic-gate new Object[] {"SrvReg", 10550Sstevel@tonic-gate Integer.toHexString(hdr.xid), 10560Sstevel@tonic-gate clientAddr, 10570Sstevel@tonic-gate new Integer(port), 10580Sstevel@tonic-gate interfac}); 10590Sstevel@tonic-gate } 10600Sstevel@tonic-gate 10610Sstevel@tonic-gate return null; 10620Sstevel@tonic-gate 10630Sstevel@tonic-gate } 10640Sstevel@tonic-gate 10650Sstevel@tonic-gate // Register the request. 10660Sstevel@tonic-gate 10670Sstevel@tonic-gate SrvLocMsg rply = serviceTable.register(rqst); 10680Sstevel@tonic-gate 10690Sstevel@tonic-gate // Forward to foreign DAs if no error. 10700Sstevel@tonic-gate 10710Sstevel@tonic-gate if (rply != null) { 10720Sstevel@tonic-gate hdr = rply.getHeader(); 10730Sstevel@tonic-gate 10740Sstevel@tonic-gate if (hdr.errCode == ServiceLocationException.OK) { 10750Sstevel@tonic-gate toForward = rqst; 10760Sstevel@tonic-gate 10770Sstevel@tonic-gate } 10780Sstevel@tonic-gate } 10790Sstevel@tonic-gate 10800Sstevel@tonic-gate return rply; 10810Sstevel@tonic-gate } 10820Sstevel@tonic-gate 10830Sstevel@tonic-gate // Dispatch a service deregistration. 10840Sstevel@tonic-gate dispatchDereg(SSrvDereg rqst, ServiceTable serviceTable)10850Sstevel@tonic-gate private SrvLocMsg dispatchDereg(SSrvDereg rqst, 10860Sstevel@tonic-gate ServiceTable serviceTable) { 10870Sstevel@tonic-gate 10880Sstevel@tonic-gate SrvLocHeader hdr = rqst.getHeader(); 10890Sstevel@tonic-gate 10900Sstevel@tonic-gate // Report error if the message was multicast. 10910Sstevel@tonic-gate 10920Sstevel@tonic-gate if (hdr.mcast && config.traceDrop()) { 10930Sstevel@tonic-gate 10940Sstevel@tonic-gate if (config.traceDrop()) { 10950Sstevel@tonic-gate config.writeLog("rh_no_multi", 10960Sstevel@tonic-gate new Object[] {"SrvDereg", 10970Sstevel@tonic-gate Integer.toHexString(hdr.xid), 10980Sstevel@tonic-gate clientAddr, 10990Sstevel@tonic-gate new Integer(port), 11000Sstevel@tonic-gate interfac}); 11010Sstevel@tonic-gate } 11020Sstevel@tonic-gate 11030Sstevel@tonic-gate return null; 11040Sstevel@tonic-gate 11050Sstevel@tonic-gate } 11060Sstevel@tonic-gate 11070Sstevel@tonic-gate // If the message came from the local host, use the SA store. 11080Sstevel@tonic-gate 11090Sstevel@tonic-gate SrvLocMsg rply = serviceTable.deregister(rqst); 11100Sstevel@tonic-gate 11110Sstevel@tonic-gate // Forward to foreign DAs if no error. 11120Sstevel@tonic-gate 11130Sstevel@tonic-gate if (rply != null) { 11140Sstevel@tonic-gate hdr = rply.getHeader(); 11150Sstevel@tonic-gate 11160Sstevel@tonic-gate if (hdr.errCode == ServiceLocationException.OK) { 11170Sstevel@tonic-gate toForward = rqst; 11180Sstevel@tonic-gate 11190Sstevel@tonic-gate } 11200Sstevel@tonic-gate } 11210Sstevel@tonic-gate 11220Sstevel@tonic-gate return rply; 11230Sstevel@tonic-gate } 11240Sstevel@tonic-gate 11250Sstevel@tonic-gate // Dispatch a service type message. 11260Sstevel@tonic-gate dispatchSrvType(SSrvTypeMsg rqst, ServiceTable serviceTable)11270Sstevel@tonic-gate private SrvLocMsg dispatchSrvType(SSrvTypeMsg rqst, 11280Sstevel@tonic-gate ServiceTable serviceTable) { 11290Sstevel@tonic-gate 11300Sstevel@tonic-gate SrvLocHeader hdr = rqst.getHeader(); 11310Sstevel@tonic-gate boolean mcast = hdr.mcast; 11320Sstevel@tonic-gate 11330Sstevel@tonic-gate // Drop if this is a DA and the request was multicast. DAs 11340Sstevel@tonic-gate // do not respond to multicast, except for DAAdverts. 11350Sstevel@tonic-gate 11360Sstevel@tonic-gate if (mcast && config.isDA()) { 11370Sstevel@tonic-gate 11380Sstevel@tonic-gate if (config.traceDrop()) { 11390Sstevel@tonic-gate config.writeLog("rh_drop_da_multi", 11400Sstevel@tonic-gate new Object[] {"SrvTypeRqst", 11410Sstevel@tonic-gate Integer.toHexString(hdr.xid), 11420Sstevel@tonic-gate clientAddr, 11430Sstevel@tonic-gate new Integer(port), 11440Sstevel@tonic-gate interfac}); 11450Sstevel@tonic-gate } 11460Sstevel@tonic-gate 11470Sstevel@tonic-gate return null; 11480Sstevel@tonic-gate 11490Sstevel@tonic-gate } 11500Sstevel@tonic-gate 11510Sstevel@tonic-gate SrvLocMsg rply = serviceTable.findServiceTypes(rqst); 11520Sstevel@tonic-gate hdr = rply.getHeader(); 11530Sstevel@tonic-gate 11540Sstevel@tonic-gate // Filter multicast replies to remove null and error returns. 11550Sstevel@tonic-gate 11560Sstevel@tonic-gate if (mcast && 11570Sstevel@tonic-gate ((hdr.errCode != ServiceLocationException.OK) || 11580Sstevel@tonic-gate (hdr.getNumReplies() == 0))) { 11590Sstevel@tonic-gate 11600Sstevel@tonic-gate if (config.traceDrop()) { 11610Sstevel@tonic-gate config.writeLog("rh_multi_error", 11620Sstevel@tonic-gate new Object[] {"SrvTypeRqst", 11630Sstevel@tonic-gate Integer.toHexString(hdr.xid), 11640Sstevel@tonic-gate clientAddr, 11650Sstevel@tonic-gate new Integer(port), 11660Sstevel@tonic-gate interfac}); 11670Sstevel@tonic-gate 11680Sstevel@tonic-gate 11690Sstevel@tonic-gate } 11700Sstevel@tonic-gate 11710Sstevel@tonic-gate return null; 11720Sstevel@tonic-gate 11730Sstevel@tonic-gate } 11740Sstevel@tonic-gate 11750Sstevel@tonic-gate return rply; 11760Sstevel@tonic-gate } 11770Sstevel@tonic-gate 11780Sstevel@tonic-gate // Dispatch an attribute request. 11790Sstevel@tonic-gate dispatchAttr(SAttrMsg rqst, ServiceTable serviceTable)11800Sstevel@tonic-gate private SrvLocMsg dispatchAttr(SAttrMsg rqst, 11810Sstevel@tonic-gate ServiceTable serviceTable) { 11820Sstevel@tonic-gate 11830Sstevel@tonic-gate SrvLocHeader hdr = rqst.getHeader(); 11840Sstevel@tonic-gate boolean mcast = hdr.mcast; 11850Sstevel@tonic-gate 11860Sstevel@tonic-gate // Drop if this is a DA and the request was multicast. DAs 11870Sstevel@tonic-gate // do not respond to multicast, except for DAAdverts. 11880Sstevel@tonic-gate 11890Sstevel@tonic-gate if (mcast && config.isDA()) { 11900Sstevel@tonic-gate 11910Sstevel@tonic-gate if (config.traceDrop()) { 11920Sstevel@tonic-gate config.writeLog("rh_drop_da_multi", 11930Sstevel@tonic-gate new Object[] {"AttrRqst", 11940Sstevel@tonic-gate Integer.toHexString(hdr.xid), 11950Sstevel@tonic-gate clientAddr, 11960Sstevel@tonic-gate new Integer(port), 11970Sstevel@tonic-gate interfac}); 11980Sstevel@tonic-gate } 11990Sstevel@tonic-gate 12000Sstevel@tonic-gate return null; 12010Sstevel@tonic-gate 12020Sstevel@tonic-gate } 12030Sstevel@tonic-gate 12040Sstevel@tonic-gate SrvLocMsg rply = serviceTable.findAttributes(rqst); 12050Sstevel@tonic-gate hdr = rply.getHeader(); 12060Sstevel@tonic-gate 12070Sstevel@tonic-gate // Filter multicast replies to remove null and error returns. 12080Sstevel@tonic-gate 12090Sstevel@tonic-gate if (mcast && 12100Sstevel@tonic-gate ((hdr.errCode != ServiceLocationException.OK) || 12110Sstevel@tonic-gate (hdr.getNumReplies() == 0))) { 12120Sstevel@tonic-gate 12130Sstevel@tonic-gate if (config.traceDrop()) { 12140Sstevel@tonic-gate config.writeLog("rh_multi_error", 12150Sstevel@tonic-gate new Object[] {"AttrRqst", 12160Sstevel@tonic-gate Integer.toHexString(hdr.xid), 12170Sstevel@tonic-gate clientAddr, 12180Sstevel@tonic-gate new Integer(port), 12190Sstevel@tonic-gate interfac}); 12200Sstevel@tonic-gate 12210Sstevel@tonic-gate } 12220Sstevel@tonic-gate 12230Sstevel@tonic-gate return null; 12240Sstevel@tonic-gate 12250Sstevel@tonic-gate } 12260Sstevel@tonic-gate 12270Sstevel@tonic-gate return rply; 12280Sstevel@tonic-gate } 12290Sstevel@tonic-gate 12300Sstevel@tonic-gate // Dispatch a service request. 12310Sstevel@tonic-gate dispatchSrv(SSrvMsg rqst, ServiceTable serviceTable)12320Sstevel@tonic-gate private SrvLocMsg dispatchSrv(SSrvMsg rqst, 12330Sstevel@tonic-gate ServiceTable serviceTable) { 12340Sstevel@tonic-gate 12350Sstevel@tonic-gate SrvLocHeader hdr = rqst.getHeader(); 12360Sstevel@tonic-gate boolean mcast = hdr.mcast; 12370Sstevel@tonic-gate String serviceType = rqst.serviceType; 12380Sstevel@tonic-gate SrvLocMsg rply = null; 12390Sstevel@tonic-gate 12400Sstevel@tonic-gate // We need to special case if this is a request for a DAAdvert 12410Sstevel@tonic-gate // and we are a DA or an SAAdvert and we are an SA only. 12420Sstevel@tonic-gate 12430Sstevel@tonic-gate if (serviceType.equals(Defaults.DA_SERVICE_TYPE.toString())) { 12440Sstevel@tonic-gate 12450Sstevel@tonic-gate // Reply only if a DA. 12460Sstevel@tonic-gate 12470Sstevel@tonic-gate if (config.isDA()) { 12480Sstevel@tonic-gate 12490Sstevel@tonic-gate 12500Sstevel@tonic-gate // Return a DAAdvert for this DA. 12510Sstevel@tonic-gate 12520Sstevel@tonic-gate rply = serviceTable.makeDAAdvert(rqst, 12530Sstevel@tonic-gate interfac, 12540Sstevel@tonic-gate config); 12550Sstevel@tonic-gate 12560Sstevel@tonic-gate hdr = rply.getHeader(); 12570Sstevel@tonic-gate 12580Sstevel@tonic-gate if ((hdr.errCode != ServiceLocationException.OK) && 12590Sstevel@tonic-gate config.traceMsg()) { 12600Sstevel@tonic-gate config.writeLog("rh_advert_error", 12610Sstevel@tonic-gate new Object[] { new Integer(hdr.errCode), 12620Sstevel@tonic-gate "DAAdvert", 12630Sstevel@tonic-gate ""}); 12640Sstevel@tonic-gate 12650Sstevel@tonic-gate } 12660Sstevel@tonic-gate } 12670Sstevel@tonic-gate 12680Sstevel@tonic-gate // If there was an error and the request was multicast, drop it 12690Sstevel@tonic-gate // by returning null. 12700Sstevel@tonic-gate 12710Sstevel@tonic-gate if (hdr.errCode != ServiceLocationException.OK && 12720Sstevel@tonic-gate mcast) { 12730Sstevel@tonic-gate 12740Sstevel@tonic-gate if (config.traceDrop()) { 12750Sstevel@tonic-gate 12760Sstevel@tonic-gate config.writeLog("rh_drop_srv", 12770Sstevel@tonic-gate new Object[] { 12780Sstevel@tonic-gate "DA SrvRqst", 12790Sstevel@tonic-gate Integer.toHexString(hdr.xid), 12800Sstevel@tonic-gate clientAddr, 12810Sstevel@tonic-gate new Integer(port), 12820Sstevel@tonic-gate interfac}); 12830Sstevel@tonic-gate 12840Sstevel@tonic-gate } 12850Sstevel@tonic-gate 12860Sstevel@tonic-gate return null; 12870Sstevel@tonic-gate 12880Sstevel@tonic-gate } 12890Sstevel@tonic-gate 12900Sstevel@tonic-gate return rply; 12910Sstevel@tonic-gate 12920Sstevel@tonic-gate } else if (serviceType.equals(Defaults.SA_SERVICE_TYPE.toString())) { 12930Sstevel@tonic-gate 12940Sstevel@tonic-gate // Note that we reply if we are a DA because somebody may want 12950Sstevel@tonic-gate // SA attributes. 12960Sstevel@tonic-gate 12970Sstevel@tonic-gate // We report error for unicast SA service request. 12980Sstevel@tonic-gate 12990Sstevel@tonic-gate if (!mcast) { 13000Sstevel@tonic-gate 13010Sstevel@tonic-gate if (config.traceDrop()) { 13020Sstevel@tonic-gate 13030Sstevel@tonic-gate config.writeLog("rh_no_srv_uni", 13040Sstevel@tonic-gate new Object[] { 13050Sstevel@tonic-gate "SA SrvRqst", 13060Sstevel@tonic-gate Integer.toHexString(hdr.xid), 13070Sstevel@tonic-gate clientAddr, 13080Sstevel@tonic-gate new Integer(port), 13090Sstevel@tonic-gate interfac}); 13100Sstevel@tonic-gate 13110Sstevel@tonic-gate } 13120Sstevel@tonic-gate 13130Sstevel@tonic-gate return null; 13140Sstevel@tonic-gate 13150Sstevel@tonic-gate } 13160Sstevel@tonic-gate 13170Sstevel@tonic-gate // Return a SAAdvert for this SA. 13180Sstevel@tonic-gate 13190Sstevel@tonic-gate try { 13200Sstevel@tonic-gate rply = serviceTable.makeSAAdvert(rqst, 13210Sstevel@tonic-gate interfac, 13220Sstevel@tonic-gate config); 13230Sstevel@tonic-gate 13240Sstevel@tonic-gate } catch (ServiceLocationException ex) { 13250Sstevel@tonic-gate config.writeLog("rh_advert_error", 13260Sstevel@tonic-gate new Object [] {new Integer(ex.getErrorCode()), 13270Sstevel@tonic-gate "SAAdvert", 13280Sstevel@tonic-gate ex.getMessage()}); 13290Sstevel@tonic-gate 13300Sstevel@tonic-gate } 13310Sstevel@tonic-gate 13320Sstevel@tonic-gate 13330Sstevel@tonic-gate if (rply == null && config.traceDrop()) { 13340Sstevel@tonic-gate 13350Sstevel@tonic-gate config.writeLog("rh_drop_srv", 13360Sstevel@tonic-gate new Object[] {"SA SrvRqst", 13370Sstevel@tonic-gate Integer.toHexString(hdr.xid), 13380Sstevel@tonic-gate clientAddr, 13390Sstevel@tonic-gate new Integer(port), 13400Sstevel@tonic-gate interfac}); 13410Sstevel@tonic-gate 13420Sstevel@tonic-gate } 13430Sstevel@tonic-gate 13440Sstevel@tonic-gate return rply; 13450Sstevel@tonic-gate 13460Sstevel@tonic-gate } 13470Sstevel@tonic-gate 13480Sstevel@tonic-gate // Drop if this is a DA and the request was multicast. DAs 13490Sstevel@tonic-gate // do not respond to multicast, except for DAAdverts. 13500Sstevel@tonic-gate 13510Sstevel@tonic-gate if (mcast && config.isDA()) { 13520Sstevel@tonic-gate 13530Sstevel@tonic-gate if (config.traceDrop()) { 13540Sstevel@tonic-gate config.writeLog("rh_drop_da_multi", 13550Sstevel@tonic-gate new Object[] {"SrvRqst", 13560Sstevel@tonic-gate Integer.toHexString(hdr.xid), 13570Sstevel@tonic-gate clientAddr, 13580Sstevel@tonic-gate new Integer(port), 13590Sstevel@tonic-gate interfac}); 13600Sstevel@tonic-gate } 13610Sstevel@tonic-gate 13620Sstevel@tonic-gate return null; 13630Sstevel@tonic-gate 13640Sstevel@tonic-gate } 13650Sstevel@tonic-gate 13660Sstevel@tonic-gate SrvLocMsg smrply = serviceTable.findServices(rqst); 13670Sstevel@tonic-gate hdr = smrply.getHeader(); 13680Sstevel@tonic-gate 13690Sstevel@tonic-gate // Filter multicast replies to remove null and error returns. 13700Sstevel@tonic-gate 13710Sstevel@tonic-gate if (mcast && 13720Sstevel@tonic-gate ((hdr.errCode != ServiceLocationException.OK) || 13730Sstevel@tonic-gate (hdr.getNumReplies() == 0))) { 13740Sstevel@tonic-gate 13750Sstevel@tonic-gate if (config.traceDrop()) { 13760Sstevel@tonic-gate config.writeLog("rh_multi_error", 13770Sstevel@tonic-gate new Object[] {"SrvRqst", 13780Sstevel@tonic-gate Integer.toHexString(hdr.xid), 13790Sstevel@tonic-gate clientAddr, 13800Sstevel@tonic-gate new Integer(port), 13810Sstevel@tonic-gate interfac}); 13820Sstevel@tonic-gate 13830Sstevel@tonic-gate } 13840Sstevel@tonic-gate 13850Sstevel@tonic-gate return null; 13860Sstevel@tonic-gate 13870Sstevel@tonic-gate } 13880Sstevel@tonic-gate 13890Sstevel@tonic-gate return smrply; 13900Sstevel@tonic-gate } 13910Sstevel@tonic-gate 13920Sstevel@tonic-gate // Return true if the host address matches one of the local interfaces. 13930Sstevel@tonic-gate isLocalHostURL(ServiceURL url)13940Sstevel@tonic-gate boolean isLocalHostURL(ServiceURL url) { 13950Sstevel@tonic-gate String hostAddr = url.getHost(); 13960Sstevel@tonic-gate Vector interfaces = config.getInterfaces(); 13970Sstevel@tonic-gate InetAddress addr = null; 13980Sstevel@tonic-gate 13990Sstevel@tonic-gate try { 14000Sstevel@tonic-gate addr = InetAddress.getByName(hostAddr); 14010Sstevel@tonic-gate 14020Sstevel@tonic-gate } catch (UnknownHostException ex) { 14030Sstevel@tonic-gate 14040Sstevel@tonic-gate // We simply ignore it. 14050Sstevel@tonic-gate 14060Sstevel@tonic-gate return false; 14070Sstevel@tonic-gate 14080Sstevel@tonic-gate } 14090Sstevel@tonic-gate 14100Sstevel@tonic-gate if (interfaces.contains(addr)) { 14110Sstevel@tonic-gate return true; 14120Sstevel@tonic-gate 14130Sstevel@tonic-gate } 14140Sstevel@tonic-gate 14150Sstevel@tonic-gate return false; 14160Sstevel@tonic-gate } 14170Sstevel@tonic-gate 14180Sstevel@tonic-gate /** 14190Sstevel@tonic-gate * Return whether this was previous responder. Only do so if the 14200Sstevel@tonic-gate * request was multicast. 14210Sstevel@tonic-gate * 14220Sstevel@tonic-gate * @return True if this host was a previous responder. 14230Sstevel@tonic-gate */ 14240Sstevel@tonic-gate isPreviousResponder(SrvLocHeader hdr)14250Sstevel@tonic-gate public boolean isPreviousResponder(SrvLocHeader hdr) { 14260Sstevel@tonic-gate 14270Sstevel@tonic-gate // If there are no previous responders, then return false, 14280Sstevel@tonic-gate // because they aren't used for this message. Also for 14290Sstevel@tonic-gate // messages that are not multicast. 14300Sstevel@tonic-gate 14310Sstevel@tonic-gate if ((hdr.previousResponders == null) || 14320Sstevel@tonic-gate (hdr.mcast == false)) { 14330Sstevel@tonic-gate return false; 14340Sstevel@tonic-gate 14350Sstevel@tonic-gate } 14360Sstevel@tonic-gate 14370Sstevel@tonic-gate Vector previousResponders = hdr.previousResponders; 14380Sstevel@tonic-gate Enumeration e = null; 14390Sstevel@tonic-gate Vector interfaces = config.getInterfaces(); 14400Sstevel@tonic-gate 14410Sstevel@tonic-gate // Check for matches against this address. 14420Sstevel@tonic-gate 14430Sstevel@tonic-gate for (e = previousResponders.elements(); e.hasMoreElements(); ) { 14440Sstevel@tonic-gate try { 14450Sstevel@tonic-gate String sHost = ((String)e.nextElement()); 14460Sstevel@tonic-gate InetAddress iaHost = InetAddress.getByName(sHost); 14470Sstevel@tonic-gate 14480Sstevel@tonic-gate if (interfaces.contains(iaHost)) { 14490Sstevel@tonic-gate return true; 14500Sstevel@tonic-gate } 14510Sstevel@tonic-gate 14520Sstevel@tonic-gate } catch (UnknownHostException ex) { 14530Sstevel@tonic-gate 14540Sstevel@tonic-gate } 14550Sstevel@tonic-gate } 14560Sstevel@tonic-gate 14570Sstevel@tonic-gate return false; 14580Sstevel@tonic-gate } 14590Sstevel@tonic-gate 14600Sstevel@tonic-gate 14610Sstevel@tonic-gate // Initialize the SLPv2 header parser class when we are loaded. 14620Sstevel@tonic-gate 14630Sstevel@tonic-gate static { 14640Sstevel@tonic-gate SrvLocHeader.addHeaderClass(Defaults.DEFAULT_SERVER_HEADER_CLASS, Defaults.version)14650Sstevel@tonic-gate SrvLocHeader.addHeaderClass(Defaults.DEFAULT_SERVER_HEADER_CLASS, 14660Sstevel@tonic-gate Defaults.version); 14670Sstevel@tonic-gate 14680Sstevel@tonic-gate } 14690Sstevel@tonic-gate 14700Sstevel@tonic-gate } 1471