@@ -37,9 +37,9 @@ static int ngx_stream_lua_socket_tcp_receive(lua_State *L);
37
37
static int ngx_stream_lua_socket_tcp_receiveany (lua_State * L );
38
38
static int ngx_stream_lua_socket_tcp_send (lua_State * L );
39
39
static int ngx_stream_lua_socket_tcp_close (lua_State * L );
40
- static int ngx_stream_lua_socket_tcp_setoption (lua_State * L );
41
40
static int ngx_stream_lua_socket_tcp_settimeout (lua_State * L );
42
41
static int ngx_stream_lua_socket_tcp_settimeouts (lua_State * L );
42
+ static int ngx_stream_lua_socket_tcp_settransparent (lua_State * L );
43
43
static void ngx_stream_lua_socket_tcp_handler (ngx_event_t * ev );
44
44
static ngx_int_t ngx_stream_lua_socket_tcp_get_peer (ngx_peer_connection_t * pc ,
45
45
void * data );
@@ -184,7 +184,6 @@ static void ngx_stream_lua_ssl_handshake_handler(ngx_connection_t *c);
184
184
static int ngx_stream_lua_ssl_free_session (lua_State * L );
185
185
#endif
186
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 );
188
187
189
188
static int ngx_stream_lua_socket_tcp_peek (lua_State * L );
190
189
static ngx_int_t ngx_stream_lua_socket_tcp_peek_resume (
@@ -210,6 +209,14 @@ enum {
210
209
SOCKET_OP_RESUME_CONN
211
210
};
212
211
212
+ enum {
213
+ NGX_STREAM_LUA_SOCKOPT_KEEPALIVE = 1 ,
214
+ NGX_STREAM_LUA_SOCKOPT_REUSEADDR ,
215
+ NGX_STREAM_LUA_SOCKOPT_TCP_NODELAY ,
216
+ NGX_STREAM_LUA_SOCKOPT_SNDBUF ,
217
+ NGX_STREAM_LUA_SOCKOPT_RCVBUF ,
218
+ };
219
+
213
220
214
221
#define ngx_stream_lua_socket_check_busy_connecting (r , u , L ) \
215
222
if ((u)->conn_waiting) { \
@@ -253,25 +260,14 @@ static char ngx_stream_lua_pattern_udata_metatable_key;
253
260
static char ngx_stream_lua_ssl_session_metatable_key ;
254
261
#endif
255
262
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
- }
263
+ #define ngx_stream_lua_tcp_socket_metatable_literal_key "__tcp_cosocket_mt"
266
264
267
265
268
266
void
269
267
ngx_stream_lua_inject_socket_tcp_api (ngx_log_t * log , lua_State * L )
270
268
{
271
269
ngx_int_t rc ;
272
270
273
- ngx_stream_lua_inject_socket_option_consts (L );
274
-
275
271
lua_createtable (L , 0 , 4 /* nrec */ ); /* ngx.socket */
276
272
277
273
lua_pushcfunction (L , ngx_stream_lua_socket_tcp );
@@ -337,7 +333,7 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
337
333
/* {{{tcp object metatable */
338
334
lua_pushlightuserdata (L , ngx_stream_lua_lightudata_mask (
339
335
tcp_socket_metatable_key ));
340
- lua_createtable (L , 0 /* narr */ , 15 /* nrec */ );
336
+ lua_createtable (L , 0 /* narr */ , 17 /* nrec */ );
341
337
342
338
lua_pushcfunction (L , ngx_stream_lua_socket_tcp_bind );
343
339
lua_setfield (L , -2 , "bind" );
@@ -367,12 +363,12 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
367
363
lua_pushcfunction (L , ngx_stream_lua_socket_tcp_close );
368
364
lua_setfield (L , -2 , "close" );
369
365
370
- lua_pushcfunction (L , ngx_stream_lua_socket_tcp_setoption );
371
- lua_setfield (L , -2 , "setoption" );
372
-
373
366
lua_pushcfunction (L , ngx_stream_lua_socket_tcp_settimeout );
374
367
lua_setfield (L , -2 , "settimeout" ); /* ngx socket mt */
375
368
369
+ lua_pushcfunction (L , ngx_stream_lua_socket_tcp_settransparent );
370
+ lua_setfield (L , -2 , "settransparent" ); /* ngx socket mt */
371
+
376
372
lua_pushcfunction (L , ngx_stream_lua_socket_tcp_settimeouts );
377
373
lua_setfield (L , -2 , "settimeouts" ); /* ngx socket mt */
378
374
@@ -388,6 +384,12 @@ ngx_stream_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L)
388
384
lua_pushvalue (L , -1 );
389
385
lua_setfield (L , -2 , "__index" );
390
386
lua_rawset (L , LUA_REGISTRYINDEX );
387
+
388
+ lua_pushliteral (L , ngx_stream_lua_tcp_socket_metatable_literal_key );
389
+ lua_pushlightuserdata (L , ngx_stream_lua_lightudata_mask (
390
+ tcp_socket_metatable_key ));
391
+ lua_rawget (L , LUA_REGISTRYINDEX );
392
+ lua_rawset (L , LUA_REGISTRYINDEX );
391
393
/* }}} */
392
394
393
395
/* {{{upstream userdata metatable */
@@ -903,8 +905,7 @@ ngx_stream_lua_socket_tcp_bind(lua_State *L)
903
905
return luaL_error (L , "no ctx found" );
904
906
}
905
907
906
- ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_CONTENT
907
- | NGX_STREAM_LUA_CONTEXT_TIMER );
908
+ ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_YIELDABLE );
908
909
909
910
luaL_checktype (L , 1 , LUA_TTABLE );
910
911
@@ -1161,7 +1162,7 @@ ngx_stream_lua_socket_tcp_connect(lua_State *L)
1161
1162
#if (NGX_HAVE_TRANSPARENT_PROXY )
1162
1163
lua_rawgeti (L , 1 , SOCKET_IP_TRANSPARENT_INDEX );
1163
1164
1164
- if (lua_tointeger (L , -1 ) > 0 ) {
1165
+ if (lua_toboolean (L , -1 )) {
1165
1166
pc -> transparent = 1 ;
1166
1167
ngx_log_debug0 (NGX_LOG_DEBUG_STREAM , r -> connection -> log , 0 ,
1167
1168
"stream lua set TCP upstream with IP_TRANSPARENT" );
@@ -3349,53 +3350,123 @@ ngx_stream_lua_socket_tcp_shutdown(lua_State *L)
3349
3350
}
3350
3351
3351
3352
3352
- static int
3353
- ngx_stream_lua_socket_tcp_setoption (lua_State * L )
3353
+ int
3354
+ ngx_stream_lua_ffi_socket_tcp_getoption (ngx_stream_lua_socket_tcp_upstream_t * u ,
3355
+ int option , int * val , u_char * err , size_t * errlen )
3354
3356
{
3355
- ngx_stream_lua_ctx_t * ctx ;
3356
- int n ;
3357
- int option ;
3357
+ socklen_t len ;
3358
+ int fd , rc ;
3358
3359
3359
- ngx_stream_lua_request_t * r ;
3360
+ if (u == NULL || u -> peer .connection == NULL ) {
3361
+ * errlen = ngx_snprintf (err , * errlen , "closed" ) - err ;
3362
+ return NGX_ERROR ;
3363
+ }
3360
3364
3361
- n = lua_gettop ( L ) ;
3365
+ fd = u -> peer . connection -> fd ;
3362
3366
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
+ if (fd == (int ) -1 ) {
3368
+ * errlen = ngx_snprintf (err , * errlen , "invalid socket fd" ) - err ;
3369
+ return NGX_ERROR ;
3367
3370
}
3368
3371
3369
- r = ngx_stream_lua_get_req (L );
3370
- if (r == NULL ) {
3371
- return luaL_error (L , "no request found" );
3372
+ len = sizeof (int );
3373
+
3374
+ switch (option ) {
3375
+ case NGX_STREAM_LUA_SOCKOPT_KEEPALIVE :
3376
+ rc = getsockopt (fd , SOL_SOCKET , SO_KEEPALIVE , (void * ) val , & len );
3377
+ break ;
3378
+
3379
+ case NGX_STREAM_LUA_SOCKOPT_REUSEADDR :
3380
+ rc = getsockopt (fd , SOL_SOCKET , SO_REUSEADDR , (void * ) val , & len );
3381
+ break ;
3382
+
3383
+ case NGX_STREAM_LUA_SOCKOPT_TCP_NODELAY :
3384
+ rc = getsockopt (fd , IPPROTO_TCP , TCP_NODELAY , (void * ) val , & len );
3385
+ break ;
3386
+
3387
+ case NGX_STREAM_LUA_SOCKOPT_SNDBUF :
3388
+ rc = getsockopt (fd , SOL_SOCKET , SO_RCVBUF , (void * ) val , & len );
3389
+ break ;
3390
+
3391
+ case NGX_STREAM_LUA_SOCKOPT_RCVBUF :
3392
+ rc = getsockopt (fd , SOL_SOCKET , SO_SNDBUF , (void * ) val , & len );
3393
+ break ;
3394
+
3395
+ default :
3396
+ * errlen = ngx_snprintf (err , * errlen , "unsupported option %d" , option )
3397
+ - err ;
3398
+ return NGX_ERROR ;
3372
3399
}
3373
3400
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
- }
3401
+ if ( rc == -1 ) {
3402
+ * errlen = ngx_strerror ( ngx_errno , err , NGX_MAX_ERROR_STR ) - err ;
3403
+ return NGX_ERROR ;
3404
+ }
3378
3405
3379
- ngx_stream_lua_check_context ( L , ctx , NGX_STREAM_LUA_CONTEXT_CONTENT
3380
- | NGX_STREAM_LUA_CONTEXT_TIMER );
3406
+ return NGX_OK ;
3407
+ }
3381
3408
3382
- luaL_checktype (L , 1 , LUA_TTABLE );
3383
3409
3384
- option = luaL_checkint (L , 2 );
3410
+ int
3411
+ ngx_stream_lua_ffi_socket_tcp_setoption (
3412
+ ngx_stream_lua_socket_tcp_upstream_t * u ,
3413
+ int option , int val , u_char * err , size_t * errlen )
3414
+ {
3415
+ socklen_t len ;
3416
+ int fd , rc ;
3385
3417
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 );
3418
+ if (u == NULL || u -> peer .connection == NULL ) {
3419
+ * errlen = ngx_snprintf (err , * errlen , "closed" ) - err ;
3420
+ return NGX_ERROR ;
3421
+ }
3422
+
3423
+ fd = u -> peer .connection -> fd ;
3395
3424
3425
+ if (fd == (int ) -1 ) {
3426
+ * errlen = ngx_snprintf (err , * errlen , "invalid socket fd" ) - err ;
3427
+ return NGX_ERROR ;
3396
3428
}
3397
3429
3398
- return 1 ;
3430
+ len = sizeof (int );
3431
+
3432
+ switch (option ) {
3433
+ case NGX_STREAM_LUA_SOCKOPT_KEEPALIVE :
3434
+ rc = setsockopt (fd , SOL_SOCKET , SO_KEEPALIVE ,
3435
+ (const void * ) & val , len );
3436
+ break ;
3437
+
3438
+ case NGX_STREAM_LUA_SOCKOPT_REUSEADDR :
3439
+ rc = setsockopt (fd , SOL_SOCKET , SO_REUSEADDR ,
3440
+ (const void * ) & val , len );
3441
+ break ;
3442
+
3443
+ case NGX_STREAM_LUA_SOCKOPT_TCP_NODELAY :
3444
+ rc = setsockopt (fd , IPPROTO_TCP , TCP_NODELAY ,
3445
+ (const void * ) & val , len );
3446
+ break ;
3447
+
3448
+ case NGX_STREAM_LUA_SOCKOPT_SNDBUF :
3449
+ rc = setsockopt (fd , SOL_SOCKET , SO_RCVBUF ,
3450
+ (const void * ) & val , len );
3451
+ break ;
3452
+
3453
+ case NGX_STREAM_LUA_SOCKOPT_RCVBUF :
3454
+ rc = setsockopt (fd , SOL_SOCKET , SO_SNDBUF ,
3455
+ (const void * ) & val , len );
3456
+ break ;
3457
+
3458
+ default :
3459
+ * errlen = ngx_snprintf (err , * errlen , "unsupported option: %d" , option )
3460
+ - err ;
3461
+ return NGX_ERROR ;
3462
+ }
3463
+
3464
+ if (rc == -1 ) {
3465
+ * errlen = ngx_strerror (ngx_errno , err , NGX_MAX_ERROR_STR ) - err ;
3466
+ return NGX_ERROR ;
3467
+ }
3468
+
3469
+ return NGX_OK ;
3399
3470
}
3400
3471
3401
3472
@@ -3510,6 +3581,43 @@ ngx_stream_lua_socket_tcp_settimeouts(lua_State *L)
3510
3581
}
3511
3582
3512
3583
3584
+ static int
3585
+ ngx_stream_lua_socket_tcp_settransparent (lua_State * L )
3586
+ {
3587
+ ngx_stream_lua_ctx_t * ctx ;
3588
+ int n ;
3589
+
3590
+ ngx_stream_lua_request_t * r ;
3591
+
3592
+ n = lua_gettop (L );
3593
+
3594
+ if (n != 1 ) {
3595
+ return luaL_error (L , "ngx.socket settransparent: expecting 1"
3596
+ "argument (including the object) but seen %d" ,
3597
+ lua_gettop (L ));
3598
+ }
3599
+
3600
+ r = ngx_stream_lua_get_req (L );
3601
+ if (r == NULL ) {
3602
+ return luaL_error (L , "no request found" );
3603
+ }
3604
+
3605
+ ctx = ngx_stream_lua_get_module_ctx (r , ngx_stream_lua_module );
3606
+ if (ctx == NULL ) {
3607
+ return luaL_error (L , "no ctx found" );
3608
+ }
3609
+
3610
+ ngx_stream_lua_check_context (L , ctx , NGX_STREAM_LUA_CONTEXT_YIELDABLE );
3611
+
3612
+ luaL_checktype (L , 1 , LUA_TTABLE );
3613
+
3614
+ lua_rawseti (L , 1 , SOCKET_IP_TRANSPARENT_INDEX );
3615
+ lua_pushboolean (L , 1 );
3616
+
3617
+ return 1 ;
3618
+ }
3619
+
3620
+
3513
3621
static void
3514
3622
ngx_stream_lua_socket_tcp_handler (ngx_event_t * ev )
3515
3623
{
0 commit comments