You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/05/04 05:07:58 UTC
[apisix] branch master updated: feat: patch tcp.sock.connect to use
our DNS resolver (#4114)
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 f914807 feat: patch tcp.sock.connect to use our DNS resolver (#4114)
f914807 is described below
commit f9148073aa5edc774b87cae7cb3eee5d634e3f61
Author: 罗泽轩 <sp...@gmail.com>
AuthorDate: Tue May 4 13:07:48 2021 +0800
feat: patch tcp.sock.connect to use our DNS resolver (#4114)
Co-authored-by: Alex Zhang <to...@apache.org>
---
apisix/core.lua | 1 +
apisix/core/resolver.lua | 51 ++++++++++++++++++++++++++++++++++++
apisix/core/utils.lua | 3 ++-
apisix/init.lua | 30 ++-------------------
apisix/patch.lua | 42 ++++++++++++++++++++++++++++-
apisix/plugins/traffic-split.lua | 3 +--
t/misc/patch.t | 25 ++++++++++++++++++
t/node/route-domain-with-local-dns.t | 4 +--
8 files changed, 125 insertions(+), 34 deletions(-)
diff --git a/apisix/core.lua b/apisix/core.lua
index b0c3da6..0ef6ae9 100644
--- a/apisix/core.lua
+++ b/apisix/core.lua
@@ -48,5 +48,6 @@ return {
dns_client = require("apisix.core.dns.client"),
etcd = require("apisix.core.etcd"),
tablepool = require("tablepool"),
+ resolver = require("apisix.core.resolver"),
empty_tab = {},
}
diff --git a/apisix/core/resolver.lua b/apisix/core/resolver.lua
new file mode 100644
index 0000000..d6b76cd
--- /dev/null
+++ b/apisix/core/resolver.lua
@@ -0,0 +1,51 @@
+--
+-- 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.
+--
+local json = require("apisix.core.json")
+local log = require("apisix.core.log")
+local utils = require("apisix.core.utils")
+
+
+local _M = {}
+
+
+function _M.init_resolver(args)
+ local dns_resolver = args and args["dns_resolver"]
+ utils.set_resolver(dns_resolver)
+ log.info("dns resolver ", json.delay_encode(dns_resolver, true))
+end
+
+
+function _M.parse_domain(host)
+ local ip_info, err = utils.dns_parse(host)
+ if not ip_info then
+ log.error("failed to parse domain: ", host, ", error: ",err)
+ return nil, err
+ end
+
+ log.info("parse addr: ", json.delay_encode(ip_info))
+ log.info("resolver: ", json.delay_encode(utils.get_resolver()))
+ log.info("host: ", host)
+ if ip_info.address then
+ log.info("dns resolver domain: ", host, " to ", ip_info.address)
+ return ip_info.address
+ end
+
+ return nil, "failed to parse domain"
+end
+
+
+return _M
diff --git a/apisix/core/utils.lua b/apisix/core/utils.lua
index 921df6a..1b304f7 100644
--- a/apisix/core/utils.lua
+++ b/apisix/core/utils.lua
@@ -114,9 +114,10 @@ end
_M.dns_parse = dns_parse
-function _M.set_resolver(resolvers)
+local function set_resolver(resolvers)
dns_resolvers = resolvers
end
+_M.set_resolver = set_resolver
function _M.get_resolver(resolvers)
diff --git a/apisix/init.lua b/apisix/init.lua
index 4a30b77..e090377 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -47,17 +47,9 @@ if ngx.config.subsystem == "http" then
end
local load_balancer
local local_conf
-local dns_resolver
local ver_header = "APISIX/" .. core.version.VERSION
-local function parse_args(args)
- dns_resolver = args and args["dns_resolver"]
- core.utils.set_resolver(dns_resolver)
- core.log.info("dns resolver", core.json.delay_encode(dns_resolver, true))
-end
-
-
local _M = {version = 0.4}
@@ -72,7 +64,7 @@ function _M.http_init(args)
"maxrecord=8000", "sizemcode=64",
"maxmcode=4000", "maxirconst=1000")
- parse_args(args)
+ core.resolver.init_resolver(args)
core.id.init()
local process = require("ngx.process")
@@ -156,24 +148,6 @@ function _M.http_ssl_phase()
end
-local function parse_domain(host)
- local ip_info, err = core.utils.dns_parse(host)
- if not ip_info then
- core.log.error("failed to parse domain: ", host, ", error: ",err)
- return nil, err
- end
-
- core.log.info("parse addr: ", core.json.delay_encode(ip_info))
- core.log.info("resolver: ", core.json.delay_encode(dns_resolver))
- core.log.info("host: ", host)
- if ip_info.address then
- core.log.info("dns resolver domain: ", host, " to ", ip_info.address)
- return ip_info.address
- else
- return nil, "failed to parse domain"
- end
-end
-_M.parse_domain = parse_domain
local function parse_domain_for_nodes(nodes)
@@ -182,7 +156,7 @@ local function parse_domain_for_nodes(nodes)
local host = node.host
if not ipmatcher.parse_ipv4(host) and
not ipmatcher.parse_ipv6(host) then
- local ip, err = parse_domain(host)
+ local ip, err = core.resolver.parse_domain(host)
if ip then
local new_node = core.table.clone(node)
new_node.host = ip
diff --git a/apisix/patch.lua b/apisix/patch.lua
index 6bea363..66bf17d 100644
--- a/apisix/patch.lua
+++ b/apisix/patch.lua
@@ -15,6 +15,7 @@
-- limitations under the License.
--
local require = require
+local ipmatcher = require("resty.ipmatcher")
local socket = require("socket")
local unix_socket = require("socket.unix")
local ssl = require("ssl")
@@ -45,6 +46,45 @@ local function get_local_conf()
end
+local patch_tcp_socket
+do
+ local old_tcp_sock_connect
+
+ local function new_tcp_sock_connect(sock, host, port, opts)
+ local core_str = require("apisix.core.string")
+ local resolver = require("apisix.core.resolver")
+
+ if host then
+ if core_str.has_prefix(host, "unix:") then
+ if not opts then
+ -- workaround for https://github.com/openresty/lua-nginx-module/issues/860
+ return old_tcp_sock_connect(sock, host)
+ end
+
+ elseif not ipmatcher.parse_ipv4(host) and not ipmatcher.parse_ipv6(host) then
+ local err
+ host, err = resolver.parse_domain(host)
+ if not host then
+ return nil, "failed to parse domain: " .. err
+ end
+ end
+ end
+
+ return old_tcp_sock_connect(sock, host, port, opts)
+ end
+
+
+ function patch_tcp_socket(sock)
+ if not old_tcp_sock_connect then
+ old_tcp_sock_connect = sock.connect
+ end
+
+ sock.connect = new_tcp_sock_connect
+ return sock
+ end
+end
+
+
local function flatten(args)
local buf = new_tab(#args, 0)
for i, v in ipairs(args) do
@@ -255,7 +295,7 @@ function _M.patch()
ngx_socket.tcp = function ()
local phase = get_phase()
if phase ~= "init" and phase ~= "init_worker" then
- return original_tcp()
+ return patch_tcp_socket(original_tcp())
end
return luasocket_tcp()
diff --git a/apisix/plugins/traffic-split.lua b/apisix/plugins/traffic-split.lua
index f7e75af..6b3ee5d 100644
--- a/apisix/plugins/traffic-split.lua
+++ b/apisix/plugins/traffic-split.lua
@@ -17,7 +17,6 @@
local core = require("apisix.core")
local upstream = require("apisix.upstream")
local schema_def = require("apisix.schema_def")
-local init = require("apisix.init")
local roundrobin = require("resty.roundrobin")
local ipmatcher = require("resty.ipmatcher")
local expr = require("resty.expr.v1")
@@ -130,7 +129,7 @@ local function parse_domain_for_node(node)
if not ipmatcher.parse_ipv4(node)
and not ipmatcher.parse_ipv6(node)
then
- local ip, err = init.parse_domain(node)
+ local ip, err = core.resolver.parse_domain(node)
if ip then
return ip
end
diff --git a/t/misc/patch.t b/t/misc/patch.t
index b94d5f5..1635715 100644
--- a/t/misc/patch.t
+++ b/t/misc/patch.t
@@ -126,3 +126,28 @@ end
}
--- error_log
failed to read: timeout
+
+
+
+=== TEST 4: resolve host by ourselves
+--- yaml_config
+apisix:
+ node_listen: 1984
+ enable_resolv_search_opt: true
+--- config
+ location /t {
+ content_by_lua_block {
+ local http = require("resty.http")
+ local httpc = http.new()
+ local res, err = httpc:request_uri("http://apisix")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ ngx.say(res.status)
+ }
+ }
+--- request
+GET /t
+--- response_body
+301
diff --git a/t/node/route-domain-with-local-dns.t b/t/node/route-domain-with-local-dns.t
index d79dc2e..0ab68ef 100644
--- a/t/node/route-domain-with-local-dns.t
+++ b/t/node/route-domain-with-local-dns.t
@@ -62,7 +62,7 @@ GET /t
--- response_body
passed
--- error_log eval
-qr/.*parse_args\(\): dns resolver\[.+\]/
+qr/.*init_resolver\(\): dns resolver \[.+\]/
--- no_error_log
[error]
@@ -75,7 +75,7 @@ GET /not_found
--- response_body
{"error_msg":"404 Route Not Found"}
--- error_log eval
-qr/.*parse_args\(\): dns resolver\[.+\]/
+qr/.*init_resolver\(\): dns resolver \[.+\]/
--- no_error_log
[error]