From 6c62619e9e73b50ffd6aaa198477ca5ffe2a3fcf Mon Sep 17 00:00:00 2001 From: ytlm Date: Mon, 1 Jul 2024 15:54:38 +0800 Subject: [PATCH] feature: stream balancer support bind_to_local_addr --- .travis.yml | 2 +- lib/ngx/balancer.lua | 53 ++++++------- t/stream/balancer-bind-localaddr.t | 118 +++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 29 deletions(-) create mode 100644 t/stream/balancer-bind-localaddr.t diff --git a/.travis.yml b/.travis.yml index ada732b5f..5f0911d01 100644 --- a/.travis.yml +++ b/.travis.yml @@ -107,7 +107,7 @@ script: - if [ "$OPENSSL_VER" = "1.1.0l" ] || [ "$answer" = "N" ]; then add_http3_module=""; fi - if [ "$answer" = "N" ] || [ "$USE_PCRE2" = "Y" ]; then disable_pcre2=""; fi - if [ "$USE_PCRE2" = "Y" ]; then PCRE_INC=$PCRE2_INC; PCRE_LIB=$PCRE2_LIB; fi - - ngx-build $NGINX_VERSION --with-ipv6 $disable_pcre2 $add_http3_module --with-http_v2_module --with-http_realip_module --with-http_ssl_module --with-pcre-jit --with-cc-opt="-I$OPENSSL_INC -I$PCRE_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB -L$PCRE_LIB -Wl,-rpath,$PCRE_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../set-misc-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug --with-stream_ssl_module --with-stream --with-ipv6 --add-module=../stream-lua-nginx-module > build.log 2>&1 || (cat build.log && exit 1) + - ngx-build $NGINX_VERSION $disable_pcre2 $add_http3_module --with-http_v2_module --with-http_realip_module --with-http_ssl_module --with-pcre-jit --with-cc-opt="-I$OPENSSL_INC -I$PCRE_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB -L$PCRE_LIB -Wl,-rpath,$PCRE_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../set-misc-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug --with-stream_ssl_module --with-stream --with-ipv6 --add-module=../stream-lua-nginx-module > build.log 2>&1 || (cat build.log && exit 1) - nginx -V - ldd `which nginx`|grep -E 'luajit|ssl|pcre' - prove -I. -Itest-nginx/lib -j$JOBS -r t diff --git a/lib/ngx/balancer.lua b/lib/ngx/balancer.lua index 5bf48a46c..909de491c 100644 --- a/lib/ngx/balancer.lua +++ b/lib/ngx/balancer.lua @@ -93,6 +93,9 @@ elseif subsystem == 'stream' then int ngx_stream_lua_ffi_balancer_set_timeouts(ngx_stream_lua_request_t *r, long connect_timeout, long timeout, char **err); + + int ngx_stream_lua_ffi_balancer_bind_to_local_addr(ngx_stream_lua_request_t *r, + const unsigned char *addr, size_t addr_len, char **err); ]] ngx_lua_ffi_balancer_set_current_peer = @@ -115,6 +118,9 @@ elseif subsystem == 'stream' then timeout, err) end + ngx_lua_ffi_balancer_bind_to_local_addr = + C.ngx_stream_lua_ffi_balancer_bind_to_local_addr + else error("unknown subsystem: " .. subsystem) end @@ -362,38 +368,29 @@ if subsystem == 'http' then end end -if subsystem == "http" then - function _M.bind_to_local_addr(addr) - local r = get_request() - if not r then - error("no request found") - end - - if type(addr) ~= "string" then - error("bad argument #1 to 'bind_to_local_addr' " - .. "(string expected, got " .. type(addr) .. ")") - end - - local errbuf_size = 1024 - local errbuf = get_string_buf(errbuf_size) - local sizep = get_size_ptr() - sizep[0] = errbuf_size - local rc = ngx_lua_ffi_balancer_bind_to_local_addr(r, addr, #addr, - errbuf, - sizep) - if rc == FFI_OK then - return true - end +function _M.bind_to_local_addr(addr) + local r = get_request() + if not r then + error("no request found") + end - return nil, ffi_str(errbuf, sizep[0]) + if type(addr) ~= "string" then + error("bad argument #1 to 'bind_to_local_addr' " + .. "(string expected, got " .. type(addr) .. ")") end -else - function _M.bind_to_local_addr(addr) - error("'bind_to_local_addr' not yet implemented in " .. subsystem .. - " subsystem", 2) + local errbuf_size = 1024 + local errbuf = get_string_buf(errbuf_size) + local sizep = get_size_ptr() + sizep[0] = errbuf_size + local rc = ngx_lua_ffi_balancer_bind_to_local_addr(r, addr, #addr, + errbuf, + sizep) + if rc == FFI_OK then + return true end -end + return nil, ffi_str(errbuf, sizep[0]) +end return _M diff --git a/t/stream/balancer-bind-localaddr.t b/t/stream/balancer-bind-localaddr.t new file mode 100644 index 000000000..809434d6f --- /dev/null +++ b/t/stream/balancer-bind-localaddr.t @@ -0,0 +1,118 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib '.'; +use t::TestCore::Stream; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 4); + +$ENV{TEST_NGINX_LUA_PACKAGE_PATH} = "$t::TestCore::Stream::lua_package_path"; + +no_long_string(); +run_tests(); + +__DATA__ + +=== TEST 1: balancer +--- stream_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH"; + + upstream backend { + server 0.0.0.1:1234 down; + balancer_by_lua_block { + local b = require "ngx.balancer" + assert(b.set_current_peer("127.0.0.1", 12345)) + } + } + + server { + listen 127.0.0.1:12345; + content_by_lua_block { + ngx.print(ngx.var.remote_addr, ":", ngx.var.remote_port) + } + } +--- stream_server_config + proxy_pass backend; + +--- request + GET /t +--- response_body eval +[ +qr/127.0.0.1/, +] +--- error_code: 200 +--- no_error_log +[error] +[warn] + + + +=== TEST 2: balancer with bind_to_local_addr(addr) +--- stream_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH"; + + upstream backend { + server 0.0.0.1:1234 down; + balancer_by_lua_block { + local b = require "ngx.balancer" + assert(b.set_current_peer("127.0.0.1", 12345)) + + assert(b.bind_to_local_addr("127.0.0.4")) + } + } + + server { + listen 127.0.0.1:12345; + content_by_lua_block { + ngx.print(ngx.var.remote_addr, ":", ngx.var.remote_port) + } + } +--- stream_server_config + proxy_pass backend; + +--- request + GET /t +--- response_body eval +[ +qr/127.0.0.4/, +] +--- error_code: 200 +--- no_error_log +[error] +[warn] + + + +=== TEST 3: balancer with bind_to_local_addr(addr and port) +--- stream_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH"; + + upstream backend { + server 0.0.0.1:1234 down; + balancer_by_lua_block { + local b = require "ngx.balancer" + assert(b.set_current_peer("127.0.0.1", 12345)) + + assert(b.bind_to_local_addr("127.0.0.8:23456")) + } + } + + server { + listen 127.0.0.1:12345; + content_by_lua_block { + ngx.print(ngx.var.remote_addr, ":", ngx.var.remote_port) + } + } +--- stream_server_config + proxy_pass backend; + +--- request + GET /t +--- response_body eval +[ +qr/127.0.0.8/, +] +--- error_code: 200 +--- no_error_log +[error] +[warn]