Skip to content

Commit f2a1329

Browse files
author
alonbg
committed
fix udp bind and update tests
1 parent a154794 commit f2a1329

5 files changed

+183
-37
lines changed

src/ngx_stream_lua_socket_udp.c

+22-15
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static void ngx_stream_lua_socket_udp_read_handler(ngx_stream_session_t *s,
5555
ngx_stream_lua_socket_udp_upstream_t *u);
5656
static void ngx_stream_lua_socket_udp_handle_success(ngx_stream_session_t *s,
5757
ngx_stream_lua_socket_udp_upstream_t *u);
58-
static ngx_int_t ngx_stream_lua_udp_connect(lua_State *L,
58+
static ngx_int_t ngx_stream_lua_udp_connect(
5959
ngx_stream_lua_udp_connection_t *uc);
6060
static int ngx_stream_lua_socket_udp_close(lua_State *L);
6161
static ngx_int_t ngx_stream_lua_socket_udp_resume(ngx_stream_session_t *s,
@@ -224,6 +224,7 @@ ngx_stream_lua_socket_udp_setpeername(lua_State *L)
224224
ngx_stream_lua_udp_connection_t *uc;
225225
int timeout;
226226
ngx_stream_lua_co_ctx_t *coctx;
227+
ngx_addr_t *local;
227228

228229
ngx_stream_lua_socket_udp_upstream_t *u;
229230

@@ -333,6 +334,14 @@ ngx_stream_lua_socket_udp_setpeername(lua_State *L)
333334

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

337+
lua_rawgeti(L, 1, SOCKET_BIND_INDEX);
338+
local = lua_touserdata(L, -1);
339+
lua_pop(L, 1);
340+
341+
if (local) {
342+
uc->local = local;
343+
}
344+
336345
lua_rawgeti(L, 1, SOCKET_TIMEOUT_INDEX);
337346
timeout = (ngx_int_t) lua_tointeger(L, -1);
338347
lua_pop(L, 1);
@@ -705,7 +714,7 @@ ngx_stream_lua_socket_resolve_retval_handler(ngx_stream_session_t *s,
705714
return 2;
706715
}
707716

708-
rc = ngx_stream_lua_udp_connect(L, uc);
717+
rc = ngx_stream_lua_udp_connect(uc);
709718

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

13721381

13731382
static ngx_int_t
1374-
ngx_stream_lua_udp_connect(lua_State *L, ngx_stream_lua_udp_connection_t *uc)
1383+
ngx_stream_lua_udp_connect(ngx_stream_lua_udp_connection_t *uc)
13751384
{
13761385
int rc;
13771386
ngx_int_t event;
@@ -1447,19 +1456,17 @@ ngx_stream_lua_udp_connect(lua_State *L, ngx_stream_lua_udp_connection_t *uc)
14471456
}
14481457
#endif
14491458

1450-
lua_rawgeti(L, 1, SOCKET_BIND_INDEX);
1451-
local = lua_touserdata(L, -1);
1452-
lua_pop(L, 1);
1459+
local = uc->local;
1460+
if (local) {
1461+
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "udp socket bind");
14531462

1454-
if (local && (uc->sockaddr->sa_family == AF_INET
1455-
|| uc->sockaddr->sa_family == AF_INET6)) {
1456-
if (bind(uc->connection->fd,
1457-
local->sockaddr, local->socklen) != 0) {
1458-
ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno,
1459-
"bind(%V) failed", &local->name);
1460-
return NGX_ERROR;
1461-
}
1462-
}
1463+
if (bind(c->fd, local->sockaddr, local->socklen) != 0) {
1464+
ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno,
1465+
"bind(%V) failed", &local->name);
1466+
1467+
return NGX_ERROR;
1468+
}
1469+
}
14631470

14641471
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &uc->log, 0,
14651472
"connect to %V, fd:%d #%d", &uc->server, s, c->number);

src/ngx_stream_lua_socket_udp.h

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef void (*ngx_stream_lua_socket_udp_upstream_handler_pt)
2626

