Skip to content

Commit

Permalink
feat: switch resolver to lua-resty-dns-client
Browse files Browse the repository at this point in the history
Signed-off-by: spacewander <spacewanderlzx@gmail.com>
  • Loading branch information
spacewander committed Jan 29, 2021
1 parent b32cec7 commit a6e4248
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 56 deletions.
4 changes: 3 additions & 1 deletion .travis/linux_openresty_common_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ script() {
export_or_prefix
openresty -V

./utils/set-dns.sh

./build-cache/grpc_server_example \
-grpc-address :50051 -grpcs-address :50052 \
-crt ./t/certs/apisix.crt -key ./t/certs/apisix.key \
Expand Down Expand Up @@ -128,7 +130,7 @@ script() {
sleep 1
cat logs/error.log

sudo sh ./t/grpc-proxy-test.sh
sh ./t/grpc-proxy-test.sh
sleep 1

./bin/apisix stop
Expand Down
92 changes: 52 additions & 40 deletions apisix/core/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,33 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local core_str = require("apisix.core.string")
local table = require("apisix.core.table")
local log = require("apisix.core.log")
local string = require("apisix.core.string")
local ngx_re = require("ngx.re")
local resolver = require("resty.dns.resolver")
local ipmatcher= require("resty.ipmatcher")
local ffi = require("ffi")
local base = require("resty.core.base")
local open = io.open
local math = math
local sub_str = string.sub
local str_byte = string.byte
local tonumber = tonumber
local tostring = tostring
local re_gsub = ngx.re.gsub
local type = type
local io_popen = io.popen
local C = ffi.C
local ffi_string = ffi.string
local core_str = require("apisix.core.string")
local table = require("apisix.core.table")
local log = require("apisix.core.log")
local string = require("apisix.core.string")
local ngx_re = require("ngx.re")
local dns_client = require("resty.dns.client")
local ipmatcher = require("resty.ipmatcher")
local ffi = require("ffi")
local base = require("resty.core.base")
local open = io.open
local math = math
local sub_str = string.sub
local str_byte = string.byte
local tonumber = tonumber
local tostring = tostring
local re_gsub = ngx.re.gsub
local type = type
local io_popen = io.popen
local C = ffi.C
local ffi_string = ffi.string
local get_string_buf = base.get_string_buf
local exiting = ngx.worker.exiting
local ngx_sleep = ngx.sleep
local exiting = ngx.worker.exiting
local ngx_sleep = ngx.sleep

local hostname
local dns_resolvers
local current_inited_resolvers
local max_sleep_interval = 1

ffi.cdef[[
Expand Down Expand Up @@ -80,19 +82,26 @@ function _M.split_uri(uri)
end


local function dns_parse(domain, resolvers)
resolvers = resolvers or _M.resolvers
local r, err = resolver:new{
nameservers = table.clone(resolvers),
retrans = 5, -- 5 retransmissions on receive timeout
timeout = 2000, -- 2 sec
}
local function dns_parse(domain)
if dns_resolvers ~= current_inited_resolvers then
local opts = {
ipv6 = true,
nameservers = table.clone(dns_resolvers),
retrans = 5, -- 5 retransmissions on receive timeout
timeout = 2000, -- 2 sec
}
local ok, err = dns_client.init(opts)
if not ok then
return nil, "failed to init the dns client: " .. err
end

if not r then
return nil, "failed to instantiate the resolver: " .. err
current_inited_resolvers = dns_resolvers
end

local answers, err = r:query(domain, nil, {})
log.info("dns resolve ", domain)

-- this function will dereference the CNAME records
local answers, err = dns_client.resolve(domain)
if not answers then
return nil, "failed to query the DNS server: " .. err
end
Expand All @@ -104,21 +113,24 @@ local function dns_parse(domain, resolvers)

local idx = math.random(1, #answers)
local answer = answers[idx]
if answer.type == 1 then
return answer
end

if answer.type ~= 5 then
return nil, "unsupport DNS answer"
local dns_type = answer.type
-- TODO: support AAAA & SRV
if dns_type == dns_client.TYPE_A then
return table.deepcopy(answer)
end

return dns_parse(answer.cname, resolvers)
return nil, "unsupport DNS answer"
end
_M.dns_parse = dns_parse


function _M.set_resolver(resolvers)
_M.resolvers = resolvers
dns_resolvers = resolvers
end


function _M.get_resolver(resolvers)
return dns_resolvers
end


Expand Down
1 change: 1 addition & 0 deletions rockspec/apisix-master-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ description = {

dependencies = {
"lua-resty-ctxdump = 0.1-0",
"lua-resty-dns-client = 5.2.0",
"lua-resty-template = 1.9",
"lua-resty-etcd = 1.4.3",
"lua-resty-balancer = 0.02rc5",
Expand Down
48 changes: 46 additions & 2 deletions t/core/utils.t
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ GET /t
local core = require("apisix.core")
local resolvers = {"8.8.8.8"}
core.utils.set_resolver(resolvers)
local ip_info, err = core.utils.dns_parse("github.com", resolvers)
local ip_info, err = core.utils.dns_parse("github.com")
if not ip_info then
core.log.error("failed to parse domain: ", host, ", error: ",err)
end
Expand All @@ -104,7 +104,7 @@ qr/"address":.+,"name":"github.com"/
core.log.error("failed to parse domain: ", host, ", error: ",err)
end
core.log.info("ip_info: ", require("toolkit.json").encode(ip_info))
ngx.say("resolvers: ", require("toolkit.json").encode(core.utils.resolvers))
ngx.say("resolvers: ", require("toolkit.json").encode(core.utils.get_resolver()))
}
}
--- request
Expand Down Expand Up @@ -245,3 +245,47 @@ res:John and \$me
res:John_David
res:JohnDavid
res:JohnDavid



=== TEST 7: resolve host from /etc/hosts
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local ip_info, err = core.utils.dns_parse("test.com")
if not ip_info then
core.log.error("failed to parse domain: ", host, ", error: ",err)
return
end
ngx.say("ip_info: ", require("toolkit.json").encode(ip_info))
}
}
--- request
GET /t
--- response_body
ip_info: {"address":"127.0.0.1","class":1,"name":"test.com","ttl":315360000,"type":1}
--- no_error_log
[error]



=== TEST 8: search host with '.org' suffix
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local ip_info, err = core.utils.dns_parse("apisix")
if not ip_info then
core.log.error("failed to parse domain: ", host, ", error: ",err)
return
end
ngx.say("ip_info: ", require("toolkit.json").encode(ip_info))
}
}
--- request
GET /t
--- response_body_like
.+"name":"apisix\.apache\.org".+
--- no_error_log
[error]
2 changes: 0 additions & 2 deletions t/grpc-proxy-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

set -ex

echo "127.0.0.1 test.com" | sudo tee -a /etc/hosts

#set ssl
curl http://127.0.0.1:9080/apisix/admin/ssl/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
Expand Down
16 changes: 8 additions & 8 deletions t/node/upstream-node-dns.t
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ passed
apisix.http_init()
local utils = require("apisix.core.utils")
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
if domain == "test.com" then
return {address = "127.0.0.2"}
end
Expand All @@ -104,7 +104,7 @@ hello world
local utils = require("apisix.core.utils")
local count = 0
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
if domain == "test.com" then
Expand Down Expand Up @@ -192,7 +192,7 @@ passed
apisix.http_init()
local utils = require("apisix.core.utils")
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
if domain == "test.com" or domain == "test2.com" then
return {address = "127.0.0.2"}
end
Expand All @@ -217,7 +217,7 @@ hello world
local utils = require("apisix.core.utils")
local count = 0
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
if domain == "test.com" or domain == "test2.com" then
Expand Down Expand Up @@ -345,7 +345,7 @@ passed
local utils = require("apisix.core.utils")
local count = 0
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
if domain == "test.com" then
Expand Down Expand Up @@ -432,7 +432,7 @@ passed
local utils = require("apisix.core.utils")
local count = 0
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
if domain == "test.com" or domain == "test2.com" then
Expand Down Expand Up @@ -501,7 +501,7 @@ proxy request to 127.0.0.[56]:1980
local utils = require("apisix.core.utils")
local count = 1
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
if domain == "test.com" or domain == "test2.com" then
return {address = "127.0.0.1"}
end
Expand Down Expand Up @@ -600,7 +600,7 @@ passed
local utils = require("apisix.core.utils")
local count = 0
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
count = count + 1
if domain == "test.com" or domain == "test2.com" then
return {address = "127.0.0." .. count}
Expand Down
4 changes: 2 additions & 2 deletions t/plugin/limit-count.t
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ passed
apisix.http_init()

local utils = require("apisix.core.utils")
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
if domain == "test.com" then
return {address = "127.0.0.1"}
end
Expand Down Expand Up @@ -1310,7 +1310,7 @@ passed
apisix.http_init()

local utils = require("apisix.core.utils")
utils.dns_parse = function (domain, resolvers) -- mock: DNS parser
utils.dns_parse = function (domain) -- mock: DNS parser
if domain == "test.com" then
return {address = "127.0.0.1"}
end
Expand Down
3 changes: 2 additions & 1 deletion utils/centos7-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ install_dependencies() {

# install development tools
yum install -y wget tar gcc automake autoconf libtool make \
curl git which
curl git which sudo

# install epel and luarocks
wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
Expand Down Expand Up @@ -70,6 +70,7 @@ run_case() {
export PATH=/usr/local/openresty-debug/nginx/sbin:/usr/local/openresty-debug/bin:$PATH
cd apisix

./utils/set-dns.sh
# run test cases
prove -Itest-nginx/lib -I./ -r t/
}
Expand Down
26 changes: 26 additions & 0 deletions utils/set-dns.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

set -ex

echo "127.0.0.1 test.com" | sudo tee -a /etc/hosts
cat /etc/hosts # check GitHub Action's configuration

echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
echo "search apache.org" | sudo tee -a /etc/resolv.conf

0 comments on commit a6e4248

Please sign in to comment.