Skip to content

Commit

Permalink
fix udp bind and update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alonbg committed Sep 14, 2016
1 parent a154794 commit f2a1329
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 37 deletions.
37 changes: 22 additions & 15 deletions src/ngx_stream_lua_socket_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static void ngx_stream_lua_socket_udp_read_handler(ngx_stream_session_t *s,
ngx_stream_lua_socket_udp_upstream_t *u);
static void ngx_stream_lua_socket_udp_handle_success(ngx_stream_session_t *s,
ngx_stream_lua_socket_udp_upstream_t *u);
static ngx_int_t ngx_stream_lua_udp_connect(lua_State *L,
static ngx_int_t ngx_stream_lua_udp_connect(
ngx_stream_lua_udp_connection_t *uc);
static int ngx_stream_lua_socket_udp_close(lua_State *L);
static ngx_int_t ngx_stream_lua_socket_udp_resume(ngx_stream_session_t *s,
Expand Down Expand Up @@ -224,6 +224,7 @@ ngx_stream_lua_socket_udp_setpeername(lua_State *L)
ngx_stream_lua_udp_connection_t *uc;
int timeout;
ngx_stream_lua_co_ctx_t *coctx;
ngx_addr_t *local;

ngx_stream_lua_socket_udp_upstream_t *u;

Expand Down Expand Up @@ -333,6 +334,14 @@ ngx_stream_lua_socket_udp_setpeername(lua_State *L)

dd("lua peer connection log: %p", &uc->log);

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

if (local) {
uc->local = local;
}

lua_rawgeti(L, 1, SOCKET_TIMEOUT_INDEX);
timeout = (ngx_int_t) lua_tointeger(L, -1);
lua_pop(L, 1);
Expand Down Expand Up @@ -705,7 +714,7 @@ ngx_stream_lua_socket_resolve_retval_handler(ngx_stream_session_t *s,
return 2;
}

rc = ngx_stream_lua_udp_connect(L, uc);
rc = ngx_stream_lua_udp_connect(uc);

if (rc != NGX_OK) {
u->socket_errno = ngx_socket_errno;
Expand Down Expand Up @@ -1371,7 +1380,7 @@ ngx_stream_lua_socket_udp_handle_success(ngx_stream_session_t *s,


static ngx_int_t
ngx_stream_lua_udp_connect(lua_State *L, ngx_stream_lua_udp_connection_t *uc)
ngx_stream_lua_udp_connect(ngx_stream_lua_udp_connection_t *uc)
{
int rc;
ngx_int_t event;
Expand Down Expand Up @@ -1447,19 +1456,17 @@ ngx_stream_lua_udp_connect(lua_State *L, ngx_stream_lua_udp_connection_t *uc)
}
#endif

lua_rawgeti(L, 1, SOCKET_BIND_INDEX);
local = lua_touserdata(L, -1);
lua_pop(L, 1);
local = uc->local;
if (local) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "udp socket bind");

if (local && (uc->sockaddr->sa_family == AF_INET
|| uc->sockaddr->sa_family == AF_INET6)) {
if (bind(uc->connection->fd,
local->sockaddr, local->socklen) != 0) {
ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno,
"bind(%V) failed", &local->name);
return NGX_ERROR;
}
}
if (bind(c->fd, local->sockaddr, local->socklen) != 0) {
ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno,
"bind(%V) failed", &local->name);

return NGX_ERROR;
}
}

ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &uc->log, 0,
"connect to %V, fd:%d #%d", &uc->server, s, c->number);
Expand Down
1 change: 1 addition & 0 deletions src/ngx_stream_lua_socket_udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ typedef void (*ngx_stream_lua_socket_udp_upstream_handler_pt)

