/*
 * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.rmi.transport.tcp;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.rmi.ConnectIOException;
import java.rmi.RemoteException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RMISocketFactory;
import java.security.AccessController;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import sun.rmi.runtime.Log;
import sun.rmi.runtime.NewThreadAction;
import sun.rmi.transport.Channel;
import sun.rmi.transport.Endpoint;
import sun.rmi.transport.Target;
import sun.rmi.transport.Transport;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetIntegerAction;
import sun.security.action.GetPropertyAction;

/**
 * TCPEndpoint represents some communication endpoint for an address
 * space (VM).
 *
 * @author Ann Wollrath
 */
public class TCPEndpoint implements Endpoint {
    /** IP address or host name */
    private String host;
    /** port number */
    private int port;
    /** custom client socket factory (null if not custom factory) */
    private final RMIClientSocketFactory csf;
    /** custom server socket factory (null if not custom factory) */
    private final RMIServerSocketFactory ssf;

    /** if local, the port number to listen on */
    private int listenPort = -1;
    /** if local, the transport object associated with this endpoint */
    private TCPTransport transport = null;

    /** the local host name */
    private static String localHost;
    /** true if real local host name is known yet */
    private static boolean localHostKnown;

    // this should be a *private* method since it is privileged
    private static int getInt(String name, int def) {
        return AccessController.doPrivileged(new GetIntegerAction(name, def));
    }

    // this should be a *private* method since it is privileged
    private static boolean getBoolean(String name) {
        return AccessController.doPrivileged(new GetBooleanAction(name));
    }

    /**
     * Returns the value of the java.rmi.server.hostname property.
     */
    private static String getHostnameProperty() {
        return AccessController.doPrivileged(
            new GetPropertyAction("java.rmi.server.hostname"));
    }

