Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: switch resolver to lua-resty-dns-client #3442

Merged
merged 1 commit into from
Feb 2, 2021
Merged
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
4 changes: 3 additions & 1 deletion .travis/linux_openresty_common_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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
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
1 change: 1 addition & 0 deletions utils/centos7-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ run_case() {

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