DNS Hook
The core calls the global HandleDNSQuery function in dns.script during built-in DNS queries. See the DNS Scripts guide for configuration and complete examples.
API Index
| Category | Member | Description |
|---|---|---|
| Hook | HandleDNSQuery(...) | Handle DNS queries |
Hook Interface
HandleDNSQuery(...)
function HandleDNSQuery(domain, ipv4, ipv6, fake)
return ips, ttl, err
end2
3
Handles one DNS query, returning an IP slice, TTL, or error.
Parameters
The core always passes all four parameters, and none is nil.
| Parameter | Type | Description |
|---|---|---|
domain | string | Domain to query; non-empty and lowercase |
ipv4 | boolean | Whether IPv4 address queries are allowed |
ipv6 | boolean | Whether IPv6 address queries are allowed |
fake | boolean | Whether FakeDNS is allowed for this query |
ipv4 and ipv6 are already restricted by the global queryStrategy; at least one is true. Normally, pass these three boolean parameters unchanged when querying an upstream.
Return Values
| Return value | Type | Description |
|---|---|---|
ips | []net.IP or nil | Query results; must be a slice, not a Lua array |
ttl | number or nil | TTL in seconds; when err == nil, must be an integer in the range 0 .. 4294967295 |
err | error, string, or nil | Only nil means no error |
Behavior
The core validates err, ttl, and ips in that order, stopping at the first error. When err is non-nil, the other two values are ignored. When there is no error, a valid TTL must be provided even if the IP result is empty.
To return an empty response, use return nil, 0, nil. An error belongs in the third position, for example return nil, nil, "query failed".
| Script result | Core behavior |
|---|---|
Validation succeeds and ips is non-empty | Query succeeds |
err == nil, valid TTL, but ips is nil or an empty slice | Query fails with an empty response |
| Returned error, invalid return-value type, or execution exception | Query fails |
Example
You can forward all three return values from serverObj:Query directly:
local dns = require("xray.dns")
local serverObj = dns.Servers[1]
function HandleDNSQuery(domain, ipv4, ipv6, fake)
return serverObj:Query(domain, ipv4, ipv6, fake)
end2
3
4
5
6