annotate src/http/modules/ngx_http_upstream_hash_module.c @ 7653:8409f9df6219

SSL: client certificate validation with OCSP (ticket #1534). OCSP validation for client certificates is enabled by the "ssl_ocsp" directive. OCSP responder can be optionally specified by "ssl_ocsp_responder". When session is reused, peer chain is not available for validation. If the verified chain contains certificates from the peer chain not available at the server, validation will fail.
author Roman Arutyunyan <arut@nginx.com>
date Fri, 22 May 2020 17:30:12 +0300
parents d964b0aee8e7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
1
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
2 /*
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
3 * Copyright (C) Roman Arutyunyan
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
4 * Copyright (C) Nginx, Inc.
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
5 */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
6
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
7
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
8 #include <ngx_config.h>
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
9 #include <ngx_core.h>
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
10 #include <ngx_http.h>
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
11
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
12
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
13 typedef struct {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
14 uint32_t hash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
15 ngx_str_t *server;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
16 } ngx_http_upstream_chash_point_t;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
17
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
18
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
19 typedef struct {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
20 ngx_uint_t number;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
21 ngx_http_upstream_chash_point_t point[1];
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
22 } ngx_http_upstream_chash_points_t;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
23
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
24
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
25 typedef struct {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
26 ngx_http_complex_value_t key;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
27 ngx_http_upstream_chash_points_t *points;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
28 } ngx_http_upstream_hash_srv_conf_t;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
29
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
30
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
31 typedef struct {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
32 /* the round robin data must be first */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
33 ngx_http_upstream_rr_peer_data_t rrp;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
34 ngx_http_upstream_hash_srv_conf_t *conf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
35 ngx_str_t key;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
36 ngx_uint_t tries;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
37 ngx_uint_t rehash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
38 uint32_t hash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
39 ngx_event_get_peer_pt get_rr_peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
40 } ngx_http_upstream_hash_peer_data_t;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
41
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
42
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
43 static ngx_int_t ngx_http_upstream_init_hash(ngx_conf_t *cf,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
44 ngx_http_upstream_srv_conf_t *us);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
45 static ngx_int_t ngx_http_upstream_init_hash_peer(ngx_http_request_t *r,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
46 ngx_http_upstream_srv_conf_t *us);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
47 static ngx_int_t ngx_http_upstream_get_hash_peer(ngx_peer_connection_t *pc,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
48 void *data);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
49
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
50 static ngx_int_t ngx_http_upstream_init_chash(ngx_conf_t *cf,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
51 ngx_http_upstream_srv_conf_t *us);
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
52 static int ngx_libc_cdecl
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
53 ngx_http_upstream_chash_cmp_points(const void *one, const void *two);
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
54 static ngx_uint_t ngx_http_upstream_find_chash_point(
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
55 ngx_http_upstream_chash_points_t *points, uint32_t hash);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
56 static ngx_int_t ngx_http_upstream_init_chash_peer(ngx_http_request_t *r,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
57 ngx_http_upstream_srv_conf_t *us);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
58 static ngx_int_t ngx_http_upstream_get_chash_peer(ngx_peer_connection_t *pc,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
59 void *data);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
60
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
61 static void *ngx_http_upstream_hash_create_conf(ngx_conf_t *cf);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
62 static char *ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
63 void *conf);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
64
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
65
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
66 static ngx_command_t ngx_http_upstream_hash_commands[] = {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
67
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
68 { ngx_string("hash"),
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
69 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
70 ngx_http_upstream_hash,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
71 NGX_HTTP_SRV_CONF_OFFSET,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
72 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
73 NULL },
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
74
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
75 ngx_null_command
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
76 };
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
77
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
78
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
79 static ngx_http_module_t ngx_http_upstream_hash_module_ctx = {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
80 NULL, /* preconfiguration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
81 NULL, /* postconfiguration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
82
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
83 NULL, /* create main configuration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
84 NULL, /* init main configuration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
85
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
86 ngx_http_upstream_hash_create_conf, /* create server configuration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
87 NULL, /* merge server configuration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
88
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
89 NULL, /* create location configuration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
90 NULL /* merge location configuration */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
91 };
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
92
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
93
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
94 ngx_module_t ngx_http_upstream_hash_module = {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
95 NGX_MODULE_V1,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
96 &ngx_http_upstream_hash_module_ctx, /* module context */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
97 ngx_http_upstream_hash_commands, /* module directives */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
98 NGX_HTTP_MODULE, /* module type */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
99 NULL, /* init master */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
100 NULL, /* init module */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
101 NULL, /* init process */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
102 NULL, /* init thread */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
103 NULL, /* exit thread */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
104 NULL, /* exit process */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
105 NULL, /* exit master */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
106 NGX_MODULE_V1_PADDING
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
107 };
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
108
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
109
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
110 static ngx_int_t
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
111 ngx_http_upstream_init_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
112 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
113 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
114 return NGX_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
115 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
116
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
117 us->peer.init = ngx_http_upstream_init_hash_peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
118
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
119 return NGX_OK;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
120 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
121
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
122
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
123 static ngx_int_t
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
124 ngx_http_upstream_init_hash_peer(ngx_http_request_t *r,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
125 ngx_http_upstream_srv_conf_t *us)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
126 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
127 ngx_http_upstream_hash_srv_conf_t *hcf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
128 ngx_http_upstream_hash_peer_data_t *hp;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
129
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
130 hp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_hash_peer_data_t));
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
131 if (hp == NULL) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
132 return NGX_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
133 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
134
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
135 r->upstream->peer.data = &hp->rrp;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
136
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
137 if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
138 return NGX_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
139 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
140
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
141 r->upstream->peer.get = ngx_http_upstream_get_hash_peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
142
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
143 hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
144
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
145 if (ngx_http_complex_value(r, &hcf->key, &hp->key) != NGX_OK) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
146 return NGX_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
147 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
148
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
149 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
150 "upstream hash key:\"%V\"", &hp->key);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
151
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
152 hp->conf = hcf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
153 hp->tries = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
154 hp->rehash = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
155 hp->hash = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
156 hp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
157
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
158 return NGX_OK;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
159 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
160
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
161
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
162 static ngx_int_t
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
163 ngx_http_upstream_get_hash_peer(ngx_peer_connection_t *pc, void *data)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
164 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
165 ngx_http_upstream_hash_peer_data_t *hp = data;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
166
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
167 time_t now;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
168 u_char buf[NGX_INT_T_LEN];
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
169 size_t size;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
170 uint32_t hash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
171 ngx_int_t w;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
172 uintptr_t m;
6121
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
173 ngx_uint_t n, p;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
174 ngx_http_upstream_rr_peer_t *peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
175
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
176 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
177 "get hash peer, try: %ui", pc->tries);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
178
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 7124
diff changeset
179 ngx_http_upstream_rr_peers_rlock(hp->rrp.peers);
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
180
7513
d964b0aee8e7 Upstream hash: fall back to round-robin if hash key is empty.
Niklas Keller <me@kelunik.com>
parents: 7300
diff changeset
181 if (hp->tries > 20 || hp->rrp.peers->single || hp->key.len == 0) {
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
182 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
183 return hp->get_rr_peer(pc, &hp->rrp);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
184 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
185
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
186 now = ngx_time();
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
187
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
188 pc->cached = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
189 pc->connection = NULL;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
190
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
191 for ( ;; ) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
192
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
193 /*
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
194 * Hash expression is compatible with Cache::Memcached:
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
195 * ((crc32([REHASH] KEY) >> 16) & 0x7fff) + PREV_HASH
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
196 * with REHASH omitted at the first iteration.
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
197 */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
198
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
199 ngx_crc32_init(hash);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
200
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
201 if (hp->rehash > 0) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
202 size = ngx_sprintf(buf, "%ui", hp->rehash) - buf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
203 ngx_crc32_update(&hash, buf, size);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
204 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
205
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
206 ngx_crc32_update(&hash, hp->key.data, hp->key.len);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
207 ngx_crc32_final(hash);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
208
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
209 hash = (hash >> 16) & 0x7fff;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
210
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
211 hp->hash += hash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
212 hp->rehash++;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
213
6121
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
214 w = hp->hash % hp->rrp.peers->total_weight;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
215 peer = hp->rrp.peers->peer;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
216 p = 0;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
217
6121
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
218 while (w >= peer->weight) {
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
219 w -= peer->weight;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
220 peer = peer->next;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
221 p++;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
222 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
223
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
224 n = p / (8 * sizeof(uintptr_t));
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
225 m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
226
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
227 if (hp->rrp.tried[n] & m) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
228 goto next;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
229 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
230
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 7124
diff changeset
231 ngx_http_upstream_rr_peer_lock(hp->rrp.peers, peer);
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 7124
diff changeset
232
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
233 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
234 "get hash peer, value:%uD, peer:%ui", hp->hash, p);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
235
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
236 if (peer->down) {
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 7124
diff changeset
237 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
238 goto next;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
239 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
240
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
241 if (peer->max_fails
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
242 && peer->fails >= peer->max_fails
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
243 && now - peer->checked <= peer->fail_timeout)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
244 {
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 7124
diff changeset
245 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
246 goto next;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
247 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
248
6705
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
249 if (peer->max_conns && peer->conns >= peer->max_conns) {
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 7124
diff changeset
250 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
6705
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
251 goto next;
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
252 }
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
253
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
254 break;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
255
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
256 next:
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
257
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
258 if (++hp->tries > 20) {
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
259 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
260 return hp->get_rr_peer(pc, &hp->rrp);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
261 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
262 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
263
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
264 hp->rrp.current = peer;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
265
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
266 pc->sockaddr = peer->sockaddr;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
267 pc->socklen = peer->socklen;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
268 pc->name = &peer->name;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
269
6099
6ff0ebd6fbf4 Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents: 5991
diff changeset
270 peer->conns++;
6ff0ebd6fbf4 Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents: 5991
diff changeset
271
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
272 if (now - peer->checked > peer->fail_timeout) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
273 peer->checked = now;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
274 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
275
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 7124
diff changeset
276 ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
277 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
278
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
279 hp->rrp.tried[n] |= m;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
280
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
281 return NGX_OK;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
282 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
283
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
284
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
285 static ngx_int_t
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
286 ngx_http_upstream_init_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
287 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
288 u_char *host, *port, c;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
289 size_t host_len, port_len, size;
6148
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
290 uint32_t hash, base_hash;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
291 ngx_str_t *server;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
292 ngx_uint_t npoints, i, j;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
293 ngx_http_upstream_rr_peer_t *peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
294 ngx_http_upstream_rr_peers_t *peers;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
295 ngx_http_upstream_chash_points_t *points;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
296 ngx_http_upstream_hash_srv_conf_t *hcf;
6148
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
297 union {
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
298 uint32_t value;
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
299 u_char byte[4];
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
300 } prev_hash;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
301
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
302 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
303 return NGX_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
304 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
305
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
306 us->peer.init = ngx_http_upstream_init_chash_peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
307
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
308 peers = us->peer.data;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
309 npoints = peers->total_weight * 160;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
310
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
311 size = sizeof(ngx_http_upstream_chash_points_t)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
312 + sizeof(ngx_http_upstream_chash_point_t) * (npoints - 1);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
313
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
314 points = ngx_palloc(cf->pool, size);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
315 if (points == NULL) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
316 return NGX_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
317 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
318
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
319 points->number = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
320
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
321 for (peer = peers->peer; peer; peer = peer->next) {
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
322 server = &peer->server;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
323
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
324 /*
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
325 * Hash expression is compatible with Cache::Memcached::Fast:
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
326 * crc32(HOST \0 PORT PREV_HASH).
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
327 */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
328
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
329 if (server->len >= 5
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
330 && ngx_strncasecmp(server->data, (u_char *) "unix:", 5) == 0)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
331 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
332 host = server->data + 5;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
333 host_len = server->len - 5;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
334 port = NULL;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
335 port_len = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
336 goto done;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
337 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
338
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
339 for (j = 0; j < server->len; j++) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
340 c = server->data[server->len - j - 1];
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
341
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
342 if (c == ':') {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
343 host = server->data;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
344 host_len = server->len - j - 1;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
345 port = server->data + server->len - j;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
346 port_len = j;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
347 goto done;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
348 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
349
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
350 if (c < '0' || c > '9') {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
351 break;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
352 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
353 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
354
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
355 host = server->data;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
356 host_len = server->len;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
357 port = NULL;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
358 port_len = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
359
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
360 done:
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
361
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
362 ngx_crc32_init(base_hash);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
363 ngx_crc32_update(&base_hash, host, host_len);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
364 ngx_crc32_update(&base_hash, (u_char *) "", 1);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
365 ngx_crc32_update(&base_hash, port, port_len);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
366
6148
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
367 prev_hash.value = 0;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
368 npoints = peer->weight * 160;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
369
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
370 for (j = 0; j < npoints; j++) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
371 hash = base_hash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
372
6148
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
373 ngx_crc32_update(&hash, prev_hash.byte, 4);
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
374 ngx_crc32_final(hash);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
375
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
376 points->point[points->number].hash = hash;
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
377 points->point[points->number].server = server;
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
378 points->number++;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
379
6148
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
380 #if (NGX_HAVE_LITTLE_ENDIAN)
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
381 prev_hash.value = hash;
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
382 #else
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
383 prev_hash.byte[0] = (u_char) (hash & 0xff);
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
384 prev_hash.byte[1] = (u_char) ((hash >> 8) & 0xff);
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
385 prev_hash.byte[2] = (u_char) ((hash >> 16) & 0xff);
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
386 prev_hash.byte[3] = (u_char) ((hash >> 24) & 0xff);
bf8b6534db3a Upstream hash: consistency across little/big endianness.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
387 #endif
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
388 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
389 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
390
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
391 ngx_qsort(points->point,
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
392 points->number,
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
393 sizeof(ngx_http_upstream_chash_point_t),
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
394 ngx_http_upstream_chash_cmp_points);
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
395
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
396 for (i = 0, j = 1; j < points->number; j++) {
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
397 if (points->point[i].hash != points->point[j].hash) {
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
398 points->point[++i] = points->point[j];
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
399 }
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
400 }
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
401
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
402 points->number = i + 1;
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
403
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
404 hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
405 hcf->points = points;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
406
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
407 return NGX_OK;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
408 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
409
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
410
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
411 static int ngx_libc_cdecl
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
412 ngx_http_upstream_chash_cmp_points(const void *one, const void *two)
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
413 {
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
414 ngx_http_upstream_chash_point_t *first =
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
415 (ngx_http_upstream_chash_point_t *) one;
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
416 ngx_http_upstream_chash_point_t *second =
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
417 (ngx_http_upstream_chash_point_t *) two;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
418
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
419 if (first->hash < second->hash) {
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
420 return -1;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
421
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
422 } else if (first->hash > second->hash) {
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
423 return 1;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
424
5991
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
425 } else {
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
426 return 0;
435ee290c2e1 Upstream hash: speedup consistent hash init.
Roman Arutyunyan <arut@nginx.com>
parents: 5717
diff changeset
427 }
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
428 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
429
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
430
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
431 static ngx_uint_t
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
432 ngx_http_upstream_find_chash_point(ngx_http_upstream_chash_points_t *points,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
433 uint32_t hash)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
434 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
435 ngx_uint_t i, j, k;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
436 ngx_http_upstream_chash_point_t *point;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
437
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
438 /* find first point >= hash */
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
439
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
440 point = &points->point[0];
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
441
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
442 i = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
443 j = points->number;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
444
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
445 while (i < j) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
446 k = (i + j) / 2;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
447
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
448 if (hash > point[k].hash) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
449 i = k + 1;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
450
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
451 } else if (hash < point[k].hash) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
452 j = k;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
453
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
454 } else {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
455 return k;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
456 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
457 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
458
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
459 return i;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
460 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
461
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
462
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
463 static ngx_int_t
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
464 ngx_http_upstream_init_chash_peer(ngx_http_request_t *r,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
465 ngx_http_upstream_srv_conf_t *us)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
466 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
467 uint32_t hash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
468 ngx_http_upstream_hash_srv_conf_t *hcf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
469 ngx_http_upstream_hash_peer_data_t *hp;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
470
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
471 if (ngx_http_upstream_init_hash_peer(r, us) != NGX_OK) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
472 return NGX_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
473 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
474
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
475 r->upstream->peer.get = ngx_http_upstream_get_chash_peer;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
476
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
477 hp = r->upstream->peer.data;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
478 hcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_hash_module);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
479
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
480 hash = ngx_crc32_long(hp->key.data, hp->key.len);
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
481
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
482 ngx_http_upstream_rr_peers_rlock(hp->rrp.peers);
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
483
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
484 hp->hash = ngx_http_upstream_find_chash_point(hcf->points, hash);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
485
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
486 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
487
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
488 return NGX_OK;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
489 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
490
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
491
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
492 static ngx_int_t
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
493 ngx_http_upstream_get_chash_peer(ngx_peer_connection_t *pc, void *data)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
494 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
495 ngx_http_upstream_hash_peer_data_t *hp = data;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
496
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
497 time_t now;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
498 intptr_t m;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
499 ngx_str_t *server;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
500 ngx_int_t total;
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
501 ngx_uint_t i, n, best_i;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
502 ngx_http_upstream_rr_peer_t *peer, *best;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
503 ngx_http_upstream_chash_point_t *point;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
504 ngx_http_upstream_chash_points_t *points;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
505 ngx_http_upstream_hash_srv_conf_t *hcf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
506
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
507 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
508 "get consistent hash peer, try: %ui", pc->tries);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
509
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
510 ngx_http_upstream_rr_peers_wlock(hp->rrp.peers);
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
511
7513
d964b0aee8e7 Upstream hash: fall back to round-robin if hash key is empty.
Niklas Keller <me@kelunik.com>
parents: 7300
diff changeset
512 if (hp->tries > 20 || hp->rrp.peers->single || hp->key.len == 0) {
7123
6c52b24fcf8e Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6705
diff changeset
513 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
6c52b24fcf8e Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6705
diff changeset
514 return hp->get_rr_peer(pc, &hp->rrp);
6c52b24fcf8e Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6705
diff changeset
515 }
6c52b24fcf8e Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6705
diff changeset
516
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
517 pc->cached = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
518 pc->connection = NULL;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
519
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
520 now = ngx_time();
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
521 hcf = hp->conf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
522
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
523 points = hcf->points;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
524 point = &points->point[0];
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
525
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
526 for ( ;; ) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
527 server = point[hp->hash % points->number].server;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
528
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
529 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
530 "consistent hash peer:%uD, server:\"%V\"",
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
531 hp->hash, server);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
532
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
533 best = NULL;
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
534 best_i = 0;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
535 total = 0;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
536
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
537 for (peer = hp->rrp.peers->peer, i = 0;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
538 peer;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
539 peer = peer->next, i++)
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
540 {
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
541 n = i / (8 * sizeof(uintptr_t));
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
542 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
543
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
544 if (hp->rrp.tried[n] & m) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
545 continue;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
546 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
547
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
548 if (peer->down) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
549 continue;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
550 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
551
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
552 if (peer->max_fails
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
553 && peer->fails >= peer->max_fails
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
554 && now - peer->checked <= peer->fail_timeout)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
555 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
556 continue;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
557 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
558
6705
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
559 if (peer->max_conns && peer->conns >= peer->max_conns) {
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
560 continue;
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
561 }
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
562
7124
3b4fa572d56d Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7123
diff changeset
563 if (peer->server.len != server->len
3b4fa572d56d Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7123
diff changeset
564 || ngx_strncmp(peer->server.data, server->data, server->len)
3b4fa572d56d Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7123
diff changeset
565 != 0)
3b4fa572d56d Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7123
diff changeset
566 {
3b4fa572d56d Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7123
diff changeset
567 continue;
3b4fa572d56d Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7123
diff changeset
568 }
3b4fa572d56d Upstream hash: reordered peer checks.
Maxim Dounin <mdounin@mdounin.ru>
parents: 7123
diff changeset
569
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
570 peer->current_weight += peer->effective_weight;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
571 total += peer->effective_weight;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
572
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
573 if (peer->effective_weight < peer->weight) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
574 peer->effective_weight++;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
575 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
576
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
577 if (best == NULL || peer->current_weight > best->current_weight) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
578 best = peer;
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
579 best_i = i;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
580 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
581 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
582
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
583 if (best) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
584 best->current_weight -= total;
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
585 goto found;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
586 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
587
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
588 hp->hash++;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
589 hp->tries++;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
590
7123
6c52b24fcf8e Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6705
diff changeset
591 if (hp->tries > 20) {
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
592 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
7123
6c52b24fcf8e Upstream hash: limited number of tries in consistent case.
Maxim Dounin <mdounin@mdounin.ru>
parents: 6705
diff changeset
593 return hp->get_rr_peer(pc, &hp->rrp);
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
594 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
595 }
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
596
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
597 found:
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
598
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
599 hp->rrp.current = best;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
600
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
601 pc->sockaddr = best->sockaddr;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
602 pc->socklen = best->socklen;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
603 pc->name = &best->name;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
604
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
605 best->conns++;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
606
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
607 if (now - best->checked > best->fail_timeout) {
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
608 best->checked = now;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
609 }
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
610
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
611 ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
612
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
613 n = best_i / (8 * sizeof(uintptr_t));
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
614 m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t));
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
615
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
616 hp->rrp.tried[n] |= m;
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
617
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
618 return NGX_OK;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
619 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
620
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
621
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
622 static void *
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
623 ngx_http_upstream_hash_create_conf(ngx_conf_t *cf)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
624 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
625 ngx_http_upstream_hash_srv_conf_t *conf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
626
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
627 conf = ngx_palloc(cf->pool, sizeof(ngx_http_upstream_hash_srv_conf_t));
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
628 if (conf == NULL) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
629 return NULL;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
630 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
631
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
632 conf->points = NULL;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
633
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
634 return conf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
635 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
636
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
637
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
638 static char *
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
639 ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
640 {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
641 ngx_http_upstream_hash_srv_conf_t *hcf = conf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
642
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
643 ngx_str_t *value;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
644 ngx_http_upstream_srv_conf_t *uscf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
645 ngx_http_compile_complex_value_t ccv;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
646
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
647 value = cf->args->elts;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
648
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
649 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
650
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
651 ccv.cf = cf;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
652 ccv.value = &value[1];
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
653 ccv.complex_value = &hcf->key;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
654
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
655 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
656 return NGX_CONF_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
657 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
658
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
659 uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
660
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
661 if (uscf->peer.init_upstream) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
662 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
663 "load balancing method redefined");
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
664 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
665
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
666 uscf->flags = NGX_HTTP_UPSTREAM_CREATE
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
667 |NGX_HTTP_UPSTREAM_WEIGHT
6705
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6702
diff changeset
668 |NGX_HTTP_UPSTREAM_MAX_CONNS
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
669 |NGX_HTTP_UPSTREAM_MAX_FAILS
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
670 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
671 |NGX_HTTP_UPSTREAM_DOWN;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
672
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
673 if (cf->args->nelts == 2) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
674 uscf->peer.init_upstream = ngx_http_upstream_init_hash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
675
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
676 } else if (ngx_strcmp(value[2].data, "consistent") == 0) {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
677 uscf->peer.init_upstream = ngx_http_upstream_init_chash;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
678
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
679 } else {
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
680 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
681 "invalid parameter \"%V\"", &value[2]);
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
682 return NGX_CONF_ERROR;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
683 }
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
684
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
685 return NGX_CONF_OK;
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents:
diff changeset
686 }