Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Table of Contents
* [TYPE_TXT](#type_txt)
* [TYPE_AAAA](#type_aaaa)
* [TYPE_SRV](#type_srv)
* [TYPE_NAPTR](#type_naptr)
* [TYPE_SPF](#type_spf)
* [CLASS_IN](#class_in)
* [SECTION_AN](#section_an)
Expand Down Expand Up @@ -375,6 +376,16 @@ See RFC 2782 for details.

[Back to TOC](#table-of-contents)

TYPE_NAPTR
----------
`syntax: typ = r.TYPE_NAPTR`

The `NAPTR` resource record type, equal to the decimal number `35`.

See RFC 2915 for details.

[Back to TOC](#table-of-contents)

TYPE_SPF
---------
`syntax: typ = r.TYPE_SPF`
Expand Down
61 changes: 61 additions & 0 deletions lib/resty/dns/resolver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ local TYPE_MX = 15
local TYPE_TXT = 16
local TYPE_AAAA = 28
local TYPE_SRV = 33
local TYPE_NAPTR = 35
local TYPE_SPF = 99

local CLASS_IN = 1
Expand All @@ -65,6 +66,7 @@ local _M = {
TYPE_TXT = TYPE_TXT,
TYPE_AAAA = TYPE_AAAA,
TYPE_SRV = TYPE_SRV,
TYPE_NAPTR = TYPE_NAPTR,
TYPE_SPF = TYPE_SPF,
CLASS_IN = CLASS_IN,
SECTION_AN = SECTION_AN,
Expand Down Expand Up @@ -208,6 +210,21 @@ local function _encode_name(s)
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: we need 2 blank lines to separate function definitions.


local function _decode_string(buf, pos)
local slen = byte(buf, pos)

if slen == 0 then
return "", pos + 1
end

if pos + 1 + slen > #buf then
return nil, 'truncated'
end

return sub(buf, pos + 1, pos + slen), pos + slen + 1
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.


local function _decode_name(buf, pos)
local labels = {}
local nptrs = 0
Expand Down Expand Up @@ -481,6 +498,50 @@ local function parse_section(answers, section, buf, start_pos, size,

pos = p

elseif typ == TYPE_NAPTR then
if len < 7 then
return nil, "bad NAPTR record value length: " .. len
end

local order_hi = byte(buf, pos)
local order_lo = byte(buf, pos + 1)
ans.order = lshift(order_hi, 8) + order_lo

local preference_hi = byte(buf, pos + 2)
local preference_lo = byte(buf, pos + 3)
ans.preference = lshift(preference_hi, 8) + preference_lo

local flags_str, p = _decode_string(buf, pos + 4)
if not flags_str then
return nil, pos
end
ans.flags = flags_str

local services_str, p = _decode_string(buf, p)
if not services_str then
return nil, pos
end
ans.services = services_str

local regexp_str, p = _decode_string(buf, p)
if not regexp_str then
return nil, pos
end
ans.regexp = regexp_str

local replacements_str,p = _decode_name(buf, p)
if not replacements_str then
return nil, pos
end
ans.replacements = replacements_str

if p - pos ~= len then
return nil, format("bad NAPTR record length: %d ~= %d",
p - pos, len)
end

pos = p

elseif typ == TYPE_NS then

local name, p = _decode_name(buf, pos)
Expand Down
19 changes: 18 additions & 1 deletion t/TestDNS.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use constant {
TYPE_CNAME => 5,
TYPE_AAAA => 28,
TYPE_SRV => 33,
TYPE_NAPTR => 35,
CLASS_INTERNET => 1,
};

Expand Down Expand Up @@ -261,6 +262,11 @@ sub encode_name ($) {
return $name;
}

sub encode_str ($) {
my $str = shift;
return chr(length($str)) . $str;
}

sub encode_record ($) {
my $ans = shift;
my $name = $ans->{name};
Expand Down Expand Up @@ -304,7 +310,6 @@ sub encode_record ($) {
$class //= CLASS_INTERNET;
}


my $srv = $ans->{srv};
if (defined $srv) {
$rddata //= pack("nnn", $ans->{priority}, $ans->{weight}, $ans->{port}) . encode_name($srv);
Expand All @@ -313,6 +318,18 @@ sub encode_record ($) {
$class //= CLASS_INTERNET;
}

my $services = $ans->{services};
if (defined $services) {
$rddata //= pack("nn", $ans->{order}, $ans->{preference})
. encode_str($ans->{flags})
. encode_str($ans->{services})
. encode_str($ans->{regexp})
. encode_name($ans->{replacements});
$rdlength //= length $rddata;
$type //= TYPE_NAPTR;
$class //= CLASS_INTERNET;
}

$type //= 0;
$class //= 0;
$ttl //= 0;
Expand Down
51 changes: 51 additions & 0 deletions t/mock.t
Original file line number Diff line number Diff line change
Expand Up @@ -1721,3 +1721,54 @@ GET /t
records: [{"address":"127.0.0.1","section":1,"type":1,"class":1,"name":"www.google.com","ttl":123456}]
--- no_error_log
[error]


=== TEST 35: NAPTR
--- http_config eval: $::HttpConfig
--- config
location /t {
content_by_lua '
local resolver = require "resty.dns.resolver"

local r, err = resolver:new{
nameservers = { {"127.0.0.1", 1953} }
}
if not r then
ngx.say("failed to instantiate resolver: ", err)
return
end

r._id = 125

local ans, err = r:query("5.4.3.2.1.e164.arpa", { qtype = r.TYPE_NAPTR })
if not ans then
ngx.say("failed to query: ", err)
return
end

local cjson = require "cjson"
ngx.say("records: ", cjson.encode(ans))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qtype => 35, # NAPTR
qname => '5.4.3.2.1.e164.arpa',
answer => [
{ name => "5.4.3.2.1.e164.arpa", ttl => 2, order => 10, preference => 100,
flags => "u",
services => "E2U+sip",
regexp => "!^\\+123456(.*)\$!sip:\\1\@example.org!",
replacements => ""
}
],
}
--- request
GET /t
--- response_body
records: [{"order":10,"preference":100,"class":1,"regexp":"!^\\+123456(.*)$!sip:\\[email protected]!","replacements":"","section":1,"flags":"u","type":35,"ttl":2,"name":"5.4.3.2.1.e164.arpa","services":"E2U+sip"}]
--- no_error_log
[error]