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/09/17 10:10:25 UTC

[apisix] branch master updated: feat(stream_route): support CIDR in ip match (#4980)

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 1a072f4  feat(stream_route): support CIDR in ip match (#4980)
1a072f4 is described below

commit 1a072f4271e74e27339823fec5817e1c2d42c719
Author: Manjusaka <me...@manjusaka.me>
AuthorDate: Fri Sep 17 18:10:17 2021 +0800

    feat(stream_route): support CIDR in ip match (#4980)
    
    Co-authored-by: spacewander <sp...@gmail.com>
---
 apisix/admin/stream_routes.lua   | 10 +++----
 apisix/stream/router/ip_port.lua | 51 ++++++++++++++++++++++++++------
 t/stream-node/sanity.t           | 64 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+), 15 deletions(-)

diff --git a/apisix/admin/stream_routes.lua b/apisix/admin/stream_routes.lua
index 241767f..de1e14d 100644
--- a/apisix/admin/stream_routes.lua
+++ b/apisix/admin/stream_routes.lua
@@ -16,7 +16,7 @@
 --
 local core = require("apisix.core")
 local utils = require("apisix.admin.utils")
-local schema_plugin = require("apisix.admin.plugins").stream_check_schema
+local stream_route_checker = require("apisix.stream.router.ip_port").stream_route_checker
 local tostring = tostring
 
 
@@ -69,11 +69,9 @@ local function check_conf(id, conf, need_id)
         end
     end
 
-    if conf.plugins then
-        local ok, err = schema_plugin(conf.plugins)
-        if not ok then
-            return nil, {error_msg = err}
-        end
+    local ok, err = stream_route_checker(conf)
+    if not ok then
+        return nil, {error_msg = err}
     end
 
     return need_id and id or true
diff --git a/apisix/stream/router/ip_port.lua b/apisix/stream/router/ip_port.lua
index 271ae73..74563f9 100644
--- a/apisix/stream/router/ip_port.lua
+++ b/apisix/stream/router/ip_port.lua
@@ -15,15 +15,15 @@
 -- limitations under the License.
 --
 local core      = require("apisix.core")
+local core_ip  = require("apisix.core.ip")
 local config_util = require("apisix.core.config_util")
-local plugin_checker = require("apisix.plugin").stream_plugin_checker
+local stream_plugin_checker = require("apisix.plugin").stream_plugin_checker
 local router_new = require("apisix.utils.router").new
 local apisix_ssl = require("apisix.ssl")
 local error     = error
 local tonumber  = tonumber
 local ipairs = ipairs
 
-
 local user_routes
 local router_ver
 local tls_router
@@ -31,16 +31,21 @@ local other_routes = {}
 local _M = {version = 0.1}
 
 
+
 local function match_addrs(route, vars)
     -- todo: use resty-ipmatcher to support multiple ip address
-    if route.value.remote_addr and
-       route.value.remote_addr ~= vars.remote_addr then
-        return false
+    if route.value.remote_addr then
+        local ok, _ = route.value.remote_addr_matcher:match(vars.remote_addr)
+        if not ok then
+            return false
+        end
     end
 
-    if route.value.server_addr and
-       route.value.server_addr ~= vars.server_addr then
-        return false
+    if route.value.server_addr then
+        local ok, _ = route.value.server_addr_matcher:match(vars.server_addr)
+        if not ok then
+            return false
+        end
     end
 
     -- todo: use resty-ipmatcher to support multiple ip address
@@ -71,6 +76,12 @@ do
             end
 
             local route = item.value
+            if item.value.remote_addr then
+                item.value.remote_addr_matcher = core_ip.create_ip_matcher({item.value.remote_addr})
+            end
+            if item.value.server_addr then
+                item.value.server_addr_matcher = core_ip.create_ip_matcher({item.value.server_addr})
+            end
             if not route.sni then
                 other_routes[other_routes_idx] = item
                 other_routes_idx = other_routes_idx + 1
@@ -176,13 +187,35 @@ function _M.routes()
     return user_routes.values, user_routes.conf_version
 end
 
+local function stream_route_checker(item)
+    if item.plugins then
+        local err, message = stream_plugin_checker(item)
+        if not err then
+            return err, message
+        end
+    end
+    -- validate the address format when remote_address or server_address is not nil
+    if item.remote_addr then
+        if not core_ip.validate_cidr_or_ip(item.remote_addr) then
+            return false, "invalid remote_addr: " .. item.remote_addr
+        end
+    end
+    if item.server_addr then
+        if not core_ip.validate_cidr_or_ip(item.server_addr) then
+            return false, "invalid server_addr: " .. item.server_addr
+        end
+    end
+    return true
+end
+_M.stream_route_checker = stream_route_checker
+
 
 function _M.stream_init_worker(filter)
     local err
     user_routes, err = core.config.new("/stream_routes", {
             automatic = true,
             item_schema = core.schema.stream_route,
-            checker = plugin_checker,
+            checker = stream_route_checker,
             filter = filter,
         })
 
diff --git a/t/stream-node/sanity.t b/t/stream-node/sanity.t
index 0da77ec..58ded0a 100644
--- a/t/stream-node/sanity.t
+++ b/t/stream-node/sanity.t
@@ -281,3 +281,67 @@ GET /t
 hello world
 --- no_error_log
 [error]
+
+
+
+=== TEST 11: set stream route (id: 1) which uses upstream_id and remote address with IP CIDR
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/stream_routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "remote_addr": "127.0.0.1/26",
+                    "upstream_id": "1"
+                }]]
+            )
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 12: hit route
+--- stream_enable
+--- stream_request eval
+mmm
+--- stream_response
+hello world
+--- no_error_log
+[error]
+
+
+
+=== TEST 13: reject bad CIDR
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/stream_routes/1',
+                ngx.HTTP_PUT,
+                [[{
+                    "remote_addr": ":/8",
+                    "upstream_id": "1"
+                }]]
+            )
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.print(body)
+        }
+    }
+--- request
+GET /t
+--- error_code: 400
+--- response_body
+{"error_msg":"invalid remote_addr: :\/8"}