Skip to content

Commit d86107b

Browse files
Alon Blayer-Gatalonbg
Alon Blayer-Gat
authored and
alonbg
committed
udp downstream api - work in progress
1 parent 6ed0a0e commit d86107b

10 files changed

+1053
-29
lines changed

src/ngx_stream_lua_socket_tcp.c

+19-14
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static int ngx_stream_lua_socket_receiveuntil_iterator(lua_State *L);
9595
static ngx_int_t ngx_stream_lua_socket_compile_pattern(u_char *data, size_t len,
9696
ngx_stream_lua_socket_compiled_pattern_t *cp, ngx_log_t *log);
9797
static int ngx_stream_lua_socket_cleanup_compiled_pattern(lua_State *L);
98-
static int ngx_stream_lua_req_socket(lua_State *L);
98+
static int ngx_stream_lua_tcp_req_socket(lua_State *L);
9999
static void ngx_stream_lua_req_socket_rev_handler(ngx_stream_session_t *s,
100100
ngx_stream_lua_ctx_t *ctx);
101101
static int ngx_stream_lua_socket_tcp_getreusedtimes(lua_State *L);
@@ -193,7 +193,7 @@ enum {
193193
static char ngx_stream_lua_req_socket_metatable_key;
194194
#endif
195195
static char ngx_stream_lua_raw_req_socket_metatable_key;
196-
static char ngx_stream_lua_tcp_socket_metatable_key;
196+
static char ngx_stream_lua_socket_tcp_metatable_key;
197197
static char ngx_stream_lua_upstream_udata_metatable_key;
198198
static char ngx_stream_lua_downstream_udata_metatable_key;
199199
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)
276276
/* }}} */
277277

278278
/* {{{tcp object metatable */
279-
lua_pushlightuserdata(L, &ngx_stream_lua_tcp_socket_metatable_key);
279+
lua_pushlightuserdata(L, &ngx_stream_lua_socket_tcp_metatable_key);
280280
lua_createtable(L, 0 /* narr */, 11 /* nrec */);
281281

282282
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)
364364
}
365365

366366

367-
void
368-
ngx_stream_lua_inject_req_socket_api(lua_State *L)
369-
{
370-
lua_pushcfunction(L, ngx_stream_lua_req_socket);
371-
lua_setfield(L, -2, "socket");
372-
}
373-
374-
375367
static int
376368
ngx_stream_lua_socket_tcp(lua_State *L)
377369
{
@@ -397,7 +389,7 @@ ngx_stream_lua_socket_tcp(lua_State *L)
397389
| NGX_STREAM_LUA_CONTEXT_TIMER);
398390

399391
lua_createtable(L, 3 /* narr */, 1 /* nrec */);
400-
lua_pushlightuserdata(L, &ngx_stream_lua_tcp_socket_metatable_key);
392+
lua_pushlightuserdata(L, &ngx_stream_lua_socket_tcp_metatable_key);
401393
lua_rawget(L, LUA_REGISTRYINDEX);
402394
lua_setmetatable(L, -2);
403395

@@ -3919,14 +3911,22 @@ ngx_stream_lua_socket_cleanup_compiled_pattern(lua_State *L)
39193911
}
39203912

39213913

