@@ -31,8 +31,10 @@ static int ngx_stream_lua_socket_udp_setpeername(lua_State *L);
3131static int ngx_stream_lua_socket_udp_send (lua_State * L );
3232static int ngx_stream_lua_socket_udp_receive (lua_State * L );
3333static int ngx_stream_lua_socket_udp_settimeout (lua_State * L );
34+ static int ngx_stream_lua_udp_req_socket (lua_State * L );
3435static 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 );
3638static int ngx_stream_lua_socket_udp_upstream_destroy (lua_State * L );
3739static 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 ;
7278static 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 ;
7481static 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+
121316static int
122317ngx_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+
11101326static void
11111327ngx_stream_lua_socket_dummy_handler (ngx_stream_session_t * s ,
11121328 ngx_stream_lua_socket_udp_upstream_t * u )
0 commit comments