Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
My first hacked version of silly Lua DNS server atop NGINX (with patched ngx_stream_lua_module).
local bit = require "bit"
local byte = string.byte
local lshift = bit.lshift
local rshift = bit.rshift
local concat = table.concat
local insert = table.insert
local char = string.char
local band = bit.band
local sub = string.sub
local gsub = string.gsub
local clear_tb = require "table.clear"
local _M = {}
local labels = {}
local resp_tb = {}
local function _decode_name(buf, pos)
clear_tb(labels)
local nptrs = 0
local p = pos
while nptrs < 128 do
local fst = byte(buf, p)
if not fst then
return nil, 'truncated';
end
-- print("fst at ", p, ": ", fst)
if fst == 0 then
if nptrs == 0 then
pos = pos + 1
end
break
end
if band(fst, 0xc0) ~= 0 then
-- being a pointer
if nptrs == 0 then
pos = pos + 2
end
nptrs = nptrs + 1
local snd = byte(buf, p + 1)
if not snd then
return nil, 'truncated'
end
p = lshift(band(fst, 0x3f), 8) + snd + 1
-- print("resolving ptr ", p, ": ", byte(buf, p))
else
-- being a label
local label = sub(buf, p + 1, p + fst)
insert(labels, label)
-- print("resolved label ", label)
p = p + fst + 1
if nptrs == 0 then
pos = p
end
end
end
return concat(labels, "."), pos
end
function send_bad_req(id, sock)
if not id then
return
end
local ident_hi = char(rshift(id, 8))
local ident_lo = char(band(id, 0xff))
local ok, err = sock:send{
ident_hi, ident_lo, "\x80\1\0\0\0\0\0\0\0\0",
}
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
end
local function _encode_name(s)
return char(#s) .. s
end
local cname
function send_ans(id, sock, raw_quest_rr, raw_quest_name)
local ident_hi = char(rshift(id, 8))
local ident_lo = char(band(id, 0xff))
if not cname then
cname = "a.foo.com"
cname = gsub(cname, "([^.]+)%.?", _encode_name) .. '\0'
end
local len = #cname
local len_hi = char(rshift(len, 8))
local len_lo = char(band(len, 0xff))
resp_tb[1] = ident_hi
resp_tb[2] = ident_lo
resp_tb[3] = "\x84\0\0\1\0\1\0\0\0\0"
resp_tb[4] = raw_quest_rr
resp_tb[5] = raw_quest_name
resp_tb[6] = "\0\x05\0\x01\0\0\x0e\x10"
resp_tb[7] = len_hi
resp_tb[8] = len_lo
resp_tb[9] = cname
local ok, err = sock:send(resp_tb)
if not ok then
ngx.log(ngx.ERR, "failed to send: ", err)
return
end
end
function _M.go()
local sock, err = ngx.req.udp_socket()
if not sock then
ngx.log(ngx.ERR, "failed to get the request socket: ", err)
return ngx.exit(ngx.ERROR)
end
local req, err = sock:receive()
if not req then
ngx.log(ngx.ERR, "failed to receive: ", err)
return ngx.exit(ngx.ERROR)
end
local id
local n = #req
if n < 12 then
ngx.log(ngx.ERR, "request truncated")
return send_bad_req(id, sock)
end
local ident_hi = byte(req, 1)
local ident_lo = byte(req, 2)
id = lshift(ident_hi, 8) + ident_lo
-- print("req id: ", id)
local flags_hi = byte(req, 3)
local flags_lo = byte(req, 4)
local flags = lshift(flags_hi, 8) + flags_lo
if band(flags, 0x8000) == 1 then
ngx.log(ngx.ERR, "bad QR flag in the DNS request")
return send_bad_req(id, sock)
end
local code = band(flags, 0xf)
local nqs_hi = byte(req, 5)
local nqs_lo = byte(req, 6)
local nqs = lshift(nqs_hi, 8) + nqs_lo
if nqs ~= 1 then
ngx.log(ngx.ERR, "bad number of questions: ", nqs)
return send_bad_req(id, sock)
end
local nan_hi = byte(req, 7)
local nan_lo = byte(req, 8)
local nan = lshift(nan_hi, 8) + nan_lo
if nan ~= 0 then
ngx.log(ngx.ERR, "bad number of answers in the request: ", nan)
return send_bad_req(id, sock)
end
local quest_qname, pos = _decode_name(req, 13)
if not quest_qname then
ngx.log(ngx.ERR, "bad question")
return send_bad_req(id, sock)
end
local raw_quest_rr = sub(req, 13, pos + 3)
local raw_quest_name = sub(req, 13, pos - 1)
-- print("question qname: ", quest_qname)
return send_ans(id, sock, raw_quest_rr, raw_quest_name)
end
return _M
worker_processes 1;
daemon on;
master_process on;
error_log logs/error.log warn;
pid logs/nginx.pid;
stream {
lua_package_path '$prefix/lualib/?.lua;;';
init_by_lua_block {
jit.opt.start("minstitch=2")
}
server {
listen 1235 udp;
content_by_lua_block {
require "dns_server".go()
}
}
}
events {
accept_mutex off;
worker_connections 1024;
}
diff --git a/src/ngx_stream_lua_socket_tcp.c b/src/ngx_stream_lua_socket_tcp.c
index 4680811..4c44b39 100644
--- a/src/ngx_stream_lua_socket_tcp.c
+++ b/src/ngx_stream_lua_socket_tcp.c
@@ -95,7 +95,7 @@ static int ngx_stream_lua_socket_receiveuntil_iterator(lua_State *L);
static ngx_int_t ngx_stream_lua_socket_compile_pattern(u_char *data, size_t len,
ngx_stream_lua_socket_compiled_pattern_t *cp, ngx_log_t *log);
static int ngx_stream_lua_socket_cleanup_compiled_pattern(lua_State *L);
-static int ngx_stream_lua_req_socket(lua_State *L);
+static int ngx_stream_lua_tcp_req_socket(lua_State *L);
static void ngx_stream_lua_req_socket_rev_handler(ngx_stream_session_t *s,
ngx_stream_lua_ctx_t *ctx);
static int ngx_stream_lua_socket_tcp_getreusedtimes(lua_State *L);
@@ -193,7 +193,7 @@ enum {
static char ngx_stream_lua_req_socket_metatable_key;
#endif
static char ngx_stream_lua_raw_req_socket_metatable_key;
-static char ngx_stream_lua_tcp_socket_metatable_key;
+static char ngx_stream_lua_socket_tcp_metatable_key;
static char ngx_stream_lua_upstream_udata_metatable_key;
static char ngx_stream_lua_downstream_udata_metatable_key;
static char ngx_stream_lua_pool_udata_metatable_key;
@@ -276,7 +276,7 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
/* }}} */
/* {{{tcp object metatable */
- lua_pushlightuserdata(L, &ngx_stream_lua_tcp_socket_metatable_key);
+ lua_pushlightuserdata(L, &ngx_stream_lua_socket_tcp_metatable_key);
lua_createtable(L, 0 /* narr */, 11 /* nrec */);
lua_pushcfunction(L, ngx_stream_lua_socket_tcp_connect);
@@ -364,14 +364,6 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
}
-void
-ngx_stream_lua_inject_req_socket_api(lua_State *L)
-{
- lua_pushcfunction(L, ngx_stream_lua_req_socket);
- lua_setfield(L, -2, "socket");
-}
-
-
static int
ngx_stream_lua_socket_tcp(lua_State *L)
{
@@ -397,7 +389,7 @@ ngx_stream_lua_socket_tcp(lua_State *L)
| NGX_STREAM_LUA_CONTEXT_TIMER);
lua_createtable(L, 3 /* narr */, 1 /* nrec */);
- lua_pushlightuserdata(L, &ngx_stream_lua_tcp_socket_metatable_key);
+ lua_pushlightuserdata(L, &ngx_stream_lua_socket_tcp_metatable_key);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
@@ -3919,14 +3911,22 @@ ngx_stream_lua_socket_cleanup_compiled_pattern(lua_State *L)
}
+void
+ngx_stream_lua_inject_tcp_req_socket_api(lua_State *L)
+{
+ lua_pushcfunction(L, ngx_stream_lua_tcp_req_socket);
+ lua_setfield(L, -2, "socket");
+}
+
+
static int
-ngx_stream_lua_req_socket(lua_State *L)
+ngx_stream_lua_tcp_req_socket(lua_State *L)
{
int n, raw;
+ ngx_stream_session_t *s;
ngx_peer_connection_t *pc;
ngx_stream_lua_srv_conf_t *lscf;
ngx_connection_t *c;
- ngx_stream_session_t *s;
ngx_stream_lua_ctx_t *ctx;
ngx_stream_lua_co_ctx_t *coctx;
ngx_stream_lua_cleanup_t *cln;
@@ -3957,6 +3957,11 @@ ngx_stream_lua_req_socket(lua_State *L)
c = s->connection;
+ if (c->type != SOCK_STREAM) {
+ return luaL_error(L, "socket api does not match connection transport",
+ lua_gettop(L));
+ }
+
#if !defined(nginx_version) || nginx_version < 1003013
lua_pushnil(L);
lua_pushliteral(L, "nginx version too old");
diff --git a/src/ngx_stream_lua_socket_tcp.h b/src/ngx_stream_lua_socket_tcp.h
index 68bcfb0..ec6e4d7 100644
--- a/src/ngx_stream_lua_socket_tcp.h
+++ b/src/ngx_stream_lua_socket_tcp.h
@@ -147,7 +147,7 @@ typedef struct {
void ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L);
-void ngx_stream_lua_inject_req_socket_api(lua_State *L);
+void ngx_stream_lua_inject_tcp_req_socket_api(lua_State *L);
void ngx_stream_lua_cleanup_conn_pools(lua_State *L);
diff --git a/src/ngx_stream_lua_socket_udp.c b/src/ngx_stream_lua_socket_udp.c
index c8014f0..366f7a4 100644
--- a/src/ngx_stream_lua_socket_udp.c
+++ b/src/ngx_stream_lua_socket_udp.c
@@ -31,8 +31,10 @@ static int ngx_stream_lua_socket_udp_setpeername(lua_State *L);
static int ngx_stream_lua_socket_udp_send(lua_State *L);
static int ngx_stream_lua_socket_udp_receive(lua_State *L);
static int ngx_stream_lua_socket_udp_settimeout(lua_State *L);
+static int ngx_stream_lua_udp_req_socket(lua_State *L);
static void ngx_stream_lua_socket_udp_finalize(ngx_stream_session_t *s,
ngx_stream_lua_socket_udp_upstream_t *u);
+static int ngx_stream_lua_socket_udp_downstream_destroy(lua_State *L);
static int ngx_stream_lua_socket_udp_upstream_destroy(lua_State *L);
static int ngx_stream_lua_socket_resolve_retval_handler(ngx_stream_session_t *s,
ngx_stream_lua_socket_udp_upstream_t *u, lua_State *L);
@@ -69,8 +71,13 @@ enum {
};
+#if 0
+static char ngx_stream_lua_req_socket_metatable_key;
+#endif
+static char ngx_stream_lua_raw_req_socket_metatable_key;
static char ngx_stream_lua_socket_udp_metatable_key;
-static char ngx_stream_lua_udp_udata_metatable_key;
+static char ngx_stream_lua_upstream_udata_metatable_key;
+static char ngx_stream_lua_downstream_udata_metatable_key;
static u_char ngx_stream_lua_socket_udp_buffer[UDP_MAX_DATAGRAM_SIZE];
@@ -106,18 +113,206 @@ ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L)
lua_rawset(L, LUA_REGISTRYINDEX);
/* }}} */
- /* udp socket object metatable */
- lua_pushlightuserdata(L, &ngx_stream_lua_udp_udata_metatable_key);
+ /* {{{upstream userdata metatable */
+ lua_pushlightuserdata(L, &ngx_stream_lua_upstream_udata_metatable_key);
lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */
lua_pushcfunction(L, ngx_stream_lua_socket_udp_upstream_destroy);
lua_setfield(L, -2, "__gc");
lua_rawset(L, LUA_REGISTRYINDEX);
/* }}} */
+ /* {{{downstream userdata metatable */
+ lua_pushlightuserdata(L, &ngx_stream_lua_downstream_udata_metatable_key);
+ lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */
+ lua_pushcfunction(L, ngx_stream_lua_socket_udp_downstream_destroy);
+ lua_setfield(L, -2, "__gc");
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ /* }}} */
+
+#if 0
+ /* {{{udp req socket object metatable */
+ lua_pushlightuserdata(L, &ngx_stream_lua_req_socket_metatable_key);
+ lua_createtable(L, 0 /* narr */, 3 /* nrec */);
+
+ lua_pushcfunction(L, ngx_stream_lua_socket_udp_receive);
+ lua_setfield(L, -2, "receive");
+
+ lua_pushcfunction(L, ngx_stream_lua_socket_udp_settimeout);
+ lua_setfield(L, -2, "settimeout"); /* ngx socket mt */
+
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ /* }}} */
+#endif
+
+ /* {{{raw udp req socket object metatable */
+ lua_pushlightuserdata(L, &ngx_stream_lua_raw_req_socket_metatable_key);
+ lua_createtable(L, 0 /* narr */, 4 /* nrec */);
+
+ lua_pushcfunction(L, ngx_stream_lua_socket_udp_receive);
+ lua_setfield(L, -2, "receive");
+
+ lua_pushcfunction(L, ngx_stream_lua_socket_udp_send);
+ lua_setfield(L, -2, "send");
+
+ lua_pushcfunction(L, ngx_stream_lua_socket_udp_settimeout);
+ lua_setfield(L, -2, "settimeout"); /* ngx socket mt */
+
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ /* }}} */
+
lua_pop(L, 1);
}
+void
+ngx_stream_lua_inject_udp_req_socket_api(lua_State *L)
+{
+ lua_pushcfunction(L, ngx_stream_lua_udp_req_socket);
+ lua_setfield(L, -2, "udp_socket");
+}
+
+
+static int
+ngx_stream_lua_udp_req_socket(lua_State *L)
+{
+ int n, raw;
+ ngx_stream_session_t *s;
+ ngx_stream_lua_udp_connection_t *pc;
+ ngx_stream_lua_srv_conf_t *lscf;
+ ngx_connection_t *c;
+ ngx_stream_lua_ctx_t *ctx;
+ ngx_stream_lua_co_ctx_t *coctx;
+ ngx_stream_lua_cleanup_t *cln;
+
+ ngx_stream_lua_socket_udp_upstream_t *u;
+
+ n = lua_gettop(L);
+ if (n == 0) {
+ raw = 0;
+
+ } else if (n == 1) {
+ raw = lua_toboolean(L, 1);
+ lua_pop(L, 1);
+
+ } else {
+ return luaL_error(L, "expecting zero arguments, but got %d",
+ lua_gettop(L));
+ }
+
+ s = ngx_stream_lua_get_session(L);
+
+ ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module);
+ if (ctx == NULL) {
+ return luaL_error(L, "no ctx found");
+ }
+
+ ngx_stream_lua_check_context(L, ctx, NGX_STREAM_LUA_CONTEXT_CONTENT);
+
+ c = s->connection;
+
+ if (c->type != SOCK_DGRAM) {
+ return luaL_error(L, "socket api does not match connection transport",
+ lua_gettop(L));
+ }
+
+#if !defined(nginx_version) || nginx_version < 1003013
+ lua_pushnil(L);
+ lua_pushliteral(L, "nginx version too old");
+ return 2;
+#else
+ if (ctx->downstream_busy_bufs) {
+ lua_pushnil(L);
+ lua_pushliteral(L, "pending data to write");
+ return 2;
+ }
+
+ dd("ctx acquired raw req socket: %d", ctx->acquired_raw_req_socket);
+
+ if (ctx->acquired_raw_req_socket) {
+ lua_pushnil(L);
+ lua_pushliteral(L, "duplicate call");
+ return 2;
+ }
+
+ ctx->acquired_raw_req_socket = 1;
+#endif
+
+ lua_createtable(L, 3 /* narr */, 1 /* nrec */); /* the object */
+
+ lua_pushlightuserdata(L, &ngx_stream_lua_raw_req_socket_metatable_key);
+
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ lua_setmetatable(L, -2);
+
+ u = lua_newuserdata(L, sizeof(ngx_stream_lua_socket_udp_upstream_t));
+ if (u == NULL) {
+ return luaL_error(L, "no memory");
+ }
+
+#if 1
+ lua_pushlightuserdata(L, &ngx_stream_lua_downstream_udata_metatable_key);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ lua_setmetatable(L, -2);
+#endif
+
+ lua_rawseti(L, 1, SOCKET_CTX_INDEX);
+
+ ngx_memzero(u, sizeof(ngx_stream_lua_socket_udp_upstream_t));
+
+ u->raw_downstream = 1;
+
+ coctx = ctx->cur_co_ctx;
+
+ u->session = s;
+
+ lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_lua_module);
+
+ u->conf = lscf;
+
+ u->read_timeout = u->conf->read_timeout;
+
+ cln = ngx_stream_lua_cleanup_add(s, 0);
+ if (cln == NULL) {
+ u->ft_type |= NGX_STREAM_LUA_SOCKET_FT_ERROR;
+ lua_pushnil(L);
+ lua_pushliteral(L, "no memory");
+ return 2;
+ }
+
+ cln->handler = ngx_stream_lua_socket_udp_cleanup;
+ cln->data = u;
+
+ u->cleanup = &cln->handler;
+
+ pc = &u->udp_connection;
+ pc->log = *c->log;
+ pc->connection = c;
+
+ dd("setting data to %p", u);
+
+ coctx->data = u;
+ ctx->downstream = u;
+
+ if (c->read->timer_set) {
+ ngx_del_timer(c->read);
+ }
+
+ if (raw) {
+ if (c->write->timer_set) {
+ ngx_del_timer(c->write);
+ }
+ }
+
+ lua_settop(L, 1);
+ return 1;
+}
+
+
static int
ngx_stream_lua_socket_udp(lua_State *L)
{
@@ -259,7 +454,7 @@ ngx_stream_lua_socket_udp_setpeername(lua_State *L)
}
#if 1
- lua_pushlightuserdata(L, &ngx_stream_lua_udp_udata_metatable_key);
+ lua_pushlightuserdata(L, &ngx_stream_lua_upstream_udata_metatable_key);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
#endif
@@ -863,7 +1058,7 @@ ngx_stream_lua_socket_udp_send(lua_State *L)
dd("sending query %.*s", (int) query.len, query.data);
- n = ngx_send(u->udp_connection.connection, query.data, query.len);
+ n = ngx_udp_send(u->udp_connection.connection, query.data, query.len);
dd("ngx_send returns %d (query len %d)", (int) n, (int) query.len);
@@ -892,6 +1087,7 @@ ngx_stream_lua_socket_udp_receive(lua_State *L)
{
ngx_stream_session_t *s;
ngx_stream_lua_socket_udp_upstream_t *u;
+ ngx_connection_t *c;
ngx_int_t rc;
ngx_stream_lua_ctx_t *ctx;
ngx_stream_lua_co_ctx_t *coctx;
@@ -961,7 +1157,19 @@ ngx_stream_lua_socket_udp_receive(lua_State *L)
"stream lua udp socket receive buffer size: %uz",
u->recv_buf_size);
- rc = ngx_stream_lua_socket_udp_read(s, u);
+ c = u->udp_connection.connection;
+
+ if (u->raw_downstream && !u->connected) {
+ u->received = c->buffer->last - c->buffer->pos;
+ c->buffer->pos =
+ ngx_copy(ngx_stream_lua_socket_udp_buffer, c->buffer->pos, u->received);
+ ngx_stream_lua_socket_udp_handle_success(s, u);
+ u->connected = 1;
+ rc = NGX_OK;
+
+ } else {
+ rc = ngx_stream_lua_socket_udp_read(s, u);
+ }
if (rc == NGX_ERROR) {
dd("read failed: %d", (int) u->ft_type);
@@ -1073,7 +1281,7 @@ ngx_stream_lua_socket_udp_finalize(ngx_stream_session_t *s,
u->resolved->ctx = NULL;
}
- if (u->udp_connection.connection) {
+ if (u->udp_connection.connection && !u->raw_downstream) {
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
"stream lua close socket connection");
@@ -1107,6 +1315,27 @@ ngx_stream_lua_socket_udp_upstream_destroy(lua_State *L)
}
+static int
+ngx_stream_lua_socket_udp_downstream_destroy(lua_State *L)
+{
+ ngx_stream_lua_socket_udp_upstream_t *u;
+
+ dd("downstream destory");
+
+ u = lua_touserdata(L, 1);
+ if (u == NULL) {
+ dd("u is NULL");
+ return 0;
+ }
+
+ if (u->cleanup) {
+ ngx_stream_lua_socket_udp_cleanup(u); /* it will clear u->cleanup */
+ }
+
+ return 0;
+}
+
+
static void
ngx_stream_lua_socket_dummy_handler(ngx_stream_session_t *s,
ngx_stream_lua_socket_udp_upstream_t *u)
diff --git a/src/ngx_stream_lua_socket_udp.h b/src/ngx_stream_lua_socket_udp.h
index 7055c4f..e7ca378 100644
--- a/src/ngx_stream_lua_socket_udp.h
+++ b/src/ngx_stream_lua_socket_udp.h
@@ -46,18 +46,20 @@ struct ngx_stream_lua_socket_udp_upstream_s {
ngx_stream_lua_resolved_t *resolved;
- ngx_uint_t ft_type;
- ngx_err_t socket_errno;
- size_t received; /* for receive */
- size_t recv_buf_size;
+ ngx_uint_t ft_type;
+ ngx_err_t socket_errno;
+ size_t received; /* for receive */
+ size_t recv_buf_size;
ngx_stream_lua_co_ctx_t *co_ctx;
-
- unsigned waiting; /* :1 */
+ unsigned raw_downstream:1;
+ unsigned waiting:1;
+ unsigned connected:1;
};
void ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L);
+void ngx_stream_lua_inject_udp_req_socket_api(lua_State *L);
#endif /* _NGX_STREAM_LUA_SOCKET_UDP_H_INCLUDED_ */
diff --git a/src/ngx_stream_lua_util.c b/src/ngx_stream_lua_util.c
index cebad77..b05eda5 100644
--- a/src/ngx_stream_lua_util.c
+++ b/src/ngx_stream_lua_util.c
@@ -491,6 +491,7 @@ ngx_stream_lua_new_thread(ngx_stream_session_t *s, lua_State *L, int *ref)
co = lua_newthread(L);
+#if 0
/* {{{ inherit coroutine's globals to main thread's globals table
* for print() function will try to find tostring() in current
* globals table.
@@ -505,6 +506,7 @@ ngx_stream_lua_new_thread(ngx_stream_session_t *s, lua_State *L, int *ref)
ngx_stream_lua_set_globals_table(co);
/* }}} */
+#endif
*ref = luaL_ref(L, -2);
@@ -3226,9 +3228,9 @@ ngx_stream_lua_inject_req_api(ngx_log_t *log, lua_State *L)
{
/* ngx.req table */
- lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* .req */
-
- ngx_stream_lua_inject_req_socket_api(L);
+ lua_createtable(L, 0 /* narr */, 2 /* nrec */); /* .req */
+ ngx_stream_lua_inject_tcp_req_socket_api(L);
+ ngx_stream_lua_inject_udp_req_socket_api(L);
lua_setfield(L, -2, "req");
}
diff --git a/t/062-count.t b/t/062-count.t
index bdb531c..7933463 100644
--- a/t/062-count.t
+++ b/t/062-count.t
@@ -46,7 +46,7 @@ ngx: 56
ngx.say("n = ", n)
}
--- stream_response
-n = 1
+n = 2
--- no_error_log
[error]
diff --git a/t/138-req-udp-socket.t b/t/138-req-udp-socket.t
new file mode 100644
index 0000000..24d2c46
--- /dev/null
+++ b/t/138-req-udp-socket.t
@@ -0,0 +1,251 @@
+# vim:set ft= ts=4 sw=4 et fdm=marker:
+
+use Test::Nginx::Socket::Lua::Dgram;
+
+repeat_each(2);
+
+plan tests => repeat_each() * (blocks() * 3 + 1);
+
+our $HtmlDir = html_dir;
+
+#$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211;
+
+no_long_string();
+#no_diff();
+#log_level 'warn';
+no_shuffle();
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: sanity
+--- ONLY
+--- dgram_server_config
+ content_by_lua_block {
+ local sock, err = ngx.req.udp_socket()
+ if not sock then
+ ngx.log(ngx.ERR, "failed to get the request socket: ", err)
+ return ngx.exit(ngx.ERROR)
+ end
+
+ local data, err = sock:receive()
+ if not data then
+ ngx.log(ngx.ERR, "failed to receive: ", err)
+ return ngx.exit(ngx.ERROR)
+ end
+
+ -- print("data: ", data)
+
+ local ok, err = sock:send("received: " .. data)
+ if not ok then
+ ngx.log(ngx.ERR, "failed to send: ", err)
+ return ngx.exit(ngx.ERROR)
+ end
+ }
+--- dgram_request chomp
+hello world! my
+--- dgram_response chomp
+received: hello world! my
+--- no_error_log
+[error]
@dongbenxipao

This comment has been minimized.

Copy link

commented Feb 4, 2017

req.udp_socket is not supported now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.