Search in sources :

Example 1 with NAPTRRecord

use of org.xbill.DNS.NAPTRRecord in project ph-web by phax.

the class NaptrResolver method resolveUNAPTR.

@Nullable
public String resolveUNAPTR() {
    final ICommonsList<NAPTRRecord> aMatchingRecords = new CommonsArrayList<>();
    for (final NAPTRRecord aRecord : m_aNaptrRecords) {
        /**
         * RFC 2915: Flags are single characters from the set [A-Z0-9]. The case
         * of the alphabetic characters is not significant. <br>
         * The labels for service requests shall be formed from the set of
         * characters [A-Z0-9]. The case of the alphabetic characters is not
         * significant.<br>
         * RFC 3404: allows "+" in service names.<br>
         * RFC 4848: allow many chars: service-parms = [ [app-service] *(":"
         * app-protocol)]<br>
         * ; The service-parms are considered case-insensitive.
         */
        if ("U".equalsIgnoreCase(aRecord.getFlags()) && m_aServiceNameMatcher.test(aRecord.getService())) {
            if (LOGGER.isDebugEnabled())
                LOGGER.debug("Found a matching U-NAPTR record: " + aRecord);
            aMatchingRecords.add(aRecord);
        }
    }
    if (aMatchingRecords.isEmpty()) {
        // No matching NAPTR present
        if (LOGGER.isWarnEnabled())
            LOGGER.warn("No matching DNS U-NAPTR records returned for '" + m_sDomainName + "'");
        return null;
    }
    // Sort by order than by preference according to RFC 2915
    aMatchingRecords.sort((x, y) -> {
        int ret = CompareHelper.compare(x.getOrder(), y.getOrder());
        if (ret == 0)
            ret = CompareHelper.compare(x.getPreference(), y.getPreference());
        return ret;
    });
    for (final NAPTRRecord aRecord : aMatchingRecords) {
        // The "U" record is terminal, so a RegExp must be present
        final String sRegEx = aRecord.getRegexp();
        // At least 3 separator chars must be present :)
        if (StringHelper.getLength(sRegEx) > 3) {
            final String sFinalDNSName = getAppliedNAPTRRegEx(sRegEx, m_sDomainName);
            if (sFinalDNSName != null) {
                if (LOGGER.isDebugEnabled())
                    LOGGER.debug("Using '" + sFinalDNSName + "' for original domain name '" + m_sDomainName + "'");
                return sFinalDNSName;
            }
        }
    }
    // Weird - no regexp present
    if (LOGGER.isWarnEnabled())
        LOGGER.warn("None of the matching DNS NAPTR records for '" + m_sDomainName + "' has a valid regular expression. Details: " + aMatchingRecords);
    return null;
}
Also used : CommonsArrayList(com.helger.commons.collection.impl.CommonsArrayList) NAPTRRecord(org.xbill.DNS.NAPTRRecord) Nullable(javax.annotation.Nullable)

Example 2 with NAPTRRecord

use of org.xbill.DNS.NAPTRRecord in project ph-web by phax.

the class NaptrLookup method lookup.

/**
 * Perform the DNS lookup based on the parameters provided in the constructor.
 *
 * @return A never <code>null</code> but maybe empty list of records.
 */
