Fix OPENDJ-1270: Avoid unnecessary DNS lookups when performing bind requests
* rename LDAP{ConnectionFactory|Listener}.getHostname() to getHostName()
* change LDAP{ConnectionFactory|Listener}.getAddress() to return InetSocketAddresses
* change constructors to only accept InetSocketAddresses instead of more generic SocketAddress
* ensure that LDAP{ConnectionFactory|Listener}.getAddress() returns an address which represents the exact socket address passed in during construction, except in the case where a listener is created with port 0 where we return the selected port
* modify LDAP{ConnectionFactory|Listener}.getHostName() to return whatever was provided as the host name during construction, which may have been a raw IP address. This avoids attempts to perform a reverse DNS lookup in the case where the provided host name was an IP address and, in particular, avoids DNS timeouts in environments where there is no DNS
* modify client bind processing to use LDAPConnectionFactory.getHostName() as the server name used for SASL authentication, and avoid any potential DNS delays as a result.
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2013 ForgeRock AS |
| | | * Portions copyright 2011-2014 ForgeRock AS |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | | import static org.forgerock.opendj.ldap.RequestHandlerFactoryAdapter.adaptRequestHandler; |
| | | |
| | | import java.net.InetAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * Returns the host name associated with the provided |
| | | * {@code InetSocketAddress}, without performing a DNS lookup. This method |
| | | * attempts to provide functionality which is compatible with |
| | | * {@code InetSocketAddress.getHostString()} in JDK7. It can be removed once |
| | | * we drop support for JDK6. |
| | | * |
| | | * @param socketAddress |
| | | * The socket address which is expected to be an instance of |
| | | * {@code InetSocketAddress}. |
| | | * @return The host name associated with the provided {@code SocketAddress}, |
| | | * or {@code null} if it is unknown. |
| | | */ |
| | | public static String getHostString(final InetSocketAddress socketAddress) { |
| | | /* |
| | | * See OPENDJ-1270 for more information about slow DNS queries. |
| | | * |
| | | * We must avoid calling getHostName() in the case where it is likely to |
| | | * perform a blocking DNS query. Ideally we would call getHostString(), |
| | | * but the method was only added in JDK7. |
| | | */ |
| | | if (socketAddress.isUnresolved()) { |
| | | /* |
| | | * Usually socket addresses are resolved on creation. If the address |
| | | * is unresolved then there must be a user provided hostname instead |
| | | * and getHostName will not perform a reverse lookup. |
| | | */ |
| | | return socketAddress.getHostName(); |
| | | } else { |
| | | /* |
| | | * Simulate getHostString() by parsing the toString() |
| | | * representation. This assumes that the toString() representation |
| | | * is stable, which I assume it is because it is documented. |
| | | */ |
| | | final InetAddress address = socketAddress.getAddress(); |
| | | final String hostSlashIp = address.toString(); |
| | | final int slashPos = hostSlashIp.indexOf('/'); |
| | | if (slashPos == 0) { |
| | | return hostSlashIp.substring(1); |
| | | } else { |
| | | return hostSlashIp.substring(0, slashPos); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Prevent instantiation. |
| | | private Connections() { |
| | | // Do nothing. |
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2013 ForgeRock AS. |
| | | * Portions copyright 2011-2014 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | |
| | | |
| | | import java.net.InetAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.net.SocketAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.spi.LDAPConnectionFactoryImpl; |
| | | import org.forgerock.opendj.ldap.spi.TransportProvider; |
| | |
| | | * @throws ProviderNotFoundException if no provider is available or if the |
| | | * provider requested using options is not found. |
| | | */ |
| | | public LDAPConnectionFactory(final SocketAddress address) { |
| | | public LDAPConnectionFactory(final InetSocketAddress address) { |
| | | this(address, new LDAPOptions()); |
| | | } |
| | | |
| | |
| | | * @throws ProviderNotFoundException if no provider is available or if the |
| | | * provider requested using options is not found. |
| | | */ |
| | | public LDAPConnectionFactory(final SocketAddress address, final LDAPOptions options) { |
| | | public LDAPConnectionFactory(final InetSocketAddress address, final LDAPOptions options) { |
| | | Reject.ifNull(address, options); |
| | | this.provider = getProvider(TransportProvider.class, options.getTransportProvider(), |
| | | options.getProviderClassLoader()); |
| | |
| | | */ |
| | | public LDAPConnectionFactory(final String host, final int port, final LDAPOptions options) { |
| | | Reject.ifNull(host, options); |
| | | final SocketAddress address = new InetSocketAddress(host, port); |
| | | final InetSocketAddress address = new InetSocketAddress(host, port); |
| | | this.provider = getProvider(TransportProvider.class, options.getTransportProvider(), |
| | | options.getProviderClassLoader()); |
| | | this.impl = provider.getLDAPConnectionFactory(address, options); |
| | | } |
| | | |
| | | /** |
| | | * Returns the {@code InetAddress} that this LDAP listener is listening on. |
| | | * Returns the {@code InetAddress} of the Directory Server. |
| | | * |
| | | * @return The {@code InetAddress} that this LDAP listener is listening on, |
| | | * or {@code null} if it is unknown. |
| | | * @return The {@code InetAddress} of the Directory Server. |
| | | */ |
| | | public InetAddress getAddress() { |
| | | final SocketAddress socketAddress = getSocketAddress(); |
| | | if (socketAddress instanceof InetSocketAddress) { |
| | | final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; |
| | | return inetSocketAddress.getAddress(); |
| | | } else { |
| | | return null; |
| | | } |
| | | return getSocketAddress().getAddress(); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the host name that this LDAP listener is listening on. |
| | | * Returns the host name of the Directory Server. The returned host name is |
| | | * the same host name that was provided during construction and may be an IP |
| | | * address. More specifically, this method will not perform a reverse DNS |
| | | * lookup. |
| | | * |
| | | * @return The host name that this LDAP listener is listening on, or |
| | | * {@code null} if it is unknown. |
| | | * @return The host name of the Directory Server. |
| | | */ |
| | | public String getHostname() { |
| | | final SocketAddress socketAddress = getSocketAddress(); |
| | | if (socketAddress instanceof InetSocketAddress) { |
| | | final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; |
| | | return inetSocketAddress.getHostName(); |
| | | } else { |
| | | return null; |
| | | } |
| | | public String getHostName() { |
| | | return Connections.getHostString(getSocketAddress()); |
| | | } |
| | | |
| | | /** |
| | | * Returns the port that this LDAP listener is listening on. |
| | | * Returns the port of the Directory Server. |
| | | * |
| | | * @return The port that this LDAP listener is listening on, or {@code -1} |
| | | * if it is unknown. |
| | | * @return The port of the Directory Server. |
| | | */ |
| | | public int getPort() { |
| | | final SocketAddress socketAddress = getSocketAddress(); |
| | | if (socketAddress instanceof InetSocketAddress) { |
| | | final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; |
| | | return inetSocketAddress.getPort(); |
| | | } else { |
| | | return -1; |
| | | } |
| | | return getSocketAddress().getPort(); |
| | | } |
| | | |
| | | /** |
| | | * Returns the address used by the connections created by this factory. |
| | | * Returns the address of the Directory Server. |
| | | * |
| | | * @return The address used by the connections. |
| | | * @return The address of the Directory Server. |
| | | */ |
| | | public SocketAddress getSocketAddress() { |
| | | public InetSocketAddress getSocketAddress() { |
| | | return impl.getSocketAddress(); |
| | | } |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2012 ForgeRock AS. |
| | | * Portions copyright 2012-2014 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | |
| | | import java.io.IOException; |
| | | import java.net.InetAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.net.SocketAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.spi.LDAPListenerImpl; |
| | | import org.forgerock.opendj.ldap.spi.TransportProvider; |
| | |
| | | final ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | final LDAPListenerOptions options) throws IOException { |
| | | Reject.ifNull(factory, options); |
| | | final SocketAddress address = new InetSocketAddress(port); |
| | | final InetSocketAddress address = new InetSocketAddress(port); |
| | | this.provider = getProvider(TransportProvider.class, options.getTransportProvider(), |
| | | options.getProviderClassLoader()); |
| | | this.impl = provider.getLDAPListener(address, factory, options); |
| | |
| | | * @throws NullPointerException |
| | | * If {@code address} or {code factory} was {@code null}. |
| | | */ |
| | | public LDAPListener(final SocketAddress address, |
| | | public LDAPListener(final InetSocketAddress address, |
| | | final ServerConnectionFactory<LDAPClientContext, Integer> factory) throws IOException { |
| | | this(address, factory, new LDAPListenerOptions()); |
| | | } |
| | |
| | | * If {@code address}, {code factory}, or {@code options} was |
| | | * {@code null}. |
| | | */ |
| | | public LDAPListener(final SocketAddress address, |
| | | public LDAPListener(final InetSocketAddress address, |
| | | final ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | final LDAPListenerOptions options) throws IOException { |
| | | Reject.ifNull(address, factory, options); |
| | |
| | | final ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | final LDAPListenerOptions options) throws IOException { |
| | | Reject.ifNull(host, factory, options); |
| | | final SocketAddress address = new InetSocketAddress(host, port); |
| | | final InetSocketAddress address = new InetSocketAddress(host, port); |
| | | this.provider = getProvider(TransportProvider.class, options.getTransportProvider(), |
| | | options.getProviderClassLoader()); |
| | | this.impl = provider.getLDAPListener(address, factory, options); |
| | |
| | | /** |
| | | * Returns the {@code InetAddress} that this LDAP listener is listening on. |
| | | * |
| | | * @return The {@code InetAddress} that this LDAP listener is listening on, |
| | | * or {@code null} if it is unknown. |
| | | * @return The {@code InetAddress} that this LDAP listener is listening on. |
| | | */ |
| | | public InetAddress getAddress() { |
| | | final SocketAddress socketAddress = getSocketAddress(); |
| | | if (socketAddress instanceof InetSocketAddress) { |
| | | final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; |
| | | return inetSocketAddress.getAddress(); |
| | | } else { |
| | | return null; |
| | | } |
| | | return getSocketAddress().getAddress(); |
| | | } |
| | | |
| | | /** |
| | | * Returns the host name that this LDAP listener is listening on. |
| | | * Returns the host name that this LDAP listener is listening on. The |
| | | * returned host name is the same host name that was provided during |
| | | * construction and may be an IP address. More specifically, this method |
| | | * will not perform a reverse DNS lookup. |
| | | * |
| | | * @return The host name that this LDAP listener is listening on, or |
| | | * {@code null} if it is unknown. |
| | | * @return The host name that this LDAP listener is listening on. |
| | | */ |
| | | public String getHostname() { |
| | | final SocketAddress socketAddress = getSocketAddress(); |
| | | if (socketAddress instanceof InetSocketAddress) { |
| | | final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; |
| | | return inetSocketAddress.getHostName(); |
| | | } else { |
| | | return null; |
| | | } |
| | | public String getHostName() { |
| | | return Connections.getHostString(getSocketAddress()); |
| | | } |
| | | |
| | | /** |
| | | * Returns the port that this LDAP listener is listening on. |
| | | * |
| | | * @return The port that this LDAP listener is listening on, or {@code -1} |
| | | * if it is unknown. |
| | | * @return The port that this LDAP listener is listening on. |
| | | */ |
| | | public int getPort() { |
| | | final SocketAddress socketAddress = getSocketAddress(); |
| | | if (socketAddress instanceof InetSocketAddress) { |
| | | final InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress; |
| | | return inetSocketAddress.getPort(); |
| | | } else { |
| | | return -1; |
| | | } |
| | | return getSocketAddress().getPort(); |
| | | } |
| | | |
| | | /** |
| | |
| | | * |
| | | * @return The address that this LDAP listener is listening on. |
| | | */ |
| | | public SocketAddress getSocketAddress() { |
| | | public InetSocketAddress getSocketAddress() { |
| | | return impl.getSocketAddress(); |
| | | } |
| | | |
| | |
| | | return provider.getName(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return impl.toString(); |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.ldap.spi; |
| | | |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.ConnectionFactory; |
| | | |
| | |
| | | * |
| | | * @return The address used by the connections. |
| | | */ |
| | | public SocketAddress getSocketAddress(); |
| | | public InetSocketAddress getSocketAddress(); |
| | | |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.ldap.spi; |
| | | |
| | | import java.io.Closeable; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | /** |
| | | * Interface for all classes that actually implement {@code LDAPListener}. |
| | |
| | | * |
| | | * @return The address that this LDAP listener is listening on. |
| | | */ |
| | | public SocketAddress getSocketAddress(); |
| | | public InetSocketAddress getSocketAddress(); |
| | | |
| | | /** |
| | | * Closes this stream and releases any system resources associated |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.ldap.spi; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.LDAPClientContext; |
| | | import org.forgerock.opendj.ldap.LDAPListenerOptions; |
| | |
| | | * Returns an implementation of {@code LDAPConnectionFactory}. |
| | | * |
| | | * @param address |
| | | * The address of the Directory Server to connect to. |
| | | * The address of the Directory Server to connect to. |
| | | * @param options |
| | | * The LDAP options to use when creating connections. |
| | | * @return an implementation of {@code LDAPConnectionFactory} |
| | | */ |
| | | LDAPConnectionFactoryImpl getLDAPConnectionFactory(SocketAddress address, LDAPOptions options); |
| | | LDAPConnectionFactoryImpl getLDAPConnectionFactory(InetSocketAddress address, |
| | | LDAPOptions options); |
| | | |
| | | /** |
| | | * Returns an implementation of {@code LDAPListener}. |
| | |
| | | * If an error occurred while trying to listen on the provided |
| | | * address. |
| | | */ |
| | | LDAPListenerImpl getLDAPListener( |
| | | SocketAddress address, |
| | | ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | LDAPListenerOptions options) throws IOException; |
| | | LDAPListenerImpl getLDAPListener(InetSocketAddress address, |
| | | ServerConnectionFactory<LDAPClientContext, Integer> factory, LDAPListenerOptions options) |
| | | throws IOException; |
| | | |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2013 ForgeRock AS |
| | | * Portions copyright 2011-2014 ForgeRock AS |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | |
| | | import static org.forgerock.opendj.ldap.TestCaseUtils.findFreeSocketAddress; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | |
| | | final Map<String, String> props = new HashMap<String, String>(); |
| | | props.put(Sasl.QOP, "auth-conf,auth-int,auth"); |
| | | saslServer = |
| | | Sasl.createSaslServer(saslMech, "ldap", clientContext |
| | | .getLocalAddress().getHostName(), props, |
| | | Sasl.createSaslServer(saslMech, "ldap", |
| | | listener.getHostName(), props, |
| | | new CallbackHandler() { |
| | | public void handle(Callback[] callbacks) |
| | | throws IOException, |
| | |
| | | * |
| | | * @return The socket address of the server. |
| | | */ |
| | | public synchronized SocketAddress getSocketAddress() { |
| | | public synchronized InetSocketAddress getSocketAddress() { |
| | | if (!isRunning) { |
| | | throw new IllegalStateException("Server is not running"); |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2012-2013 ForgeRock AS. |
| | | * Portions copyright 2012-2014 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | |
| | | * |
| | | * @return The free port. |
| | | */ |
| | | public static SocketAddress findFreeSocketAddress() { |
| | | public static InetSocketAddress findFreeSocketAddress() { |
| | | try { |
| | | ServerSocket serverLdapSocket = new ServerSocket(); |
| | | serverLdapSocket.setReuseAddress(true); |
| | | serverLdapSocket.bind(new InetSocketAddress("127.0.0.1", 0)); |
| | | final SocketAddress address = serverLdapSocket.getLocalSocketAddress(); |
| | | serverLdapSocket.close(); |
| | | return address; |
| | | return (InetSocketAddress) address; |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | |
| | | * |
| | | * @return The socket address of the server. |
| | | */ |
| | | public static SocketAddress getServerSocketAddress() { |
| | | public static InetSocketAddress getServerSocketAddress() { |
| | | return LDAPServer.getInstance().getSocketAddress(); |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap.spi; |
| | |
| | | import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult; |
| | | import static org.mockito.Mockito.mock; |
| | | |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.Connection; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | |
| | | public final class BasicLDAPConnectionFactory implements LDAPConnectionFactoryImpl { |
| | | |
| | | private final LDAPOptions options; |
| | | private final SocketAddress socketAddress; |
| | | private final InetSocketAddress socketAddress; |
| | | |
| | | /** |
| | | * Creates a new LDAP connection factory which does nothing. |
| | |
| | | * @param options |
| | | * The LDAP connection options to use when creating connections. |
| | | */ |
| | | public BasicLDAPConnectionFactory(final SocketAddress address, final LDAPOptions options) { |
| | | public BasicLDAPConnectionFactory(final InetSocketAddress address, final LDAPOptions options) { |
| | | this.socketAddress = address; |
| | | this.options = new LDAPOptions(options); |
| | | } |
| | |
| | | * |
| | | * @return The address of the Directory Server. |
| | | */ |
| | | public SocketAddress getSocketAddress() { |
| | | public InetSocketAddress getSocketAddress() { |
| | | return socketAddress; |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap.spi; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.LDAPClientContext; |
| | | import org.forgerock.opendj.ldap.LDAPListenerOptions; |
| | |
| | | */ |
| | | public final class BasicLDAPListener implements LDAPListenerImpl { |
| | | private final ServerConnectionFactory<LDAPClientContext, Integer> connectionFactory; |
| | | private final SocketAddress socketAddress; |
| | | private final InetSocketAddress socketAddress; |
| | | |
| | | /** |
| | | * Creates a new LDAP listener implementation which does nothing. |
| | |
| | | * @throws IOException |
| | | * is never thrown with this do-nothing implementation |
| | | */ |
| | | public BasicLDAPListener(final SocketAddress address, |
| | | public BasicLDAPListener(final InetSocketAddress address, |
| | | final ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | final LDAPListenerOptions options) throws IOException { |
| | | this.connectionFactory = factory; |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public SocketAddress getSocketAddress() { |
| | | public InetSocketAddress getSocketAddress() { |
| | | return socketAddress; |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.ldap.spi; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.LDAPClientContext; |
| | | import org.forgerock.opendj.ldap.LDAPListenerOptions; |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public LDAPConnectionFactoryImpl getLDAPConnectionFactory(SocketAddress address, LDAPOptions options) { |
| | | public LDAPConnectionFactoryImpl getLDAPConnectionFactory(InetSocketAddress address, LDAPOptions options) { |
| | | return new BasicLDAPConnectionFactory(address, options); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public LDAPListenerImpl getLDAPListener( |
| | | SocketAddress address, |
| | | InetSocketAddress address, |
| | | ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | LDAPListenerOptions options) |
| | | throws IOException { |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | package com.forgerock.opendj.grizzly; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | |
| | | import org.forgerock.opendj.grizzly.GrizzlyLDAPConnectionFactory; |
| | | import org.forgerock.opendj.grizzly.GrizzlyLDAPListener; |
| | |
| | | */ |
| | | public class GrizzlyTransportProvider implements TransportProvider { |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public LDAPConnectionFactoryImpl getLDAPConnectionFactory(SocketAddress address, LDAPOptions options) { |
| | | public LDAPConnectionFactoryImpl getLDAPConnectionFactory(InetSocketAddress address, |
| | | LDAPOptions options) { |
| | | return new GrizzlyLDAPConnectionFactory(address, options); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public LDAPListenerImpl getLDAPListener( |
| | | SocketAddress address, |
| | | ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | LDAPListenerOptions options) |
| | | public LDAPListenerImpl getLDAPListener(InetSocketAddress address, |
| | | ServerConnectionFactory<LDAPClientContext, Integer> factory, LDAPListenerOptions options) |
| | | throws IOException { |
| | | return new GrizzlyLDAPListener(address, factory, options); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public String getName() { |
| | | return "Grizzly"; |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2013 ForgeRock AS |
| | | * Portions Copyright 2011-2014 ForgeRock AS |
| | | */ |
| | | |
| | | package org.forgerock.opendj.grizzly; |
| | |
| | | import static org.forgerock.opendj.ldap.ErrorResultException.newErrorResult; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.InetSocketAddress; |
| | | import java.security.GeneralSecurityException; |
| | | import java.util.List; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | |
| | | import org.forgerock.opendj.io.LDAPWriter; |
| | | import org.forgerock.opendj.ldap.AbstractAsynchronousConnection; |
| | | import org.forgerock.opendj.ldap.ConnectionEventListener; |
| | | import org.forgerock.opendj.ldap.Connections; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | import org.forgerock.opendj.ldap.FutureResult; |
| | | import org.forgerock.opendj.ldap.IntermediateResponseHandler; |
| | |
| | | import org.glassfish.grizzly.ssl.SSLFilter; |
| | | |
| | | import com.forgerock.opendj.util.CompletedFutureResult; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | /** |
| | |
| | | final BindClient context; |
| | | try { |
| | | context = |
| | | request.createBindClient( |
| | | connection.getPeerAddress() instanceof InetSocketAddress |
| | | ? ((InetSocketAddress) connection.getPeerAddress()).getHostName() |
| | | : connection.getPeerAddress().toString()); |
| | | request.createBindClient(Connections.getHostString(factory.getSocketAddress())); |
| | | } catch (final Exception e) { |
| | | // FIXME: I18N need to have a better error message. |
| | | // FIXME: Is this the best result code? |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2013 ForgeRock AS |
| | | * Portions copyright 2011-2014 ForgeRock AS |
| | | */ |
| | | |
| | | package org.forgerock.opendj.grizzly; |
| | |
| | | import static org.forgerock.opendj.ldap.TimeoutChecker.TIMEOUT_CHECKER; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.concurrent.ExecutionException; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | |
| | | private final LDAPClientFilter clientFilter; |
| | | private final FilterChain defaultFilterChain; |
| | | private final LDAPOptions options; |
| | | private final SocketAddress socketAddress; |
| | | private final InetSocketAddress socketAddress; |
| | | |
| | | /** |
| | | * Prevents the transport and timeoutChecker being released when there are |
| | |
| | | * @param options |
| | | * The LDAP connection options to use when creating connections. |
| | | */ |
| | | public GrizzlyLDAPConnectionFactory(final SocketAddress address, final LDAPOptions options) { |
| | | public GrizzlyLDAPConnectionFactory(final InetSocketAddress address, final LDAPOptions options) { |
| | | this(address, options, null); |
| | | } |
| | | |
| | |
| | | * Grizzly TCP Transport NIO implementation to use for |
| | | * connections. If {@code null}, default transport will be used. |
| | | */ |
| | | public GrizzlyLDAPConnectionFactory(final SocketAddress address, final LDAPOptions options, |
| | | public GrizzlyLDAPConnectionFactory(final InetSocketAddress address, final LDAPOptions options, |
| | | TCPNIOTransport transport) { |
| | | this.transport = DEFAULT_TRANSPORT.acquireIfNull(transport); |
| | | this.socketAddress = address; |
| | | this.options = new LDAPOptions(options); |
| | | this.clientFilter = new LDAPClientFilter(this.options.getDecodeOptions(), 0); |
| | | this.defaultFilterChain = GrizzlyUtils.buildFilterChain(this.transport.get().getProcessor(), clientFilter); |
| | | this.defaultFilterChain = |
| | | GrizzlyUtils.buildFilterChain(this.transport.get().getProcessor(), clientFilter); |
| | | |
| | | } |
| | | |
| | |
| | | return future; |
| | | } |
| | | |
| | | /** |
| | | * Returns the address of the Directory Server. |
| | | * |
| | | * @return The address of the Directory Server. |
| | | */ |
| | | public SocketAddress getSocketAddress() { |
| | | @Override |
| | | public InetSocketAddress getSocketAddress() { |
| | | return socketAddress; |
| | | } |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2013 ForgeRock AS |
| | | * Portions copyright 2011-2014 ForgeRock AS |
| | | */ |
| | | |
| | | package org.forgerock.opendj.grizzly; |
| | |
| | | import static org.forgerock.opendj.grizzly.DefaultTCPNIOTransport.DEFAULT_TRANSPORT; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.concurrent.atomic.AtomicBoolean; |
| | | |
| | | import org.forgerock.opendj.ldap.Connections; |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | | import org.forgerock.opendj.ldap.LDAPClientContext; |
| | | import org.forgerock.opendj.ldap.LDAPListenerOptions; |
| | |
| | | private final ServerConnectionFactory<LDAPClientContext, Integer> connectionFactory; |
| | | private final TCPNIOServerConnection serverConnection; |
| | | private final AtomicBoolean isClosed = new AtomicBoolean(); |
| | | private final InetSocketAddress socketAddress; |
| | | |
| | | /** |
| | | * Creates a new LDAP listener implementation which will listen for LDAP |
| | |
| | | * If an error occurred while trying to listen on the provided |
| | | * address. |
| | | */ |
| | | public GrizzlyLDAPListener(final SocketAddress address, |
| | | public GrizzlyLDAPListener(final InetSocketAddress address, |
| | | final ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | final LDAPListenerOptions options) throws IOException { |
| | | this(address, factory, options, null); |
| | |
| | | * If an error occurred while trying to listen on the provided |
| | | * address. |
| | | */ |
| | | public GrizzlyLDAPListener(final SocketAddress address, |
| | | public GrizzlyLDAPListener(final InetSocketAddress address, |
| | | final ServerConnectionFactory<LDAPClientContext, Integer> factory, |
| | | final LDAPListenerOptions options, TCPNIOTransport transport) throws IOException { |
| | | this.transport = DEFAULT_TRANSPORT.acquireIfNull(transport); |
| | | this.connectionFactory = factory; |
| | | |
| | | final DecodeOptions decodeOptions = new DecodeOptions(options.getDecodeOptions()); |
| | | final LDAPServerFilter serverFilter = new LDAPServerFilter(this, decodeOptions, options |
| | | .getMaxRequestSize()); |
| | | final FilterChain ldapChain = GrizzlyUtils.buildFilterChain(this.transport.get().getProcessor(), serverFilter); |
| | | final LDAPServerFilter serverFilter = |
| | | new LDAPServerFilter(this, decodeOptions, options.getMaxRequestSize()); |
| | | final FilterChain ldapChain = |
| | | GrizzlyUtils.buildFilterChain(this.transport.get().getProcessor(), serverFilter); |
| | | final TCPNIOBindingHandler bindingHandler = |
| | | TCPNIOBindingHandler.builder(this.transport.get()).processor(ldapChain).build(); |
| | | this.serverConnection = bindingHandler.bind(address, options.getBacklog()); |
| | | |
| | | /* |
| | | * Get the socket address now, ensuring that the host is the same as the |
| | | * one provided in the constructor. The port will have changed if 0 was |
| | | * passed in. |
| | | */ |
| | | final int port = ((InetSocketAddress) serverConnection.getLocalAddress()).getPort(); |
| | | socketAddress = new InetSocketAddress(Connections.getHostString(address), port); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public SocketAddress getSocketAddress() { |
| | | return serverConnection.getLocalAddress(); |
| | | public InetSocketAddress getSocketAddress() { |
| | | return socketAddress; |
| | | } |
| | | |
| | | @Override |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | * Copyright 2013-2014 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.grizzly; |
| | |
| | | import static org.mockito.Mockito.verify; |
| | | import static org.mockito.Mockito.verifyZeroInteractions; |
| | | |
| | | import java.net.SocketAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | import org.forgerock.opendj.ldap.Connections; |
| | |
| | | } |
| | | |
| | | private void doTestRequestTimeout(boolean isPersistentSearch) throws Exception { |
| | | SocketAddress address = TestCaseUtils.findFreeSocketAddress(); |
| | | InetSocketAddress address = TestCaseUtils.findFreeSocketAddress(); |
| | | |
| | | /* |
| | | * Use a mock server implementation which will ignore incoming requests |