2727
typedef struct {
2828
ngx_connection_t *connection;
29+
ngx_addr_t *local;
2930
struct sockaddr *sockaddr;
3031
socklen_t socklen;
3132
ngx_str_t server;

t/087-udp-socket.t

+4-2
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ qr/content_by_lua_block\(nginx\.conf:\d+\):7: bad session/
287287

288288
=== TEST 6: connect again immediately
289289
--- stream_server_config
290-
291290
content_by_lua_block {
292291
local sock = ngx.socket.udp()
293292
local port = $TEST_NGINX_MEMCACHED_PORT
@@ -301,7 +300,7 @@ qr/content_by_lua_block\(nginx\.conf:\d+\):7: bad session/
301300
ngx.say("connected: ", ok)
302301

303302
ok, err = sock:setpeername("127.0.0.1", port)
304-
if not ok then
303+
if not ok then
305304
ngx.say("failed to connect: ", err)
306305
return
307306
end
@@ -520,6 +519,8 @@ lua udp socket receive buffer size: 8192
520519
=== TEST 11: access the google DNS server (using domain names)
521520
--- stream_server_config
522521
lua_resolver $TEST_NGINX_RESOLVER ipv6=off;
522+
#lua_resolver agentzh.org ipv6=off;
523+
#lua_resolver 8.8.8.8 ipv6=off;
523524
content_by_lua_block {
524525
-- avoid flushing google in "check leak" testing mode:
525526
local counter = package.loaded.counter
@@ -540,6 +541,7 @@ lua udp socket receive buffer size: 8192
540541
udp:settimeout(2000) -- 2 sec
541542

542543
local ok, err = udp:setpeername("google-public-dns-a.google.com", 53)
544+
--local ok, err = udp:setpeername("127.0.1.1", 53)
543545
if not ok then
544546
ngx.say("failed to connect: ", err)
545547
return

t/141-tcp-socket-bind.t

+55-9
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ repeat_each(2);
66

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

9-
my $local_ip = `ifconfig | grep -oE '([0-9]{1,3}\\.?){4}' | grep '\\.' | grep -v '127.0.0.1' | head -n 1`;
9+
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`;
1010
chomp $local_ip;
1111

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

19+
1620
no_long_string();
1721
#no_diff();
1822
#log_level 'warn';
@@ -25,7 +29,7 @@ __DATA__
2529
=== TEST 1: upstream sockets bind 127.0.0.1
2630
--- stream_config
2731
server {
28-
listen 2986;
32+
listen 127.0.1.2:2986;
2933
content_by_lua_block {
3034
ngx.say(ngx.var.remote_addr)
3135
}
@@ -42,7 +46,7 @@ server {
4246
return
4347
end
4448

45-
local ok, err = sock:connect("127.0.0.1", port)
49+
local ok, err = sock:connect("127.0.1.2", port)
4650
if not ok then
4751
ngx.log(ngx.ERR, err)
4852
return
@@ -65,7 +69,7 @@ server {
6569
=== TEST 2: upstream sockets bind non loopback ip
6670
--- stream_config
6771
server {
68-
listen 2986;
72+
listen 127.0.1.2:2986;
6973
content_by_lua_block {
7074
ngx.say(ngx.var.remote_addr)
7175
}
@@ -82,7 +86,7 @@ server {
8286
return
8387
end
8488

85-
local ok, err = sock:connect("127.0.0.1", port)
89+
local ok, err = sock:connect("127.0.1.2", port)
8690
if not ok then
8791
ngx.log(ngx.ERR, err)
8892
return
@@ -105,7 +109,7 @@ ip matched
105109
=== TEST 3: upstream sockets bind not exist ip
106110
--- stream_config
107111
server {
108-
listen 2986;
112+
listen 127.0.1.2:2986;
109113
content_by_lua_block {
110114
ngx.say(ngx.var.remote_addr)
111115
}
@@ -121,7 +125,7 @@ server {
121125
ngx.log(ngx.INFO, err)
122126
end
123127

124-
local ok, err = sock:connect("127.0.0.1", port)
128+
local ok, err = sock:connect("127.0.1.2", port)
125129
if not ok then
126130
ngx.say(err)
127131
end
@@ -139,7 +143,7 @@ cannot assign requested address
139143
=== TEST 4: upstream sockets bind invalid ip
140144
--- stream_config
141145
server {
142-
listen 2986;
146+
listen 127.0.1.2:2986;
143147
content_by_lua_block {
144148
ngx.say(ngx.var.remote_addr)
145149
}
@@ -155,7 +159,7 @@ server {
155159
ngx.say(err)
156160
end
157161

158-
local ok, err = sock:connect("127.0.0.1", port)
162+
local ok, err = sock:connect("127.0.1.2", port)
159163
if not ok then
160164
ngx.log(ngx.ERR, err)
161165
end
@@ -173,3 +177,45 @@ bad address
173177
127.0.0.1
174178
--- no_error_log
175179
[error]
180+
181+
182+
=== TEST 5: upstream sockets bind 127.0.0.1 and resolve peername
183+
--- SKIP
184+
--- stream_config
185+
lua_resolver $TEST_NGINX_LOCAL_DOMAIN_SERVER ipv6=off;
186+
server {
187+
listen localhost:2986;
188+
content_by_lua_block {
189+
ngx.say(ngx.var.remote_addr)
190+
}
191+
}
192+
--- stream_server_config
193+
content_by_lua_block {
194+
local ip = "127.0.0.1"
195+
local port = 2986
196+
local sock = ngx.socket.tcp()
197+
198+
local ok, err = sock:bind(ip)
199+
if not ok then
200+
ngx.log(ngx.ERR, err)
201+
return
202+
end
203+
204+
local ok, err = sock:connect("localhost", port)
205+
if not ok then
206+
ngx.log(ngx.ERR, err)
207+
return
208+
end
209+
210+
local line, err, part = sock:receive()
211+
if line then
212+
ngx.say(line)
213+
else
214+
ngx.log(ngx.ERR, err)
215+
end
216+
}
217+
218+
--- stream_response
219+
127.0.0.1
220+
--- no_error_log
221+
[error]

0 commit comments

Comments
 (0)