@Nonnull
public ICommonsList<NAPTRRecord> lookup() {
    // Omit the final dot
    final String sDomainName = m_aDomainName.toString(true);
    if (LOGGER.isInfoEnabled())
        LOGGER.info("Trying to look up NAPTR on '" + sDomainName + "'" + (m_nMaxRetries > 0 ? " with " + m_nMaxRetries + " retries" : "") + " using network mode " + m_eLookupMode);
    final BooleanSupplier aIsEnabled = m_bDebugMode ? LOGGER::isInfoEnabled : LOGGER::isDebugEnabled;
    final Consumer<String> aLogger = m_bDebugMode ? LOGGER::info : LOGGER::debug;
    final StopWatch aSW = StopWatch.createdStarted();
    try {
        // Use the default (static) cache that is used by default
        final ExtendedResolver aResolver = ResolverHelper.createExtendedResolver(m_aCustomDNSServers);
        aResolver.setRetries(m_nMaxRetries);
        if (m_aTimeout != null)
            aResolver.setTimeout(m_aTimeout);
        final Lookup aLookup = new Lookup(m_aDomainName, Type.NAPTR);
        aLookup.setResolver(aResolver);
        int nLookupRuns = 0;
        boolean bCanTryAgain = true;
        Record[] aRecords = null;
        if (m_eLookupMode.isUDP()) {
            if (aIsEnabled.getAsBoolean())
                aLogger.accept("  Trying UDP for NAPTR lookup after " + nLookupRuns + " unsuccessful lopkups");
            // By default try UDP
            // Stumbled upon an issue, where UDP datagram size was too small for MTU
            // size of 1500
            int nLeft = m_nMaxRetries;
            do {
                aRecords = aLookup.run();
                if (aIsEnabled.getAsBoolean())
                    aLogger.accept("    Result of UDP lookup " + nLookupRuns + ": " + aLookup.getErrorString());
                nLeft--;
                nLookupRuns++;
            } while (aLookup.getResult() == Lookup.TRY_AGAIN && nLeft >= 0);
            if (aLookup.getResult() != Lookup.TRY_AGAIN)
                bCanTryAgain = false;
        }
        if (bCanTryAgain && m_eLookupMode.isTCP()) {
            if (aIsEnabled.getAsBoolean())
                aLogger.accept("  Trying TCP for NAPTR lookup after " + nLookupRuns + " unsuccessful lopkups");
            // Retry with TCP instead of UDP
            aResolver.setTCP(true);
            // Restore max retries for TCP
            int nLeft = m_nMaxRetries;
            do {
                aRecords = aLookup.run();
                if (aIsEnabled.getAsBoolean())
                    aLogger.accept("    Result of TCP lookup " + nLookupRuns + ": " + aLookup.getErrorString());
                nLeft--;
                nLookupRuns++;
            } while (aLookup.getResult() == Lookup.TRY_AGAIN && nLeft >= 0);
        }
        if (aLookup.getResult() != Lookup.SUCCESSFUL) {
            // Wrong domain name
            if (LOGGER.isWarnEnabled())
                LOGGER.warn("Error looking up '" + sDomainName + "': " + aLookup.getErrorString());
            return new CommonsArrayList<>();
        }
        final ICommonsList<NAPTRRecord> ret = new CommonsArrayList<>();
        for (final Record aRecord : aRecords) ret.add((NAPTRRecord) aRecord);
        if (aIsEnabled.getAsBoolean())
            aLogger.accept("  Returning " + ret.size() + " NAPTR record(s) for '" + sDomainName + "' after " + nLookupRuns + " lookups");
        return ret;
    } finally {
        // Check execution time
        aSW.stop();
        final Duration aDuration = aSW.getDuration();
        if (m_aExecutionDurationWarn != null && aDuration.compareTo(m_aExecutionDurationWarn) > 0) {
            final String sMessage = "Looking up NAPTR record of '" + sDomainName + "'" + (m_nMaxRetries > 0 ? " with " + m_nMaxRetries + " retries" : "");
            m_aExecutionTimeExceededHandlers.forEach(x -> x.onLookupTimeExceeded(sMessage, aDuration, m_aExecutionDurationWarn));
        }
    }
}
Also used : ExtendedResolver(org.xbill.DNS.ExtendedResolver) Duration(java.time.Duration) StopWatch(com.helger.commons.timing.StopWatch) NAPTRRecord(org.xbill.DNS.NAPTRRecord) Lookup(org.xbill.DNS.Lookup) NAPTRRecord(org.xbill.DNS.NAPTRRecord) Record(org.xbill.DNS.Record) BooleanSupplier(java.util.function.BooleanSupplier) CommonsArrayList(com.helger.commons.collection.impl.CommonsArrayList) Nonnull(javax.annotation.Nonnull)

Aggregations

CommonsArrayList (com.helger.commons.collection.impl.CommonsArrayList)2 NAPTRRecord (org.xbill.DNS.NAPTRRecord)2 StopWatch (com.helger.commons.timing.StopWatch)1 Duration (java.time.Duration)1 BooleanSupplier (java.util.function.BooleanSupplier)1 Nonnull (javax.annotation.Nonnull)1 Nullable (javax.annotation.Nullable)1 ExtendedResolver (org.xbill.DNS.ExtendedResolver)1 Lookup (org.xbill.DNS.Lookup)1 Record (org.xbill.DNS.Record)1