1818
1919
2020static int ngx_stream_lua_socket_tcp (lua_State * L );
21+ static int ngx_stream_lua_socket_tcp_bind (lua_State * L );
2122static int ngx_stream_lua_socket_tcp_connect (lua_State * L );
2223#if (NGX_STREAM_SSL )
2324static int ngx_stream_lua_socket_tcp_sslhandshake (lua_State * L );
@@ -147,7 +148,8 @@ static void ngx_stream_lua_socket_tcp_close_connection(ngx_connection_t *c);
147148enum {
148149 SOCKET_CTX_INDEX = 1 ,
149150 SOCKET_TIMEOUT_INDEX = 2 ,
150- SOCKET_KEY_INDEX = 3
151+ SOCKET_KEY_INDEX = 3 ,
152+ SOCKET_BIND_INDEX = 4 /* only in upstream cosocket */
151153};
152154
153155
@@ -277,7 +279,10 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
277279
278280 /* {{{tcp object metatable */
279281 lua_pushlightuserdata (L , & ngx_stream_lua_tcp_socket_metatable_key );
280- lua_createtable (L , 0 /* narr */ , 11 /* nrec */ );
282+ lua_createtable (L , 0 /* narr */ , 12 /* nrec */ );
283+
284+ lua_pushcfunction (L , ngx_stream_lua_socket_tcp_bind );
285+ lua_setfield (L , -2 , "bind" );
281286
282287 lua_pushcfunction (L , ngx_stream_lua_socket_tcp_connect );
283288 lua_setfield (L , -2 , "connect" );
@@ -396,7 +401,7 @@ ngx_stream_lua_socket_tcp(lua_State *L)
396401 ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_CONTENT
397402 | NGX_STREAM_LUA_CONTEXT_TIMER );
398403
399- lua_createtable (L , 3 /* narr */ , 1 /* nrec */ );
404+ lua_createtable (L , 4 /* narr */ , 1 /* nrec */ );
400405 lua_pushlightuserdata (L , & ngx_stream_lua_tcp_socket_metatable_key );
401406 lua_rawget (L , LUA_REGISTRYINDEX );
402407 lua_setmetatable (L , -2 );
@@ -407,6 +412,54 @@ ngx_stream_lua_socket_tcp(lua_State *L)
407412}
408413
409414
415+ static int
416+ ngx_stream_lua_socket_tcp_bind (lua_State * L )
417+ {
418+ ngx_stream_session_t * s ;
419+ ngx_stream_lua_ctx_t * ctx ;
420+ int n ;
421+ u_char * text ;
422+ size_t len ;
423+ ngx_addr_t * local ;
424+
425+ n = lua_gettop (L );
426+ if (n != 2 ) {
427+ return luaL_error (L , "expecting 2 arguments, but got %d" ,
428+ lua_gettop (L ));
429+ }
430+
431+ s = ngx_stream_lua_get_session (L );
432+ if (s == NULL ) {
433+ return luaL_error (L , "no request found" );
434+ }
435+
436+ ctx = ngx_stream_get_module_ctx (s , ngx_stream_lua_module );
437+ if (ctx == NULL ) {
438+ return luaL_error (L , "no ctx found" );
439+ }
440+
441+ ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_CONTENT
442+ | NGX_STREAM_LUA_CONTEXT_TIMER );
443+
444+ luaL_checktype (L , 1 , LUA_TTABLE );
445+
446+ text = (u_char * ) luaL_checklstring (L , 2 , & len );
447+ local = ngx_stream_lua_parse_addr (L , text , len );
448+ if (local == NULL ) {
449+ lua_pushnil (L );
450+ lua_pushfstring (L , "bad address" );
451+ return 2 ;
452+ }
453+
454+ /* TODO: we may reuse the userdata here */
455+ lua_rawseti (L , 1 , SOCKET_BIND_INDEX );
456+ ngx_log_debug1 (NGX_LOG_DEBUG_STREAM , s -> connection -> log , 0 ,
457+ "lua tcp socket bind ip: %V" , & local -> name );
458+ lua_pushboolean (L , 1 );
459+ return 1 ;
460+ }
461+
462+
410463static int
411464ngx_stream_lua_socket_tcp_connect (lua_State * L )
412465{
@@ -423,6 +476,7 @@ ngx_stream_lua_socket_tcp_connect(lua_State *L)
423476 ngx_int_t rc ;
424477 ngx_stream_lua_srv_conf_t * lscf ;
425478 ngx_peer_connection_t * pc ;
479+ ngx_addr_t * local ;
426480 int timeout ;
427481 unsigned custom_pool ;
428482 int key_index ;
@@ -579,6 +633,14 @@ ngx_stream_lua_socket_tcp_connect(lua_State *L)
579633
580634 dd ("lua peer connection log: %p" , pc -> log );
581635
636+ lua_rawgeti (L , 1 , SOCKET_BIND_INDEX );
637+ local = lua_touserdata (L , -1 );
638+ lua_pop (L , 1 );
639+
640+ if (local ) {
641+ u -> peer .local = local ;
642+ }
643+
582644 lua_rawgeti (L , 1 , SOCKET_TIMEOUT_INDEX );
583645 timeout = (ngx_int_t ) lua_tointeger (L , -1 );
584646 lua_pop (L , 1 );
0 commit comments