3914+
void
3915+
ngx_stream_lua_inject_tcp_req_socket_api(lua_State *L)
3916+
{
3917+
lua_pushcfunction(L, ngx_stream_lua_tcp_req_socket);
3918+
lua_setfield(L, -2, "socket");
3919+
}
3920+
3921+
39223922
static int
3923-
ngx_stream_lua_req_socket(lua_State *L)
3923+
ngx_stream_lua_tcp_req_socket(lua_State *L)
39243924
{
39253925
int n, raw;
3926+
ngx_stream_session_t *s;
39263927
ngx_peer_connection_t *pc;
39273928
ngx_stream_lua_srv_conf_t *lscf;
39283929
ngx_connection_t *c;
3929-
ngx_stream_session_t *s;
39303930
ngx_stream_lua_ctx_t *ctx;
39313931
ngx_stream_lua_co_ctx_t *coctx;
39323932
ngx_stream_lua_cleanup_t *cln;
@@ -3957,6 +3957,11 @@ ngx_stream_lua_req_socket(lua_State *L)
39573957

39583958
c = s->connection;
39593959

3960+
if (c->type != SOCK_STREAM) {
3961+
return luaL_error(L, "socket api does not match connection transport",
3962+
lua_gettop(L));
3963+
}
3964+
39603965
#if !defined(nginx_version) || nginx_version < 1003013
39613966
lua_pushnil(L);
39623967
lua_pushliteral(L, "nginx version too old");

src/ngx_stream_lua_socket_tcp.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ typedef struct {
147147

148148

149149
void ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L);
150-
void ngx_stream_lua_inject_req_socket_api(lua_State *L);
150+
void ngx_stream_lua_inject_tcp_req_socket_api(lua_State *L);
151151
void ngx_stream_lua_cleanup_conn_pools(lua_State *L);
152152

153153

src/ngx_stream_lua_socket_udp.c

+220-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ static int ngx_stream_lua_socket_udp_setpeername(lua_State *L);
3131
static int ngx_stream_lua_socket_udp_send(lua_State *L);
3232
static int ngx_stream_lua_socket_udp_receive(lua_State *L);
3333
static int ngx_stream_lua_socket_udp_settimeout(lua_State *L);
34+
static int ngx_stream_lua_udp_req_socket(lua_State *L);
3435
static void ngx_stream_lua_socket_udp_finalize(ngx_stream_session_t *s,
3536
ngx_stream_lua_socket_udp_upstream_t *u);
37+
static int ngx_stream_lua_socket_udp_downstream_destroy(lua_State *L);
3638
static int ngx_stream_lua_socket_udp_upstream_destroy(lua_State *L);
3739
static int ngx_stream_lua_socket_resolve_retval_handler(ngx_stream_session_t *s,
3840
ngx_stream_lua_socket_udp_upstream_t *u, lua_State *L);
@@ -69,8 +71,13 @@ enum {
6971
};
7072

7173

74+
#if 0
75+
static char ngx_stream_lua_req_socket_metatable_key;
76+
#endif
77+
static char ngx_stream_lua_raw_req_socket_metatable_key;
7278
static char ngx_stream_lua_socket_udp_metatable_key;
73-
static char ngx_stream_lua_udp_udata_metatable_key;
79+
static char ngx_stream_lua_upstream_udata_metatable_key;
80+
static char ngx_stream_lua_downstream_udata_metatable_key;
7481
static u_char ngx_stream_lua_socket_udp_buffer[UDP_MAX_DATAGRAM_SIZE];
7582

7683

@@ -106,18 +113,206 @@ ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L)
106113
lua_rawset(L, LUA_REGISTRYINDEX);
107114
/* }}} */
108115

109-
/* udp socket object metatable */
110-
lua_pushlightuserdata(L, &ngx_stream_lua_udp_udata_metatable_key);
116+
/* {{{upstream userdata metatable */
117+
lua_pushlightuserdata(L, &ngx_stream_lua_upstream_udata_metatable_key);
111118
lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */
112119
lua_pushcfunction(L, ngx_stream_lua_socket_udp_upstream_destroy);
113120
lua_setfield(L, -2, "__gc");
114121
lua_rawset(L, LUA_REGISTRYINDEX);
115122
/* }}} */
116123

124+
/* {{{downstream userdata metatable */
125+
lua_pushlightuserdata(L, &ngx_stream_lua_downstream_udata_metatable_key);
126+
lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */
127+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_downstream_destroy);
128+
lua_setfield(L, -2, "__gc");
129+
lua_rawset(L, LUA_REGISTRYINDEX);
130+
/* }}} */
131+
132+
#if 0
133+
/* {{{udp req socket object metatable */
134+
lua_pushlightuserdata(L, &ngx_stream_lua_req_socket_metatable_key);
135+
lua_createtable(L, 0 /* narr */, 3 /* nrec */);
136+
137+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_receive);
138+
lua_setfield(L, -2, "receive");
139+
140+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_settimeout);
141+
lua_setfield(L, -2, "settimeout"); /* ngx socket mt */
142+
143+
lua_pushvalue(L, -1);
144+
lua_setfield(L, -2, "__index");
145+
146+
lua_rawset(L, LUA_REGISTRYINDEX);
147+
/* }}} */
148+
#endif
149+
150+
/* {{{raw udp req socket object metatable */
151+
lua_pushlightuserdata(L, &ngx_stream_lua_raw_req_socket_metatable_key);
152+
lua_createtable(L, 0 /* narr */, 4 /* nrec */);
153+
154+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_receive);
155+
lua_setfield(L, -2, "receive");
156+
157+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_send);
158+
lua_setfield(L, -2, "send");
159+
160+
lua_pushcfunction(L, ngx_stream_lua_socket_udp_settimeout);
161+
lua_setfield(L, -2, "settimeout"); /* ngx socket mt */
162+
163+
lua_pushvalue(L, -1);
164+
lua_setfield(L, -2, "__index");
165+
lua_rawset(L, LUA_REGISTRYINDEX);
166+
/* }}} */
167+
117168
lua_pop(L, 1);
118169
}
119170

