/**
  * Retrieves the set of active client connections that have been established through this
  * connection handler.
  *
  * @return The set of active client connections that have been established through this connection
  *     handler.
  */
 @Override
 public Collection<ClientConnection> getClientConnections() {
   List<ClientConnection> connectionList = new LinkedList<>();
   for (LDAPRequestHandler requestHandler : requestHandlers) {
     connectionList.addAll(requestHandler.getClientConnections());
   }
   return connectionList;
 }
  /** {@inheritDoc} */
  @Override
  public void processServerShutdown(LocalizableMessage reason) {
    shutdownRequested = true;

    try {
      for (LDAPRequestHandler requestHandler : requestHandlers) {
        try {
          requestHandler.processServerShutdown(reason);
        } catch (Exception ignored) {
        }
      }
    } catch (Exception ignored) {
    }
  }
  /** {@inheritDoc} */
  @Override
  public void finalizeConnectionHandler(LocalizableMessage finalizeReason) {
    shutdownRequested = true;
    currentConfig.removeLDAPChangeListener(this);

    if (connMonitor != null) {
      DirectoryServer.deregisterMonitorProvider(connMonitor);
    }

    if (statTracker != null) {
      DirectoryServer.deregisterMonitorProvider(statTracker);
    }

    DirectoryServer.deregisterSupportedLDAPVersion(2, this);
    DirectoryServer.deregisterSupportedLDAPVersion(3, this);

    try {
      selector.wakeup();
    } catch (Exception e) {
      logger.traceException(e);
    }

    for (LDAPRequestHandler requestHandler : requestHandlers) {
      requestHandler.processServerShutdown(finalizeReason);
    }

    // Shutdown the connection finalizer and ensure that any pending
    // unclosed connections are closed.
    synchronized (connectionFinalizerLock) {
      connectionFinalizer.shutdown();
      connectionFinalizer = null;

      Runnable r = new ConnectionFinalizerRunnable();
      r.run(); // Flush active queue.
      r.run(); // Flush pending queue.
    }
  }
  private void acceptConnection(SocketChannel clientChannel) throws DirectoryException {
    try {
      clientChannel.socket().setKeepAlive(currentConfig.isUseTCPKeepAlive());
      clientChannel.socket().setTcpNoDelay(currentConfig.isUseTCPNoDelay());
    } catch (SocketException se) {
      // TCP error occurred because connection reset/closed? In any case,
      // just close it and ignore.
      // See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6378870
      close(clientChannel);
    }

    // Check to see if the core server rejected the
    // connection (e.g., already too many connections
    // established).
    LDAPClientConnection clientConnection =
        new LDAPClientConnection(this, clientChannel, getProtocol());
    if (clientConnection.getConnectionID() < 0) {
      clientConnection.disconnect(
          DisconnectReason.ADMIN_LIMIT_EXCEEDED, true, ERR_CONNHANDLER_REJECTED_BY_SERVER.get());
      return;
    }

    InetAddress clientAddr = clientConnection.getRemoteAddress();
    // Check to see if the client is on the denied list.
    // If so, then reject it immediately.
    if (!deniedClients.isEmpty() && AddressMask.matchesAny(deniedClients, clientAddr)) {
      clientConnection.disconnect(
          DisconnectReason.CONNECTION_REJECTED,
          currentConfig.isSendRejectionNotice(),
          ERR_CONNHANDLER_DENIED_CLIENT.get(
              clientConnection.getClientHostPort(), clientConnection.getServerHostPort()));
      return;
    }
    // Check to see if there is an allowed list and if
    // there is whether the client is on that list. If
    // not, then reject the connection.
    if (!allowedClients.isEmpty() && !AddressMask.matchesAny(allowedClients, clientAddr)) {
      clientConnection.disconnect(
          DisconnectReason.CONNECTION_REJECTED,
          currentConfig.isSendRejectionNotice(),
          ERR_CONNHANDLER_DISALLOWED_CLIENT.get(
              clientConnection.getClientHostPort(), clientConnection.getServerHostPort()));
      return;
    }

    // If we've gotten here, then we'll take the
    // connection so invoke the post-connect plugins and
    // register the client connection with a request
    // handler.
    try {
      PluginConfigManager pluginManager = DirectoryServer.getPluginConfigManager();
      PluginResult.PostConnect pluginResult =
          pluginManager.invokePostConnectPlugins(clientConnection);
      if (!pluginResult.continueProcessing()) {
        clientConnection.disconnect(
            pluginResult.getDisconnectReason(),
            pluginResult.sendDisconnectNotification(),
            pluginResult.getErrorMessage());
        return;
      }

      LDAPRequestHandler requestHandler = requestHandlers[requestHandlerIndex++];
      if (requestHandlerIndex >= numRequestHandlers) {
        requestHandlerIndex = 0;
      }
      requestHandler.registerClient(clientConnection);
    } catch (Exception e) {
      logger.traceException(e);

      LocalizableMessage message =
          INFO_CONNHANDLER_UNABLE_TO_REGISTER_CLIENT.get(
              clientConnection.getClientHostPort(),
              clientConnection.getServerHostPort(),
              getExceptionMessage(e));
      logger.debug(message);

      clientConnection.disconnect(
          DisconnectReason.SERVER_ERROR, currentConfig.isSendRejectionNotice(), message);
    }
  }