lua-resty-dns-server
OpenResty 的 Lua DNS 服务器驱动
$ opm get selboo/lua-resty-dns-server
名称
[!构建状态](https://travis-ci.org/vislee/lua-resty-dns-server)
lua-resty-dns-server - OpenResty 的 Lua DNS 服务器驱动
状态
该库仍处于早期开发阶段,并且仍然是实验性的。
描述
该 Lua 库为 ngx_lua nginx 模块提供了一个 DNS 服务器驱动
https://github.com/openresty/stream-lua-nginx-module/#readme
概要
lua_package_path "/path/to/lua-resty-dns-server/lib/?.lua;;";
stream {
server {
listen 53 udp;
content_by_lua_block {
local server = require 'resty.dns.server'
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
return ngx.exit(ngx.ERROR)
end
local req, err = sock:receive()
if not req then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(req)
if not request then
ngx.log(ngx.ERR, "failed to decode request: ", err)
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
ngx.exit(ngx.ERROR)
end
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "subnet addr: ", subnet.address, " mask: ", subnet.mask, " family: ", subnet.family)
end
local cname = "sinacloud.com"
if query.qtype == server.TYPE_CNAME or
query.qtype == server.TYPE_AAAA or query.qtype == server.TYPE_A then
local err = dns:create_cname_answer(query.qname, 600, cname)
if err then
ngx.log(ngx.ERR, "failed to create cname answer: ", err)
return
end
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
}
}
server {
listen 53;
content_by_lua_block {
local bit = require 'bit'
local lshift = bit.lshift
local rshift = bit.rshift
local band = bit.band
local byte = string.byte
local char = string.char
local server = require 'resty.dns.server'
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
return ngx.exit(ngx.ERROR)
end
local buf, err = sock:receive(2)
if not buf then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local len_hi = byte(buf, 1)
local len_lo = byte(buf, 2)
local len = lshift(len_hi, 8) + len_lo
local data, err = sock:receive(len)
if not data then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(data)
if not request then
ngx.log(ngx.ERR, "failed to decode dns request: ", err)
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "subnet addr: ", subnet.address, " mask: ", subnet.mask, " family: ", subnet.family)
end
if query.qtype == server.TYPE_CNAME or query.qtype == server.TYPE_A then
dns:create_cname_answer(query.qname, 600, "sinacloud.com")
elseif query.qtype == server.TYPE_AAAA then
local resp_header, err = dns:create_response_header(server.RCODE_NOT_IMPLEMENTED)
resp_header.ra = 0
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local len = #resp
local len_hi = char(rshift(len, 8))
local len_lo = char(band(len, 0xff))
local ok, err = sock:send({len_hi, len_lo, resp})
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
return
}
}
}
方法
new
语法: s, err = class:new()
创建一个 dns.server 对象。在出错时返回 nil 和一个消息字符串。
decode_request
语法: request, err = s:decode_request(buf)
解析 DNS 请求。
返回的请求是 lua 表格,它包含以下字段
header:header也是一个 lua 表格,它通常包含以下字段
名称 ====
[](https://travis-ci.org/vislee/lua-resty-dns-server)
lua-resty-dns-server - OpenResty 的 Lua DNS 服务器驱动
目录 =================
* [名称](#name) * [状态](#status) * [描述](#description) * [概要](#synopsis) * [方法](#methods) * [new](#new) * [decode_request](#decode_request) * [create_a_answer](#create_a_answer) * [create_aaaa_answer](#create_aaaa_answer) * [create_cname_answer](#create_cname_answer) * [create_txt_answer](#create_txt_answer) * [create_ns_answer](#create_ns_answer) * [create_soa_answer](#create_soa_answer) * [create_mx_answer](#create_mx_answer) * [create_srv_answer](#create_srv_answer) * [create_response_header](#create_response_header) * [encode_response](#encode_response) * [常量](#constants) * [TYPE_A](#type_a) * [TYPE_NS](#type_ns) * [TYPE_CNAME](#type_cname) * [TYPE_SOA](#type_soa) * [TYPE_MX](#type_mx) * [TYPE_TXT](#type_txt) * [TYPE_AAAA](#type_aaaa) * [TYPE_SRV](#type_srv) * [TYPE_ANY](#type_any) * [RCODE_NOT_IMPLEMENTED](#rcode_not_implemented) * [待办事项](#todo) * [作者](#author) * [版权和许可](#copyright-and-license) * [另请参阅](#see-also)
状态 ======
该库仍处于早期开发阶段,并且仍然是实验性的。
描述 ===========
该 Lua 库为 ngx_lua nginx 模块提供了一个 DNS 服务器驱动
https://github.com/openresty/stream-lua-nginx-module/#readme
概要 ========
```nginx lua_package_path "/path/to/lua-resty-dns-server/lib/?.lua;;";
stream { server { listen 53 udp; content_by_lua_block { local server = require 'resty.dns.server' local sock, err = ngx.req.socket() if not sock then ngx.log(ngx.ERR, "failed to get the request socket: ", err) return ngx.exit(ngx.ERROR) end
local req, err = sock:receive()
if not req then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(req)
if not request then
ngx.log(ngx.ERR, "failed to decode request: ", err)
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
ngx.exit(ngx.ERROR)
end
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "subnet addr: ", subnet.address, " mask: ", subnet.mask, " family: ", subnet.family)
end
local cname = "sinacloud.com"
if query.qtype == server.TYPE_CNAME or
query.qtype == server.TYPE_AAAA or query.qtype == server.TYPE_A then
local err = dns:create_cname_answer(query.qname, 600, cname)
if err then
ngx.log(ngx.ERR, "failed to create cname answer: ", err)
return
end
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
}
}
server {
listen 53;
content_by_lua_block {
local bit = require 'bit'
local lshift = bit.lshift
local rshift = bit.rshift
local band = bit.band
local byte = string.byte
local char = string.char
local server = require 'resty.dns.server'
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
return ngx.exit(ngx.ERROR)
end
local buf, err = sock:receive(2)
if not buf then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local len_hi = byte(buf, 1)
local len_lo = byte(buf, 2)
local len = lshift(len_hi, 8) + len_lo
local data, err = sock:receive(len)
if not data then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(data)
if not request then
ngx.log(ngx.ERR, "failed to decode dns request: ", err)
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "subnet addr: ", subnet.address, " mask: ", subnet.mask, " family: ", subnet.family)
end
if query.qtype == server.TYPE_CNAME or query.qtype == server.TYPE_A then
dns:create_cname_answer(query.qname, 600, "sinacloud.com")
elseif query.qtype == server.TYPE_AAAA then
local resp_header, err = dns:create_response_header(server.RCODE_NOT_IMPLEMENTED)
resp_header.ra = 0
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local len = #resp
local len_hi = char(rshift(len, 8))
local len_lo = char(band(len, 0xff))
local ok, err = sock:send({len_hi, len_lo, resp})
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
return
}
}
}
```
[返回目录](#table-of-contents)
方法 =======
[返回目录](#table-of-contents)
new --- `语法: s, err = class:new()`
创建一个 dns.server 对象。在出错时返回 `nil` 和一个消息字符串。
[返回目录](#table-of-contents)
decode_request -------------- `语法: request, err = s:decode_request(buf)`
解析 DNS 请求。
返回的请求是 lua 表格,它包含以下字段
* `header`: `header` 也是一个 lua 表格,它通常包含以下字段
* `id` : The identifier assigned by the program that generates any kind of query.
* `qr` : The field specifies whether this message is a query (`0`), or a response (`1`).
* `opcode` : The field specifies kind of query in this message.
* `tc` : The field specifies that this message was truncated due to length greater than that permitted on the transmission channel.
* `rd` : Recursion Desired. If `RD` is set, it directs the name server to pursue the query recursively.
* `rcode` : response code.
* `qdcount` : The field specifying the number of entries in the question section.
* `questions` : `questions` 中的每个条目也是一个 lua 表格,它包含以下内容
* `qname` : A domain name of query.
* `qtype` : Specifies the type of the query.
* `qclass` : Specifies the class of the query. Usually the field is `IN` for the Internet.
[返回目录](#table-of-contents)
create_a_answer -------------- `语法: err = s:create_a_answer(name, ttl, ipv4)`
创建 A 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `ipv4`
The IPv4 address.
[返回目录](#table-of-contents)
create_aaaa_answer --------------- `语法: err = s:create_aaaa_answer(name, ttl, ipv6)`
创建 AAAA 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `ipv6`
The IPv6 address.
[返回目录](#table-of-contents)
create_cname_answer ------------------- `语法: err = s:create_cname_answer(name, ttl, cname)`
创建 CNAME 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `cname`
The name for an alias.
[返回目录](#table-of-contents)
create_txt_answer ------------------ `语法: err = s:create_txt_answer(name, ttl, txt)`
创建 txt 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `txt`
The text strings.
[返回目录](#table-of-contents)
create_ns_answer ---------------- `语法: err = s:create_ns_answer(name, ttl, nsdname)`
创建 NS 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `nsdname`
The specifies a host which should be authoritative for the specified class and domain.
[返回目录](#table-of-contents)
create_soa_answer ----------------- `语法: err = s:create_soa_answer(name, ttl, mname, rname, serial, refresh, retry, expire, minimum)`
创建 SOA 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `mname`
The the name server that was the original or primary source of data for this zone.
* `rname`
The mailbox of the person responsible for this zone.
* `serial`
The unsigned 32 bit version number of the original copy of the zone.
* `refresh`
A 32 bit time interval before the zone should be refreshed.
* `retry`
A 32 bit time interval that should elapse before a failed refresh should be retried.
* `expire`
A 32 bit time value that specifies the upper limit on the time interval that can elapse before the zone is no longer authoritative.
* `minimum`
The unsigned 32 bit minimum TTL field that should be exported with any RR from this zone.
[返回目录](#table-of-contents)
create_mx_answer ---------------- `语法: err = s:create_mx_answer(name, ttl, preference, exchange)`
创建 MX 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `preference`
The preference of this mail exchange.
* `exchange`
The mail exchange.
[返回目录](#table-of-contents)
create_srv_answer ----------------- `语法: err = s:create_srv_answer(name, ttl, priority, weight, port, target)`
创建 SRV 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `priority`
The priority of this target host.
* `weight`
The weight field specifies a relative weight for entries with the same priority.
* `port`
The port on this target host of this service.
* `target`
The domain name of the target host.
[返回目录](#table-of-contents)
create_response_header ----------------- `语法: resp_header, err = s:create_response_header(rcode)`
[返回目录](#table-of-contents)
encode_response --------------- `语法: resp = s:encode_response()`
对 DNS 回答进行编码。在响应时返回消息字符串或 `nil`。
[返回目录](#table-of-contents)
常量 =========
[返回目录](#table-of-contents)
TYPE_A ------
`A` 资源记录类型,等于十进制数 `1`。
[返回目录](#table-of-contents)
TYPE_NS -------
`NS` 资源记录类型,等于十进制数 `2`。
[返回目录](#table-of-contents)
TYPE_CNAME ----------
`CNAME` 资源记录类型,等于十进制数 `5`。
[返回目录](#table-of-contents)
TYPE_SOA ----------
`SOA` 资源记录类型,等于十进制数 `6`。
[返回目录](#table-of-contents)
TYPE_MX -------
`MX` 资源记录类型,等于十进制数 `15`。
[返回目录](#table-of-contents)
TYPE_TXT --------
`TXT` 资源记录类型,等于十进制数 `16`。
[返回目录](#table-of-contents)
TYPE_AAAA --------- `语法: typ = s.TYPE_AAAA`
`AAAA` 资源记录类型,等于十进制数 `28`。
[返回目录](#table-of-contents)
TYPE_SRV --------- `语法: typ = s.TYPE_SRV`
`SRV` 资源记录类型,等于十进制数 `33`。
有关详细信息,请参阅 RFC 2782。
[返回目录](#table-of-contents)
TYPE_ANY --------- `语法: typ = s.TYPE_ANY`
所有资源记录类型,等于十进制数 `255`。
[返回目录](#table-of-contents)
RCODE_FORMAT_ERROR ------------------
[返回目录](#table-of-contents)
RCODE_NOT_IMPLEMENTED ---------------------
[返回目录](#table-of-contents)
待办事项 ====
[返回目录](#table-of-contents)
作者 ======
wenqiang li(vislee)
guocan xu(selboo)
[返回目录](#table-of-contents)
版权和许可 =====================
该模块在 BSD 许可下授权。
版权所有 (C) 2018-2019,vislee 所有。
保留所有权利。
在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用本软件,无论是否经过修改
* 源代码的重新分发必须保留上述版权声明、此条件列表和以下免责声明。
* 二进制形式的重新分发必须在随分发提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。
本软件按“原样”提供,版权所有者和贡献者不承担任何明示或暗示的担保,包括但不限于适销性和特定用途适用性的暗示担保。在任何情况下,版权所有者或贡献者均不对因使用本软件而造成的任何直接、间接、偶然、特殊、惩罚性或后果性损害(包括但不限于采购替代商品或服务的费用;使用、数据或利润损失;或业务中断)负责,无论是在合同、严格责任或侵权(包括疏忽或其他原因)的情况下,即使已被告知可能发生此类损害。
[返回目录](#table-of-contents)
另请参阅 ======== * stream-lua-nginx-module: https://github.com/openresty/stream-lua-nginx-module/#readme * [lua-resty-dns](https://github.com/openresty/lua-resty-dns) 库。 * 该 [ngx_stream_ipdb_module](https://github.com/vislee/ngx_stream_ipdb_module) 库可以支持区域解析。
[返回目录](#table-of-contents) id : 由生成任何类型查询的程序分配的标识符。 qr : 该字段指定此消息是查询 (0) 还是响应 (1)。 opcode : 该字段指定此消息中的查询类型。 tc : 该字段指定此消息由于长度大于传输通道允许的长度而被截断。 rd : 递归所需。如果设置了 RD,则指示名称服务器递归地执行查询。 rcode : 响应代码。 qdcount : 指定问题部分中条目数量的字段。
questions: `questions` 中的每个条目也是一个 lua 表格,它包含以下内容
名称 ====
[](https://travis-ci.org/vislee/lua-resty-dns-server)
lua-resty-dns-server - OpenResty 的 Lua DNS 服务器驱动
目录 =================
* [名称](#name) * [状态](#status) * [描述](#description) * [概要](#synopsis) * [方法](#methods) * [new](#new) * [decode_request](#decode_request) * [create_a_answer](#create_a_answer) * [create_aaaa_answer](#create_aaaa_answer) * [create_cname_answer](#create_cname_answer) * [create_txt_answer](#create_txt_answer) * [create_ns_answer](#create_ns_answer) * [create_soa_answer](#create_soa_answer) * [create_mx_answer](#create_mx_answer) * [create_srv_answer](#create_srv_answer) * [create_response_header](#create_response_header) * [encode_response](#encode_response) * [常量](#constants) * [TYPE_A](#type_a) * [TYPE_NS](#type_ns) * [TYPE_CNAME](#type_cname) * [TYPE_SOA](#type_soa) * [TYPE_MX](#type_mx) * [TYPE_TXT](#type_txt) * [TYPE_AAAA](#type_aaaa) * [TYPE_SRV](#type_srv) * [TYPE_ANY](#type_any) * [RCODE_NOT_IMPLEMENTED](#rcode_not_implemented) * [待办事项](#todo) * [作者](#author) * [版权和许可](#copyright-and-license) * [另请参阅](#see-also)
状态 ======
该库仍处于早期开发阶段,并且仍然是实验性的。
描述 ===========
该 Lua 库为 ngx_lua nginx 模块提供了一个 DNS 服务器驱动
https://github.com/openresty/stream-lua-nginx-module/#readme
概要 ========
```nginx lua_package_path "/path/to/lua-resty-dns-server/lib/?.lua;;";
stream { server { listen 53 udp; content_by_lua_block { local server = require 'resty.dns.server' local sock, err = ngx.req.socket() if not sock then ngx.log(ngx.ERR, "failed to get the request socket: ", err) return ngx.exit(ngx.ERROR) end
local req, err = sock:receive()
if not req then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(req)
if not request then
ngx.log(ngx.ERR, "failed to decode request: ", err)
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
ngx.exit(ngx.ERROR)
end
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "subnet addr: ", subnet.address, " mask: ", subnet.mask, " family: ", subnet.family)
end
local cname = "sinacloud.com"
if query.qtype == server.TYPE_CNAME or
query.qtype == server.TYPE_AAAA or query.qtype == server.TYPE_A then
local err = dns:create_cname_answer(query.qname, 600, cname)
if err then
ngx.log(ngx.ERR, "failed to create cname answer: ", err)
return
end
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local ok, err = sock:send(resp)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
}
}
server {
listen 53;
content_by_lua_block {
local bit = require 'bit'
local lshift = bit.lshift
local rshift = bit.rshift
local band = bit.band
local byte = string.byte
local char = string.char
local server = require 'resty.dns.server'
local sock, err = ngx.req.socket()
if not sock then
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
return ngx.exit(ngx.ERROR)
end
local buf, err = sock:receive(2)
if not buf then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local len_hi = byte(buf, 1)
local len_lo = byte(buf, 2)
local len = lshift(len_hi, 8) + len_lo
local data, err = sock:receive(len)
if not data then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local dns = server:new()
local request, err = dns:decode_request(data)
if not request then
ngx.log(ngx.ERR, "failed to decode dns request: ", err)
return
end
local query = request.questions[1]
ngx.log(ngx.DEBUG, "qname: ", query.qname, " qtype: ", query.qtype)
local subnet = request.subnet[1]
if subnet then
ngx.log(ngx.DEBUG, "subnet addr: ", subnet.address, " mask: ", subnet.mask, " family: ", subnet.family)
end
if query.qtype == server.TYPE_CNAME or query.qtype == server.TYPE_A then
dns:create_cname_answer(query.qname, 600, "sinacloud.com")
elseif query.qtype == server.TYPE_AAAA then
local resp_header, err = dns:create_response_header(server.RCODE_NOT_IMPLEMENTED)
resp_header.ra = 0
else
dns:create_soa_answer("test.com", 600, "a.root-test.com", "vislee.test.com", 1515161223, 1800, 900, 604800, 86400)
end
local resp = dns:encode_response()
local len = #resp
local len_hi = char(rshift(len, 8))
local len_lo = char(band(len, 0xff))
local ok, err = sock:send({len_hi, len_lo, resp})
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
return
}
}
}
```
[返回目录](#table-of-contents)
方法 =======
[返回目录](#table-of-contents)
new --- `语法: s, err = class:new()`
创建一个 dns.server 对象。在出错时返回 `nil` 和一个消息字符串。
[返回目录](#table-of-contents)
decode_request -------------- `语法: request, err = s:decode_request(buf)`
解析 DNS 请求。
返回的请求是 lua 表格,它包含以下字段
* `header`: `header` 也是一个 lua 表格,它通常包含以下字段
* `id` : The identifier assigned by the program that generates any kind of query.
* `qr` : The field specifies whether this message is a query (`0`), or a response (`1`).
* `opcode` : The field specifies kind of query in this message.
* `tc` : The field specifies that this message was truncated due to length greater than that permitted on the transmission channel.
* `rd` : Recursion Desired. If `RD` is set, it directs the name server to pursue the query recursively.
* `rcode` : response code.
* `qdcount` : The field specifying the number of entries in the question section.
* `questions` : `questions` 中的每个条目也是一个 lua 表格,它包含以下内容
* `qname` : A domain name of query.
* `qtype` : Specifies the type of the query.
* `qclass` : Specifies the class of the query. Usually the field is `IN` for the Internet.
[返回目录](#table-of-contents)
create_a_answer -------------- `语法: err = s:create_a_answer(name, ttl, ipv4)`
创建 A 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `ipv4`
The IPv4 address.
[返回目录](#table-of-contents)
create_aaaa_answer --------------- `语法: err = s:create_aaaa_answer(name, ttl, ipv6)`
创建 AAAA 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `ipv6`
The IPv6 address.
[返回目录](#table-of-contents)
create_cname_answer ------------------- `语法: err = s:create_cname_answer(name, ttl, cname)`
创建 CNAME 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `cname`
The name for an alias.
[返回目录](#table-of-contents)
create_txt_answer ------------------ `语法: err = s:create_txt_answer(name, ttl, txt)`
创建 txt 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `txt`
The text strings.
[返回目录](#table-of-contents)
create_ns_answer ---------------- `语法: err = s:create_ns_answer(name, ttl, nsdname)`
创建 NS 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `nsdname`
The specifies a host which should be authoritative for the specified class and domain.
[返回目录](#table-of-contents)
create_soa_answer ----------------- `语法: err = s:create_soa_answer(name, ttl, mname, rname, serial, refresh, retry, expire, minimum)`
创建 SOA 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `mname`
The the name server that was the original or primary source of data for this zone.
* `rname`
The mailbox of the person responsible for this zone.
* `serial`
The unsigned 32 bit version number of the original copy of the zone.
* `refresh`
A 32 bit time interval before the zone should be refreshed.
* `retry`
A 32 bit time interval that should elapse before a failed refresh should be retried.
* `expire`
A 32 bit time value that specifies the upper limit on the time interval that can elapse before the zone is no longer authoritative.
* `minimum`
The unsigned 32 bit minimum TTL field that should be exported with any RR from this zone.
[返回目录](#table-of-contents)
create_mx_answer ---------------- `语法: err = s:create_mx_answer(name, ttl, preference, exchange)`
创建 MX 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `preference`
The preference of this mail exchange.
* `exchange`
The mail exchange.
[返回目录](#table-of-contents)
create_srv_answer ----------------- `语法: err = s:create_srv_answer(name, ttl, priority, weight, port, target)`
创建 SRV 记录。在出错时返回 `nil` 或一个消息字符串。它通常包含以下字段
* `name`
The resource record name.
* `ttl`
The time-to-live (TTL) value in seconds for the current resource record.
* `priority`
The priority of this target host.
* `weight`
The weight field specifies a relative weight for entries with the same priority.
* `port`
The port on this target host of this service.
* `target`
The domain name of the target host.
[返回目录](#table-of-contents)
create_response_header ----------------- `语法: resp_header, err = s:create_response_header(rcode)`
[返回目录](#table-of-contents)
encode_response --------------- `语法: resp = s:encode_response()`
对 DNS 回答进行编码。在响应时返回消息字符串或 `nil`。
[返回目录](#table-of-contents)
常量 =========
[返回目录](#table-of-contents)
TYPE_A ------
`A` 资源记录类型,等于十进制数 `1`。
[返回目录](#table-of-contents)
TYPE_NS -------
`NS` 资源记录类型,等于十进制数 `2`。
[返回目录](#table-of-contents)
TYPE_CNAME ----------
`CNAME` 资源记录类型,等于十进制数 `5`。
[返回目录](#table-of-contents)
TYPE_SOA ----------
`SOA` 资源记录类型,等于十进制数 `6`。
[返回目录](#table-of-contents)
TYPE_MX -------
`MX` 资源记录类型,等于十进制数 `15`。
[返回目录](#table-of-contents)
TYPE_TXT --------
`TXT` 资源记录类型,等于十进制数 `16`。
[返回目录](#table-of-contents)
TYPE_AAAA --------- `语法: typ = s.TYPE_AAAA`
`AAAA` 资源记录类型,等于十进制数 `28`。
[返回目录](#table-of-contents)
TYPE_SRV --------- `语法: typ = s.TYPE_SRV`
`SRV` 资源记录类型,等于十进制数 `33`。
有关详细信息,请参阅 RFC 2782。
[返回目录](#table-of-contents)
TYPE_ANY --------- `语法: typ = s.TYPE_ANY`
所有资源记录类型,等于十进制数 `255`。
[返回目录](#table-of-contents)
RCODE_FORMAT_ERROR ------------------
[返回目录](#table-of-contents)
RCODE_NOT_IMPLEMENTED ---------------------
[返回目录](#table-of-contents)
待办事项 ====
[返回目录](#table-of-contents)
作者 ======
wenqiang li(vislee)
guocan xu(selboo)
[返回目录](#table-of-contents)
版权和许可 =====================
该模块在 BSD 许可下授权。
版权所有 (C) 2018-2019,vislee 所有。
保留所有权利。
在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用本软件,无论是否经过修改
* 源代码的重新分发必须保留上述版权声明、此条件列表和以下免责声明。
* 二进制形式的重新分发必须在随分发提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。
本软件按“原样”提供,版权所有者和贡献者不承担任何明示或暗示的担保,包括但不限于适销性和特定用途适用性的暗示担保。在任何情况下,版权所有者或贡献者均不对因使用本软件而造成的任何直接、间接、偶然、特殊、惩罚性或后果性损害(包括但不限于采购替代商品或服务的费用;使用、数据或利润损失;或业务中断)负责,无论是在合同、严格责任或侵权(包括疏忽或其他原因)的情况下,即使已被告知可能发生此类损害。
[返回目录](#table-of-contents)
另请参阅 ======== * stream-lua-nginx-module: https://github.com/openresty/stream-lua-nginx-module/#readme * [lua-resty-dns](https://github.com/openresty/lua-resty-dns) 库。 * 该 [ngx_stream_ipdb_module](https://github.com/vislee/ngx_stream_ipdb_module) 库可以支持区域解析。
[返回目录](#table-of-contents) qname : 查询的域名。 qtype : 指定查询的类型。 qclass : 指定查询的类别。通常,该字段是互联网的 IN。
create_a_answer
语法: err = s:create_a_answer(name, ttl, ipv4)
创建 A 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
ipv4IPv4 地址。
create_aaaa_answer
语法: err = s:create_aaaa_answer(name, ttl, ipv6)
创建 AAAA 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
ipv6IPv6 地址。
create_cname_answer
语法: err = s:create_cname_answer(name, ttl, cname)
创建 CNAME 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
cname别名的名称。
create_txt_answer
语法: err = s:create_txt_answer(name, ttl, txt)
创建 txt 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
txt文本字符串。
create_ns_answer
语法: err = s:create_ns_answer(name, ttl, nsdname)
创建 NS 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
nsdname指定对指定类别和域具有权威性的主机。
create_soa_answer
语法: err = s:create_soa_answer(name, ttl, mname, rname, serial, refresh, retry, expire, minimum)
创建 SOA 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
mname作为此区域数据的原始或主要来源的名称服务器。
rname负责此区域的人员的邮箱。
serial区域原始副本的无符号 32 位版本号。
refresh区域应刷新之前的 32 位时间间隔。
retry刷新失败后应经过的 32 位时间间隔,之后应重试刷新。
expire指定区域不再具有权威性的时间间隔的上限的 32 位时间值。
minimum应从此区域导出任何 RR 的无符号 32 位最小 TTL 字段。
create_mx_answer
语法: err = s:create_mx_answer(name, ttl, preference, exchange)
创建 MX 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
preference此邮件交换的首选权重。
exchange邮件交换。
create_srv_answer
语法: err = s:create_srv_answer(name, ttl, priority, weight, port, target)
创建 SRV 记录。在出错时返回 nil 或一个消息字符串。它通常包含以下字段
name资源记录名称。
ttl当前资源记录的生存时间 (TTL) 值(以秒为单位)。
priority此目标主机的优先级。
weight权重字段指定具有相同优先级的条目的相对权重。
port此服务的目标主机上的端口。
target目标主机的域名。
create_response_header
语法: resp_header, err = s:create_response_header(rcode)
encode_response
语法: resp = s:encode_response()
对 DNS 回答进行编码。在响应时返回消息字符串或 nil。
常量
TYPE_A
`A` 资源记录类型,等于十进制数 1。
TYPE_NS
NS 资源记录类型,等于十进制数字 2。
TYPE_CNAME
CNAME 资源记录类型,等于十进制数字 5。
TYPE_SOA
SOA 资源记录类型,等于十进制数字 6。
TYPE_MX
MX 资源记录类型,等于十进制数字 15。
TYPE_TXT
TXT 资源记录类型,等于十进制数字 16。
TYPE_AAAA
语法: typ = s.TYPE_AAAA
AAAA 资源记录类型,等于十进制数字 28。
TYPE_SRV
语法: typ = s.TYPE_SRV
SRV 资源记录类型,等于十进制数字 33。
有关详细信息,请参阅 RFC 2782。
TYPE_ANY
语法: typ = s.TYPE_ANY
所有资源记录类型,等于十进制数字 255。
RCODE_FORMAT_ERROR
RCODE_NOT_IMPLEMENTED
待办事项
作者
wenqiang li(vislee)
guocan xu(selboo)
版权和许可
该模块在 BSD 许可下授权。
版权所有 (C) 2018-2019,vislee 所有。
保留所有权利。
在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用本软件,无论是否经过修改
源代码的再分发必须保留上述版权声明、此条件列表和以下免责声明。
二进制形式的再分发必须在随发行提供的文档和/或其他材料中复制上述版权声明、此条件列表和以下免责声明。
本软件按“原样”提供,版权所有者和贡献者不承担任何明示或暗示的担保,包括但不限于适销性和特定用途适用性的暗示担保。在任何情况下,版权所有者或贡献者均不对因使用本软件而造成的任何直接、间接、偶然、特殊、惩罚性或后果性损害(包括但不限于采购替代商品或服务的费用;使用、数据或利润损失;或业务中断)负责,无论是在合同、严格责任或侵权(包括疏忽或其他原因)的情况下,即使已被告知可能发生此类损害。
另请参见
stream-lua-nginx-module: https://github.com/openresty/stream-lua-nginx-module/#readme
此 ngx_stream_ipdb_module 库可以支持区域解析。
作者
selboo
许可证
2bsd
版本
-
OpenResty 的 Lua DNS 服务器驱动程序 2020-07-21 07:38:45