Support per-remap geo DB handles in header_rewrite#13042
Support per-remap geo DB handles in header_rewrite#13042cmcfarlen wants to merge 1 commit intoapache:masterfrom
Conversation
Replace the single global geo DB handle with a cache of handles keyed by path, allowing different remap rules to use different MMDB files via --geo-db-path. The handle is threaded through RulesConfig -> Resources -> ConditionGeo::get_geo_*() methods. The cache deduplicates when multiple rules share the same path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> (cherry picked from commit 8713ad4)
There was a problem hiding this comment.
Pull request overview
This PR updates the header_rewrite plugin’s Geo condition plumbing to support per-remap Geo DB “handles” (selected via --geo-db-path), enabling different remap rule instances to use different MaxMind DB files while deduplicating handles for identical paths.
Changes:
- Thread a
geo_handlepointer fromRulesConfig→Resources→ConditionGeo::get_geo_*()calls. - Replace the single MaxMind global DB with a path-keyed cache of opened DB handles.
- Update GeoIP and MaxMind condition implementations to use the passed handle instead of global state.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| plugins/header_rewrite/resources.h | Adds Resources::geo_handle to carry a per-instance Geo handle through request evaluation. |
| plugins/header_rewrite/header_rewrite.cc | Initializes a Geo handle per global/remap instance and attaches it to Resources during execution. |
| plugins/header_rewrite/conditions.h | Updates ConditionGeo virtual API to accept a geo_handle parameter. |
| plugins/header_rewrite/conditions.cc | Passes res.geo_handle into Geo lookups during evaluation and value appends. |
| plugins/header_rewrite/conditions_geo.h | Updates Geo backends’ initLibrary and lookup signatures to accept/return a handle. |
| plugins/header_rewrite/conditions_geo_maxmind.cc | Implements a path-keyed cache of MaxMind DB handles and uses per-handle schema + MMDB state. |
| plugins/header_rewrite/conditions_geo_geoip.cc | Introduces a singleton handle set for GeoIP DB objects and routes lookups through the handle. |
Comments suppressed due to low confidence (1)
plugins/header_rewrite/header_rewrite.cc:92
- RulesConfig now owns a per-instance geo_handle, but there is no participation in the handle cache lifetime (no release/decrement in ~RulesConfig / TSRemapDeleteInstance). If the MaxMind cache is updated to close handles when unused, RulesConfig should release its handle so handles don’t become permanently pinned after remap rule reloads.
RulesConfig(int timezone, int inboundIpSource, void *geo_handle = nullptr)
: _timezone(timezone), _inboundIpSource(inboundIpSource), _geo_handle(geo_handle)
{
Dbg(dbg_ctl, "RulesConfig CTOR");
_cont = TSContCreate(cont_rewrite_headers, nullptr);
TSContDataSet(_cont, static_cast<void *>(this));
}
~RulesConfig()
{
Dbg(dbg_ctl, "RulesConfig DTOR");
TSContDestroy(_cont);
}
| struct MmdbHandle { | ||
| MMDB_s db; | ||
| MmdbSchema schema = MmdbSchema::NESTED; | ||
| }; | ||
|
|
||
| static std::map<std::string, MmdbHandle *> gMmdbCache; | ||
| static std::mutex gMmdbCacheMutex; | ||
|
|
There was a problem hiding this comment.
The new MaxMind handle cache stores heap-allocated MmdbHandle instances (and their MMDB_s mmaps) for the lifetime of the process, but there is no corresponding MMDB_close()/delete path. This can lead to unbounded growth in mapped memory / open files if remap instances are recreated over time with different --geo-db-path values. Consider adding reference counting and cleanup (e.g., close+erase when the last RulesConfig using a path is deleted), or a bounded/evicting cache with explicit teardown on shutdown/reload.
zwoop
left a comment
There was a problem hiding this comment.
I think Copilot's comment is a red herring mostly, the use cases it fears are just not likely to happen.
Replace the single global geo DB handle with a cache of handles keyed by path, allowing different remap rules to use different MMDB files via --geo-db-path. The handle is threaded through RulesConfig -> Resources -> ConditionGeo::get_geo_*() methods. The cache deduplicates when multiple rules share the same path.