typedef struct {
ngx_connection_t *connection;
ngx_addr_t *local;
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t server;
Expand Down
6 changes: 4 additions & 2 deletions t/087-udp-socket.t
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ qr/content_by_lua_block\(nginx\.conf:\d+\):7: bad session/

=== TEST 6: connect again immediately
--- stream_server_config

content_by_lua_block {
local sock = ngx.socket.udp()
local port = $TEST_NGINX_MEMCACHED_PORT
Expand All @@ -301,7 +300,7 @@ qr/content_by_lua_block\(nginx\.conf:\d+\):7: bad session/
ngx.say("connected: ", ok)

ok, err = sock:setpeername("127.0.0.1", port)
if not ok then
if not ok then
ngx.say("failed to connect: ", err)
return
end
Expand Down Expand Up @@ -520,6 +519,8 @@ lua udp socket receive buffer size: 8192
=== TEST 11: access the google DNS server (using domain names)
--- stream_server_config
lua_resolver $TEST_NGINX_RESOLVER ipv6=off;
#lua_resolver agentzh.org ipv6=off;
#lua_resolver 8.8.8.8 ipv6=off;
content_by_lua_block {
-- avoid flushing google in "check leak" testing mode:
local counter = package.loaded.counter
Expand All @@ -540,6 +541,7 @@ lua udp socket receive buffer size: 8192
udp:settimeout(2000) -- 2 sec

local ok, err = udp:setpeername("google-public-dns-a.google.com", 53)
--local ok, err = udp:setpeername("127.0.1.1", 53)
if not ok then
ngx.say("failed to connect: ", err)
return
Expand Down
64 changes: 55 additions & 9 deletions t/141-tcp-socket-bind.t
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ repeat_each(2);

plan tests => repeat_each() * (blocks() * 3 + 2);

my $local_ip = `ifconfig | grep -oE '([0-9]{1,3}\\.?){4}' | grep '\\.' | grep -v '127.0.0.1' | head -n 1`;
my $local_ip = `ifconfig | grep -oE 'addr:([0-9]{1,3}+\\.){3}[0-9]{1,3}' | sed -e 's/addr://' | grep -v '127.0.0.1' | head -n 1`;
chomp $local_ip;

my $local_domain_server = `dig something | grep -oE ' ([0-9]{1,3}+\\.){3}[0-9]{1,3}'`;
chomp $local_domain_server;
$ENV{TEST_NGINX_LOCAL_DOMAIN_SERVER} ||= $local_domain_server;
$ENV{TEST_NGINX_SERVER_IP} ||= $local_ip;
$ENV{TEST_NGINX_NOT_EXIST_IP} ||= '8.8.8.8';
$ENV{TEST_NGINX_INVALID_IP} ||= '127.0.0.1:8899';


no_long_string();
#no_diff();
#log_level 'warn';
Expand All @@ -25,7 +29,7 @@ __DATA__
=== TEST 1: upstream sockets bind 127.0.0.1
--- stream_config
server {
listen 2986;
listen 127.0.1.2:2986;
content_by_lua_block {
ngx.say(ngx.var.remote_addr)
}
Expand All @@ -42,7 +46,7 @@ server {
return
end

local ok, err = sock:connect("127.0.0.1", port)
local ok, err = sock:connect("127.0.1.2", port)
if not ok then
ngx.log(ngx.ERR, err)
return
Expand All @@ -65,7 +69,7 @@ server {
=== TEST 2: upstream sockets bind non loopback ip
--- stream_config
server {
listen 2986;
listen 127.0.1.2:2986;
content_by_lua_block {
ngx.say(ngx.var.remote_addr)
}
Expand All @@ -82,7 +86,7 @@ server {
return
end

local ok, err = sock:connect("127.0.0.1", port)
local ok, err = sock:connect("127.0.1.2", port)
if not ok then
ngx.log(ngx.ERR, err)
return
Expand All @@ -105,7 +109,7 @@ ip matched
=== TEST 3: upstream sockets bind not exist ip
--- stream_config
server {
listen 2986;
listen 127.0.1.2:2986;
content_by_lua_block {
ngx.say(ngx.var.remote_addr)
}
Expand All @@ -121,7 +125,7 @@ server {
ngx.log(ngx.INFO, err)
end

local ok, err = sock:connect("127.0.0.1", port)
local ok, err = sock:connect("127.0.1.2", port)
if not ok then
ngx.say(err)
end
Expand All @@ -139,7 +143,7 @@ cannot assign requested address
=== TEST 4: upstream sockets bind invalid ip
--- stream_config
server {
listen 2986;
listen 127.0.1.2:2986;
content_by_lua_block {
ngx.say(ngx.var.remote_addr)
}
Expand All @@ -155,7 +159,7 @@ server {
ngx.say(err)
end

local ok, err = sock:connect("127.0.0.1", port)
local ok, err = sock:connect("127.0.1.2", port)
if not ok then
ngx.log(ngx.ERR, err)
end
Expand All @@ -173,3 +177,45 @@ bad address
127.0.0.1
--- no_error_log
[error]


=== TEST 5: upstream sockets bind 127.0.0.1 and resolve peername
--- SKIP
--- stream_config
lua_resolver $TEST_NGINX_LOCAL_DOMAIN_SERVER ipv6=off;
server {
listen localhost:2986;
content_by_lua_block {
ngx.say(ngx.var.remote_addr)
}
}
--- stream_server_config
content_by_lua_block {
local ip = "127.0.0.1"
local port = 2986
local sock = ngx.socket.tcp()

local ok, err = sock:bind(ip)
if not ok then
ngx.log(ngx.ERR, err)
return
end

local ok, err = sock:connect("localhost", port)
if not ok then
ngx.log(ngx.ERR, err)
return
end

local line, err, part = sock:receive()
if line then
ngx.say(line)
else
ngx.log(ngx.ERR, err)
end
}

--- stream_response
127.0.0.1
--- no_error_log
[error]
Loading

0 comments on commit f2a1329

Please sign in to comment.