28
28
29
29
30
30
static int ngx_stream_lua_socket_tcp (lua_State * L );
31
+ static int ngx_stream_lua_socket_tcp_bind (lua_State * L );
31
32
static int ngx_stream_lua_socket_tcp_connect (lua_State * L );
32
33
#if (NGX_STREAM_SSL )
33
34
static int ngx_stream_lua_socket_tcp_sslhandshake (lua_State * L );
@@ -183,9 +184,11 @@ static void ngx_stream_lua_ssl_handshake_handler(ngx_connection_t *c);
183
184
static int ngx_stream_lua_ssl_free_session (lua_State * L );
184
185
#endif
185
186
static void ngx_stream_lua_socket_tcp_close_connection (ngx_connection_t * c );
187
+ static void ngx_stream_lua_inject_socket_option_consts (lua_State * L );
186
188
187
189
static int ngx_stream_lua_socket_tcp_peek (lua_State * L );
188
- static ngx_int_t ngx_stream_lua_socket_tcp_peek_resume (ngx_stream_lua_request_t * r );
190
+ static ngx_int_t ngx_stream_lua_socket_tcp_peek_resume (
191
+ ngx_stream_lua_request_t * r );
189
192
static int ngx_stream_lua_socket_tcp_shutdown (lua_State * L );
190
193
191
194
@@ -195,6 +198,8 @@ enum {
195
198
SOCKET_CONNECT_TIMEOUT_INDEX = 2 ,
196
199
SOCKET_SEND_TIMEOUT_INDEX = 4 ,
197
200
SOCKET_READ_TIMEOUT_INDEX = 5 ,
201
+ SOCKET_BIND_INDEX = 6 , /* only in upstream cosocket */
202
+ SOCKET_IP_TRANSPARENT_INDEX = 7
198
203
};
199
204
200
205
@@ -249,11 +254,24 @@ static char ngx_stream_lua_ssl_session_metatable_key;
249
254
#endif
250
255
251
256
257
+ static void
258
+ ngx_stream_lua_inject_socket_option_consts (lua_State * L )
259
+ {
260
+ /* {{{ socket option constants */
261
+ #if (NGX_HAVE_TRANSPARENT_PROXY )
262
+ lua_pushinteger (L , NGX_STREAM_LUA_SOCKET_OPTION_TRANSPARENT );
263
+ lua_setfield (L , -2 , "IP_TRANSPARENT" );
264
+ #endif
265
+ }
266
+
267
+
252
268
void
253
269
ngx_stream_lua_inject_socket_tcp_api (ngx_log_t * log , lua_State * L )
254
270
{
255
271
ngx_int_t rc ;
256
272
273
+ ngx_stream_lua_inject_socket_option_consts (L );
274
+
257
275
lua_createtable (L , 0 , 4 /* nrec */ ); /* ngx.socket */
258
276
259
277
lua_pushcfunction (L , ngx_stream_lua_socket_tcp );
@@ -319,7 +337,10 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
319
337
/* {{{tcp object metatable */
320
338
lua_pushlightuserdata (L , ngx_stream_lua_lightudata_mask (
321
339
tcp_socket_metatable_key ));
322
- lua_createtable (L , 0 /* narr */ , 14 /* nrec */ );
340
+ lua_createtable (L , 0 /* narr */ , 15 /* nrec */ );
341
+
342
+ lua_pushcfunction (L , ngx_stream_lua_socket_tcp_bind );
343
+ lua_setfield (L , -2 , "bind" );
323
344
324
345
lua_pushcfunction (L , ngx_stream_lua_socket_tcp_connect );
325
346
lua_setfield (L , -2 , "connect" );
@@ -457,7 +478,8 @@ ngx_stream_lua_socket_tcp(lua_State *L)
457
478
458
479
static void
459
480
ngx_stream_lua_socket_tcp_create_socket_pool (lua_State * L ,
460
- ngx_stream_lua_request_t * r , ngx_str_t key , ngx_int_t pool_size , ngx_int_t backlog ,
481
+ ngx_stream_lua_request_t * r , ngx_str_t key , ngx_int_t pool_size ,
482
+ ngx_int_t backlog ,
461
483
ngx_stream_lua_socket_pool_t * * spool )
462
484
{
463
485
u_char * p ;
@@ -854,6 +876,55 @@ ngx_stream_lua_socket_tcp_connect_helper(lua_State *L,
854
876
}
855
877
856
878
879
+ static int
880
+ ngx_stream_lua_socket_tcp_bind (lua_State * L )
881
+ {
882
+ ngx_stream_lua_ctx_t * ctx ;
883
+ int n ;
884
+ u_char * text ;
885
+ size_t len ;
886
+ ngx_addr_t * local ;
887
+
888
+ ngx_stream_lua_request_t * r ;
889
+
890
+ n = lua_gettop (L );
891
+ if (n != 2 ) {
892
+ return luaL_error (L , "expecting 2 arguments, but got %d" ,
893
+ lua_gettop (L ));
894
+ }
895
+
896
+ r = ngx_stream_lua_get_req (L );
897
+ if (r == NULL ) {
898
+ return luaL_error (L , "no request found" );
899
+ }
900
+
901
+ ctx = ngx_stream_lua_get_module_ctx (r , ngx_stream_lua_module );
902
+ if (ctx == NULL ) {
903
+ return luaL_error (L , "no ctx found" );
904
+ }
905
+
906
+ ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_CONTENT
907
+ | NGX_STREAM_LUA_CONTEXT_TIMER );
908
+
909
+ luaL_checktype (L , 1 , LUA_TTABLE );
910
+
911
+ text = (u_char * ) luaL_checklstring (L , 2 , & len );
912
+ local = ngx_stream_lua_parse_addr (L , text , len );
913
+ if (local == NULL ) {
914
+ lua_pushnil (L );
915
+ lua_pushfstring (L , "bad address" );
916
+ return 2 ;
917
+ }
918
+
919
+ /* TODO: we may reuse the userdata here */
920
+ lua_rawseti (L , 1 , SOCKET_BIND_INDEX );
921
+ ngx_log_debug1 (NGX_LOG_DEBUG_STREAM , r -> connection -> log , 0 ,
922
+ "lua tcp socket bind ip: %V" , & local -> name );
923
+ lua_pushboolean (L , 1 );
924
+ return 1 ;
925
+ }
926
+
927
+
857
928
static int
858
929
ngx_stream_lua_socket_tcp_connect (lua_State * L )
859
930
{
@@ -864,6 +935,7 @@ ngx_stream_lua_socket_tcp_connect(lua_State *L)
864
935
u_char * p ;
865
936
size_t len ;
866
937
ngx_peer_connection_t * pc ;
938
+ ngx_addr_t * local ;
867
939
int connect_timeout , send_timeout , read_timeout ;
868
940
unsigned custom_pool ;
869
941
int key_index ;
@@ -1078,6 +1150,26 @@ ngx_stream_lua_socket_tcp_connect(lua_State *L)
1078
1150
1079
1151
lua_pop (L , 3 );
1080
1152
1153
+ lua_rawgeti (L , 1 , SOCKET_BIND_INDEX );
1154
+ local = lua_touserdata (L , -1 );
1155
+ lua_pop (L , 1 );
1156
+
1157
+ if (local ) {
1158
+ u -> peer .local = local ;
1159
+ }
1160
+
1161
+ #if (NGX_HAVE_TRANSPARENT_PROXY )
1162
+ lua_rawgeti (L , 1 , SOCKET_IP_TRANSPARENT_INDEX );
1163
+
1164
+ if (lua_tointeger (L , -1 ) > 0 ) {
1165
+ pc -> transparent = 1 ;
1166
+ ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , r -> connection -> log , 0 ,
1167
+ "stream lua set TCP upstream with IP_TRANSPARENT" );
1168
+ }
1169
+
1170
+ lua_pop (L , 1 );
1171
+ #endif
1172
+
1081
1173
if (connect_timeout > 0 ) {
1082
1174
u -> connect_timeout = (ngx_msec_t ) connect_timeout ;
1083
1175
@@ -1205,7 +1297,8 @@ ngx_stream_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx)
1205
1297
addr .data = text ;
1206
1298
1207
1299
for (i = 0 ; i < ctx -> naddrs ; i ++ ) {
1208
- addr .len = ngx_sock_ntop (ur -> addrs [i ].sockaddr , ur -> addrs [i ].socklen ,
1300
+ addr .len = ngx_sock_ntop (ur -> addrs [i ].sockaddr ,
1301
+ ur -> addrs [i ].socklen ,
1209
1302
text , NGX_SOCKADDR_STRLEN , 0 );
1210
1303
1211
1304
ngx_log_debug1 (NGX_LOG_DEBUG_STREAM , r -> connection -> log , 0 ,
@@ -3259,8 +3352,50 @@ ngx_stream_lua_socket_tcp_shutdown(lua_State *L)
3259
3352
static int
3260
3353
ngx_stream_lua_socket_tcp_setoption (lua_State * L )
3261
3354
{
3262
- /* TODO */
3263
- return 0 ;
3355
+ ngx_stream_lua_ctx_t * ctx ;
3356
+ int n ;
3357
+ int option ;
3358
+
3359
+ ngx_stream_lua_request_t * r ;
3360
+
3361
+ n = lua_gettop (L );
3362
+
3363
+ if (n < 2 ) {
3364
+ return luaL_error (L , "ngx.socket setoption: expecting 2 or 3 "
3365
+ "arguments (including the object) but seen %d" ,
3366
+ lua_gettop (L ));
3367
+ }
3368
+
3369
+ r = ngx_stream_lua_get_req (L );
3370
+ if (r == NULL ) {
3371
+ return luaL_error (L , "no request found" );
3372
+ }
3373
+
3374
+ ctx = ngx_stream_lua_get_module_ctx (r , ngx_stream_lua_module );
3375
+ if (ctx == NULL ) {
3376
+ return luaL_error (L , "no ctx found" );
3377
+ }
3378
+
3379
+ ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_CONTENT
3380
+ | NGX_STREAM_LUA_CONTEXT_TIMER );
3381
+
3382
+ luaL_checktype (L , 1 , LUA_TTABLE );
3383
+
3384
+ option = luaL_checkint (L , 2 );
3385
+
3386
+ switch (option ) {
3387
+ #if (NGX_HAVE_TRANSPARENT_PROXY )
3388
+ case NGX_STREAM_LUA_SOCKET_OPTION_TRANSPARENT :
3389
+ lua_rawseti (L , 1 , SOCKET_IP_TRANSPARENT_INDEX );
3390
+ lua_pushboolean (L , 1 );
3391
+ break ;
3392
+ #endif
3393
+ default :
3394
+ return luaL_error (L , "invalid tcp socket option: %d" , option );
3395
+
3396
+ }
3397
+
3398
+ return 1 ;
3264
3399
}
3265
3400
3266
3401
@@ -4252,7 +4387,8 @@ ngx_stream_lua_socket_tcp_conn_op_resume_handler(ngx_event_t *ev)
4252
4387
4253
4388
4254
4389
static int
4255
- ngx_stream_lua_socket_tcp_conn_op_resume_retval_handler (ngx_stream_lua_request_t * r ,
4390
+ ngx_stream_lua_socket_tcp_conn_op_resume_retval_handler (
4391
+ ngx_stream_lua_request_t * r ,
4256
4392
ngx_stream_lua_socket_tcp_upstream_t * u , lua_State * L )
4257
4393
{
4258
4394
int nret ;
@@ -5048,7 +5184,9 @@ ngx_stream_lua_req_socket_tcp(lua_State *L)
5048
5184
raw = 1 ;
5049
5185
5050
5186
r = ngx_stream_lua_get_req (L );
5051
-
5187
+ if (r == NULL ) {
5188
+ return luaL_error (L , "no request found" );
5189
+ }
5052
5190
5053
5191
ctx = ngx_stream_lua_get_module_ctx (r , ngx_stream_lua_module );
5054
5192
if (ctx == NULL ) {
@@ -5068,8 +5206,6 @@ ngx_stream_lua_req_socket_tcp(lua_State *L)
5068
5206
return 2 ;
5069
5207
}
5070
5208
5071
-
5072
-
5073
5209
dd ("ctx acquired raw req socket: %d" , ctx -> acquired_raw_req_socket );
5074
5210
5075
5211
if (ctx -> acquired_raw_req_socket ) {
@@ -5192,6 +5328,7 @@ ngx_stream_lua_req_socket_rev_handler(ngx_stream_lua_request_t *r)
5192
5328
u -> read_event_handler (r , u );
5193
5329
}
5194
5330
5331
+
5195
5332
static int
5196
5333
ngx_stream_lua_socket_tcp_getreusedtimes (lua_State * L )
5197
5334
{
0 commit comments