120171

172+
void
173+
ngx_stream_lua_inject_udp_req_socket_api(lua_State *L)
174+
{
175+
lua_pushcfunction(L, ngx_stream_lua_udp_req_socket);
176+
lua_setfield(L, -2, "udp_socket");
177+
}
178+
179+
180+
static int
181+
ngx_stream_lua_udp_req_socket(lua_State *L)
182+
{
183+
int n, raw;
184+
ngx_stream_session_t *s;
185+
ngx_stream_lua_udp_connection_t *pc;
186+
ngx_stream_lua_srv_conf_t *lscf;
187+
ngx_connection_t *c;
188+
ngx_stream_lua_ctx_t *ctx;
189+
ngx_stream_lua_co_ctx_t *coctx;
190+
ngx_stream_lua_cleanup_t *cln;
191+
192+
ngx_stream_lua_socket_udp_upstream_t *u;
193+
194+
n = lua_gettop(L);
195+
if (n == 0) {
196+
raw = 0;
197+
198+
} else if (n == 1) {
199+
raw = lua_toboolean(L, 1);
200+
lua_pop(L, 1);
201+
202+
} else {
203+
return luaL_error(L, "expecting zero arguments, but got %d",
204+
lua_gettop(L));
205+
}
206+
207+
s = ngx_stream_lua_get_session(L);
208+
209+
ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module);
210+
if (ctx == NULL) {
211+
return luaL_error(L, "no ctx found");
212+
}
213+
214+
ngx_stream_lua_check_context(L, ctx, NGX_STREAM_LUA_CONTEXT_CONTENT);
215+
216+
c = s->connection;
217+
218+
if (c->type != SOCK_DGRAM) {
219+
return luaL_error(L, "socket api does not match connection transport",
220+
lua_gettop(L));
221+
}
222+
223+
#if !defined(nginx_version) || nginx_version < 1003013
224+
lua_pushnil(L);
225+
lua_pushliteral(L, "nginx version too old");
226+
return 2;
227+
#else
228+
if (ctx->downstream_busy_bufs) {
229+
lua_pushnil(L);
230+
lua_pushliteral(L, "pending data to write");
231+
return 2;
232+
}
233+
234+
dd("ctx acquired raw req socket: %d", ctx->acquired_raw_req_socket);
235+
236+
if (ctx->acquired_raw_req_socket) {
237+
lua_pushnil(L);
238+
lua_pushliteral(L, "duplicate call");
239+
return 2;
240+
}
241+
242+
ctx->acquired_raw_req_socket = 1;
243+
#endif
244+
245+
lua_createtable(L, 3 /* narr */, 1 /* nrec */); /* the object */
246+
247+
lua_pushlightuserdata(L, &ngx_stream_lua_raw_req_socket_metatable_key);
248+
249+
lua_rawget(L, LUA_REGISTRYINDEX);
250+
lua_setmetatable(L, -2);
251+
252+
u = lua_newuserdata(L, sizeof(ngx_stream_lua_socket_udp_upstream_t));
253+
if (u == NULL) {
254+
return luaL_error(L, "no memory");
255+
}
256+
257+
#if 1
258+
lua_pushlightuserdata(L, &ngx_stream_lua_downstream_udata_metatable_key);
259+
lua_rawget(L, LUA_REGISTRYINDEX);
260+
lua_setmetatable(L, -2);
261+
#endif
262+
263+
lua_rawseti(L, 1, SOCKET_CTX_INDEX);
264+
265+
ngx_memzero(u, sizeof(ngx_stream_lua_socket_udp_upstream_t));
266+
267+
u->raw_downstream = 1;
268+
269+
coctx = ctx->cur_co_ctx;
270+
271+
u->session = s;
272+
273+
lscf = ngx_stream_get_module_srv_conf(s, ngx_stream_lua_module);
274+
275+
u->conf = lscf;
276+
277+
u->read_timeout = u->conf->read_timeout;
278+
279+
cln = ngx_stream_lua_cleanup_add(s, 0);
280+
if (cln == NULL) {
281+
u->ft_type |= NGX_STREAM_LUA_SOCKET_FT_ERROR;
282+
lua_pushnil(L);
283+
lua_pushliteral(L, "no memory");
284+
return 2;
285+
}
286+
287+
cln->handler = ngx_stream_lua_socket_udp_cleanup;
288+
cln->data = u;
289+
290+
u->cleanup = &cln->handler;
291+
292+
pc = &u->udp_connection;
293+
pc->log = *c->log;
294+
pc->connection = c;
295+
296+
dd("setting data to %p", u);
297+
298+
coctx->data = u;
299+
ctx->downstream = u;
300+
301+
if (c->read->timer_set) {
302+
ngx_del_timer(c->read);
303+
}
304+
305+
if (raw) {
306+
if (c->write->timer_set) {
307+
ngx_del_timer(c->write);
308+
}
309+
}
310+
311+
lua_settop(L, 1);
312+
return 1;
313+
}
314+
315+
121316
static int
122317
ngx_stream_lua_socket_udp(lua_State *L)
123318
{
@@ -259,7 +454,7 @@ ngx_stream_lua_socket_udp_setpeername(lua_State *L)
259454
}
260455

