@@ -24,6 +24,7 @@ typedef struct {
24
24
ngx_connection_t * connection ;
25
25
socklen_t socklen ;
26
26
ngx_sockaddr_t sockaddr ;
27
+ ngx_sockaddr_t local_sockaddr ;
27
28
ngx_str_t host ;
28
29
/* try to avoid allocating memory from the connection pool */
29
30
u_char host_data [NGX_BALANCER_DEF_HOST_LEN ];
@@ -52,6 +53,7 @@ struct ngx_http_lua_balancer_peer_data_s {
52
53
53
54
struct sockaddr * sockaddr ;
54
55
socklen_t socklen ;
56
+ ngx_addr_t * local ;
55
57
56
58
ngx_str_t host ;
57
59
ngx_str_t * addr_text ;
@@ -91,7 +93,7 @@ static void ngx_http_lua_balancer_close_handler(ngx_event_t *ev);
91
93
static ngx_connection_t * ngx_http_lua_balancer_get_cached_item (
92
94
ngx_http_lua_srv_conf_t * lscf , ngx_peer_connection_t * pc , ngx_str_t * name );
93
95
static ngx_uint_t ngx_http_lua_balancer_calc_hash (ngx_str_t * name ,
94
- struct sockaddr * sockaddr , socklen_t socklen );
96
+ struct sockaddr * sockaddr , socklen_t socklen , ngx_addr_t * local );
95
97
96
98
97
99
static struct sockaddr * ngx_http_lua_balancer_default_server_sockaddr ;
@@ -452,6 +454,10 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data)
452
454
}
453
455
}
454
456
457
+ if (bp -> local != NULL ) {
458
+ pc -> local = bp -> local ;
459
+ }
460
+
455
461
if (bp -> sockaddr && bp -> socklen ) {
456
462
pc -> sockaddr = bp -> sockaddr ;
457
463
pc -> socklen = bp -> socklen ;
@@ -646,7 +652,8 @@ ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc, void *data,
646
652
647
653
ngx_queue_insert_head (& lscf -> balancer .cache , q );
648
654
hash = ngx_http_lua_balancer_calc_hash (host ,
649
- bp -> sockaddr , bp -> socklen );
655
+ bp -> sockaddr , bp -> socklen ,
656
+ bp -> local );
650
657
item -> hash = hash ;
651
658
hash %= lscf -> balancer .bucket_cnt ;
652
659
ngx_queue_insert_head (& lscf -> balancer .buckets [hash ], & item -> hnode );
@@ -672,6 +679,15 @@ ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc, void *data,
672
679
673
680
item -> socklen = pc -> socklen ;
674
681
ngx_memcpy (& item -> sockaddr , pc -> sockaddr , pc -> socklen );
682
+ if (pc -> local ) {
683
+ ngx_memcpy (& item -> local_sockaddr ,
684
+ pc -> local -> sockaddr , pc -> local -> socklen );
685
+
686
+ } else {
687
+ ngx_memzero (& item -> local_sockaddr ,
688
+ sizeof (item -> local_sockaddr ));
689
+ }
690
+
675
691
if (host -> data && host -> len ) {
676
692
if (host -> len <= sizeof (item -> host_data )) {
677
693
ngx_memcpy (item -> host_data , host -> data , host -> len );
@@ -704,6 +720,7 @@ ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc, void *data,
704
720
return ;
705
721
706
722
invalid :
723
+
707
724
ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , pc -> log , 0 ,
708
725
"lua balancer: keepalive not saving connection %p" ,
709
726
c );
@@ -915,6 +932,68 @@ ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r,
915
932
}
916
933
917
934
935
+ int
936
+ ngx_http_lua_ffi_balancer_bind_to_local_addr (ngx_http_request_t * r ,
937
+ const u_char * addr , size_t addr_len ,
938
+ u_char * errbuf , size_t * errbuf_size )
939
+ {
940
+ u_char * p ;
941
+ ngx_http_lua_ctx_t * ctx ;
942
+ ngx_http_upstream_t * u ;
943
+ ngx_int_t rc ;
944
+
945
+ ngx_http_lua_balancer_peer_data_t * bp ;
946
+
947
+ if (r == NULL ) {
948
+ p = ngx_snprintf (errbuf , * errbuf_size , "no request found" );
949
+ * errbuf_size = p - errbuf ;
950
+ return NGX_ERROR ;
951
+ }
952
+
953
+ u = r -> upstream ;
954
+
955
+ if (u == NULL ) {
956
+ p = ngx_snprintf (errbuf , * errbuf_size , "no upstream found" );
957
+ * errbuf_size = p - errbuf ;
958
+ return NGX_ERROR ;
959
+ }
960
+
961
+ ctx = ngx_http_get_module_ctx (r , ngx_http_lua_module );
962
+ if (ctx == NULL ) {
963
+ p = ngx_snprintf (errbuf , * errbuf_size , "no ctx found" );
964
+ * errbuf_size = p - errbuf ;
965
+ return NGX_ERROR ;
966
+ }
967
+
968
+ if ((ctx -> context & NGX_HTTP_LUA_CONTEXT_BALANCER ) == 0 ) {
969
+ p = ngx_snprintf (errbuf , * errbuf_size ,
970
+ "API disabled in the current context" );
971
+ * errbuf_size = p - errbuf ;
972
+ return NGX_ERROR ;
973
+ }
974
+
975
+ bp = (ngx_http_lua_balancer_peer_data_t * ) u -> peer .data ;
976
+
977
+ if (bp -> local == NULL ) {
978
+ bp -> local = ngx_palloc (r -> pool , sizeof (ngx_addr_t ));
979
+ if (bp -> local == NULL ) {
980
+ p = ngx_snprintf (errbuf , * errbuf_size , "no memory" );
981
+ * errbuf_size = p - errbuf ;
982
+ return NGX_ERROR ;
983
+ }
984
+ }
985
+
986
+ rc = ngx_parse_addr_port (r -> pool , bp -> local , (u_char * ) addr , addr_len );
987
+ if (rc == NGX_ERROR ) {
988
+ p = ngx_snprintf (errbuf , * errbuf_size , "invalid addr %s" , addr );
989
+ * errbuf_size = p - errbuf ;
990
+ return NGX_ERROR ;
991
+ }
992
+
993
+ return NGX_OK ;
994
+ }
995
+
996
+
918
997
int
919
998
ngx_http_lua_ffi_balancer_enable_keepalive (ngx_http_request_t * r ,
920
999
unsigned long timeout , unsigned int max_requests , char * * err )
@@ -1328,12 +1407,15 @@ ngx_http_lua_upstream_get_ssl_name(ngx_http_request_t *r,
1328
1407
1329
1408
static ngx_uint_t
1330
1409
ngx_http_lua_balancer_calc_hash (ngx_str_t * name ,
1331
- struct sockaddr * sockaddr , socklen_t socklen )
1410
+ struct sockaddr * sockaddr , socklen_t socklen , ngx_addr_t * local )
1332
1411
{
1333
1412
ngx_uint_t hash ;
1334
1413
1335
1414
hash = ngx_hash_key_lc (name -> data , name -> len );
1336
1415
hash ^= ngx_hash_key ((u_char * ) sockaddr , socklen );
1416
+ if (local != NULL ) {
1417
+ hash ^= ngx_hash_key ((u_char * ) local -> sockaddr , local -> socklen );
1418
+ }
1337
1419
1338
1420
return hash ;
1339
1421
}
@@ -1349,12 +1431,14 @@ ngx_http_lua_balancer_get_cached_item(ngx_http_lua_srv_conf_t *lscf,
1349
1431
ngx_connection_t * c ;
1350
1432
struct sockaddr * sockaddr ;
1351
1433
socklen_t socklen ;
1434
+ ngx_addr_t * local ;
1352
1435
ngx_http_lua_balancer_ka_item_t * item ;
1353
1436
1354
1437
sockaddr = pc -> sockaddr ;
1355
1438
socklen = pc -> socklen ;
1439
+ local = pc -> local ;
1356
1440
1357
- hash = ngx_http_lua_balancer_calc_hash (name , sockaddr , socklen );
1441
+ hash = ngx_http_lua_balancer_calc_hash (name , sockaddr , socklen , pc -> local );
1358
1442
head = & lscf -> balancer .buckets [hash % lscf -> balancer .bucket_cnt ];
1359
1443
1360
1444
c = NULL ;
@@ -1372,7 +1456,11 @@ ngx_http_lua_balancer_get_cached_item(ngx_http_lua_srv_conf_t *lscf,
1372
1456
(u_char * ) sockaddr ,
1373
1457
item -> socklen , socklen ) == 0
1374
1458
&& ngx_strncasecmp (name -> data ,
1375
- item -> host .data , name -> len ) == 0 )
1459
+ item -> host .data , name -> len ) == 0
1460
+ && (local == NULL
1461
+ || ngx_memn2cmp ((u_char * ) & item -> local_sockaddr ,
1462
+ (u_char * ) local -> sockaddr ,
1463
+ socklen , local -> socklen ) == 0 ))
1376
1464
{
1377
1465
c = item -> connection ;
1378
1466
ngx_queue_remove (q );
0 commit comments