Mercurial > hg > nginx-quic
annotate src/http/ngx_http_upstream_round_robin.c @ 4041:f87edc142316 stable-1.0
Merge of r3960, r3961, r3962, r3963, r3965:
SSL related fixes:
*) MSIE export versions are rare now, so RSA 512 key is generated on demand
and is shared among all hosts instead of pregenerating for every HTTPS host
on configuraiton phase. This decreases start time for configuration with
large number of HTTPS hosts.
*) ECDHE support; patch by Adrian Kotelba
*) fix build by gcc46 with -Wunused-value option
*) fix SSL connection issues on platforms with 32-bit off_t
*) do not try to reuse and save a SSL session for a peer created on the fly
by ngx_http_upstream_create_round_robin_peer(), since the peer lives
only during request so the saved SSL session will never be used again
and just causes memory leak
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 29 Aug 2011 12:35:53 +0000 |
parents | 7af1e5fe102c |
children | 74a93d3fdd85 e917fc5eceb7 |
rev | line source |
---|---|
884 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
1956
cb8c0c8e0c27
use ngx_int_t in ngx_sort() callback
Igor Sysoev <igor@sysoev.ru>
parents:
1887
diff
changeset
|
12 static ngx_int_t ngx_http_upstream_cmp_servers(const void *one, |
cb8c0c8e0c27
use ngx_int_t in ngx_sort() callback
Igor Sysoev <igor@sysoev.ru>
parents:
1887
diff
changeset
|
13 const void *two); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
14 static ngx_uint_t |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
15 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers); |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
16 |
4041
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
17 #if (NGX_HTTP_SSL) |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
18 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
19 static ngx_int_t ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
20 void *data); |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
21 static void ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
22 void *data); |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
23 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
24 #endif |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
25 |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
26 |
884 | 27 ngx_int_t |
28 ngx_http_upstream_init_round_robin(ngx_conf_t *cf, | |
29 ngx_http_upstream_srv_conf_t *us) | |
30 { | |
31 ngx_url_t u; | |
32 ngx_uint_t i, j, n; | |
33 ngx_http_upstream_server_t *server; | |
1378 | 34 ngx_http_upstream_rr_peers_t *peers, *backup; |
884 | 35 |
36 us->peer.init = ngx_http_upstream_init_round_robin_peer; | |
37 | |
38 if (us->servers) { | |
39 server = us->servers->elts; | |
40 | |
1378 | 41 n = 0; |
42 | |
884 | 43 for (i = 0; i < us->servers->nelts; i++) { |
1378 | 44 if (server[i].backup) { |
45 continue; | |
46 } | |
47 | |
884 | 48 n += server[i].naddrs; |
49 } | |
50 | |
51 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
52 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
53 if (peers == NULL) { | |
54 return NGX_ERROR; | |
55 } | |
56 | |
1378 | 57 peers->single = (n == 1); |
884 | 58 peers->number = n; |
59 peers->name = &us->host; | |
60 | |
61 n = 0; | |
62 | |
63 for (i = 0; i < us->servers->nelts; i++) { | |
64 for (j = 0; j < server[i].naddrs; j++) { | |
1378 | 65 if (server[i].backup) { |
66 continue; | |
67 } | |
68 | |
884 | 69 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; |
70 peers->peer[n].socklen = server[i].addrs[j].socklen; | |
71 peers->peer[n].name = server[i].addrs[j].name; | |
72 peers->peer[n].max_fails = server[i].max_fails; | |
73 peers->peer[n].fail_timeout = server[i].fail_timeout; | |
74 peers->peer[n].down = server[i].down; | |
1376
6ff8c0c1e194
"down" server caused endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1344
diff
changeset
|
75 peers->peer[n].weight = server[i].down ? 0 : server[i].weight; |
6ff8c0c1e194
"down" server caused endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1344
diff
changeset
|
76 peers->peer[n].current_weight = peers->peer[n].weight; |
884 | 77 n++; |
78 } | |
79 } | |
80 | |
81 us->peer.data = peers; | |
82 | |
1379 | 83 ngx_sort(&peers->peer[0], (size_t) n, |
84 sizeof(ngx_http_upstream_rr_peer_t), | |
85 ngx_http_upstream_cmp_servers); | |
86 | |
1378 | 87 /* backup servers */ |
88 | |
89 n = 0; | |
90 | |
91 for (i = 0; i < us->servers->nelts; i++) { | |
92 if (!server[i].backup) { | |
93 continue; | |
94 } | |
95 | |
96 n += server[i].naddrs; | |
97 } | |
98 | |
99 if (n == 0) { | |
100 return NGX_OK; | |
101 } | |
102 | |
103 backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
104 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
105 if (backup == NULL) { | |
106 return NGX_ERROR; | |
107 } | |
108 | |
109 peers->single = 0; | |
110 backup->single = 0; | |
111 backup->number = n; | |
112 backup->name = &us->host; | |
113 | |
114 n = 0; | |
115 | |
116 for (i = 0; i < us->servers->nelts; i++) { | |
117 for (j = 0; j < server[i].naddrs; j++) { | |
118 if (!server[i].backup) { | |
119 continue; | |
120 } | |
121 | |
122 backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
123 backup->peer[n].socklen = server[i].addrs[j].socklen; | |
124 backup->peer[n].name = server[i].addrs[j].name; | |
125 backup->peer[n].weight = server[i].weight; | |
126 backup->peer[n].current_weight = server[i].weight; | |
127 backup->peer[n].max_fails = server[i].max_fails; | |
128 backup->peer[n].fail_timeout = server[i].fail_timeout; | |
129 backup->peer[n].down = server[i].down; | |
130 n++; | |
131 } | |
132 } | |
133 | |
134 peers->next = backup; | |
135 | |
1379 | 136 ngx_sort(&backup->peer[0], (size_t) n, |
137 sizeof(ngx_http_upstream_rr_peer_t), | |
138 ngx_http_upstream_cmp_servers); | |
139 | |
884 | 140 return NGX_OK; |
141 } | |
142 | |
143 | |
144 /* an upstream implicitly defined by proxy_pass, etc. */ | |
145 | |
906 | 146 if (us->port == 0 && us->default_port == 0) { |
147 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
148 "no port in upstream \"%V\" in %s:%ui", | |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1465
diff
changeset
|
149 &us->host, us->file_name, us->line); |
906 | 150 return NGX_ERROR; |
151 } | |
152 | |
884 | 153 ngx_memzero(&u, sizeof(ngx_url_t)); |
154 | |
155 u.host = us->host; | |
916 | 156 u.port = (in_port_t) (us->port ? us->port : us->default_port); |
884 | 157 |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1556
diff
changeset
|
158 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { |
884 | 159 if (u.err) { |
160 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
896
f247db60fc85
fix fastcgi and memcached upstreams
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
161 "%s in upstream \"%V\" in %s:%ui", |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1465
diff
changeset
|
162 u.err, &us->host, us->file_name, us->line); |
884 | 163 } |
164 | |
165 return NGX_ERROR; | |
166 } | |
167 | |
168 n = u.naddrs; | |
169 | |
170 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
171 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
172 if (peers == NULL) { | |
173 return NGX_ERROR; | |
174 } | |
175 | |
1378 | 176 peers->single = (n == 1); |
884 | 177 peers->number = n; |
178 peers->name = &us->host; | |
179 | |
180 for (i = 0; i < u.naddrs; i++) { | |
1564 | 181 peers->peer[i].sockaddr = u.addrs[i].sockaddr; |
182 peers->peer[i].socklen = u.addrs[i].socklen; | |
183 peers->peer[i].name = u.addrs[i].name; | |
184 peers->peer[i].weight = 1; | |
185 peers->peer[i].current_weight = 1; | |
186 peers->peer[i].max_fails = 1; | |
187 peers->peer[i].fail_timeout = 10; | |
884 | 188 } |
189 | |
190 us->peer.data = peers; | |
191 | |
1378 | 192 /* implicitly defined upstream has no backup servers */ |
193 | |
884 | 194 return NGX_OK; |
195 } | |
196 | |
197 | |
1956
cb8c0c8e0c27
use ngx_int_t in ngx_sort() callback
Igor Sysoev <igor@sysoev.ru>
parents:
1887
diff
changeset
|
198 static ngx_int_t |
1379 | 199 ngx_http_upstream_cmp_servers(const void *one, const void *two) |
200 { | |
201 ngx_http_upstream_rr_peer_t *first, *second; | |
202 | |
203 first = (ngx_http_upstream_rr_peer_t *) one; | |
204 second = (ngx_http_upstream_rr_peer_t *) two; | |
205 | |
206 return (first->weight < second->weight); | |
207 } | |
208 | |
209 | |
884 | 210 ngx_int_t |
211 ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r, | |
212 ngx_http_upstream_srv_conf_t *us) | |
213 { | |
214 ngx_uint_t n; | |
215 ngx_http_upstream_rr_peer_data_t *rrp; | |
216 | |
217 rrp = r->upstream->peer.data; | |
218 | |
219 if (rrp == NULL) { | |
220 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); | |
221 if (rrp == NULL) { | |
222 return NGX_ERROR; | |
223 } | |
224 | |
225 r->upstream->peer.data = rrp; | |
226 } | |
227 | |
228 rrp->peers = us->peer.data; | |
229 rrp->current = 0; | |
230 | |
231 if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { | |
232 rrp->tried = &rrp->data; | |
233 rrp->data = 0; | |
234 | |
235 } else { | |
236 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) | |
237 / (8 * sizeof(uintptr_t)); | |
238 | |
239 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
240 if (rrp->tried == NULL) { | |
241 return NGX_ERROR; | |
242 } | |
243 } | |
244 | |
245 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
246 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
247 r->upstream->peer.tries = rrp->peers->number; | |
248 #if (NGX_HTTP_SSL) | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
249 r->upstream->peer.set_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
250 ngx_http_upstream_set_round_robin_peer_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
251 r->upstream->peer.save_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
252 ngx_http_upstream_save_round_robin_peer_session; |
884 | 253 #endif |
254 | |
255 return NGX_OK; | |
256 } | |
257 | |
258 | |
259 ngx_int_t | |
1658 | 260 ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, |
261 ngx_http_upstream_resolved_t *ur) | |
262 { | |
263 u_char *p; | |
264 size_t len; | |
265 ngx_uint_t i, n; | |
266 struct sockaddr_in *sin; | |
267 ngx_http_upstream_rr_peers_t *peers; | |
268 ngx_http_upstream_rr_peer_data_t *rrp; | |
269 | |
270 rrp = r->upstream->peer.data; | |
271 | |
272 if (rrp == NULL) { | |
273 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); | |
274 if (rrp == NULL) { | |
275 return NGX_ERROR; | |
276 } | |
277 | |
278 r->upstream->peer.data = rrp; | |
279 } | |
280 | |
281 peers = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
282 + sizeof(ngx_http_upstream_rr_peer_t) * (ur->naddrs - 1)); | |
283 if (peers == NULL) { | |
284 return NGX_ERROR; | |
285 } | |
286 | |
287 peers->single = (ur->naddrs == 1); | |
288 peers->number = ur->naddrs; | |
289 peers->name = &ur->host; | |
290 | |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
291 if (ur->sockaddr) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
292 peers->peer[0].sockaddr = ur->sockaddr; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
293 peers->peer[0].socklen = ur->socklen; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
294 peers->peer[0].name = ur->host; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
295 peers->peer[0].weight = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
296 peers->peer[0].current_weight = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
297 peers->peer[0].max_fails = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
298 peers->peer[0].fail_timeout = 10; |
1658 | 299 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
300 } else { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
301 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
302 for (i = 0; i < ur->naddrs; i++) { |
1658 | 303 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
304 len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
305 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
306 p = ngx_pnalloc(r->pool, len); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
307 if (p == NULL) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
308 return NGX_ERROR; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
309 } |
1658 | 310 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
311 len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
312 len = ngx_sprintf(&p[len], ":%d", ur->port) - p; |
1658 | 313 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
314 sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
315 if (sin == NULL) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
316 return NGX_ERROR; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
317 } |
1658 | 318 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
319 sin->sin_family = AF_INET; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
320 sin->sin_port = htons(ur->port); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
321 sin->sin_addr.s_addr = ur->addrs[i]; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
322 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
323 peers->peer[i].sockaddr = (struct sockaddr *) sin; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
324 peers->peer[i].socklen = sizeof(struct sockaddr_in); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
325 peers->peer[i].name.len = len; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
326 peers->peer[i].name.data = p; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
327 peers->peer[i].weight = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
328 peers->peer[i].current_weight = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
329 peers->peer[i].max_fails = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
330 peers->peer[i].fail_timeout = 10; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
331 } |
1658 | 332 } |
333 | |
334 rrp->peers = peers; | |
335 rrp->current = 0; | |
336 | |
337 if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { | |
338 rrp->tried = &rrp->data; | |
339 rrp->data = 0; | |
340 | |
341 } else { | |
342 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) | |
343 / (8 * sizeof(uintptr_t)); | |
344 | |
345 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
346 if (rrp->tried == NULL) { | |
347 return NGX_ERROR; | |
348 } | |
349 } | |
350 | |
351 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
352 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
353 r->upstream->peer.tries = rrp->peers->number; | |
354 #if (NGX_HTTP_SSL) | |
4041
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
355 r->upstream->peer.set_session = ngx_http_upstream_empty_set_session; |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
356 r->upstream->peer.save_session = ngx_http_upstream_empty_save_session; |
1658 | 357 #endif |
358 | |
359 return NGX_OK; | |
360 } | |
361 | |
362 | |
363 ngx_int_t | |
884 | 364 ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) |
365 { | |
366 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
367 | |
1378 | 368 time_t now; |
369 uintptr_t m; | |
370 ngx_int_t rc; | |
371 ngx_uint_t i, n; | |
372 ngx_connection_t *c; | |
373 ngx_http_upstream_rr_peer_t *peer; | |
374 ngx_http_upstream_rr_peers_t *peers; | |
884 | 375 |
376 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
377 "get rr peer, try: %ui", pc->tries); | |
378 | |
379 now = ngx_time(); | |
380 | |
381 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
382 | |
383 if (rrp->peers->last_cached) { | |
384 | |
385 /* cached connection */ | |
386 | |
387 c = rrp->peers->cached[rrp->peers->last_cached]; | |
388 rrp->peers->last_cached--; | |
389 | |
390 /* ngx_unlock_mutex(ppr->peers->mutex); */ | |
391 | |
392 #if (NGX_THREADS) | |
393 c->read->lock = c->read->own_lock; | |
394 c->write->lock = c->write->own_lock; | |
395 #endif | |
396 | |
397 pc->connection = c; | |
398 pc->cached = 1; | |
399 | |
400 return NGX_OK; | |
401 } | |
402 | |
403 pc->cached = 0; | |
404 pc->connection = NULL; | |
405 | |
1378 | 406 if (rrp->peers->single) { |
884 | 407 peer = &rrp->peers->peer[0]; |
408 | |
409 } else { | |
410 | |
411 /* there are several peers */ | |
412 | |
413 if (pc->tries == rrp->peers->number) { | |
414 | |
415 /* it's a first try - get a current peer */ | |
416 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
417 i = pc->tries; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
418 |
884 | 419 for ( ;; ) { |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
420 rrp->current = ngx_http_upstream_get_peer(rrp->peers); |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
421 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
422 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
423 "get rr peer, current: %ui %i", |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
424 rrp->current, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
425 rrp->peers->peer[rrp->current].current_weight); |
884 | 426 |
427 n = rrp->current / (8 * sizeof(uintptr_t)); | |
1206
451e34738078
fix worker endless loop on 64-bit platform if 33+ backend has fall
Igor Sysoev <igor@sysoev.ru>
parents:
916
diff
changeset
|
428 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); |
884 | 429 |
430 if (!(rrp->tried[n] & m)) { | |
431 peer = &rrp->peers->peer[rrp->current]; | |
432 | |
433 if (!peer->down) { | |
434 | |
435 if (peer->max_fails == 0 | |
436 || peer->fails < peer->max_fails) | |
437 { | |
438 break; | |
439 } | |
440 | |
441 if (now - peer->accessed > peer->fail_timeout) { | |
442 peer->fails = 0; | |
443 break; | |
444 } | |
445 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
446 peer->current_weight = 0; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
447 |
884 | 448 } else { |
449 rrp->tried[n] |= m; | |
450 } | |
451 | |
452 pc->tries--; | |
453 } | |
454 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
455 if (pc->tries == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
456 goto failed; |
884 | 457 } |
458 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
459 if (--i == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
460 ngx_log_error(NGX_LOG_ALERT, pc->log, 0, |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
461 "round robin upstream stuck on %ui tries", |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
462 pc->tries); |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
463 goto failed; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
464 } |
884 | 465 } |
466 | |
467 peer->current_weight--; | |
468 | |
469 } else { | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
470 |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
471 i = pc->tries; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
472 |
884 | 473 for ( ;; ) { |
474 n = rrp->current / (8 * sizeof(uintptr_t)); | |
1206
451e34738078
fix worker endless loop on 64-bit platform if 33+ backend has fall
Igor Sysoev <igor@sysoev.ru>
parents:
916
diff
changeset
|
475 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); |
884 | 476 |
477 if (!(rrp->tried[n] & m)) { | |
478 | |
479 peer = &rrp->peers->peer[rrp->current]; | |
480 | |
481 if (!peer->down) { | |
482 | |
483 if (peer->max_fails == 0 | |
484 || peer->fails < peer->max_fails) | |
485 { | |
486 break; | |
487 } | |
488 | |
489 if (now - peer->accessed > peer->fail_timeout) { | |
490 peer->fails = 0; | |
491 break; | |
492 } | |
493 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
494 peer->current_weight = 0; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
495 |
884 | 496 } else { |
497 rrp->tried[n] |= m; | |
498 } | |
499 | |
500 pc->tries--; | |
501 } | |
502 | |
503 rrp->current++; | |
504 | |
505 if (rrp->current >= rrp->peers->number) { | |
506 rrp->current = 0; | |
507 } | |
508 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
509 if (pc->tries == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
510 goto failed; |
884 | 511 } |
512 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
513 if (--i == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
514 ngx_log_error(NGX_LOG_ALERT, pc->log, 0, |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
515 "round robin upstream stuck on %ui tries", |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
516 pc->tries); |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
517 goto failed; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
518 } |
884 | 519 } |
520 | |
521 peer->current_weight--; | |
522 } | |
523 | |
524 rrp->tried[n] |= m; | |
525 } | |
526 | |
527 pc->sockaddr = peer->sockaddr; | |
528 pc->socklen = peer->socklen; | |
529 pc->name = &peer->name; | |
530 | |
531 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
532 | |
1378 | 533 if (pc->tries == 1 && rrp->peers->next) { |
534 pc->tries += rrp->peers->next->number; | |
535 | |
536 n = rrp->peers->next->number / (8 * sizeof(uintptr_t)) + 1; | |
1389 | 537 for (i = 0; i < n; i++) { |
1378 | 538 rrp->tried[i] = 0; |
539 } | |
540 } | |
541 | |
884 | 542 return NGX_OK; |
543 | |
544 failed: | |
545 | |
1378 | 546 peers = rrp->peers; |
547 | |
548 if (peers->next) { | |
549 | |
550 /* ngx_unlock_mutex(peers->mutex); */ | |
551 | |
552 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers"); | |
553 | |
554 rrp->peers = peers->next; | |
555 pc->tries = rrp->peers->number; | |
556 | |
557 n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1; | |
1389 | 558 for (i = 0; i < n; i++) { |
1378 | 559 rrp->tried[i] = 0; |
560 } | |
561 | |
562 rc = ngx_http_upstream_get_round_robin_peer(pc, rrp); | |
563 | |
564 if (rc != NGX_BUSY) { | |
565 return rc; | |
566 } | |
567 | |
568 /* ngx_lock_mutex(peers->mutex); */ | |
569 } | |
570 | |
884 | 571 /* all peers failed, mark them as live for quick recovery */ |
572 | |
1378 | 573 for (i = 0; i < peers->number; i++) { |
574 peers->peer[i].fails = 0; | |
884 | 575 } |
576 | |
1378 | 577 /* ngx_unlock_mutex(peers->mutex); */ |
884 | 578 |
1378 | 579 pc->name = peers->name; |
884 | 580 |
581 return NGX_BUSY; | |
582 } | |
583 | |
584 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
585 static ngx_uint_t |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
586 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers) |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
587 { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
588 ngx_uint_t i, n; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
589 ngx_http_upstream_rr_peer_t *peer; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
590 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
591 peer = &peers->peer[0]; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
592 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
593 for ( ;; ) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
594 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
595 for (i = 0; i < peers->number; i++) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
596 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
597 if (peer[i].current_weight <= 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
598 continue; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
599 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
600 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
601 n = i; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
602 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
603 while (i < peers->number - 1) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
604 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
605 i++; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
606 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
607 if (peer[i].current_weight <= 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
608 continue; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
609 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
610 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
611 if (peer[n].current_weight * 1000 / peer[i].current_weight |
1465
a9132739bb57
balance more fair when there are several servers with equal weights,
Igor Sysoev <igor@sysoev.ru>
parents:
1463
diff
changeset
|
612 > peer[n].weight * 1000 / peer[i].weight) |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
613 { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
614 return n; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
615 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
616 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
617 n = i; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
618 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
619 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
620 if (peer[i].current_weight > 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
621 n = i; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
622 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
623 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
624 return n; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
625 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
626 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
627 for (i = 0; i < peers->number; i++) { |
1887
abbef7b5dab8
set absolute weight, this fixes bogus "no live upstream" case when
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
628 peer[i].current_weight = peer[i].weight; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
629 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
630 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
631 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
632 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
633 |
884 | 634 void |
635 ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, | |
636 ngx_uint_t state) | |
637 { | |
638 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
639 | |
640 time_t now; | |
641 ngx_http_upstream_rr_peer_t *peer; | |
642 | |
643 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
644 "free rr peer %ui %ui", pc->tries, state); | |
645 | |
646 if (state == 0 && pc->tries == 0) { | |
647 return; | |
648 } | |
649 | |
650 /* TODO: NGX_PEER_KEEPALIVE */ | |
651 | |
1378 | 652 if (rrp->peers->single) { |
884 | 653 pc->tries = 0; |
654 return; | |
655 } | |
656 | |
657 if (state & NGX_PEER_FAILED) { | |
658 now = ngx_time(); | |
659 | |
660 peer = &rrp->peers->peer[rrp->current]; | |
661 | |
662 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
663 | |
664 peer->fails++; | |
665 peer->accessed = now; | |
666 | |
2204
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
667 if (peer->max_fails) { |
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
668 peer->current_weight -= peer->weight / peer->max_fails; |
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
669 } |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
670 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
671 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
672 "free rr peer failed: %ui %i", |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
673 rrp->current, peer->current_weight); |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
674 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
675 if (peer->current_weight < 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
676 peer->current_weight = 0; |
884 | 677 } |
678 | |
679 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
680 } | |
681 | |
682 rrp->current++; | |
683 | |
684 if (rrp->current >= rrp->peers->number) { | |
685 rrp->current = 0; | |
686 } | |
687 | |
688 if (pc->tries) { | |
689 pc->tries--; | |
690 } | |
691 | |
692 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
693 } | |
694 | |
695 | |
696 #if (NGX_HTTP_SSL) | |
697 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
698 ngx_int_t |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
699 ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc, |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
700 void *data) |
884 | 701 { |
702 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
703 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
704 ngx_int_t rc; |
884 | 705 ngx_ssl_session_t *ssl_session; |
706 ngx_http_upstream_rr_peer_t *peer; | |
707 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
708 peer = &rrp->peers->peer[rrp->current]; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
709 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
710 /* TODO: threads only mutex */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
711 /* ngx_lock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
712 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
713 ssl_session = peer->ssl_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
714 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
715 rc = ngx_ssl_set_session(pc->connection, ssl_session); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
716 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
717 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 718 "set session: %p:%d", |
719 ssl_session, ssl_session ? ssl_session->references : 0); | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
720 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
721 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
722 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
723 return rc; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
724 } |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
725 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
726 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
727 void |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
728 ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc, |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
729 void *data) |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
730 { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
731 ngx_http_upstream_rr_peer_data_t *rrp = data; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
732 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
733 ngx_ssl_session_t *old_ssl_session, *ssl_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
734 ngx_http_upstream_rr_peer_t *peer; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
735 |
884 | 736 ssl_session = ngx_ssl_get_session(pc->connection); |
737 | |
738 if (ssl_session == NULL) { | |
739 return; | |
740 } | |
741 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
742 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 743 "save session: %p:%d", ssl_session, ssl_session->references); |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
744 |
884 | 745 peer = &rrp->peers->peer[rrp->current]; |
746 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
747 /* TODO: threads only mutex */ |
884 | 748 /* ngx_lock_mutex(rrp->peers->mutex); */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
749 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
750 old_ssl_session = peer->ssl_session; |
884 | 751 peer->ssl_session = ssl_session; |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
752 |
884 | 753 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
754 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
755 if (old_ssl_session) { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
756 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
757 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 758 "old session: %p:%d", |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
759 old_ssl_session, old_ssl_session->references); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
760 |
884 | 761 /* TODO: may block */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
762 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
763 ngx_ssl_free_session(old_ssl_session); |
884 | 764 } |
765 } | |
766 | |
4041
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
767 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
768 static ngx_int_t |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
769 ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data) |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
770 { |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
771 return NGX_OK; |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
772 } |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
773 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
774 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
775 static void |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
776 ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data) |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
777 { |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
778 return; |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
779 } |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
780 |
884 | 781 #endif |