mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Valery Kharseko
3 days ago 88f1a8b11a45b44bedb89fb80ff97004e45f4bf3
Reduce per-bind allocations on the bind hot path (#672)
2 files modified
87 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/core/BindOperationBasis.java 13 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/PasswordPolicyState.java 74 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/core/BindOperationBasis.java
@@ -53,6 +53,15 @@
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /**
   * The cancel request sent to the other operations in progress when a bind
   * starts. CancelRequest and LocalizableMessage are both immutable (the
   * message is rendered per locale when used), so a single shared instance
   * avoids building both objects on every bind.
   */
  private static final CancelRequest CANCEL_ALL_BY_BIND_REQUEST =
      new CancelRequest(true, INFO_CANCELED_BY_BIND_REQUEST.get());
  /** The credentials used for SASL authentication. */
  private ByteString saslCredentials;
@@ -484,9 +493,7 @@
    clientConnection.setUnauthenticated();
    // Abandon any operations that may be in progress for the client.
    LocalizableMessage cancelReason = INFO_CANCELED_BY_BIND_REQUEST.get();
    CancelRequest cancelRequest = new CancelRequest(true, cancelReason);
    clientConnection.cancelAllOperationsExcept(cancelRequest, getMessageID());
    clientConnection.cancelAllOperationsExcept(CANCEL_ALL_BY_BIND_REQUEST, getMessageID());
    // This flag is set to true as soon as a workflow has been executed.
    boolean workflowExecuted = false;
opendj-server-legacy/src/main/java/org/opends/server/core/PasswordPolicyState.java
@@ -1963,27 +1963,50 @@
      return false;
    }
    boolean isAuthPassword = passwordPolicy.isAuthPasswordSyntax();
    for (Attribute a : attrList)
    {
      for (ByteString v : a)
      {
        try
        {
          String[] pwComponents = getPwComponents(v);
          String schemeName = pwComponents[0];
          PasswordStorageScheme<?> scheme = getPasswordStorageScheme(schemeName);
          if (scheme == null)
          String schemeName;
          boolean matches;
          if (isAuthPassword)
          {
            if (logger.isTraceEnabled())
            String[] pwComponents = getPwComponents(v);
            schemeName = pwComponents[0];
            PasswordStorageScheme<?> scheme = getPasswordStorageScheme(schemeName);
            if (scheme == null)
            {
              logger.trace("User entry %s contains a password with scheme %s that is not defined in the server.",
                                  userDNString, schemeName);
              traceUndefinedScheme(schemeName);
              continue;
            }
            continue;
            matches = passwordMatches(password, pwComponents, scheme);
          }
          else
          {
            // This method runs for every bind: parse the {scheme} prefix at
            // the byte level instead of materializing the whole stored value
            // as a String only to convert its payload back to bytes.
            int closePos = userPasswordSchemeEnd(v);
            if (closePos < 0)
            {
              // Malformed value: raise the same errors as the String decoder.
              getPwComponents(v);
              continue;
            }
            schemeName = toLowerCase(v.subSequence(1, closePos).toString());
            PasswordStorageScheme<?> scheme = DirectoryServer.getPasswordStorageScheme(schemeName);
            if (scheme == null)
            {
              traceUndefinedScheme(schemeName);
              continue;
            }
            matches = scheme.passwordMatches(password, v.subSequence(closePos + 1, v.length()));
          }
          if (passwordMatches(password, pwComponents, scheme))
          if (matches)
          {
            if (logger.isTraceEnabled())
            {
@@ -2024,6 +2047,37 @@
  }
  /**
   * Returns the index of the closing brace of the {scheme} prefix of the
   * provided user password value, or -1 if the value is not well-formed
   * (also when the scheme name is empty, mirroring
   * {@link UserPasswordSyntax#decodeUserPassword(String)}).
   */
  private static int userPasswordSchemeEnd(ByteString v)
  {
    if (v.length() == 0 || v.byteAt(0) != '{')
    {
      return -1;
    }
    for (int i = 1; i < v.length(); i++)
    {
      if (v.byteAt(i) == '}')
      {
        return i > 1 ? i : -1;
      }
    }
    return -1;
  }
  private void traceUndefinedScheme(String schemeName)
  {
    if (logger.isTraceEnabled())
    {
      logger.trace("User entry %s contains a password with scheme %s that is not defined in the server.",
          userDNString, schemeName);
    }
  }
  /**
   * Indicates whether the provided password value is pre-encoded.
   *
   * @param  passwordValue  The value for which to make the determination.