261456
#if 1
262-
lua_pushlightuserdata(L, &ngx_stream_lua_udp_udata_metatable_key);
457+
lua_pushlightuserdata(L, &ngx_stream_lua_upstream_udata_metatable_key);
263458
lua_rawget(L, LUA_REGISTRYINDEX);
264459
lua_setmetatable(L, -2);
265460
#endif
@@ -1107,6 +1302,27 @@ ngx_stream_lua_socket_udp_upstream_destroy(lua_State *L)
11071302
}
11081303

11091304

1305+
static int
1306+
ngx_stream_lua_socket_udp_downstream_destroy(lua_State *L)
1307+
{
1308+
ngx_stream_lua_socket_udp_upstream_t *u;
1309+
1310+
dd("downstream destory");
1311+
1312+
u = lua_touserdata(L, 1);
1313+
if (u == NULL) {
1314+
dd("u is NULL");
1315+
return 0;
1316+
}
1317+
1318+
if (u->cleanup) {
1319+
ngx_stream_lua_socket_udp_cleanup(u); /* it will clear u->cleanup */
1320+
}
1321+
1322+
return 0;
1323+
}
1324+
1325+
11101326
static void
11111327
ngx_stream_lua_socket_dummy_handler(ngx_stream_session_t *s,
11121328
ngx_stream_lua_socket_udp_upstream_t *u)

src/ngx_stream_lua_socket_udp.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,19 @@ struct ngx_stream_lua_socket_udp_upstream_s {
4646

4747
ngx_stream_lua_resolved_t *resolved;
4848

49-
ngx_uint_t ft_type;
50-
ngx_err_t socket_errno;
51-
size_t received; /* for receive */
52-
size_t recv_buf_size;
49+
ngx_uint_t ft_type;
50+
ngx_err_t socket_errno;
51+
size_t received; /* for receive */
52+
size_t recv_buf_size;
5353

5454
ngx_stream_lua_co_ctx_t *co_ctx;
55-
56-
unsigned waiting; /* :1 */
55+
unsigned raw_downstream:1;
56+
unsigned waiting; /* :1 */
5757
};
5858

5959

6060
void ngx_stream_lua_inject_socket_udp_api(ngx_log_t *log, lua_State *L);
61+
void ngx_stream_lua_inject_udp_req_socket_api(lua_State *L);
6162

6263

6364
#endif /* _NGX_STREAM_LUA_SOCKET_UDP_H_INCLUDED_ */

0 commit comments

Comments
 (0)