Skip to content

feature: support tcp binding ip:port or ip of ipv4 or ipv6 #2412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
36 changes: 32 additions & 4 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",
/* Correct the parameter check and allow 2 or 3 parameters */
if (n != 2 && n != 3) {
return luaL_error(L, "expecting 2 or 3 arguments, but got %d",
lua_gettop(L));
}

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

luaL_checktype(L, 1, LUA_TTABLE);

port = 0;
/* handle case: host:port */
/* Hit the following parameter combination:
* sock:bind("127.0.0.1", port) */
if (n == 3) {
if (!lua_isnumber(L, 3)) {
lua_pushnil(L);
lua_pushfstring(L, "expecting port to be a"
"number but got type: %s", luaL_typename(L, 3));
return 2;
}

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);
Expand All @@ -874,9 +896,11 @@ ngx_http_lua_socket_tcp_bind(lua_State *L)
return 2;
}

if (port > 0) {
ngx_inet_set_port(local->sockaddr, (in_port_t) port);
}
/* 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 @@ -1129,6 +1153,10 @@ ngx_http_lua_socket_tcp_connect(lua_State *L)

lua_rawgeti(L, 1, SOCKET_BIND_INDEX);
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 +3447,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
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"