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