    /**
     * Find host name of local machine.  Property "java.rmi.server.hostname"
     * is used if set, so server administrator can compensate for the possible
     * inablility to get fully qualified host name from VM.
     */
    static {
        localHostKnown = true;
        localHost = getHostnameProperty();

        // could try querying CGI program here?
        if (localHost == null) {
            try {
                InetAddress localAddr = InetAddress.getLocalHost();
                byte[] raw = localAddr.getAddress();
                if ((raw[0] == 127) &&
                    (raw[1] ==   0) &&
                    (raw[2] ==   0) &&
                    (raw[3] ==   1)) {
                    localHostKnown = false;
                }

                /* if the user wishes to use a fully qualified domain
                 * name then attempt to find one.
                 */
                if (getBoolean("java.rmi.server.useLocalHostName")) {
                    localHost = FQDN.attemptFQDN(localAddr);
                } else {
                    /* default to using ip addresses, names will
                     * work across seperate domains.
                     */
                    localHost = localAddr.getHostAddress();
                }
            } catch (Exception e) {
                localHostKnown = false;
                localHost = null;
            }
        }

        if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
            TCPTransport.tcpLog.log(Log.BRIEF,
                "localHostKnown = " + localHostKnown +
                ", localHost = " + localHost);
        }
    }

    /** maps an endpoint key containing custom socket factories to
     * their own unique endpoint */
    // TBD: should this be a weak hash table?
    private static final
        Map<TCPEndpoint,LinkedList<TCPEndpoint>> localEndpoints =
        new HashMap<TCPEndpoint,LinkedList<TCPEndpoint>>();

    /**
     * Create an endpoint for a specified host and port.
     * This should not be used by external classes to create endpoints
     * for servers in this VM; use getLocalEndpoint instead.
     */
    public TCPEndpoint(String host, int port) {
        this(host, port, null, null);
    }

    /**
     * Create a custom socket factory endpoint for a specified host and port.
     * This should not be used by external classes to create endpoints
     * for servers in this VM; use getLocalEndpoint instead.
     */
    public TCPEndpoint(String host, int port, RMIClientSocketFactory csf,
                       RMIServerSocketFactory ssf)
    {
        if (host == null)
            host = "";
        this.host = host;
        this.port = port;
        this.csf = csf;
        this.ssf = ssf;
    }

    /**
     * Get an endpoint for the local address space on specified port.
     * If port number is 0, it returns shared default endpoint object
     * whose host name and port may or may not have been determined.
     */
    public static TCPEndpoint getLocalEndpoint(int port) {
        return getLocalEndpoint(port, null, null);
    }

    public static TCPEndpoint getLocalEndpoint(int port,
                                               RMIClientSocketFactory csf,
                                               RMIServerSocketFactory ssf)
    {
        /*
         * Find mapping for an endpoint key to the list of local unique
         * endpoints for this client/server socket factory pair (perhaps
         * null) for the specific port.
         */
        TCPEndpoint ep = null;

        synchronized (localEndpoints) {
            TCPEndpoint endpointKey = new TCPEndpoint(null, port, csf, ssf);
            LinkedList<TCPEndpoint> epList = localEndpoints.get(endpointKey);
            String localHost = resampleLocalHost();

            if (epList == null) {
                /*
                 * Create new endpoint list.
                 */
                ep = new TCPEndpoint(localHost, port, csf, ssf);
                epList = new LinkedList<TCPEndpoint>();
                epList.add(ep);
                ep.listenPort = port;
                ep.transport = new TCPTransport(epList);
                localEndpoints.put(endpointKey, epList);

                if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
                    TCPTransport.tcpLog.log(Log.BRIEF,
                        "created local endpoint for socket factory " + ssf +
                        " on port " + port);
                }
            } else {
                synchronized (epList) {
                    ep = epList.getLast();
                    String lastHost = ep.host;
                    int lastPort =  ep.port;
                    TCPTransport lastTransport = ep.transport;
                    // assert (localHost == null ^ lastHost != null)
                    if (localHost != null && !localHost.equals(lastHost)) {
                        /*
                         * Hostname has been updated; add updated endpoint
                         * to list.
                         */
                        if (lastPort != 0) {
                            /*
                             * Remove outdated endpoints only if the
                             * port has already been set on those endpoints.
                             */
                            epList.clear();
                        }
                        ep = new TCPEndpoint(localHost, lastPort, csf, ssf);
                        ep.listenPort = port;
                        ep.transport = lastTransport;
                        epList.add(ep);
                    }
                }
            }
        }

        return ep;
    }

    /**
     * Resamples the local hostname and returns the possibly-updated
     * local hostname.
     */
    private static String resampleLocalHost() {

        String hostnameProperty = getHostnameProperty();

        synchronized (localEndpoints) {
            // assert(localHostKnown ^ (localHost == null))

            if (hostnameProperty != null) {
                if (!localHostKnown) {
                    /*
                     * If the local hostname is unknown, update ALL
                     * existing endpoints with the new hostname.
                     */
                    setLocalHost(hostnameProperty);
                } else if (!hostnameProperty.equals(localHost)) {
                    /*
                     * Only update the localHost field for reference
                     * in future endpoint creation.
                     */
                    localHost = hostnameProperty;

                    if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
                        TCPTransport.tcpLog.log(Log.BRIEF,
                            "updated local hostname to: " + localHost);
                    }
                }
            }
            return localHost;
        }
    }

    /**
     * Set the local host name, if currently unknown.
     */
    static void setLocalHost(String host) {
        // assert (host != null)

        synchronized (localEndpoints) {
            /*
             * If host is not known, change the host field of ALL
             * the local endpoints.
             */
            if (!localHostKnown) {
                localHost = host;
                localHostKnown = true;

                if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
                    TCPTransport.tcpLog.log(Log.BRIEF,
                        "local host set to " + host);
                }
                for (LinkedList<TCPEndpoint> epList : localEndpoints.values())
                {
                    synchronized (epList) {
                        for (TCPEndpoint ep : epList) {
                            ep.host = host;
                        }
                    }
                }
            }
        }
    }

    /**
     * Set the port of the (shared) default endpoint object.
     * When first created, it contains port 0 because the transport
     * hasn't tried to listen to get assigned a port, or if listening
     * failed, a port hasn't been assigned from the server.
     */
    static void setDefaultPort(int port, RMIClientSocketFactory csf,
                               RMIServerSocketFactory ssf)
    {
        TCPEndpoint endpointKey = new TCPEndpoint(null, 0, csf, ssf);

        synchronized (localEndpoints) {
            LinkedList<TCPEndpoint> epList = localEndpoints.get(endpointKey);

            synchronized (epList) {
                int size = epList.size();
                TCPEndpoint lastEp = epList.getLast();

                for (TCPEndpoint ep : epList) {
                    ep.port = port;
                }
                if (size > 1) {
                    /*
                     * Remove all but the last element of the list
                     * (which contains the most recent hostname).
                     */
                    epList.clear();
                    epList.add(lastEp);
                }
            }

            /*
             * Allow future exports to use the actual bound port
             * explicitly (see 6269166).
             */
            TCPEndpoint newEndpointKey = new TCPEndpoint(null, port, csf, ssf);
            localEndpoints.put(newEndpointKey, epList);

            if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
                TCPTransport.tcpLog.log(Log.BRIEF,
                    "default port for server socket factory " + ssf +
                    " and client socket factory " + csf +
                    " set to " + port);
            }
        }
    }

    /**
     * Returns transport for making connections to remote endpoints;
     * (here, the default transport at port 0 is used).
     */
    public Transport getOutboundTransport() {
        TCPEndpoint localEndpoint = getLocalEndpoint(0, null, null);
        return localEndpoint.transport;
    }

    /**
     * Returns the current list of known transports.
     * The returned list is an unshared collection of Transports,
     * including all transports which may have channels to remote
     * endpoints.
     */
    private static Collection<TCPTransport> allKnownTransports() {
        // Loop through local endpoints, getting the transport of each one.
        Set<TCPTransport> s;
        synchronized (localEndpoints) {
            // presize s to number of localEndpoints
            s = new HashSet<TCPTransport>(localEndpoints.size());
            for (LinkedList<TCPEndpoint> epList : localEndpoints.values()) {
                /*
                 * Each local endpoint has its transport added to s.
                 * Note: the transport is the same for all endpoints
                 * in the list, so it is okay to pick any one of them.
                 */
                TCPEndpoint ep = epList.getFirst();
                s.add(ep.transport);
            }
        }
        return s;
    }

    /**
     * Release idle outbound connections to reduce demand on I/O resources.
     * All transports are asked to release excess connections.
     */
    public static void shedConnectionCaches() {
        for (TCPTransport transport : allKnownTransports()) {
            transport.shedConnectionCaches();
        }
    }

    /**
     * Export the object to accept incoming calls.
     */
    public void exportObject(Target target) throws RemoteException {
        transport.exportObject(target);
    }

    /**
     * Returns a channel for this (remote) endpoint.
     */
    public Channel getChannel() {
        return getOutboundTransport().getChannel(this);
    }

    /**
     * Returns address for endpoint
     */
    public String getHost() {
        return host;
    }

    /**
     * Returns the port for this endpoint.  If this endpoint was
     * created as a server endpoint (using getLocalEndpoint) for a
     * default/anonymous port and its inbound transport has started
     * listening, this method returns (instead of zero) the actual
     * bound port suitable for passing to clients.
     **/
    public int getPort() {
        return port;
    }

    /**
     * Returns the port that this endpoint's inbound transport listens
     * on, if this endpoint was created as a server endpoint (using
     * getLocalEndpoint).  If this endpoint was created for the
     * default/anonymous port, then this method returns zero even if
     * the transport has started listening.
     **/
    public int getListenPort() {
        return listenPort;
    }

    /**
     * Returns the transport for incoming connections to this
     * endpoint, if this endpoint was created as a server endpoint
     * (using getLocalEndpoint).
     **/
    public Transport getInboundTransport() {
        return transport;
    }

    /**
     * Get the client socket factory associated with this endpoint.
     */
    public RMIClientSocketFactory getClientSocketFactory() {
        return csf;
    }

    /**
     * Get the server socket factory associated with this endpoint.
     */
    public RMIServerSocketFactory getServerSocketFactory() {
        return ssf;
    }

    /**
     * Return string representation for endpoint.
     */
    public String toString() {
        return "[" + host + ":" + port +
            (ssf != null ? "," + ssf : "") +
            (csf != null ? "," + csf : "") +
            "]";
    }

    public int hashCode() {
        return port;
    }

    public boolean equals(Object obj) {
        if ((obj != null) && (obj instanceof TCPEndpoint)) {
            TCPEndpoint ep = (TCPEndpoint) obj;
            if (port != ep.port || !host.equals(ep.host))
                return false;
            if (((csf == null) ^ (ep.csf == null)) ||
                ((ssf == null) ^ (ep.ssf == null)))
                return false;
            /*
             * Fix for 4254510: perform socket factory *class* equality check
             * before socket factory equality check to avoid passing
             * a potentially naughty socket factory to this endpoint's
             * {client,server} socket factory equals method.
             */
            if ((csf != null) &&
                !(csf.getClass() == ep.csf.getClass() && csf.equals(ep.csf)))
                return false;
            if ((ssf != null) &&
                !(ssf.getClass() == ep.ssf.getClass() && ssf.equals(ep.ssf)))
                return false;
            return true;
        } else {
            return false;
        }
    }

    /* codes for the self-describing formats of wire representation */
    private static final int FORMAT_HOST_PORT           = 0;
    private static final int FORMAT_HOST_PORT_FACTORY   = 1;

    /**
     * Write endpoint to output stream.
     */
    public void write(ObjectOutput out) throws IOException {
        if (csf == null) {
            out.writeByte(FORMAT_HOST_PORT);
            out.writeUTF(host);
            out.writeInt(port);
        } else {
            out.writeByte(FORMAT_HOST_PORT_FACTORY);
            out.writeUTF(host);
            out.writeInt(port);
            out.writeObject(csf);
        }
    }

    /**
     * Get the endpoint from the input stream.
     * @param in the input stream
     * @exception IOException If id could not be read (due to stream failure)
     */
    public static TCPEndpoint read(ObjectInput in)
        throws IOException, ClassNotFoundException
    {
        String host;
        int port;
        RMIClientSocketFactory csf = null;

        byte format = in.readByte();
        switch (format) {
          case FORMAT_HOST_PORT:
            host = in.readUTF();
            port = in.readInt();
            break;

          case FORMAT_HOST_PORT_FACTORY:
            host = in.readUTF();
            port = in.readInt();
            csf = (RMIClientSocketFactory) in.readObject();
          break;

          default:
            throw new IOException("invalid endpoint format");
        }
        return new TCPEndpoint(host, port, csf, null);
    }

    /**
     * Write endpoint to output stream in older format used by
     * UnicastRef for JDK1.1 compatibility.
     */
    public void writeHostPortFormat(DataOutput out) throws IOException {
        if (csf != null) {
            throw new InternalError("TCPEndpoint.writeHostPortFormat: " +
                "called for endpoint with non-null socket factory");
        }
        out.writeUTF(host);
        out.writeInt(port);
    }

    /**
     * Create a new endpoint from input stream data.
     * @param in the input stream
     */
    public static TCPEndpoint readHostPortFormat(DataInput in)
        throws IOException
    {
        String host = in.readUTF();
        int port = in.readInt();
        return new TCPEndpoint(host, port);
    }

    private static RMISocketFactory chooseFactory() {
        RMISocketFactory sf = RMISocketFactory.getSocketFactory();
        if (sf == null) {
            sf = TCPTransport.defaultSocketFactory;
        }
        return sf;
    }

    /**
     * Open and return new client socket connection to endpoint.
     */
    Socket newSocket() throws RemoteException {
        if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
            TCPTransport.tcpLog.log(Log.VERBOSE,
                "opening socket to " + this);
        }

        Socket socket;

        try {
            RMIClientSocketFactory clientFactory = csf;
            if (clientFactory == null) {
                clientFactory = chooseFactory();
            }
            socket = clientFactory.createSocket(host, port);

        } catch (java.net.UnknownHostException e) {
            throw new java.rmi.UnknownHostException(
                "Unknown host: " + host, e);
        } catch (java.net.ConnectException e) {
            throw new java.rmi.ConnectException(
                "Connection refused to host: " + host, e);
        } catch (IOException e) {
            // We might have simply run out of file descriptors
            try {
                TCPEndpoint.shedConnectionCaches();
                // REMIND: should we retry createSocket?
            } catch (OutOfMemoryError mem) {
                // don't quit if out of memory
            } catch (Exception ex) {
                // don't quit if shed fails non-catastrophically
            }

            throw new ConnectIOException("Exception creating connection to: " +
                host, e);
        }

        // set socket to disable Nagle's algorithm (always send immediately)
        // TBD: should this be left up to socket factory instead?
        try {
            socket.setTcpNoDelay(true);
        } catch (Exception e) {
            // if we fail to set this, ignore and proceed anyway
        }

        // fix 4187495: explicitly set SO_KEEPALIVE to prevent client hangs
        try {
            socket.setKeepAlive(true);
        } catch (Exception e) {
            // ignore and proceed
        }

        return socket;
    }

    /**
     * Return new server socket to listen for connections on this endpoint.
     */
    ServerSocket newServerSocket() throws IOException {
        if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
            TCPTransport.tcpLog.log(Log.VERBOSE,
                "creating server socket on " + this);
        }

        RMIServerSocketFactory serverFactory = ssf;
        if (serverFactory == null) {
            serverFactory = chooseFactory();
        }
        ServerSocket server = serverFactory.createServerSocket(listenPort);

        // if we listened on an anonymous port, set the default port
        // (for this socket factory)
        if (listenPort == 0)
            setDefaultPort(server.getLocalPort(), csf, ssf);

        return server;
    }

    /**
     * The class FQDN encapsulates a routine that makes a best effort
     * attempt to retrieve the fully qualified domain name of the local
     * host.
     *
     * @author  Laird Dornin
     */
    private static class FQDN implements Runnable {

        /**
         * strings in which we can store discovered fqdn
         */
        private String reverseLookup;

        private String hostAddress;

        private FQDN(String hostAddress) {
            this.hostAddress = hostAddress;
        }

        /**
         * Do our best to obtain a fully qualified hostname for the local
         * host.  Perform the following steps to get a localhostname:
         *
         * 1. InetAddress.getLocalHost().getHostName() - if contains
         *    '.' use as FQDN
         * 2. if no '.' query name service for FQDN in a thread
         *    Note: We query the name service for an FQDN by creating
         *    an InetAddress via a stringified copy of the local ip
         *    address; this creates an InetAddress with a null hostname.
         *    Asking for the hostname of this InetAddress causes a name
         *    service lookup.
         *
         * 3. if name service takes too long to return, use ip address
         * 4. if name service returns but response contains no '.'
         *    default to ipaddress.
         */
        static String attemptFQDN(InetAddress localAddr)
            throws java.net.UnknownHostException
        {

            String hostName = localAddr.getHostName();

            if (hostName.indexOf('.') < 0 ) {

                String hostAddress = localAddr.getHostAddress();
                FQDN f = new FQDN(hostAddress);

                int nameServiceTimeOut =
                    TCPEndpoint.getInt("sun.rmi.transport.tcp.localHostNameTimeOut",
                                       10000);

                try {
                    synchronized(f) {
                        f.getFQDN();

                        /* wait to obtain an FQDN */
                        f.wait(nameServiceTimeOut);
                    }
                } catch (InterruptedException e) {
                    /* propagate the exception to the caller */
                    Thread.currentThread().interrupt();
                }
                hostName = f.getHost();

                if ((hostName == null) || (hostName.equals(""))
                    || (hostName.indexOf('.') < 0 )) {

                    hostName = hostAddress;
                }
            }
            return hostName;
        }

        /**
         * Method that that will start a thread to wait to retrieve a
         * fully qualified domain name from a name service.  The spawned
         * thread may never return but we have marked it as a daemon so the vm
         * will terminate appropriately.
         */
        private void getFQDN() {

            /* FQDN finder will run in RMI threadgroup. */
            Thread t = AccessController.doPrivileged(
                new NewThreadAction(FQDN.this, "FQDN Finder", true));
            t.start();
        }

        private synchronized String getHost() {
            return reverseLookup;
        }

        /**
         * thread to query a name service for the fqdn of this host.
         */
        public void run()  {

            String name = null;

            try {
                name = InetAddress.getByName(hostAddress).getHostName();
            } catch (java.net.UnknownHostException e) {
            } finally {
                synchronized(this) {
                    reverseLookup = name;
                    this.notify();
                }
            }
        }
    }
}
