Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
7 changes: 0 additions & 7 deletions apisix/balancer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ local set_more_tries = balancer.set_more_tries
local get_last_failure = balancer.get_last_failure
local set_timeouts = balancer.set_timeouts
local ngx_now = ngx.now
local str_byte = string.byte

local module_name = "balancer"
local pickers = {}
Expand Down Expand Up @@ -195,12 +194,6 @@ end
local function pick_server(route, ctx)
local up_conf = ctx.upstream_conf

for _, node in ipairs(up_conf.nodes) do
if core.utils.parse_ipv6(node.host) and str_byte(node.host, 1) ~= str_byte("[") then
node.host = '[' .. node.host .. ']'
end
end

local nodes_count = #up_conf.nodes
if nodes_count == 1 then
local node = up_conf.nodes[1]
Expand Down
17 changes: 15 additions & 2 deletions apisix/upstream.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ local tostring = tostring
local ipairs = ipairs
local pairs = pairs
local pcall = pcall
local str_byte = string.byte
local ngx_var = ngx.var
local is_http = ngx.config.subsystem == "http"
local upstreams
Expand Down Expand Up @@ -325,10 +326,16 @@ function _M.upstreams()
end


function _M.check_schema(conf)
local function check_schema(conf)
for _, node in ipairs(conf.nodes or {}) do
if core.utils.parse_ipv6(node.host) and str_byte(node.host, 1) ~= str_byte("[") then
return false, "IPv6 address must be enclosed with '[' and ']'"
end
end
return core.schema.check(core.schema.upstream, conf)
end

_M.check_schema = check_schema

local function get_chash_key_schema(hash_on)
if not hash_on then
Expand Down Expand Up @@ -357,7 +364,7 @@ end

local function check_upstream_conf(in_dp, conf)
if not in_dp then
local ok, err = core.schema.check(core.schema.upstream, conf)
local ok, err = check_schema(conf)
if not ok then
return false, "invalid configuration: " .. err
end
Expand Down Expand Up @@ -396,6 +403,12 @@ local function check_upstream_conf(in_dp, conf)
.. "wrong ssl type"
end
end
else
for _, node in ipairs(conf.nodes or {}) do
if core.utils.parse_ipv6(node.host) and str_byte(node.host, 1) ~= str_byte("[") then
node = "[" .. node.host .. "]"
end
end
end

if is_http then
Expand Down
30 changes: 30 additions & 0 deletions t/admin/upstream.t
Original file line number Diff line number Diff line change
Expand Up @@ -722,3 +722,33 @@ GET /t
GET /t
--- response_body
passed



=== TEST 23: verify wrong Ipv6
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local t = require("lib.test_admin")

local data = {
nodes = {
{host = "::1", port = 80, weight = 1},
},
type = "roundrobin"
}
local code, body = t.test('/apisix/admin/upstreams',
ngx.HTTP_POST,
core.json.encode(data)
)

ngx.status = code
ngx.print(body)
}
}
--- request
GET /t
--- error_code: 400
--- response_body
{"error_msg":"invalid configuration: IPv6 address must be enclosed with '[' and ']'"}
66 changes: 66 additions & 0 deletions t/core/schema_def.t
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,69 @@ passed
}
--- response_body
passed



=== TEST 5: validate IPv6 address format in upstream nodes
--- config
location /t {
content_by_lua_block {
local schema_def = require("apisix.schema_def")
local core = require("apisix.core")
local upstream = require("apisix.upstream")
local t = require("lib.test_admin")
-- Test valid IPv6 addresses (enclosed in brackets)
local valid_cases = {
{
nodes = {
{host = "[::1]", port = 80, weight = 1},
},
type = "roundrobin"
},
{
nodes = {
{host = "[2001:db8::1]", port = 80, weight = 1},
},
type = "roundrobin"
}
}

for _, ups in ipairs(valid_cases) do
local ok, err = upstream.check_schema(ups)
if not ok then
ngx.log(ngx.ERR, "Expected valid case failed: ", err)
end
assert(ok, "Valid IPv6 case should pass: " .. (err or ""))
end

-- Test invalid IPv6 addresses (not enclosed in brackets)
local invalid_cases = {
{
nodes = {
{host = "::1", port = 80, weight = 1},
},
type = "roundrobin"
},
{
nodes = {
{host = "2001:db8::1", port = 80, weight = 1},
},
type = "roundrobin"
}
}

for i, ups in ipairs(invalid_cases) do
local ok, err = upstream.check_schema(ups)
if ok then
ngx.log(ngx.ERR, "Expected invalid case passed: ", i)
end
assert(not ok, "Invalid IPv6 case should fail")
assert(string.find(err, "IPv6 address must be enclosed with '%[' and '%]'"),
"Error should mention IPv6 enclosure requirement")
end

ngx.say("passed")
}
}
--- response_body
passed
Loading