Skip to main content

DomainResolver

DomainResolver is an advanced support node that resolves a line's destination domain before forwarding that line's upstream Init.

Normal users usually should not configure this node manually. Several higher-level nodes create and configure it internally, including TcpConnector, UdpConnector, Router, Socks5Client, VlessClient, and TrojanClient. Use the public settings on those nodes first unless you are deliberately building a custom chain that sets line->routing_context.dest_ctx yourself.

What It Does​

DomainResolver reads and updates the line destination address context:

line->routing_context.dest_ctx

If the destination is already an IP address, or has already been resolved, DomainResolver forwards Init immediately. If the destination is a domain name, it submits asynchronous DNS on the current worker, applies the configured domain strategy, writes the selected IP back into dest_ctx, then forwards the delayed Init.

It does not:

  • open sockets
  • create lines
  • transform payload bytes
  • prepend protocol data
  • resolve src_ctx

Typical Placement​

Manual placement is advanced. Put it after a node that sets dest_ctx to a domain and before a node that requires a concrete IP address.

TcpListener -> Socks5Server -> DomainResolver -> TcpConnector

In many real configs this is unnecessary because the connector/protocol node inserts its own internal resolver.

Basic Example​

{
"name": "resolve-domain",
"type": "DomainResolver",
"settings": {
"strategy": "prefer-ipv4",
"verbose": false
},
"next": "outbound"
}

Fields​

FieldTypeRequiredDescription
typestringYesMust be DomainResolver.
settingsobjectNoOptional settings object. If present, it must be an object.
nextstringUsuallyThe node that receives the line after destination resolution in the upstream direction.

DomainResolver accepts upstream Init and downstream Est. Downstream Init and upstream Est use the constructor defaults that reject unsupported callbacks. Payload, Pause/Resume, and Finish retain their ordinary bidirectional meanings.

Settings​

FieldDefaultDescription
strategycore dns.domain-strategyDNS result selection strategy. Accepts core-settings, accept-dns-returned-order, prefer-ipv4, prefer-ipv6, only-ipv4, or only-ipv6.
verbosefalseLogs DNS start messages at debug level. Resolved-address logs still use the normal DNS debug logger.

strategy can be given as a string or as the internal domain-strategy value accepted by the shared parser.

Runtime Flow​

On upstream Init:

  1. line state is initialized
  2. dest_ctx is inspected
  3. if no DNS is needed, upstream Init is forwarded to next
  4. if DNS is needed, the node enters resolving state and returns
  5. when DNS completes, the selected address is written into dest_ctx
  6. the delayed upstream Init is forwarded
  7. payloads queued during DNS are replayed upstream

Downstream payloads forward directly once next Init has started, including replies during Init itself.

Pending Payloads​

Upstream payloads are retained during DNS, adjacent Init reentry, or an older ordered backlog. Admission checks both logical bytes and retained allocation charge against 2 MiB per line before enqueue. Overflow closes only prev before next Init, or both initialized directions afterwards.

Transport Est forwards promptly once the path opens. The backlog drains in FIFO order while the consumer permits it; nested input cannot overtake older input. Pause received during DNS remains effective when the adjacent path opens.

The first retained input pauses only the initiating source, after FIFO ownership and accounting are published. This local DNS/order hold is separate from received Pause permission and does not pause DNS or the transport being initialized. It stays active through drain callbacks and is released only when the FIFO is empty and the adjacent consumer permits sending. Reentrant Pause/Resume cannot overtake older input, clear another pressure reason, or resurrect work after Finish.

Once next Init has returned, the pending FIFO is empty and local pressure notifications are settled, a normal line permanently bypasses this node. The resolver destroys and zeros its full line state first, including any embedded preparation storage. Nodes using that storage must consume or copy it during Init; it is unavailable afterward. Later callbacks go directly between the resolver's neighbors, and no later Finish reaches the resolver. Actual worker packet lines remain active.

Failure Behavior​

The line is rejected when:

  • the destination is not an IP address and not a domain
  • async DNS submission fails
  • DNS returns no usable address for the configured strategy
  • the pending payload queue exceeds its limit

DomainResolver does not retry DNS by itself. Retry behavior belongs in the higher-level node or transport design.

Node Metadata​

DomainResolver is an internal transparent support node: it keeps per-line state but neither creates nor destroys lines or changes payload bytes.

Source-backed metadata:

PropertyValue
node flagskNodeFlagSupportsSplice
can_have_prevtrue
can_have_nexttrue
layer_groupkNodeLayerAnything
layer_group_prev_nodekNodeLayerSameAsNext
layer_group_next_nodekNodeLayerSameAsPrev
required_padding_left0 bytes