Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 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
35 changes: 29 additions & 6 deletions src/ngx_http_lua_socket_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,11 +843,13 @@ ngx_http_lua_socket_tcp_bind(lua_State *L)
u_char *text;
size_t len;
ngx_addr_t *local;
int port;

n = lua_gettop(L);

if (n != 2) {
return luaL_error(L, "expecting 2 arguments, but got %d",
// 修正参数检查,允许2或3个参数
if (n != 2 && n != 3) {
return luaL_error(L, "expecting 2 or 3 arguments, but got %d",
lua_gettop(L));
}

Expand All @@ -865,9 +867,26 @@ ngx_http_lua_socket_tcp_bind(lua_State *L)

luaL_checktype(L, 1, LUA_TTABLE);

port = 0;
/* most popular suit: host:port */
if (n == 3 && lua_isnumber(L, 3)) {

/* Hit the following parameter combination:
* sock:bind("127.0.0.1", port)
*/

port = (int) lua_tointeger(L, 3);

if (port < 0 || port > 65535) {
lua_pushnil(L);
lua_pushfstring(L, "bad port number: %d", port);
return 2;
}
}

text = (u_char *) luaL_checklstring(L, 2, &len);

local = ngx_http_lua_parse_addr(L, text, len);
local = ngx_http_lua_parse_addr_port(L, text, len, port);
if (local == NULL) {
lua_pushnil(L);
lua_pushfstring(L, "bad address");
Expand All @@ -876,7 +895,7 @@ ngx_http_lua_socket_tcp_bind(lua_State *L)

/* TODO: we may reuse the userdata here */
lua_rawseti(L, 1, SOCKET_BIND_INDEX);

ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"lua tcp socket bind ip: %V", &local->name);

Expand Down Expand Up @@ -1128,7 +1147,11 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)
dd("lua peer connection log: %p", pc->log);

lua_rawgeti(L, 1, SOCKET_BIND_INDEX);
local = lua_touserdata(L, -1);
local = lua_touserdata(L, -1);

ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"lua tcp socket sock:connect ip: %V", &local->name);

lua_pop(L, 1);

if (local) {
Expand Down Expand Up @@ -3419,7 +3442,7 @@ ngx_http_lua_socket_tcp_handler(ngx_event_t *ev)
static ngx_int_t
ngx_http_lua_socket_tcp_get_peer(ngx_peer_connection_t *pc, void *data)
{
/* empty */
pc->type = SOCK_STREAM;
return NGX_OK;
}

Expand Down
18 changes: 18 additions & 0 deletions src/ngx_http_lua_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -4555,6 +4555,24 @@ ngx_http_lua_parse_addr(lua_State *L, u_char *text, size_t len)
}


ngx_addr_t *
ngx_http_lua_parse_addr_port(lua_State *L, u_char *text, size_t len, int port)
{
ngx_addr_t *addr;

addr = ngx_http_lua_parse_addr(L, text, len);
if (addr == NULL) {
return addr;
}

if (port > 0) {
ngx_inet_set_port(addr->sockaddr, (in_port_t) port);
}

return addr;
}


void
ngx_http_lua_ffi_bypass_if_checks(ngx_http_request_t *r)
{
Expand Down
2 changes: 2 additions & 0 deletions src/ngx_http_lua_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ ngx_int_t ngx_http_lua_decode_base64mime(ngx_str_t *dst, ngx_str_t *src);

ngx_addr_t *ngx_http_lua_parse_addr(lua_State *L, u_char *text, size_t len);

ngx_addr_t *ngx_http_lua_parse_addr_port(lua_State *L, u_char *text, size_t len, int port);

size_t ngx_http_lua_escape_log(u_char *dst, u_char *src, size_t size);


Expand Down
61 changes: 61 additions & 0 deletions t/168-tcp-socket-bind.t
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,64 @@ GET /t
connected: 1
--- no_error_log
[error]


=== TEST 7: upstream sockets bind with ip port
--- config
server_tokens off;
location /t {
set $port $TEST_NGINX_SERVER_PORT;
content_by_lua_block {
local ip = "127.0.0.1"
local port = ngx.var.port

local sock = ngx.socket.tcp()

local ok, err = sock:bind(ip, 12345)
if not ok then
ngx.say("failed to bind", err)
return
end

local ok, err = sock:connect("127.0.0.1", port)
if not ok then
ngx.say("failed to connect: ", err)
return
end

local ok, err = sock:setoption("reuseaddr", 1)
if not ok then
ngx.say("setoption reuseaddr failed: ", err)
end

ngx.say("connected: ", ok)

local bytes, err = sock:send("GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: keepalive\r\n\r\n")
if not bytes then
ngx.say("failed to send request: ", err)
return
end

local reader = sock:receiveuntil("\r\n0\r\n\r\n")
local data, err = reader()

if not data then
ngx.say("failed to receive response body: ", err)
return
end
sock:close()
ngx.say(data)

}
}

location /foo {
echo bind: $remote_addr:$remote_port;
}
--- request
GET /t
--- response_body eval
qr/bind:\s127\.0\.0\.1:12345|failed\s+to\s+connect:\s+address\s+already\s+in\s+use/
--- error_log eval
"lua tcp socket bind ip: 127.0.0.1"