prosgarz35 opened a new pull request, #3211:
URL: https://github.com/apache/james-project/pull/3211

   ## Summary
   
   This pull request integrates a high-performance in-memory cache powered by 
[Caffeine](https://github.com/ben-manes/caffeine) directly into 
`DNSJavaService`. It intercepts queries ahead of dnsjava's internal cache, 
offering per-entry dynamic TTL expiration, SOA negative caching support, 
bounded corridor enforcement, and backward-compatible XML configuration.
   
   ---
   
   ## Motivation & Problem Statement
   
   In high-throughput mail processing environments (SMTP reception, relaying, 
SPF/DKIM/DMARC checks), DNS resolution latency and upstream resolver 
rate-limiting can become severe bottlenecks:
   1. **Redundant Upstream DNS Queries**: High-frequency lookups (`MX`, `A`, 
`ALL_A`, `TXT`, and `PTR`) frequently query upstream resolvers even for 
identical records when upstream TTLs are short or negative lookups occur.
   2. **Lack of Per-Record TTL & Corridor Controls**: The existing dnsjava 
`Cache` implementation lacks flexible, granular control over per-entry 
expiration, corridor clamping (min/max protection), and negative caching tuning 
without affecting global JVM properties.
   3. **Cache Stampede & Zero-TTL Thrashing**: Misconfigured or malicious 
upstream records specifying a 0-second TTL force constant network round-trips 
without a lower protective floor.
   
   ---
   
   ## Key Changes & Architecture
   
   ### 1. Caffeine Cache Integration
   - Embedded Caffeine cache (`caffeineCache`) introduced in front of dnsjava 
`Lookup`.
   - Type-safe composite key `DnsKey(DnsRecordType type, Object target)` 
supporting:
     - `MX`: Mail exchange lookups
     - `A`: Hostname to IPv4/IPv6 single address
     - `ALL_A`: Hostname to all IP addresses
     - `TXT`: Text records (SPF, DKIM, DMARC)
     - `PTR`: Reverse IP resolution (FCrDNS, connection logging)
   - Normalized case handling (`normalizeKey`) for hostnames using `Locale.US` 
to avoid redundant misses.
   - Values stored wrapped in `DnsValue<T>(T value, long ttlSeconds)`.
   
   ### 2. Per-Entry Dynamic Expiration (`Expiry`)
   - Implemented a custom `Expiry<DnsKey, DnsValue<?>>` policy dynamically 
calculating nanos via `ttlNanos(value)` using individual record TTLs.
   - Eviction honors both max capacity (`maxcachesize`, default: 50,000) and 
entry-level TTLs.
   
   ### 3. Granular Positive & Negative TTL Corridor Protection
   To prevent cache stampede from 0-second TTLs while simultaneously ensuring 
stale records do not persist indefinitely:
   - **Corridor Bounds**:
     - `cacheMinTTL` (default: 60s, hard floor: 60s) to `cacheMaxTTL` (default: 
86400s / 1 day, hard cap: 7 days).
     - `negativeCacheMinTTL` (default: 60s, hard floor: 60s) to 
`negativeCacheMaxTTL` (default: 3600s / 1 hour).
   - **Inheritance & Fallbacks**:
     - `inheritTTL`: When `true`, uses minimum TTL across returned DNS records 
clamped within the corridor. When `false`, uses `cacheFallbackTTL` (default: 
300s).
     - `inheritNegativeTTL`: When `true`, respects upstream SOA negative TTL 
clamped within the corridor. When `false` or if SOA is absent, uses 
`negativeCacheFallbackTTL` (default: 60s).
   - **JVM Fallback Integration**:
     - Automatically respects `networkaddress.cache.ttl` and 
`networkaddress.cache.negative.ttl` (as well as `sun.net.inetaddr.*`) as 
defaults if explicit XML overrides are not provided.
   
   ### 4. Configuration Schema Updates (`dnsservice.xml`)
   Added comprehensive, documented XML elements with full backward 
compatibility (all tags optional):
   ```xml
   <dnsservice>
     <autodiscover>true</autodiscover>
     <authoritative>false</authoritative>
     <maxcachesize>50000</maxcachesize>
   
     <!-- Positive Cache Settings -->
     <inheritTTL>true</inheritTTL>
     <cacheFallbackTTL>300</cacheFallbackTTL>
     <cacheMinTTL>60</cacheMinTTL>
     <cacheMaxTTL>86400</cacheMaxTTL>
   
     <!-- Negative Cache Settings -->
     <inheritNegativeTTL>true</inheritNegativeTTL>
     <negativeCacheFallbackTTL>60</negativeCacheFallbackTTL>
     <negativeCacheMinTTL>60</negativeCacheMinTTL>
     <negativeCacheMaxTTL>3600</negativeCacheMaxTTL>
   </dnsservice>
   ```
   
   ### 5. Dependency Updates
   - Upgraded `com.github.ben-manes.caffeine:caffeine` from `3.2.1` to `3.3.0` 
in root `pom.xml`.
   - Added `caffeine` dependency to 
`server/dns-service/dnsservice-dnsjava/pom.xml`.
   
   ---
   
   ## Clean Code, KISS & DRY Compliance
   - **DRY**: Extracted static helpers `normalizeKey()`, `ttlNanos()`, 
`sanitizeBoundedTtl()`, `resolveJvmSecurityTtl()`, and `computeRecordsTtl()`.
   - **KISS**: Separated fallback defaults from max bounds to avoid 
dual-purpose ambiguity; eliminated dead constants (`CACHE_TTL_DISABLE`).
   - **Formatting & Imports**: Fully conforms to Apache James checkstyle rules 
(ordered import groups: `java.*`, `jakarta.*`, `org.*`, `com.*`).
   
   ---
   
   ## Verification & Testing
   - Built and validated with Maven 3.9.16 on JDK 25 (targeting release 21):
     ```bash
     mvn compile checkstyle:check -pl server/dns-service/dnsservice-dnsjava
     ```
   - **Results**:
     - `BUILD SUCCESS`
     - `0 Checkstyle violations`


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to