xray.dns
Provides interfaces for DNS queries and upstream server access.
local dns = require("xray.dns")API Index
| Category | Member | Description |
|---|---|---|
| Function | dns.Query(domain, ipv4, ipv6, fake) | Query through Xray's DNS client |
| Field | dns.Servers | Upstream server array |
| Object | serverObj | A single DNS upstream server |
| Field | serverObj.ID | Server identifier |
| Method | serverObj:Query(domain, ipv4, ipv6, fake) | Query a specific upstream directly |
Functions
dns.Query
local ips, ttl, err = dns.Query(domain, ipv4, ipv6, fake)Queries a domain through Xray's DNS client. Unavailable in the DNS Hook, because the script takes over that very query flow.
Parameters
| Parameter | Type | Description |
|---|---|---|
domain | string | Domain to query |
ipv4 | boolean | Whether IPv4 queries are allowed |
ipv6 | boolean | Whether IPv6 queries are allowed |
fake | boolean | Whether FakeDNS is allowed |
Return Values
| Return value | Type | Description |
|---|---|---|
ips | []net.IP or nil | Query results |
ttl | number | TTL in seconds, in the range 0 .. 4294967295; never nil |
err | error or nil | Query error; nil means no error |
Behavior
All four parameters must be passed explicitly with the correct types; otherwise a Lua exception is raised.
The query follows the client's global query-type restrictions, Hosts, and upstream configuration. If a DNS script is configured, the query is also handled by that script. System DNS is used if built-in DNS is not configured.
Returns a non-empty IP slice on success; returns nil, 0, err if the query fails or no address is available.
Example
local ips, ttl, err = dns.Query("example.com", true, true, false)
if err == nil and ips ~= nil and #ips > 0 then
local firstIP = ips[1]:String()
end2
3
4
Fields
dns.Servers
local servers = dns.Servers| Name | Type | Description |
|---|---|---|
dns.Servers | table | Array of serverObj, indexed from 1, in configuration order |
When built-in DNS is used, the list contains the configured upstreams. If DNS or upstream servers are not configured, the list contains only localhost (system DNS).
Use ipairs to iterate over the list; servers[i] is nil for an out-of-range index.
Example
for _, serverObj in ipairs(dns.Servers) do
local id = serverObj.ID
end2
3
Objects
server
serverObj represents a DNS upstream server, including its identifier and query method.
| Property | Description |
|---|---|
| Go implementation | luaDNSServer in app/dns |
| Lua representation | table |
| Obtained from | An array element of dns.Servers |
ID
local id = serverObj.ID| Name | Type | Description |
|---|---|---|
serverObj.ID | string | The id field in the DNS server configuration; never nil |
If id is omitted, it is "", including for servers configured as strings. The automatically added system DNS upstream has ID "localhost".
If you need to distinguish servers by ID, configure unique values yourself; the core does not check for duplicates.
Query
local ips, ttl, err = serverObj:Query(domain, ipv4, ipv6, fake)Queries the upstream represented by serverObj.
Parameters and Return Values
Parameter requirements and return-value types are the same as for dns.Query.
Behavior
A normally configured upstream returns a non-empty IP slice, TTL, and nil on success. If the query fails, no address meets the conditions, or FakeDNS is queried with fake == false, returns nil, 0, err.
Queries this server directly, bypassing global Hosts and the DNS script. The server's own queryStrategy, cache, timeoutMs, clientIP, tag, and expectedIPs / unexpectedIPs with their corresponding actPrior / actUnprior settings still take effect.
Example
Return the first upstream's query result directly from the DNS Hook:
function HandleDNSQuery(domain, ipv4, ipv6, fake)
return dns.Servers[1]:Query(domain, ipv4, ipv6, fake)
end2
3