This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-jspf.git
commit 048417cccbad594ccb28476a155e5305f7416cf4 Author: Quan Tran <[email protected]> AuthorDate: Wed Nov 4 23:31:58 2026 +0700 [FIX] DNSServiceXBillImpl.getRecords: no unchecked exception from dnsjava dnsjava's Lookup throws ClassCastException on some malformed answers, as an UPDATE message holding a CNAME or DNAME without data. getRecords let it escape, although DNSService declares only TimeoutException: the executors now read it as a lookup error, but any other caller of getRecords got the unchecked exception instead of a TimeoutException. Report it as a TimeoutException, a DNS error, so a temperror (RFC 7208 2.6.6: "a transient (generally DNS) error"), as Lookup does with TRY_AGAIN for the answers it rejects, and log it. --- .../apache/james/jspf/impl/DNSServiceXBillImpl.java | 20 ++++++++++++++++++-- .../apache/james/jspf/DNSServiceXBillImplTest.java | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java b/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java index a0614cd..d92bfe5 100644 --- a/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java +++ b/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java @@ -199,6 +199,21 @@ public class DNSServiceXBillImpl implements DNSService { } } + /** + * @param query the lookup of the given request + * @return the answer of the lookup + * @throws TimeoutException on a DNS error, as dnsjava's ClassCastException on some malformed + * answers: DNSService declares no other exception (RFC 7208 4.4) + */ + private static Record[] run(Lookup query, Name name, int type) throws TimeoutException { + try { + return query.run(); + } catch (RuntimeException e) { + LOGGER.warn("Unexpected error of the DNS lookup of {} (type {})", name, Type.string(type), e); + throw new TimeoutException(e.toString()); + } + } + /** * @return the records of the given type: an answer can hold others */ @@ -306,10 +321,11 @@ public class DNSServiceXBillImpl implements DNSService { LOGGER.debug("Start {}-Record lookup for : {}", recordTypeDescription, request.getHostname()); // RFC 7208 4.3: a fully qualified name, not looked up under the search path of the host - Lookup query = new Lookup(Name.fromString(request.getHostname(), Name.root), dnsJavaType); + Name name = Name.fromString(request.getHostname(), Name.root); + Lookup query = new Lookup(name, dnsJavaType); query.setResolver(resolver); - Record[] rr = query.run(); + Record[] rr = run(query, name, dnsJavaType); int queryResult = query.getResult(); diff --git a/resolver/src/test/java/org/apache/james/jspf/DNSServiceXBillImplTest.java b/resolver/src/test/java/org/apache/james/jspf/DNSServiceXBillImplTest.java index 66abff9..ff02b21 100644 --- a/resolver/src/test/java/org/apache/james/jspf/DNSServiceXBillImplTest.java +++ b/resolver/src/test/java/org/apache/james/jspf/DNSServiceXBillImplTest.java @@ -25,6 +25,7 @@ import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; import org.apache.james.jspf.core.DNSRequest; +import org.apache.james.jspf.core.exceptions.TimeoutException; import org.apache.james.jspf.helpers.AnsweringResolver; import org.apache.james.jspf.impl.DNSServiceXBillImpl; import org.junit.Test; @@ -32,6 +33,7 @@ import org.slf4j.LoggerFactory; import org.xbill.DNS.CNAMERecord; import org.xbill.DNS.DClass; import org.xbill.DNS.Flags; +import org.xbill.DNS.Lookup; import org.xbill.DNS.Message; import org.xbill.DNS.Name; import org.xbill.DNS.Record; @@ -106,6 +108,21 @@ public class DNSServiceXBillImplTest { assertNull(DNSServiceXBillImpl.convertRecordsToList(answer)); } + @Test(timeout = 10000) + public void getRecordsShouldReportADnsErrorForAnAnswerDnsjavaCannotProcess() throws Exception { + // opcode UPDATE, and the answer "example.com CNAME" of RDLENGTH 0: dnsjava's Lookup throws ClassCastException + byte[] message = Base64.getDecoder().decode("AAErAAABAAEAAAAAB2V4YW1wbGUDY29tAAAQAAHADAAFAAAAAA5RAABj"); + DNSServiceXBillImpl dns = new DNSServiceXBillImpl(new AnsweringResolver(message)); + Lookup.getDefaultCache(DClass.IN).clearCache(); + + try { + dns.getRecords(new DNSRequest("example.com", DNSRequest.TXT)); + fail("the lookup should fail"); + } catch (TimeoutException e) { + // DNSService declares only TimeoutException: a DNS error (RFC 7208 4.4) + } + } + @Test(timeout = 10000) public void getRecordsAsyncShouldEndALookupWhoseAnswerHoldsACnameOfAnotherName() throws Exception { AnsweringResolver resolver = new AnsweringResolver(Base64.getDecoder().decode(CNAME_OF_THE_ROOT)); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
