This document covers the IP address management system implemented by the ipmap package and its integration with the DNS resolution system via dns53.ipmapper. The IPMap provides a persistent cache mapping hostnames to IP addresses, supports reverse lookups (IP to hostname), and implements the IPMapper interface that bridges DNS queries with the transport layer.
Key responsibilities include:
IPMap and IPSet data structures.IPMapper interface.Sources: intra/protect/ipmap/ipmap.go82-134 intra/dns53/ipmapper.go44-70
The IP address management system consists of the IPMap cache, the IPMapper resolution interface, and the ipmapper implementation that bridges DNS transports with the cache.
Architecture Overview: IPMap System Components
Sources: intra/protect/ipmap/ipmap.go136-149 intra/protect/ipmap/ipmap.go82-101 intra/dns53/ipmapper.go44-49
The ipmap struct maintains three separate maps for different types of hostname-to-IP mappings, plus reverse lookup trees for IP-to-hostname resolution. It uses an internal IPMapper for performing resolutions when entries are missing or expired.
IPMap Internal Structure
| Field | Type | Purpose |
|---|---|---|
m | map[string]*IPSet | Regular hostnames (cleared on Clear()). intra/protect/ipmap/ipmap.go140 |
p | map[string]*IPSet | Protected hostnames (never cleared, immutable IPs). intra/protect/ipmap/ipmap.go141 |
ip | map[string]*IPSet | IP address entries (confirmed IP only). intra/protect/ipmap/ipmap.go142 |
rptr | x.IpTree | Reverse map: IP → hostname(s) for regular entries. intra/protect/ipmap/ipmap.go145 |
pptr | x.IpTree | Reverse map: IP → hostname(s) for protected entries. intra/protect/ipmap/ipmap.go146 |
r | *core.Volatile[IPMapper] | Reference to the current DNS resolver implementation. intra/protect/ipmap/ipmap.go148 |
Sources: intra/protect/ipmap/ipmap.go136-149
Each IPSet represents all known IP addresses for a single hostname, with tracking for confirmed IPs and failure counts.
IPSet Field Summary
| Field | Type | Purpose |
|---|---|---|
ips | []netip.Addr | All known IPs for the server (protected by mu). intra/protect/ipmap/ipmap.go155 |
typ | IPSetType | Protected, Regular, or IPAddr. intra/protect/ipmap/ipmap.go156 |
r | IPMapper | Resolver used for on-demand resolution. intra/protect/ipmap/ipmap.go158 |
seed | []string | Bootstrap IPs or IP:ports (immutable). intra/protect/ipmap/ipmap.go159 |
confirmed | atomic.Value | Last successful IP that worked. intra/protect/ipmap/ipmap.go161 |
fails | atomic.Uint32 | Consecutive failures of the confirmed IP. intra/protect/ipmap/ipmap.go162 |
Sources: intra/protect/ipmap/ipmap.go153-166
The IPSetType determines how an IPSet is managed, resolved, and cleared.
| Type | Resolved? | Cleared? | Use Case |
|---|---|---|---|
Protected | Via dnsx.System only | Never | Bootstrap DNS servers (e.g., DoH/DoT endpoints). intra/protect/ipmap/ipmap.go49 |
Regular | Yes, via default resolver | Yes | Normal hostnames (e.g., google.com). intra/protect/ipmap/ipmap.go50 |
IPAddr | No | N/A | Direct IP addresses (e.g., 8.8.8.8). intra/protect/ipmap/ipmap.go51 |
AutoType | Yes | Yes | Dynamic resolution with fallback to seeds. intra/protect/ipmap/ipmap.go52 |
Sources: intra/protect/ipmap/ipmap.go45-53
The IPMapper interface abstracts DNS resolution and serves as the bridge between the IPMap cache and the actual DNS resolver implementations. It supports both raw DNS message lookups and higher-level netip.Addr lookups.
IPMapper Interface Definition
Sources: intra/protect/ipmap/ipmap.go82-101 intra/dns53/ipmapper.go51
The ipmapper struct in intra/dns53 implements the IPMapper interface, providing the actual DNS resolution logic that populates the IPMap cache. It integrates with the central dnsx.Resolver and dnsx.Gateway.
ipmapper Architecture
| Field | Type | Purpose |
|---|---|---|
id | string | Always dnsx.IpMapper. intra/dns53/ipmapper.go45 |
r | dnsx.ResolverSelf | Reference to the central DNS resolver. intra/dns53/ipmapper.go46 |
g | dnsx.Gateway | Gateway for Application Level Gateway (ALG) IP translation. intra/dns53/ipmapper.go47 |
ba | *core.Barrier[answer, string] | Coalesces duplicate concurrent requests (10s TTL). intra/dns53/ipmapper.go48 |
Sources: intra/dns53/ipmapper.go44-49 intra/dns53/ipmapper.go28
The core.Barrier prevents duplicate concurrent DNS queries for the same hostname. Concurrent requests for the same key (hostname + UID/TID) wait for the first caller's result via the ba.Do() pattern. intra/dns53/ipmapper.go154-162
After DNS resolution, ipmapper undoes ALG (Application Level Gateway) translations by calling m.undoAlgAndOrNat64(). This ensures that fake IPs generated for DNS64 or internal mapping are translated back to real IPs before being returned or stored. intra/dns53/ipmapper.go200-202
Sources: intra/dns53/ipmapper.go111-209
The IPMap maintains two IP tree structures (rptr and pptr) that map IP addresses back to hostnames. This is used for identifying the origin of connections. These trees are implemented using x.IpTree (a thread-safe critbit trie).
Reverse Lookup Flow
ReverseGet(ip netip.Addr) checks the regular tree rptr. intra/protect/ipmap/ipmap.go126pptr. intra/protect/ipmap/ipmap.go146Sources: intra/protect/ipmap/ipmap.go136-149 intra/backend/core_iptree.go61-84
The IPSet tracks which IP address successfully connected, enabling intelligent selection.
ips slice. intra/dialers/ips.go135-142confirmed IP, it is cleared. intra/dialers/ips.go154-160fails exceeds the maxFailLimit (8), the confirmed IP is disconfirmed. intra/protect/ipmap/ipmap.go41Sources: intra/dialers/ips.go131-165 intra/protect/ipmap/ipmap.go153-166
The dialers package provides high-level functions that utilize the IPMap system for network operations. It manages the global ipm instance and provides wrappers for resolution.
| Function | Purpose |
|---|---|
For(hostOrIP) | Returns addresses for hostOrIP from cache, resolving them if missing. intra/dialers/ips.go87-93 |
Ptr(ip) | Returns hostnames from the ipmap cache, given an IP address. intra/dialers/ips.go96-98 |
Confirmed(hostOrIP) | Returns the netip.Addr confirmed to be working for the host. intra/dialers/ips.go100-105 |
Clear() | Removes all IPSets from the map (excluding protected entries). intra/dialers/ips.go123-128 |
The dialers package uses renew to re-seed or refresh IP addresses for a host. It handles logic for protected hosts (which never resolve) and fallback to seed addresses when a resolution attempt returns an empty set.
Dialing Strategy: Code Entity Flow
Sources: intra/dialers/ips.go35-82 intra/protect/ipmap/ipmap.go103-124
Refresh this wiki