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 2001-2002 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate //  RequestHandler.java: Handle an incoming request in a separate thread.
287c478bd9Sstevel@tonic-gate //  Author:           James Kempf
297c478bd9Sstevel@tonic-gate //  Created On:       Mon May 18 14:00:27 1998
307c478bd9Sstevel@tonic-gate //  Last Modified By: James Kempf
317c478bd9Sstevel@tonic-gate //  Last Modified On: Mon Mar  8 16:12:13 1999
327c478bd9Sstevel@tonic-gate //  Update Count:     173
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.net.*;
397c478bd9Sstevel@tonic-gate import java.util.*;
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /**
427c478bd9Sstevel@tonic-gate  * Handle an incoming request in a separate thread. The request
437c478bd9Sstevel@tonic-gate  * may have arrived via datagram, or it may have arrived via
447c478bd9Sstevel@tonic-gate  * stream.
457c478bd9Sstevel@tonic-gate  *
467c478bd9Sstevel@tonic-gate  * @author James Kempf, Erik Guttman
477c478bd9Sstevel@tonic-gate  */
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate class RequestHandler extends Thread {
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate     private SLPConfig config;		// Config for system properties.
537c478bd9Sstevel@tonic-gate     private ServerDATable daTable;	// DA table in server for reg and dereg
547c478bd9Sstevel@tonic-gate     private InetAddress interfac = null; // Interface on which request came in.
557c478bd9Sstevel@tonic-gate     private Socket sock = null;		// Socket for incoming stream request.
567c478bd9Sstevel@tonic-gate     private DatagramPacket packet = null; // Packet for datagram requests.
577c478bd9Sstevel@tonic-gate     private InetAddress clientAddr = null; // Internet address of the client.
587c478bd9Sstevel@tonic-gate     private int port = 0;		// Port to use.
597c478bd9Sstevel@tonic-gate     private ServiceTable serviceTable = null;
607c478bd9Sstevel@tonic-gate     private SrvLocMsg toForward = null;	 // Reg or dereg to forward.
617c478bd9Sstevel@tonic-gate     private InputStream inStream = null;
627c478bd9Sstevel@tonic-gate     private OutputStream outStream = null;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate     static private Hashtable inProgress = new Hashtable();
657c478bd9Sstevel@tonic-gate 				// Keeps track of in progress requests
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate     // When a request handler gets GC'd, make sure it's open socket is closed.
687c478bd9Sstevel@tonic-gate     //  We simply let the exception propagate, because it is ignored.
697c478bd9Sstevel@tonic-gate 
finalize()707c478bd9Sstevel@tonic-gate     protected void finalize() throws IOException {
717c478bd9Sstevel@tonic-gate 	if (sock != null) sock.close();
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate     }
747c478bd9Sstevel@tonic-gate 
RequestHandler(InputStream in, OutputStream out, SLPConfig config_in)757c478bd9Sstevel@tonic-gate     RequestHandler(InputStream in, OutputStream out, SLPConfig config_in) {
767c478bd9Sstevel@tonic-gate 	config = config_in;
777c478bd9Sstevel@tonic-gate 	sock = null;
787c478bd9Sstevel@tonic-gate 	inStream = in;
797c478bd9Sstevel@tonic-gate 	outStream = out;
807c478bd9Sstevel@tonic-gate 	clientAddr = config.getLoopback();
817c478bd9Sstevel@tonic-gate 	port = 427;
827c478bd9Sstevel@tonic-gate 	interfac = clientAddr;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	try {
857c478bd9Sstevel@tonic-gate 	    serviceTable = ServiceTable.getServiceTable();
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	    // Taken care of in initialization code.
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	}
927c478bd9Sstevel@tonic-gate     }
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate     // Request arrived via stream. Set the incoming socket, spawn
957c478bd9Sstevel@tonic-gate     //  a separate thread in which to run.
967c478bd9Sstevel@tonic-gate 
RequestHandler(Socket sock_in, InetAddress interfac, SLPConfig config_in)977c478bd9Sstevel@tonic-gate     RequestHandler(Socket sock_in, InetAddress interfac, SLPConfig config_in) {
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	Assert.slpassert((sock_in != null),
1007c478bd9Sstevel@tonic-gate 		      "rh_null_sock",
1017c478bd9Sstevel@tonic-gate 		      new Object[0]);
1027c478bd9Sstevel@tonic-gate 	Assert.slpassert((config_in != null),
1037c478bd9Sstevel@tonic-gate 		      "ls_null_config",
1047c478bd9Sstevel@tonic-gate 		      new Object[0]);
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	config = config_in;
1077c478bd9Sstevel@tonic-gate 	sock = sock_in;
1087c478bd9Sstevel@tonic-gate 	clientAddr = sock.getInetAddress();
1097c478bd9Sstevel@tonic-gate 	port = sock.getPort();
1107c478bd9Sstevel@tonic-gate 	this.interfac = interfac;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	try {
1137c478bd9Sstevel@tonic-gate 	    serviceTable = ServiceTable.getServiceTable();
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	    // Taken care of in initialization code.
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate     }
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate     // Request arrived via datagram. Set the incoming packet, spawn
1237c478bd9Sstevel@tonic-gate     //  a separate thread in which to run.
1247c478bd9Sstevel@tonic-gate 
RequestHandler(DatagramPacket packet_in, InetAddress interfac, SLPConfig config_in)1257c478bd9Sstevel@tonic-gate     RequestHandler(DatagramPacket packet_in,
1267c478bd9Sstevel@tonic-gate 		   InetAddress interfac,
1277c478bd9Sstevel@tonic-gate 		   SLPConfig config_in) {
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	Assert.slpassert((packet_in != null),
1307c478bd9Sstevel@tonic-gate 		      "rh_null_packy",
1317c478bd9Sstevel@tonic-gate 		      new Object[0]);
1327c478bd9Sstevel@tonic-gate 	Assert.slpassert((config_in != null),
1337c478bd9Sstevel@tonic-gate 		      "ls_null_config",
1347c478bd9Sstevel@tonic-gate 		      new Object[0]);
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	config = config_in;
1377c478bd9Sstevel@tonic-gate 	packet = packet_in;
1387c478bd9Sstevel@tonic-gate 	clientAddr = packet.getAddress();
1397c478bd9Sstevel@tonic-gate 	port = packet.getPort();
1407c478bd9Sstevel@tonic-gate 	this.interfac = interfac;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	try {
1437c478bd9Sstevel@tonic-gate 	    serviceTable = ServiceTable.getServiceTable();
1447c478bd9Sstevel@tonic-gate 	    daTable = ServerDATable.getServerDATable();
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 	} catch (ServiceLocationException ex) {
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	    // Taken care of in initialziation code.
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	}
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate     }
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate     /**
1557c478bd9Sstevel@tonic-gate      * Return a stringified buffer, suitable for printing, for
1567c478bd9Sstevel@tonic-gate      * debugging.
1577c478bd9Sstevel@tonic-gate      *
1587c478bd9Sstevel@tonic-gate      * @param bytes The byte buffer.
1597c478bd9Sstevel@tonic-gate      * @return A string with the ASCII characters as characters, otherwise
1607c478bd9Sstevel@tonic-gate      *         convert to escape notation.
1617c478bd9Sstevel@tonic-gate      */
1627c478bd9Sstevel@tonic-gate 
stringifyBuffer(byte[] bytes)1637c478bd9Sstevel@tonic-gate     static String stringifyBuffer(byte[] bytes) {
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	StringBuffer buf = new StringBuffer();
1667c478bd9Sstevel@tonic-gate 	int i, n = bytes.length;
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; i++) {
1697c478bd9Sstevel@tonic-gate 	    byte b = bytes[i];
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	    if ((b >= 0x21) && (b < 0x7e)) {
1727c478bd9Sstevel@tonic-gate 		buf.append((char)b);
1737c478bd9Sstevel@tonic-gate 	    } else {
1747c478bd9Sstevel@tonic-gate 		buf.append("\\"+Integer.toHexString(((int)b) & 0xFF));
1757c478bd9Sstevel@tonic-gate 	    }
1767c478bd9Sstevel@tonic-gate 	}
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	return buf.toString();
1797c478bd9Sstevel@tonic-gate     }
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate     // If a stream thread, then get the request first. Process the
1827c478bd9Sstevel@tonic-gate     //  request and reply to client.
1837c478bd9Sstevel@tonic-gate 
run()1847c478bd9Sstevel@tonic-gate     public void run() {
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	// Is this a stream or datagram thread?
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 	if (sock != null || inStream != null) {
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	    // Label appropriately.
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	    setName("Stream Request Handler "+clientAddr+":"+port);
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	    if (sock != null) {
1957c478bd9Sstevel@tonic-gate 		// Set the socket to block until there are bytes to read.
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 		try {
1987c478bd9Sstevel@tonic-gate 		    sock.setSoTimeout(0);
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 		} catch (SocketException ex) {
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 		}
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	    }
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	    // get DA Table
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	    try {
2097c478bd9Sstevel@tonic-gate 		daTable = ServerDATable.getServerDATable();
2107c478bd9Sstevel@tonic-gate 	    } catch (ServiceLocationException e) {
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 		// Taken care of in initialziation code.
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	    }
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	    // Stream needs to loop through until requests are completed.
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	    handleStream();
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	    if (sock != null) {
2217c478bd9Sstevel@tonic-gate 		try {
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 		    sock.close();
2247c478bd9Sstevel@tonic-gate 		    sock = null;
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 		} catch (IOException ex) {
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 		}
2297c478bd9Sstevel@tonic-gate 	    }
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	} else {
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	    // Label appropriately.
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	    setName("Datagram Request Handler "+clientAddr+":"+port);
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	    byte[] inbuf = packet.getData();
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	    // Copy xid for use in hash key.
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	    byte[] xidBuf = new byte[2];
2427c478bd9Sstevel@tonic-gate 	    System.arraycopy(inbuf, SrvLocHeader.XID_OFFSET, xidBuf, 0, 2);
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 	    // If this request is already in progress, drop new request.
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate 	    int xid = 0;
2477c478bd9Sstevel@tonic-gate 	    xid = (int)((char)xidBuf[0] & 0xFF) << 8;
2487c478bd9Sstevel@tonic-gate 	    xid += (int)((char)xidBuf[1] & 0xFF);
2497c478bd9Sstevel@tonic-gate 	    String syncTableKey =
2507c478bd9Sstevel@tonic-gate 		(new Integer(xid)).toString() +  clientAddr.getHostAddress();
2517c478bd9Sstevel@tonic-gate 	    boolean there = false;
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	    synchronized (inProgress) {
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 		there = (inProgress.get(syncTableKey) != null);
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 		if (!there) {
2587c478bd9Sstevel@tonic-gate 		    inProgress.put(syncTableKey, this);
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 		}
2617c478bd9Sstevel@tonic-gate 	    }
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	    // Drop if we are processing it already.
2647c478bd9Sstevel@tonic-gate 
2657c478bd9Sstevel@tonic-gate 	    if (there) {
2667c478bd9Sstevel@tonic-gate 		if (config.traceDrop()) {
2677c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_rqst_in_progress",
2687c478bd9Sstevel@tonic-gate 				    new Object[] {clientAddr,
2697c478bd9Sstevel@tonic-gate 						      new Integer(port),
2707c478bd9Sstevel@tonic-gate 						      interfac});
2717c478bd9Sstevel@tonic-gate 		}
2727c478bd9Sstevel@tonic-gate 		return;
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	    }
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 	    // We can simply cut to the chase and process the datagram
2777c478bd9Sstevel@tonic-gate 	    //  request.
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	    DataInputStream dis =
2807c478bd9Sstevel@tonic-gate 		new DataInputStream(new ByteArrayInputStream(inbuf));
2817c478bd9Sstevel@tonic-gate 	    ByteArrayOutputStream baos = new ByteArrayOutputStream();
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 	    try {
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 		handleRequest(dis, baos, false);
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 		byte[] outbuf = baos.toByteArray();
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 		// Open a data output stream for the outgoing request. There
2907c478bd9Sstevel@tonic-gate 		//  is no buffer for reply or it is empty, the request was
2917c478bd9Sstevel@tonic-gate 		//  multicast and nothing was sent back.
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 		if (outbuf != null && outbuf.length > 0) {
2947c478bd9Sstevel@tonic-gate 		    sendDatagramReply(outbuf);
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 		}
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	    } catch (IOException ex) {
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 		// No excuse for an EOF exception here.
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 		if (config.traceDrop()) {
3037c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_datagram_ioe",
3047c478bd9Sstevel@tonic-gate 				    new Object[] {clientAddr,
3057c478bd9Sstevel@tonic-gate 						      new Integer(port),
3067c478bd9Sstevel@tonic-gate 						      interfac,
3077c478bd9Sstevel@tonic-gate 						      ex.getMessage()});
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 		}
3107c478bd9Sstevel@tonic-gate 	    }
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	    // Remove the lock for this request. We do this just before the
3137c478bd9Sstevel@tonic-gate 	    //  run() method exits and the thread expires to reduce the
3147c478bd9Sstevel@tonic-gate 	    //  window in which a new copy of the request could come in.
3157c478bd9Sstevel@tonic-gate 	    //  We need to be sure that we only remove if it is this
3167c478bd9Sstevel@tonic-gate 	    //  request handler.
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	    synchronized (inProgress) {
3197c478bd9Sstevel@tonic-gate 		RequestHandler rh =
3207c478bd9Sstevel@tonic-gate 		    (RequestHandler)inProgress.get(syncTableKey);
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 		if (rh == this) {
3237c478bd9Sstevel@tonic-gate 		    inProgress.remove(syncTableKey);
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 		}
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	    }
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	}
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate     }
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate     // Handle an incoming stream.
3347c478bd9Sstevel@tonic-gate 
handleStream()3357c478bd9Sstevel@tonic-gate     private void handleStream() {
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	try {
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	    DataInputStream dis = null;
3407c478bd9Sstevel@tonic-gate 	    DataOutputStream dos = null;
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate 	    if (inStream != null) {
3437c478bd9Sstevel@tonic-gate 		dis = new DataInputStream(inStream);
3447c478bd9Sstevel@tonic-gate 		dos = new DataOutputStream(outStream);
3457c478bd9Sstevel@tonic-gate 	    } else {
3467c478bd9Sstevel@tonic-gate 		// use the socket
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 		dis = new DataInputStream(sock.getInputStream());
3497c478bd9Sstevel@tonic-gate 		dos = new DataOutputStream(sock.getOutputStream());
3507c478bd9Sstevel@tonic-gate 	    }
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	    // Loop while the client still wants to send something. But we
3537c478bd9Sstevel@tonic-gate 	    //  only read one SLP message at a time on the connection,
3547c478bd9Sstevel@tonic-gate 	    //  returning if it there are no more bytes to read. Note that
3557c478bd9Sstevel@tonic-gate 	    //  we have to use a do/while loop here so that the read hangs
3567c478bd9Sstevel@tonic-gate 	    //  until something shows up.
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	    do {
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate 		// Handle the new request.
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 		boolean parseError = handleRequest(dis, baos, true);
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 		dos.write(baos.toByteArray(), 0, baos.size());
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 		// Forward reg or dereg to foreign DAs that need to know
3697c478bd9Sstevel@tonic-gate 		//  about it.
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 		if (toForward != null) {
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate 		    try {
3747c478bd9Sstevel@tonic-gate 			daTable.forwardSAMessage(toForward, clientAddr);
3757c478bd9Sstevel@tonic-gate 			toForward = null;
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 		    } catch (ServiceLocationException ex) {
3787c478bd9Sstevel@tonic-gate 			config.writeLog("sa_forwarding_exception",
3797c478bd9Sstevel@tonic-gate 					new Object[] {
3807c478bd9Sstevel@tonic-gate 			    new Short(ex.getErrorCode()),
3817c478bd9Sstevel@tonic-gate 				Integer.toHexString(toForward.getHeader().xid),
3827c478bd9Sstevel@tonic-gate 				ex.getMessage()});
3837c478bd9Sstevel@tonic-gate 		    }
3847c478bd9Sstevel@tonic-gate 		}
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 		// If there was a parse error, then break out and close the
3877c478bd9Sstevel@tonic-gate 		//  stream, because it may have lingering bytes.
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 		if (parseError && config.traceMsg()) {
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_tcp_error",
3927c478bd9Sstevel@tonic-gate 				    new Object[] {clientAddr,
3937c478bd9Sstevel@tonic-gate 						      new Integer(port),
3947c478bd9Sstevel@tonic-gate 						      interfac});
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 		    break;
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 		}
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	    } while (true);
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 	} catch (EOFException ex) {
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate 	    if (config.traceMsg()) {
4057c478bd9Sstevel@tonic-gate 		config.writeLog("rh_socket_closed",
4067c478bd9Sstevel@tonic-gate 				new Object[] {clientAddr,
4077c478bd9Sstevel@tonic-gate 						  new Integer(port),
4087c478bd9Sstevel@tonic-gate 						  interfac});
4097c478bd9Sstevel@tonic-gate 	    }
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	} catch (IOException ex) {
4137c478bd9Sstevel@tonic-gate 
4147c478bd9Sstevel@tonic-gate 	    // An error occured during input.
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
4177c478bd9Sstevel@tonic-gate 		config.writeLog("ioexception_server_stream",
4187c478bd9Sstevel@tonic-gate 				new Object[] {clientAddr,
4197c478bd9Sstevel@tonic-gate 						  new Integer(port),
4207c478bd9Sstevel@tonic-gate 						  interfac,
4217c478bd9Sstevel@tonic-gate 						  ex.getMessage()});
4227c478bd9Sstevel@tonic-gate 	    }
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	}
4257c478bd9Sstevel@tonic-gate     }
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate     // Send a byte buffer reply through a datagram socket.
4287c478bd9Sstevel@tonic-gate 
sendDatagramReply(byte[] outbuf)4297c478bd9Sstevel@tonic-gate     private void sendDatagramReply(byte[] outbuf) {
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate 	DatagramSocket ds = null;
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate 	try {
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	    // Open the socket.
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate 	    ds = new DatagramSocket();
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 	    // Format the outgoing packet.
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 	    DatagramPacket dpOut =
4427c478bd9Sstevel@tonic-gate 		new DatagramPacket(outbuf, outbuf.length, clientAddr, port);
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 	    // Send the reply.
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 	    ds.send(dpOut);
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	    // Forward reg or dereg to foreign DAs that need to know about it.
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 	    if (toForward != null) {
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 		try {
4537c478bd9Sstevel@tonic-gate 		    daTable.forwardSAMessage(toForward, clientAddr);
4547c478bd9Sstevel@tonic-gate 		    toForward = null;
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate 		} catch (ServiceLocationException ex) {
4577c478bd9Sstevel@tonic-gate 		    config.writeLog("sle_forward_error",
4587c478bd9Sstevel@tonic-gate 			  new Object[] {
4597c478bd9Sstevel@tonic-gate 			new Integer(ex.getErrorCode()),
4607c478bd9Sstevel@tonic-gate 			    Integer.toHexString(toForward.getHeader().xid),
4617c478bd9Sstevel@tonic-gate 			    ex.getMessage()});
4627c478bd9Sstevel@tonic-gate 		}
4637c478bd9Sstevel@tonic-gate 	    }
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 	} catch (SocketException ex) {
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	    // Failure in reply.
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
4707c478bd9Sstevel@tonic-gate 		config.writeLog("rh_socket_error",
4717c478bd9Sstevel@tonic-gate 				new Object[] {clientAddr,
4727c478bd9Sstevel@tonic-gate 						  new Integer(port),
4737c478bd9Sstevel@tonic-gate 						  interfac,
4747c478bd9Sstevel@tonic-gate 						  ex.getMessage()});
4757c478bd9Sstevel@tonic-gate 	    }
4767c478bd9Sstevel@tonic-gate 	} catch (IOException ex) {
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	    // Failure in reply.
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
4817c478bd9Sstevel@tonic-gate 		config.writeLog(
4827c478bd9Sstevel@tonic-gate 				"rh_ioexception_reply",
4837c478bd9Sstevel@tonic-gate 				new Object[] {clientAddr,
4847c478bd9Sstevel@tonic-gate 						  new Integer(port),
4857c478bd9Sstevel@tonic-gate 						  interfac,
4867c478bd9Sstevel@tonic-gate 						  ex.getMessage()});
4877c478bd9Sstevel@tonic-gate 	    }
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	} finally {
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	    if (ds != null) {
4927c478bd9Sstevel@tonic-gate 		ds.close();
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate 	    }
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	}
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate     }
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate     // Handle an incoming stream containing an SLP request.
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate     private boolean
handleRequest(DataInputStream dis, ByteArrayOutputStream baos, boolean isTCP)5037c478bd9Sstevel@tonic-gate 	handleRequest(DataInputStream dis,
5047c478bd9Sstevel@tonic-gate 		      ByteArrayOutputStream baos,
5057c478bd9Sstevel@tonic-gate 		      boolean isTCP)
5067c478bd9Sstevel@tonic-gate 	throws IOException {
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	boolean parseError = false;
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	// Decode the message.
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 	SrvLocMsg msg = internalize(dis, isTCP);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	// If there was an error converting the request, then don't
5157c478bd9Sstevel@tonic-gate 	// process further.
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate 	SrvLocMsg rply = msg;
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 	if (msg != null) {
5207c478bd9Sstevel@tonic-gate 	    SrvLocHeader hdr = msg.getHeader();
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 	    if (hdr.errCode == ServiceLocationException.OK) {
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 		if (config.traceMsg()) {
5257c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_rqst_in",
5267c478bd9Sstevel@tonic-gate 				    new Object[] {Integer.toHexString(hdr.xid),
5277c478bd9Sstevel@tonic-gate 						      clientAddr,
5287c478bd9Sstevel@tonic-gate 						      new Integer(port),
5297c478bd9Sstevel@tonic-gate 						      interfac,
5307c478bd9Sstevel@tonic-gate 						      msg.getHeader()});
5317c478bd9Sstevel@tonic-gate 		}
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 		// Dispatch the message to the service table.
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 		rply = dispatch(msg);
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 		// If no reply, then simply return.
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 		if (rply == null) {
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 		    if (config.traceMsg()) {
5437c478bd9Sstevel@tonic-gate 			config.writeLog("rh_rply_null",
5447c478bd9Sstevel@tonic-gate 					new Object[] {
5457c478bd9Sstevel@tonic-gate 			    Integer.toHexString(hdr.xid),
5467c478bd9Sstevel@tonic-gate 				clientAddr,
5477c478bd9Sstevel@tonic-gate 				new Integer(port),
5487c478bd9Sstevel@tonic-gate 				interfac});
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 		    }
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate 		    return parseError;
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 		}
5557c478bd9Sstevel@tonic-gate 	    } else {
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 		// Drop if multicast.
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 		if (msg.getHeader().mcast) {
5607c478bd9Sstevel@tonic-gate 		    rply = null;
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 		    if (config.traceDrop()) {
5637c478bd9Sstevel@tonic-gate 			config.writeLog("rh_multi_error",
5647c478bd9Sstevel@tonic-gate 					new Object[] {
5657c478bd9Sstevel@tonic-gate 			    msg.getClass().getName(),
5667c478bd9Sstevel@tonic-gate 				Integer.toHexString(hdr.xid),
5677c478bd9Sstevel@tonic-gate 				clientAddr,
5687c478bd9Sstevel@tonic-gate 				new Integer(port),
5697c478bd9Sstevel@tonic-gate 				interfac});
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 		    }
5737c478bd9Sstevel@tonic-gate 		} else if (isTCP) {
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 		    // Set the parse error flag so that the stream gets closed.
5767c478bd9Sstevel@tonic-gate 		    //  It's easier than trying to keep track of the number of
5777c478bd9Sstevel@tonic-gate 		    //  bytes read. Otherwise, the remnents of the message
5787c478bd9Sstevel@tonic-gate 		    //  hang around.
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 		    parseError = true;
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 		}
5837c478bd9Sstevel@tonic-gate 	    }
5847c478bd9Sstevel@tonic-gate 	}
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate 	// Reply to the client if necessary. Note that if the reply is null
5877c478bd9Sstevel@tonic-gate 	//  here, there was a problem parsing the message in and so formulating
5887c478bd9Sstevel@tonic-gate 	//  a reply may be impossible (for example, the message may not
5897c478bd9Sstevel@tonic-gate 	//  be parsable beyond the function code.
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	if (rply != null) {
5927c478bd9Sstevel@tonic-gate 	    SrvLocHeader hdr = rply.getHeader();
5937c478bd9Sstevel@tonic-gate 	    ServiceLocationException ex = null;
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate 	    // Parse out the message.
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 	    try {
5987c478bd9Sstevel@tonic-gate 		hdr.externalize(baos, false, isTCP);
5997c478bd9Sstevel@tonic-gate 	    } catch (ServiceLocationException sle) {
6007c478bd9Sstevel@tonic-gate 		ex = sle;
6017c478bd9Sstevel@tonic-gate 	    }
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 	    if (config.traceMsg()) {
6047c478bd9Sstevel@tonic-gate 		config.writeLog("rh_rply_out",
6057c478bd9Sstevel@tonic-gate 				new Object[] {Integer.toHexString(hdr.xid),
6067c478bd9Sstevel@tonic-gate 						  clientAddr,
6077c478bd9Sstevel@tonic-gate 						  new Integer(port),
6087c478bd9Sstevel@tonic-gate 						  interfac,
6097c478bd9Sstevel@tonic-gate 						  rply.getHeader()});
6107c478bd9Sstevel@tonic-gate 	    }
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate 	    if (ex != null) {
6137c478bd9Sstevel@tonic-gate 		baos.reset();
6147c478bd9Sstevel@tonic-gate 		rply = hdr.makeErrorReply(ex);
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate 		Assert.slpassert(msg != null,
6177c478bd9Sstevel@tonic-gate 			      "rh_header_class_error",
6187c478bd9Sstevel@tonic-gate 			      new Object[] {ex.getMessage()});
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 		hdr = rply.getHeader();
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 		try {
6237c478bd9Sstevel@tonic-gate 		    hdr.externalize(baos, false, isTCP);
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 		} catch (ServiceLocationException exx) {
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate 		}
6287c478bd9Sstevel@tonic-gate 	    }
6297c478bd9Sstevel@tonic-gate 	} else if (config.traceMsg()) {
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate 	    // Print error message.
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	    String xidStr = "<null message>";
6347c478bd9Sstevel@tonic-gate 
6357c478bd9Sstevel@tonic-gate 	    if (msg != null) {
6367c478bd9Sstevel@tonic-gate 		SrvLocHeader hdr = msg.getHeader();
6377c478bd9Sstevel@tonic-gate 		xidStr = Integer.toHexString(hdr.xid);
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 	    }
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 	    config.writeLog("rh_rply_null",
6427c478bd9Sstevel@tonic-gate 			    new Object[] {xidStr,
6437c478bd9Sstevel@tonic-gate 					      clientAddr,
6447c478bd9Sstevel@tonic-gate 					      new Integer(port),
6457c478bd9Sstevel@tonic-gate 					      interfac});
6467c478bd9Sstevel@tonic-gate 	}
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 	return parseError;
6497c478bd9Sstevel@tonic-gate     }
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate     /**
6527c478bd9Sstevel@tonic-gate      * Internalize the byte array in the input stream into a SrvLocMsg
6537c478bd9Sstevel@tonic-gate      * subclass. It will be an appropriate subclass for the SA/DA.
6547c478bd9Sstevel@tonic-gate      *
6557c478bd9Sstevel@tonic-gate      * @param dis The input stream containing the packet.
6567c478bd9Sstevel@tonic-gate      * @param viaTCP True if the outgoing stream is via TCP.
6577c478bd9Sstevel@tonic-gate      * @return The right SrvLocMsg subclass appropriate for the SA/DA.
6587c478bd9Sstevel@tonic-gate      *		If null is returned, it means that the function code was
6597c478bd9Sstevel@tonic-gate      *		not recognized.
6607c478bd9Sstevel@tonic-gate      *		If any error occurs during creation, an error request is
6617c478bd9Sstevel@tonic-gate      *		returned with the error code set.
6627c478bd9Sstevel@tonic-gate      */
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate     private SrvLocMsg
internalize(DataInputStream dis, boolean viaTCP)6657c478bd9Sstevel@tonic-gate 	internalize(DataInputStream dis, boolean viaTCP) throws IOException {
6667c478bd9Sstevel@tonic-gate 
6677c478bd9Sstevel@tonic-gate 	int ver = 0, fun = 0;
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 	Assert.slpassert((dis != null),
6707c478bd9Sstevel@tonic-gate 		      "rh_null_bais",
6717c478bd9Sstevel@tonic-gate 		      new Object[0]);
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 	try {
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	    // Pull off the version number and function code.
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate 	    byte[] b = new byte[2];
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate 	    dis.readFully(b, 0, 2);
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	    ver = (int) ((char)b[0] & 0XFF);
6827c478bd9Sstevel@tonic-gate 	    fun = (int) ((char)b[1] & 0XFF);
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 	} catch (IOException ex) {
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	    // Print an error message, but only if not EOF.
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	    if (!(ex instanceof EOFException)) {
6897c478bd9Sstevel@tonic-gate 		printInternalizeErrorMessage(ver, fun, ex);
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 	    }
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 	    // Throw the exception, so streams can terminate.
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	    throw ex;
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	}
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 	SrvLocMsg msg = null;
7007c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = null;
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate 	try {
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 	    hdr = SrvLocHeader.newInstance(ver);
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 	    // Unrecognized version number if header not returned.
7077c478bd9Sstevel@tonic-gate 	    //  We only throw an exception if the version number
7087c478bd9Sstevel@tonic-gate 	    //  is greater than the current default version number.
7097c478bd9Sstevel@tonic-gate 	    //  otherwise, the packet is from an earlier version
7107c478bd9Sstevel@tonic-gate 	    //  of the protocol and should be ignored if we are
7117c478bd9Sstevel@tonic-gate 	    //  not operating in compatibility mode.
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate 	    if (hdr == null) {
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 		if (ver > Defaults.version ||
7167c478bd9Sstevel@tonic-gate 		    (config.isV1Supported() && config.isDA())) {
7177c478bd9Sstevel@tonic-gate 							// code problem...
7187c478bd9Sstevel@tonic-gate 		    throw
7197c478bd9Sstevel@tonic-gate 			new ServiceLocationException(
7207c478bd9Sstevel@tonic-gate 				ServiceLocationException.VERSION_NOT_SUPPORTED,
7217c478bd9Sstevel@tonic-gate 				"rh_version_number_error",
7227c478bd9Sstevel@tonic-gate 				new Object[] {new Integer(ver),
7237c478bd9Sstevel@tonic-gate 						  clientAddr,
7247c478bd9Sstevel@tonic-gate 						  new Integer(port),
7257c478bd9Sstevel@tonic-gate 						  interfac});
7267c478bd9Sstevel@tonic-gate 		} else {
7277c478bd9Sstevel@tonic-gate 		    return null;
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate 		}
7307c478bd9Sstevel@tonic-gate 	    }
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate 	    // If we've come via TCP, clear the packet length so the
7337c478bd9Sstevel@tonic-gate 	    //  eventual reply won't be checked for overflow.
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	    if (viaTCP) {
7367c478bd9Sstevel@tonic-gate 		hdr.setPacketLength(Integer.MAX_VALUE);
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	    }
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate 	    // Parse the header.
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 	    hdr.parseHeader(fun, dis);
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate 	    // Parse body.
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 	    if ((msg = hdr.parseMsg(dis)) != null) {
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 		// Parse options, if any.
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 		hdr.parseOptions(dis);
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate 	    }
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate 	} catch (Exception ex) {
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate 	    printInternalizeErrorMessage(ver, fun, ex);
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 	    msg = null;
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 	    // If this is a DAAdvert or an SAAdvert, or there's no header,
7617c478bd9Sstevel@tonic-gate 	    //  return null cause we don't need to return anything or
7627c478bd9Sstevel@tonic-gate 	    //  can't.
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate 	    if (fun != SrvLocHeader.DAAdvert &&
7657c478bd9Sstevel@tonic-gate 		fun != SrvLocHeader.SAAdvert &&
7667c478bd9Sstevel@tonic-gate 		hdr != null) {
7677c478bd9Sstevel@tonic-gate 
7687c478bd9Sstevel@tonic-gate 		// Let header create message.
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate 		msg = hdr.makeErrorReply(ex);
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 	    }
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate 	}
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 	return msg;
7777c478bd9Sstevel@tonic-gate     }
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate     // Print an error message for errors during internalization.
7807c478bd9Sstevel@tonic-gate 
printInternalizeErrorMessage(int ver, int fun, Exception ex)7817c478bd9Sstevel@tonic-gate     private void printInternalizeErrorMessage(int ver, int fun, Exception ex) {
7827c478bd9Sstevel@tonic-gate 
7837c478bd9Sstevel@tonic-gate 	if (config.traceDrop()) {
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	    StringWriter sw = new StringWriter();
7867c478bd9Sstevel@tonic-gate 	    PrintWriter pw = new PrintWriter(sw);
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate 	    ex.printStackTrace(pw);
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate 	    short errCode = ServiceLocationException.INTERNAL_SYSTEM_ERROR;
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate 	    if (ex instanceof ServiceLocationException) {
7937c478bd9Sstevel@tonic-gate 		errCode = ((ServiceLocationException)ex).getErrorCode();
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	    } else if (ex instanceof IllegalArgumentException) {
7967c478bd9Sstevel@tonic-gate 		errCode = ServiceLocationException.PARSE_ERROR;
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate 	    }
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	    String exMsg = "(" + errCode + "):" + ex.getMessage();
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate 	    config.writeLog("rh_unparse_exception",
8037c478bd9Sstevel@tonic-gate 			    new Object[] {clientAddr,
8047c478bd9Sstevel@tonic-gate 					      new Integer(port),
8057c478bd9Sstevel@tonic-gate 					      interfac,
8067c478bd9Sstevel@tonic-gate 					      new Integer(ver),
8077c478bd9Sstevel@tonic-gate 					      new Integer(fun),
8087c478bd9Sstevel@tonic-gate 					      exMsg,
8097c478bd9Sstevel@tonic-gate 					      sw.toString()});
8107c478bd9Sstevel@tonic-gate 	}
8117c478bd9Sstevel@tonic-gate     }
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate     /**
8147c478bd9Sstevel@tonic-gate      * Dispatch the service request object to the service table.
8157c478bd9Sstevel@tonic-gate      * The SA table is used for the following:
8167c478bd9Sstevel@tonic-gate      *
8177c478bd9Sstevel@tonic-gate      * @param rqst Service request object.
8187c478bd9Sstevel@tonic-gate      * @return A SrvLocMsg object to reply with, or null if no reply.
8197c478bd9Sstevel@tonic-gate      */
8207c478bd9Sstevel@tonic-gate 
dispatch(SrvLocMsg rqst)8217c478bd9Sstevel@tonic-gate     SrvLocMsg dispatch(SrvLocMsg rqst) {
8227c478bd9Sstevel@tonic-gate 
8237c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = rqst.getHeader();
8247c478bd9Sstevel@tonic-gate 	boolean mcast = hdr.mcast;
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate 	// Check CDAAdvert and CSAAdvert before we check the previous
8277c478bd9Sstevel@tonic-gate 	//  responders list, because they don't have any.
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate 	if (rqst instanceof CDAAdvert) {  // DA advert...
8307c478bd9Sstevel@tonic-gate 	    CDAAdvert msg = (CDAAdvert)rqst;
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	    // For V1, V2 messages know.
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate 	    msg.setIsUnsolicited(true);
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate 	    // If passive detection is off, ignore it, but only if it wasn't
8377c478bd9Sstevel@tonic-gate 	    //  a signal to stop.
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate 	    if (!config.passiveDADetection() &&
8407c478bd9Sstevel@tonic-gate 		msg.isUnsolicited() &&
8417c478bd9Sstevel@tonic-gate 		!msg.isGoingDown()) {
8427c478bd9Sstevel@tonic-gate 		if (config.traceDrop()) {
8437c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_passive_drop",
8447c478bd9Sstevel@tonic-gate 				    new Object[] {msg.URL,
8457c478bd9Sstevel@tonic-gate 						      hdr.scopes});
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 		}
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	    } else if (msg.isGoingDown() && msg.isUnsolicited() &&
8507c478bd9Sstevel@tonic-gate 		       isLocalHostURL(msg.URL) && config.isDA()) {
8517c478bd9Sstevel@tonic-gate 
8527c478bd9Sstevel@tonic-gate 		// We've been asked to terminate.
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 		// Check scopes.
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate 		Vector scopes = (Vector)hdr.scopes.clone();
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 		DATable.filterScopes(scopes,
8597c478bd9Sstevel@tonic-gate 				     config.getSAConfiguredScopes(), true);
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 		// If all scopes not equal, it isn't a shutdown message for us.
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate 		if (scopes.size() > 0) {
8647c478bd9Sstevel@tonic-gate 		    daTable.handleAdvertIn(msg);
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate 		} else {
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 		    Vector discoveredScopes = new Vector();
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 		    try {
8717c478bd9Sstevel@tonic-gate 			discoveredScopes = daTable.findScopes();
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate 		    } catch (ServiceLocationException ex) {
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate 			// Ignore, we're going down anyway and it's
8767c478bd9Sstevel@tonic-gate 			// just a report.
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 		    }
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 		    // It is a shutdown message for us.
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate 		    Vector serverScopes = config.getSAConfiguredScopes();
8837c478bd9Sstevel@tonic-gate 		    Vector interfaces = config.getInterfaces();
8847c478bd9Sstevel@tonic-gate 		    Vector daAttributes = config.getDAAttributes();
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 		    if (config.traceAll() ||
8877c478bd9Sstevel@tonic-gate 			config.traceMsg() ||
8887c478bd9Sstevel@tonic-gate 			config.traceDrop() ||
8897c478bd9Sstevel@tonic-gate 			config.traceDATraffic()) {
8907c478bd9Sstevel@tonic-gate 
8917c478bd9Sstevel@tonic-gate 			config.writeLog("goodby_da",
8927c478bd9Sstevel@tonic-gate 					new Object[] {interfaces,
8937c478bd9Sstevel@tonic-gate 							  serverScopes,
8947c478bd9Sstevel@tonic-gate 							  discoveredScopes,
8957c478bd9Sstevel@tonic-gate 							  daAttributes});
8967c478bd9Sstevel@tonic-gate 		    }
897*55fea89dSDan Cross 
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate 		    // We don't reply, which means that the client will
9007c478bd9Sstevel@tonic-gate 		    // time out.
9017c478bd9Sstevel@tonic-gate 
9027c478bd9Sstevel@tonic-gate 		    System.exit(0);
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate 		}
9057c478bd9Sstevel@tonic-gate 	    } else {
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate 		// The implementation specific DA table handles this.
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate 		daTable.handleAdvertIn(msg);
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 	    }
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 	    return null;
9147c478bd9Sstevel@tonic-gate 
9157c478bd9Sstevel@tonic-gate 	} else if (rqst instanceof CSAAdvert) {// SA advert...
9167c478bd9Sstevel@tonic-gate 	    CSAAdvert msg = (CSAAdvert)rqst;
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 	    // We are only interested in it if we may be going down.
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate 	    if ((hdr.xid == 0) && isLocalHostURL(msg.URL) && !config.isDA()) {
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 		// Check scopes.
9237c478bd9Sstevel@tonic-gate 
9247c478bd9Sstevel@tonic-gate 		Vector scopes = (Vector)hdr.scopes.clone();
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 		DATable.filterScopes(scopes,
9277c478bd9Sstevel@tonic-gate 				     config.getSAConfiguredScopes(), true);
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 		// If all scopes not equal, it isn't a shutdown message for us.
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate 		if (scopes.size() <= 0) {
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 		    Vector discoveredScopes = new Vector();
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 		    try {
9367c478bd9Sstevel@tonic-gate 			discoveredScopes = daTable.findScopes();
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 		    } catch (ServiceLocationException ex) {
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate 			// Ignore, we're going down anyway and it's just a
9417c478bd9Sstevel@tonic-gate 			// report.
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 		    }
9447c478bd9Sstevel@tonic-gate 
9457c478bd9Sstevel@tonic-gate 		    // It is a shutdown message for us.
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate 		    Vector serverScopes = config.getSAConfiguredScopes();
9487c478bd9Sstevel@tonic-gate 		    Vector interfaces = config.getInterfaces();
9497c478bd9Sstevel@tonic-gate 		    Vector saAttributes = config.getSAAttributes();
9507c478bd9Sstevel@tonic-gate 
9517c478bd9Sstevel@tonic-gate 		    if (config.traceAll() ||
9527c478bd9Sstevel@tonic-gate 			config.traceMsg() ||
9537c478bd9Sstevel@tonic-gate 			config.traceDrop() ||
9547c478bd9Sstevel@tonic-gate 			config.traceDATraffic()) {
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 			config.writeLog("goodby",
9577c478bd9Sstevel@tonic-gate 					new Object[] {interfaces,
9587c478bd9Sstevel@tonic-gate 							  serverScopes,
9597c478bd9Sstevel@tonic-gate 							  discoveredScopes,
9607c478bd9Sstevel@tonic-gate 							  saAttributes});
9617c478bd9Sstevel@tonic-gate 		    }
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate 		    System.exit(0);
9647c478bd9Sstevel@tonic-gate 		}
9657c478bd9Sstevel@tonic-gate 	    }
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 	    // Otherwise, drop it for now.
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
9707c478bd9Sstevel@tonic-gate 		config.writeLog("rh_client_sa_advert_drop",
9717c478bd9Sstevel@tonic-gate 				new Object[] {Integer.toHexString(hdr.xid),
9727c478bd9Sstevel@tonic-gate 						  clientAddr,
9737c478bd9Sstevel@tonic-gate 						  new Integer(port),
9747c478bd9Sstevel@tonic-gate 						  interfac});
9757c478bd9Sstevel@tonic-gate 	    }
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 	    return null;
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate 	}
9807c478bd9Sstevel@tonic-gate 
9817c478bd9Sstevel@tonic-gate 	if (rqst instanceof SSrvReg) { // registration...
9827c478bd9Sstevel@tonic-gate 
9837c478bd9Sstevel@tonic-gate 	    return dispatchReg((SSrvReg)rqst,
9847c478bd9Sstevel@tonic-gate 			       serviceTable);
9857c478bd9Sstevel@tonic-gate 
9867c478bd9Sstevel@tonic-gate 	} else if (rqst instanceof SSrvDereg) { // deregistration...
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 	    return dispatchDereg((SSrvDereg)rqst,
9897c478bd9Sstevel@tonic-gate 				 serviceTable);
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate 	}
9927c478bd9Sstevel@tonic-gate 
9937c478bd9Sstevel@tonic-gate 
9947c478bd9Sstevel@tonic-gate 	// If we are on the previous responder list, then ignore this
9957c478bd9Sstevel@tonic-gate 	//  request.
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 	if (isPreviousResponder(hdr)) {
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
10007c478bd9Sstevel@tonic-gate 		config.writeLog("rh_prev_resp",
10017c478bd9Sstevel@tonic-gate 				new Object[] {Integer.toHexString(hdr.xid),
10027c478bd9Sstevel@tonic-gate 						  clientAddr,
10037c478bd9Sstevel@tonic-gate 						  new Integer(port),
10047c478bd9Sstevel@tonic-gate 						  interfac});
10057c478bd9Sstevel@tonic-gate 	    }
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 	    return null;
10087c478bd9Sstevel@tonic-gate 
10097c478bd9Sstevel@tonic-gate 	}
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate 	// Now check requests with previous responders.
10127c478bd9Sstevel@tonic-gate 
10137c478bd9Sstevel@tonic-gate 	if (rqst instanceof SSrvTypeMsg) {	// service types...
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate 	    return dispatchSrvType((SSrvTypeMsg)rqst,
10167c478bd9Sstevel@tonic-gate 				   serviceTable);
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	} else if (rqst instanceof SAttrMsg) { // attributes...
10197c478bd9Sstevel@tonic-gate 
10207c478bd9Sstevel@tonic-gate 	    return dispatchAttr((SAttrMsg)rqst,
10217c478bd9Sstevel@tonic-gate 				serviceTable);
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 	} else if (rqst instanceof SSrvMsg) { // services...
10247c478bd9Sstevel@tonic-gate 
10257c478bd9Sstevel@tonic-gate 	    return dispatchSrv((SSrvMsg)rqst,
10267c478bd9Sstevel@tonic-gate 			       serviceTable);
10277c478bd9Sstevel@tonic-gate 
10287c478bd9Sstevel@tonic-gate 	} else {				    // error...
10297c478bd9Sstevel@tonic-gate 
10307c478bd9Sstevel@tonic-gate 	    Assert.slpassert(false,
10317c478bd9Sstevel@tonic-gate 			  "rh_rqst_type_err",
10327c478bd9Sstevel@tonic-gate 			  new Object[] {rqst});
10337c478bd9Sstevel@tonic-gate 
10347c478bd9Sstevel@tonic-gate 	}
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate 	return null;
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate     }
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate     // Dispatch a service registration.
10427c478bd9Sstevel@tonic-gate 
dispatchReg(SSrvReg rqst, ServiceTable serviceTable)10437c478bd9Sstevel@tonic-gate     private SrvLocMsg dispatchReg(SSrvReg rqst,
10447c478bd9Sstevel@tonic-gate 				  ServiceTable serviceTable) {
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = rqst.getHeader();
10477c478bd9Sstevel@tonic-gate 
10487c478bd9Sstevel@tonic-gate 	// Report error if the message was multicast.
10497c478bd9Sstevel@tonic-gate 
10507c478bd9Sstevel@tonic-gate 	if (hdr.mcast && config.traceDrop()) {
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
10537c478bd9Sstevel@tonic-gate 		config.writeLog("rh_no_multi",
10547c478bd9Sstevel@tonic-gate 				new Object[] {"SrvReg",
10557c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
10567c478bd9Sstevel@tonic-gate 						  clientAddr,
10577c478bd9Sstevel@tonic-gate 						  new Integer(port),
10587c478bd9Sstevel@tonic-gate 						  interfac});
10597c478bd9Sstevel@tonic-gate 	    }
10607c478bd9Sstevel@tonic-gate 
10617c478bd9Sstevel@tonic-gate 	    return null;
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 	}
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	// Register the request.
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate 	SrvLocMsg rply = serviceTable.register(rqst);
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate 	// Forward to foreign DAs if no error.
10707c478bd9Sstevel@tonic-gate 
10717c478bd9Sstevel@tonic-gate 	if (rply != null) {
10727c478bd9Sstevel@tonic-gate 	    hdr = rply.getHeader();
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate 	    if (hdr.errCode == ServiceLocationException.OK) {
10757c478bd9Sstevel@tonic-gate 		toForward = rqst;
1076*55fea89dSDan Cross 
10777c478bd9Sstevel@tonic-gate 	    }
10787c478bd9Sstevel@tonic-gate 	}
10797c478bd9Sstevel@tonic-gate 
10807c478bd9Sstevel@tonic-gate 	return rply;
10817c478bd9Sstevel@tonic-gate     }
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate     // Dispatch a service deregistration.
10847c478bd9Sstevel@tonic-gate 
dispatchDereg(SSrvDereg rqst, ServiceTable serviceTable)10857c478bd9Sstevel@tonic-gate     private SrvLocMsg dispatchDereg(SSrvDereg rqst,
10867c478bd9Sstevel@tonic-gate 				    ServiceTable serviceTable) {
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = rqst.getHeader();
10897c478bd9Sstevel@tonic-gate 
10907c478bd9Sstevel@tonic-gate 	// Report error if the message was multicast.
10917c478bd9Sstevel@tonic-gate 
10927c478bd9Sstevel@tonic-gate 	if (hdr.mcast && config.traceDrop()) {
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
10957c478bd9Sstevel@tonic-gate 		config.writeLog("rh_no_multi",
10967c478bd9Sstevel@tonic-gate 				new Object[] {"SrvDereg",
10977c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
10987c478bd9Sstevel@tonic-gate 						  clientAddr,
10997c478bd9Sstevel@tonic-gate 						  new Integer(port),
11007c478bd9Sstevel@tonic-gate 						  interfac});
11017c478bd9Sstevel@tonic-gate 	    }
11027c478bd9Sstevel@tonic-gate 
11037c478bd9Sstevel@tonic-gate 	    return null;
11047c478bd9Sstevel@tonic-gate 
11057c478bd9Sstevel@tonic-gate 	}
11067c478bd9Sstevel@tonic-gate 
11077c478bd9Sstevel@tonic-gate 	// If the message came from the local host, use the SA store.
11087c478bd9Sstevel@tonic-gate 
11097c478bd9Sstevel@tonic-gate 	SrvLocMsg rply = serviceTable.deregister(rqst);
11107c478bd9Sstevel@tonic-gate 
11117c478bd9Sstevel@tonic-gate 	// Forward to foreign DAs if no error.
11127c478bd9Sstevel@tonic-gate 
11137c478bd9Sstevel@tonic-gate 	if (rply != null) {
11147c478bd9Sstevel@tonic-gate 	    hdr = rply.getHeader();
11157c478bd9Sstevel@tonic-gate 
11167c478bd9Sstevel@tonic-gate 	    if (hdr.errCode == ServiceLocationException.OK) {
11177c478bd9Sstevel@tonic-gate 		toForward = rqst;
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 	    }
11207c478bd9Sstevel@tonic-gate 	}
11217c478bd9Sstevel@tonic-gate 
11227c478bd9Sstevel@tonic-gate 	return rply;
11237c478bd9Sstevel@tonic-gate     }
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate     // Dispatch a service type message.
11267c478bd9Sstevel@tonic-gate 
dispatchSrvType(SSrvTypeMsg rqst, ServiceTable serviceTable)11277c478bd9Sstevel@tonic-gate     private SrvLocMsg dispatchSrvType(SSrvTypeMsg rqst,
11287c478bd9Sstevel@tonic-gate 				      ServiceTable serviceTable) {
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = rqst.getHeader();
11317c478bd9Sstevel@tonic-gate 	boolean mcast = hdr.mcast;
11327c478bd9Sstevel@tonic-gate 
11337c478bd9Sstevel@tonic-gate 	// Drop if this is a DA and the request was multicast. DAs
11347c478bd9Sstevel@tonic-gate 	//  do not respond to multicast, except for DAAdverts.
11357c478bd9Sstevel@tonic-gate 
11367c478bd9Sstevel@tonic-gate 	if (mcast && config.isDA()) {
11377c478bd9Sstevel@tonic-gate 
11387c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
11397c478bd9Sstevel@tonic-gate 		config.writeLog("rh_drop_da_multi",
11407c478bd9Sstevel@tonic-gate 				new Object[] {"SrvTypeRqst",
11417c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
11427c478bd9Sstevel@tonic-gate 						  clientAddr,
11437c478bd9Sstevel@tonic-gate 						  new Integer(port),
11447c478bd9Sstevel@tonic-gate 						  interfac});
11457c478bd9Sstevel@tonic-gate 	    }
11467c478bd9Sstevel@tonic-gate 
11477c478bd9Sstevel@tonic-gate 	    return null;
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate 	}
11507c478bd9Sstevel@tonic-gate 
11517c478bd9Sstevel@tonic-gate 	SrvLocMsg rply = serviceTable.findServiceTypes(rqst);
11527c478bd9Sstevel@tonic-gate 	hdr = rply.getHeader();
11537c478bd9Sstevel@tonic-gate 
11547c478bd9Sstevel@tonic-gate 	// Filter multicast replies to remove null and error returns.
11557c478bd9Sstevel@tonic-gate 
11567c478bd9Sstevel@tonic-gate 	if (mcast &&
11577c478bd9Sstevel@tonic-gate 	    ((hdr.errCode != ServiceLocationException.OK) ||
11587c478bd9Sstevel@tonic-gate 	    (hdr.getNumReplies() == 0))) {
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
11617c478bd9Sstevel@tonic-gate 		config.writeLog("rh_multi_error",
11627c478bd9Sstevel@tonic-gate 				new Object[] {"SrvTypeRqst",
11637c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
11647c478bd9Sstevel@tonic-gate 						  clientAddr,
11657c478bd9Sstevel@tonic-gate 						  new Integer(port),
11667c478bd9Sstevel@tonic-gate 						  interfac});
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate 
11697c478bd9Sstevel@tonic-gate 	    }
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate 	    return null;
11727c478bd9Sstevel@tonic-gate 
11737c478bd9Sstevel@tonic-gate 	}
11747c478bd9Sstevel@tonic-gate 
11757c478bd9Sstevel@tonic-gate 	return rply;
11767c478bd9Sstevel@tonic-gate     }
11777c478bd9Sstevel@tonic-gate 
11787c478bd9Sstevel@tonic-gate     // Dispatch an attribute request.
11797c478bd9Sstevel@tonic-gate 
dispatchAttr(SAttrMsg rqst, ServiceTable serviceTable)11807c478bd9Sstevel@tonic-gate     private SrvLocMsg dispatchAttr(SAttrMsg rqst,
11817c478bd9Sstevel@tonic-gate 				   ServiceTable serviceTable) {
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = rqst.getHeader();
11847c478bd9Sstevel@tonic-gate 	boolean mcast = hdr.mcast;
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 	// Drop if this is a DA and the request was multicast. DAs
11877c478bd9Sstevel@tonic-gate 	//  do not respond to multicast, except for DAAdverts.
11887c478bd9Sstevel@tonic-gate 
11897c478bd9Sstevel@tonic-gate 	if (mcast && config.isDA()) {
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
11927c478bd9Sstevel@tonic-gate 		config.writeLog("rh_drop_da_multi",
11937c478bd9Sstevel@tonic-gate 				new Object[] {"AttrRqst",
11947c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
11957c478bd9Sstevel@tonic-gate 						  clientAddr,
11967c478bd9Sstevel@tonic-gate 						  new Integer(port),
11977c478bd9Sstevel@tonic-gate 						  interfac});
11987c478bd9Sstevel@tonic-gate 	    }
11997c478bd9Sstevel@tonic-gate 
12007c478bd9Sstevel@tonic-gate 	    return null;
12017c478bd9Sstevel@tonic-gate 
12027c478bd9Sstevel@tonic-gate 	}
12037c478bd9Sstevel@tonic-gate 
12047c478bd9Sstevel@tonic-gate 	SrvLocMsg rply = serviceTable.findAttributes(rqst);
12057c478bd9Sstevel@tonic-gate 	hdr = rply.getHeader();
12067c478bd9Sstevel@tonic-gate 
12077c478bd9Sstevel@tonic-gate 	// Filter multicast replies to remove null and error returns.
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 	if (mcast &&
12107c478bd9Sstevel@tonic-gate 	    ((hdr.errCode != ServiceLocationException.OK) ||
12117c478bd9Sstevel@tonic-gate 	    (hdr.getNumReplies() == 0))) {
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
12147c478bd9Sstevel@tonic-gate 		config.writeLog("rh_multi_error",
12157c478bd9Sstevel@tonic-gate 				new Object[] {"AttrRqst",
12167c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
12177c478bd9Sstevel@tonic-gate 						  clientAddr,
12187c478bd9Sstevel@tonic-gate 						  new Integer(port),
12197c478bd9Sstevel@tonic-gate 						  interfac});
12207c478bd9Sstevel@tonic-gate 
12217c478bd9Sstevel@tonic-gate 	    }
12227c478bd9Sstevel@tonic-gate 
12237c478bd9Sstevel@tonic-gate 	    return null;
12247c478bd9Sstevel@tonic-gate 
12257c478bd9Sstevel@tonic-gate 	}
12267c478bd9Sstevel@tonic-gate 
12277c478bd9Sstevel@tonic-gate 	return rply;
12287c478bd9Sstevel@tonic-gate     }
12297c478bd9Sstevel@tonic-gate 
12307c478bd9Sstevel@tonic-gate     // Dispatch a service request.
12317c478bd9Sstevel@tonic-gate 
dispatchSrv(SSrvMsg rqst, ServiceTable serviceTable)12327c478bd9Sstevel@tonic-gate     private SrvLocMsg dispatchSrv(SSrvMsg rqst,
12337c478bd9Sstevel@tonic-gate 				  ServiceTable serviceTable) {
12347c478bd9Sstevel@tonic-gate 
12357c478bd9Sstevel@tonic-gate 	SrvLocHeader hdr = rqst.getHeader();
12367c478bd9Sstevel@tonic-gate 	boolean mcast = hdr.mcast;
12377c478bd9Sstevel@tonic-gate 	String serviceType = rqst.serviceType;
12387c478bd9Sstevel@tonic-gate 	SrvLocMsg rply = null;
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate 	// We need to special case if this is a request for a DAAdvert
12417c478bd9Sstevel@tonic-gate 	//  and we are a DA or an SAAdvert and we are an SA only.
12427c478bd9Sstevel@tonic-gate 
12437c478bd9Sstevel@tonic-gate 	if (serviceType.equals(Defaults.DA_SERVICE_TYPE.toString())) {
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate 	    // Reply only if a DA.
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 	    if (config.isDA()) {
12487c478bd9Sstevel@tonic-gate 
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 		// Return a DAAdvert for this DA.
12517c478bd9Sstevel@tonic-gate 
12527c478bd9Sstevel@tonic-gate 		rply = serviceTable.makeDAAdvert(rqst,
12537c478bd9Sstevel@tonic-gate 						 interfac,
12547c478bd9Sstevel@tonic-gate 						 config);
12557c478bd9Sstevel@tonic-gate 
12567c478bd9Sstevel@tonic-gate 		hdr = rply.getHeader();
12577c478bd9Sstevel@tonic-gate 
12587c478bd9Sstevel@tonic-gate 		if ((hdr.errCode != ServiceLocationException.OK) &&
12597c478bd9Sstevel@tonic-gate 		    config.traceMsg()) {
12607c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_advert_error",
12617c478bd9Sstevel@tonic-gate 				    new Object[] { new Integer(hdr.errCode),
12627c478bd9Sstevel@tonic-gate 						       "DAAdvert",
12637c478bd9Sstevel@tonic-gate 						       ""});
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate 		}
12667c478bd9Sstevel@tonic-gate 	    }
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate 	    // If there was an error and the request was multicast, drop it
12697c478bd9Sstevel@tonic-gate 	    //  by returning null.
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate 	    if (hdr.errCode != ServiceLocationException.OK &&
12727c478bd9Sstevel@tonic-gate 		mcast) {
12737c478bd9Sstevel@tonic-gate 
12747c478bd9Sstevel@tonic-gate 		if (config.traceDrop()) {
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_drop_srv",
12777c478bd9Sstevel@tonic-gate 				    new Object[] {
12787c478bd9Sstevel@tonic-gate 			"DA SrvRqst",
12797c478bd9Sstevel@tonic-gate 			    Integer.toHexString(hdr.xid),
12807c478bd9Sstevel@tonic-gate 			    clientAddr,
12817c478bd9Sstevel@tonic-gate 			    new Integer(port),
12827c478bd9Sstevel@tonic-gate 			    interfac});
12837c478bd9Sstevel@tonic-gate 
12847c478bd9Sstevel@tonic-gate 		}
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 		return null;
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate 	    }
12897c478bd9Sstevel@tonic-gate 
12907c478bd9Sstevel@tonic-gate 	    return rply;
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate 	} else if (serviceType.equals(Defaults.SA_SERVICE_TYPE.toString())) {
12937c478bd9Sstevel@tonic-gate 
12947c478bd9Sstevel@tonic-gate 	    // Note that we reply if we are a DA because somebody may want
12957c478bd9Sstevel@tonic-gate 	    //  SA attributes.
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	    // We report error for unicast SA service request.
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate 	    if (!mcast) {
1300*55fea89dSDan Cross 
13017c478bd9Sstevel@tonic-gate 		if (config.traceDrop()) {
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate 		    config.writeLog("rh_no_srv_uni",
13047c478bd9Sstevel@tonic-gate 				    new Object[] {
13057c478bd9Sstevel@tonic-gate 			"SA SrvRqst",
13067c478bd9Sstevel@tonic-gate 			    Integer.toHexString(hdr.xid),
13077c478bd9Sstevel@tonic-gate 			    clientAddr,
13087c478bd9Sstevel@tonic-gate 			    new Integer(port),
13097c478bd9Sstevel@tonic-gate 			    interfac});
13107c478bd9Sstevel@tonic-gate 
13117c478bd9Sstevel@tonic-gate 		}
13127c478bd9Sstevel@tonic-gate 
13137c478bd9Sstevel@tonic-gate 		return null;
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate 	    }
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	    // Return a SAAdvert for this SA.
13187c478bd9Sstevel@tonic-gate 
13197c478bd9Sstevel@tonic-gate 	    try {
13207c478bd9Sstevel@tonic-gate 		rply = serviceTable.makeSAAdvert(rqst,
13217c478bd9Sstevel@tonic-gate 						 interfac,
13227c478bd9Sstevel@tonic-gate 						 config);
13237c478bd9Sstevel@tonic-gate 
13247c478bd9Sstevel@tonic-gate 	    } catch (ServiceLocationException ex) {
13257c478bd9Sstevel@tonic-gate 		config.writeLog("rh_advert_error",
13267c478bd9Sstevel@tonic-gate 				new Object [] {new Integer(ex.getErrorCode()),
13277c478bd9Sstevel@tonic-gate 						   "SAAdvert",
13287c478bd9Sstevel@tonic-gate 						   ex.getMessage()});
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate 	    }
13317c478bd9Sstevel@tonic-gate 
13327c478bd9Sstevel@tonic-gate 
13337c478bd9Sstevel@tonic-gate 	    if (rply == null && config.traceDrop()) {
13347c478bd9Sstevel@tonic-gate 
13357c478bd9Sstevel@tonic-gate 		config.writeLog("rh_drop_srv",
13367c478bd9Sstevel@tonic-gate 				new Object[] {"SA SrvRqst",
13377c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
13387c478bd9Sstevel@tonic-gate 						  clientAddr,
13397c478bd9Sstevel@tonic-gate 						  new Integer(port),
13407c478bd9Sstevel@tonic-gate 						  interfac});
13417c478bd9Sstevel@tonic-gate 
13427c478bd9Sstevel@tonic-gate 	    }
13437c478bd9Sstevel@tonic-gate 
13447c478bd9Sstevel@tonic-gate 	    return rply;
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate 	}
13477c478bd9Sstevel@tonic-gate 
13487c478bd9Sstevel@tonic-gate 	// Drop if this is a DA and the request was multicast. DAs
13497c478bd9Sstevel@tonic-gate 	//  do not respond to multicast, except for DAAdverts.
13507c478bd9Sstevel@tonic-gate 
13517c478bd9Sstevel@tonic-gate 	if (mcast && config.isDA()) {
13527c478bd9Sstevel@tonic-gate 
13537c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
13547c478bd9Sstevel@tonic-gate 		config.writeLog("rh_drop_da_multi",
13557c478bd9Sstevel@tonic-gate 				new Object[] {"SrvRqst",
13567c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
13577c478bd9Sstevel@tonic-gate 						  clientAddr,
13587c478bd9Sstevel@tonic-gate 						  new Integer(port),
13597c478bd9Sstevel@tonic-gate 						  interfac});
13607c478bd9Sstevel@tonic-gate 	    }
13617c478bd9Sstevel@tonic-gate 
13627c478bd9Sstevel@tonic-gate 	    return null;
13637c478bd9Sstevel@tonic-gate 
13647c478bd9Sstevel@tonic-gate 	}
13657c478bd9Sstevel@tonic-gate 
13667c478bd9Sstevel@tonic-gate 	SrvLocMsg smrply = serviceTable.findServices(rqst);
13677c478bd9Sstevel@tonic-gate 	hdr = smrply.getHeader();
13687c478bd9Sstevel@tonic-gate 
13697c478bd9Sstevel@tonic-gate 	// Filter multicast replies to remove null and error returns.
13707c478bd9Sstevel@tonic-gate 
13717c478bd9Sstevel@tonic-gate 	if (mcast &&
13727c478bd9Sstevel@tonic-gate 	    ((hdr.errCode != ServiceLocationException.OK) ||
13737c478bd9Sstevel@tonic-gate 	    (hdr.getNumReplies() == 0))) {
13747c478bd9Sstevel@tonic-gate 
13757c478bd9Sstevel@tonic-gate 	    if (config.traceDrop()) {
13767c478bd9Sstevel@tonic-gate 		config.writeLog("rh_multi_error",
13777c478bd9Sstevel@tonic-gate 				new Object[] {"SrvRqst",
13787c478bd9Sstevel@tonic-gate 						  Integer.toHexString(hdr.xid),
13797c478bd9Sstevel@tonic-gate 						  clientAddr,
13807c478bd9Sstevel@tonic-gate 						  new Integer(port),
13817c478bd9Sstevel@tonic-gate 						  interfac});
13827c478bd9Sstevel@tonic-gate 
13837c478bd9Sstevel@tonic-gate 	    }
13847c478bd9Sstevel@tonic-gate 
13857c478bd9Sstevel@tonic-gate 	    return null;
13867c478bd9Sstevel@tonic-gate 
13877c478bd9Sstevel@tonic-gate 	}
13887c478bd9Sstevel@tonic-gate 
13897c478bd9Sstevel@tonic-gate 	return smrply;
13907c478bd9Sstevel@tonic-gate     }
13917c478bd9Sstevel@tonic-gate 
13927c478bd9Sstevel@tonic-gate     // Return true if the host address matches one of the local interfaces.
13937c478bd9Sstevel@tonic-gate 
isLocalHostURL(ServiceURL url)13947c478bd9Sstevel@tonic-gate     boolean isLocalHostURL(ServiceURL url) {
13957c478bd9Sstevel@tonic-gate 	String hostAddr = url.getHost();
13967c478bd9Sstevel@tonic-gate 	Vector interfaces = config.getInterfaces();
13977c478bd9Sstevel@tonic-gate 	InetAddress addr = null;
13987c478bd9Sstevel@tonic-gate 
13997c478bd9Sstevel@tonic-gate 	try {
14007c478bd9Sstevel@tonic-gate 	    addr = InetAddress.getByName(hostAddr);
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate 	} catch (UnknownHostException ex) {
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 	    // We simply ignore it.
14057c478bd9Sstevel@tonic-gate 
14067c478bd9Sstevel@tonic-gate 	    return false;
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 	}
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate 	if (interfaces.contains(addr)) {
14117c478bd9Sstevel@tonic-gate 	    return true;
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate 	}
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate 	return false;
14167c478bd9Sstevel@tonic-gate     }
14177c478bd9Sstevel@tonic-gate 
14187c478bd9Sstevel@tonic-gate     /**
14197c478bd9Sstevel@tonic-gate      * Return whether this was previous responder. Only do so if the
14207c478bd9Sstevel@tonic-gate      * request was multicast.
14217c478bd9Sstevel@tonic-gate      *
14227c478bd9Sstevel@tonic-gate      * @return True if this host was a previous responder.
14237c478bd9Sstevel@tonic-gate      */
14247c478bd9Sstevel@tonic-gate 
isPreviousResponder(SrvLocHeader hdr)14257c478bd9Sstevel@tonic-gate     public boolean isPreviousResponder(SrvLocHeader hdr) {
14267c478bd9Sstevel@tonic-gate 
14277c478bd9Sstevel@tonic-gate 	// If there are no previous responders, then return false,
14287c478bd9Sstevel@tonic-gate 	//  because they aren't used for this message. Also for
14297c478bd9Sstevel@tonic-gate 	//  messages that are not multicast.
14307c478bd9Sstevel@tonic-gate 
14317c478bd9Sstevel@tonic-gate 	if ((hdr.previousResponders == null) ||
14327c478bd9Sstevel@tonic-gate 	    (hdr.mcast == false)) {
14337c478bd9Sstevel@tonic-gate 	    return false;
14347c478bd9Sstevel@tonic-gate 
14357c478bd9Sstevel@tonic-gate 	}
14367c478bd9Sstevel@tonic-gate 
14377c478bd9Sstevel@tonic-gate 	Vector previousResponders = hdr.previousResponders;
14387c478bd9Sstevel@tonic-gate 	Enumeration e = null;
14397c478bd9Sstevel@tonic-gate 	Vector interfaces = config.getInterfaces();
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 	// Check for matches against this address.
14427c478bd9Sstevel@tonic-gate 
14437c478bd9Sstevel@tonic-gate 	for (e = previousResponders.elements(); e.hasMoreElements(); ) {
14447c478bd9Sstevel@tonic-gate 	    try {
14457c478bd9Sstevel@tonic-gate 		String sHost = ((String)e.nextElement());
14467c478bd9Sstevel@tonic-gate 		InetAddress iaHost = InetAddress.getByName(sHost);
14477c478bd9Sstevel@tonic-gate 
14487c478bd9Sstevel@tonic-gate 		if (interfaces.contains(iaHost)) {
14497c478bd9Sstevel@tonic-gate 		    return true;
14507c478bd9Sstevel@tonic-gate 		}
14517c478bd9Sstevel@tonic-gate 
14527c478bd9Sstevel@tonic-gate 	    } catch (UnknownHostException ex) {
14537c478bd9Sstevel@tonic-gate 
14547c478bd9Sstevel@tonic-gate 	    }
14557c478bd9Sstevel@tonic-gate 	}
14567c478bd9Sstevel@tonic-gate 
14577c478bd9Sstevel@tonic-gate 	return false;
14587c478bd9Sstevel@tonic-gate     }
14597c478bd9Sstevel@tonic-gate 
14607c478bd9Sstevel@tonic-gate 
14617c478bd9Sstevel@tonic-gate     // Initialize the SLPv2 header parser class when we are loaded.
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate     static {
14647c478bd9Sstevel@tonic-gate 
SrvLocHeader.addHeaderClass(Defaults.DEFAULT_SERVER_HEADER_CLASS, Defaults.version)14657c478bd9Sstevel@tonic-gate 	SrvLocHeader.addHeaderClass(Defaults.DEFAULT_SERVER_HEADER_CLASS,
14667c478bd9Sstevel@tonic-gate 				    Defaults.version);
14677c478bd9Sstevel@tonic-gate 
14687c478bd9Sstevel@tonic-gate     }
14697c478bd9Sstevel@tonic-gate 
14707c478bd9Sstevel@tonic-gate }
1471