This is an automated email from the ASF dual-hosted git repository. spacewander pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push: new 563b259 feat: switch resolver to lua-resty-dns-client (#3442) 563b259 is described below commit 563b259a5a632b4776e253dd6fefc9d20b88a8f9 Author: 罗泽轩 <spacewander...@gmail.com> AuthorDate: Tue Feb 2 09:07:40 2021 +0800 feat: switch resolver to lua-resty-dns-client (#3442) Signed-off-by: spacewander <spacewander...@gmail.com> --- .travis/linux_openresty_common_runner.sh | 4 +- apisix/core/utils.lua | 92 ++++++++++++++++++-------------- rockspec/apisix-master-0.rockspec | 1 + t/core/utils.t | 48 ++++++++++++++++- t/grpc-proxy-test.sh | 2 - t/node/upstream-node-dns.t | 16 +++--- t/plugin/limit-count.t | 4 +- utils/centos7-ci.sh | 1 + utils/set-dns.sh | 26 +++++++++ 9 files changed, 139 insertions(+), 55 deletions(-) diff --git a/.travis/linux_openresty_common_runner.sh b/.travis/linux_openresty_common_runner.sh index a67c1a9..fe50864 100755 --- a/.travis/linux_openresty_common_runner.sh +++ b/.travis/linux_openresty_common_runner.sh @@ -99,6 +99,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 \ @@ -129,7 +131,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 diff --git a/apisix/core/utils.lua b/apisix/core/utils.lua index 8629d97..60e3068 100644 --- a/apisix/core/utils.lua +++ b/apisix/core/utils.lua @@ -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[[ @@ -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 @@ -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 diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index ee08a4c..98c1416 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -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", diff --git a/t/core/utils.t b/t/core/utils.t index 3b2acec..42cba26 100644 --- a/t/core/utils.t +++ b/t/core/utils.t @@ -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 @@ -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 @@ -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] diff --git a/t/grpc-proxy-test.sh b/t/grpc-proxy-test.sh index 6e80d17..7ffa965 100755 --- a/t/grpc-proxy-test.sh +++ b/t/grpc-proxy-test.sh @@ -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 ' { diff --git a/t/node/upstream-node-dns.t b/t/node/upstream-node-dns.t index f660c6e..c70e60f 100644 --- a/t/node/upstream-node-dns.t +++ b/t/node/upstream-node-dns.t @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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} diff --git a/t/plugin/limit-count.t b/t/plugin/limit-count.t index 7cf8f4f..3a5f8a5 100644 --- a/t/plugin/limit-count.t +++ b/t/plugin/limit-count.t @@ -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 @@ -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 diff --git a/utils/centos7-ci.sh b/utils/centos7-ci.sh index 9e8d817..b65a5e5 100755 --- a/utils/centos7-ci.sh +++ b/utils/centos7-ci.sh @@ -72,6 +72,7 @@ run_case() { cd apisix + ./utils/set-dns.sh # run test cases prove -Itest-nginx/lib -I./ -r t/ } diff --git a/utils/set-dns.sh b/utils/set-dns.sh new file mode 100755 index 0000000..618b033 --- /dev/null +++ b/utils/set-dns.sh @@ -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