Skip to content

Avoid Double DNS Lookup for Names with Labels >= ndots #388

@bhaveshthakker

Description

@bhaveshthakker

Summary:

This issue reports a performance inefficiency in the org.xbill.DNS.Lookup class, specifically related to how it handles DNS lookups for names with a number of labels greater than or equal to the configured ndots value. This can lead to unnecessary double lookups, causing delays, especially when the DNS resolver has timeouts.

Problem Description:

  • A change (commit hash) introduced logic to lookup a name as absolute after search path exhaustion.
  • However, when the provided name already has more labels than the configured ndots value and is not an absolute name (i.e., it doesn't end with a dot), this logic results in the code attempting to resolve the name twice:
    1. An initial absolute lookup is performed because the name is already considered "absolute enough" based on ndots.
    2. After exhausting the search path, a second absolute lookup is attempted again.
  • This double lookup causes unnecessary network overhead and delays, particularly if the DNS server is slow or unresponsive. It can also exacerbate timeout issues.

Example Scenario:

Consider the following configuration:

  • DNS search path: internal.lan
  • ndots: 2

And an application trying to resolve the name my-service.internal.

  1. The name my-service.internal has 2 labels, and because ndots is also 2, it triggers an initial absolute lookup for my-service.internal..
  2. After the initial lookup, the code will iterate over the search path.
  3. After the search path is exhausted, the code attempts to resolve the name my-service.internal. again, causing a double lookup.

Impact:

  • Performance degradation, especially in environments with slow DNS resolvers.
  • Increased probability of timeouts.

Proposed Solution:

The fix is to avoid the second absolute lookup if an initial absolute lookup was already performed. We can achieve this by tracking whether the initial lookup was performed and conditionally skipping the final lookup after the search path is exhausted.

Code Snippet (Illustrative - Java):

Here's a code snippet demonstrating the issue and the proposed fix. The code is based on the Lookup.java class.

// Original code (problematic)
    if (searchPath == null) {
      resolve(name, Name.root);
    } else {
      if (name.labels() > ndots) { // <-- Initial absolute lookup
        resolve(name, Name.root);
      }
      if (done) {
        return;
      }
      for (String element : searchPath) {
        if (element == null || element.isEmpty()){
          continue;
        }
        Name suffix = Name.fromString(element, Name.root);
        Name full = Name.relative(name, suffix);
        resolve(full, suffix);
        if (done) {
          break;
        }
      }
      resolve(name, Name.root);  // <-- Double lookup, always performed
    }
/ /Proposed fix
    if (searchPath == null) {
      resolve(name, Name.root);
    } else {
      boolean sendInitialAbsoluteQuery = name.labels() > ndots; // <-- Track if the initial absolute lookup was done
      if (sendInitialAbsoluteQuery) {
        resolve(name, Name.root); // <-- Initial absolute lookup
      }
      if (done) {
        return;
      }
      for (String element : searchPath) {
        if (element == null || element.isEmpty()){
          continue;
        }
        Name suffix = Name.fromString(element, Name.root);
        Name full = Name.relative(name, suffix);
        resolve(full, suffix);
        if (done) {
          break;
        }
      }
      if (!sendInitialAbsoluteQuery) { // <-- Skip the final absolute lookup if initial was performed
        resolve(name, Name.root);
      }
    }

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions