Mercurial > hg > nginx-quic
annotate src/stream/ngx_stream_upstream_round_robin.c @ 6832:ec10ce307dc0
Map: the "volatile" parameter.
By default, "map" creates cacheable variables [1]. With this
parameter it creates a non-cacheable variable.
An original idea was to deduce the cacheability of the "map"
variable by checking the cacheability of variables specified
in source and resulting values, but it turned to be too hard.
For example, a cacheable variable can be overridden with the
"set" directive or with the SSI "set" command. Also, keeping
"map" variables cacheable by default is good for performance
reasons. This required adding a new parameter.
[1] Before db699978a33f (1.11.0), the cacheability of the
"map" variable could vary depending on the cacheability of
variables specified in resulting values (ticket #1090).
This is believed to be a bug rather than a feature.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Thu, 08 Dec 2016 17:51:49 +0300 |
parents | d1d0dd69a419 |
children | 54cf51c4f07a |
rev | line source |
---|---|
6115 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_stream.h> | |
11 | |
12 | |
13 #define ngx_stream_upstream_tries(p) ((p)->number \ | |
14 + ((p)->next ? (p)->next->number : 0)) | |
15 | |
16 | |
17 static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer( | |
18 ngx_stream_upstream_rr_peer_data_t *rrp); | |
19 | |
20 #if (NGX_STREAM_SSL) | |
21 | |
22 static ngx_int_t ngx_stream_upstream_set_round_robin_peer_session( | |
23 ngx_peer_connection_t *pc, void *data); | |
24 static void ngx_stream_upstream_save_round_robin_peer_session( | |
25 ngx_peer_connection_t *pc, void *data); | |
6643
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
26 static ngx_int_t ngx_stream_upstream_empty_set_session( |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
27 ngx_peer_connection_t *pc, void *data); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
28 static void ngx_stream_upstream_empty_save_session(ngx_peer_connection_t *pc, |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
29 void *data); |
6115 | 30 |
31 #endif | |
32 | |
33 | |
34 ngx_int_t | |
35 ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, | |
36 ngx_stream_upstream_srv_conf_t *us) | |
37 { | |
38 ngx_url_t u; | |
39 ngx_uint_t i, j, n, w; | |
40 ngx_stream_upstream_server_t *server; | |
41 ngx_stream_upstream_rr_peer_t *peer, **peerp; | |
42 ngx_stream_upstream_rr_peers_t *peers, *backup; | |
43 | |
44 us->peer.init = ngx_stream_upstream_init_round_robin_peer; | |
45 | |
46 if (us->servers) { | |
47 server = us->servers->elts; | |
48 | |
49 n = 0; | |
50 w = 0; | |
51 | |
52 for (i = 0; i < us->servers->nelts; i++) { | |
53 if (server[i].backup) { | |
54 continue; | |
55 } | |
56 | |
57 n += server[i].naddrs; | |
58 w += server[i].naddrs * server[i].weight; | |
59 } | |
60 | |
61 if (n == 0) { | |
62 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
63 "no servers in upstream \"%V\" in %s:%ui", | |
64 &us->host, us->file_name, us->line); | |
65 return NGX_ERROR; | |
66 } | |
67 | |
68 peers = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t)); | |
69 if (peers == NULL) { | |
70 return NGX_ERROR; | |
71 } | |
72 | |
73 peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n); | |
74 if (peer == NULL) { | |
75 return NGX_ERROR; | |
76 } | |
77 | |
78 peers->single = (n == 1); | |
79 peers->number = n; | |
80 peers->weighted = (w != n); | |
81 peers->total_weight = w; | |
82 peers->name = &us->host; | |
83 | |
84 n = 0; | |
85 peerp = &peers->peer; | |
86 | |
87 for (i = 0; i < us->servers->nelts; i++) { | |
88 if (server[i].backup) { | |
89 continue; | |
90 } | |
91 | |
92 for (j = 0; j < server[i].naddrs; j++) { | |
93 peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
94 peer[n].socklen = server[i].addrs[j].socklen; | |
95 peer[n].name = server[i].addrs[j].name; | |
96 peer[n].weight = server[i].weight; | |
97 peer[n].effective_weight = server[i].weight; | |
98 peer[n].current_weight = 0; | |
6705 | 99 peer[n].max_conns = server[i].max_conns; |
6115 | 100 peer[n].max_fails = server[i].max_fails; |
101 peer[n].fail_timeout = server[i].fail_timeout; | |
102 peer[n].down = server[i].down; | |
103 peer[n].server = server[i].name; | |
104 | |
105 *peerp = &peer[n]; | |
106 peerp = &peer[n].next; | |
107 n++; | |
108 } | |
109 } | |
110 | |
111 us->peer.data = peers; | |
112 | |
113 /* backup servers */ | |
114 | |
115 n = 0; | |
116 w = 0; | |
117 | |
118 for (i = 0; i < us->servers->nelts; i++) { | |
119 if (!server[i].backup) { | |
120 continue; | |
121 } | |
122 | |
123 n += server[i].naddrs; | |
124 w += server[i].naddrs * server[i].weight; | |
125 } | |
126 | |
127 if (n == 0) { | |
128 return NGX_OK; | |
129 } | |
130 | |
131 backup = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t)); | |
132 if (backup == NULL) { | |
133 return NGX_ERROR; | |
134 } | |
135 | |
136 peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n); | |
137 if (peer == NULL) { | |
138 return NGX_ERROR; | |
139 } | |
140 | |
141 peers->single = 0; | |
142 backup->single = 0; | |
143 backup->number = n; | |
144 backup->weighted = (w != n); | |
145 backup->total_weight = w; | |
146 backup->name = &us->host; | |
147 | |
148 n = 0; | |
149 peerp = &backup->peer; | |
150 | |
151 for (i = 0; i < us->servers->nelts; i++) { | |
152 if (!server[i].backup) { | |
153 continue; | |
154 } | |
155 | |
156 for (j = 0; j < server[i].naddrs; j++) { | |
157 peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
158 peer[n].socklen = server[i].addrs[j].socklen; | |
159 peer[n].name = server[i].addrs[j].name; | |
160 peer[n].weight = server[i].weight; | |
161 peer[n].effective_weight = server[i].weight; | |
162 peer[n].current_weight = 0; | |
6705 | 163 peer[n].max_conns = server[i].max_conns; |
6115 | 164 peer[n].max_fails = server[i].max_fails; |
165 peer[n].fail_timeout = server[i].fail_timeout; | |
166 peer[n].down = server[i].down; | |
167 peer[n].server = server[i].name; | |
168 | |
169 *peerp = &peer[n]; | |
170 peerp = &peer[n].next; | |
171 n++; | |
172 } | |
173 } | |
174 | |
175 peers->next = backup; | |
176 | |
177 return NGX_OK; | |
178 } | |
179 | |
180 | |
181 /* an upstream implicitly defined by proxy_pass, etc. */ | |
182 | |
183 if (us->port == 0) { | |
184 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
185 "no port in upstream \"%V\" in %s:%ui", | |
186 &us->host, us->file_name, us->line); | |
187 return NGX_ERROR; | |
188 } | |
189 | |
190 ngx_memzero(&u, sizeof(ngx_url_t)); | |
191 | |
192 u.host = us->host; | |
193 u.port = us->port; | |
194 | |
195 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { | |
196 if (u.err) { | |
197 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
198 "%s in upstream \"%V\" in %s:%ui", | |
199 u.err, &us->host, us->file_name, us->line); | |
200 } | |
201 | |
202 return NGX_ERROR; | |
203 } | |
204 | |
205 n = u.naddrs; | |
206 | |
207 peers = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peers_t)); | |
208 if (peers == NULL) { | |
209 return NGX_ERROR; | |
210 } | |
211 | |
212 peer = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_rr_peer_t) * n); | |
213 if (peer == NULL) { | |
214 return NGX_ERROR; | |
215 } | |
216 | |
217 peers->single = (n == 1); | |
218 peers->number = n; | |
219 peers->weighted = 0; | |
220 peers->total_weight = n; | |
221 peers->name = &us->host; | |
222 | |
223 peerp = &peers->peer; | |
224 | |
225 for (i = 0; i < u.naddrs; i++) { | |
226 peer[i].sockaddr = u.addrs[i].sockaddr; | |
227 peer[i].socklen = u.addrs[i].socklen; | |
228 peer[i].name = u.addrs[i].name; | |
229 peer[i].weight = 1; | |
230 peer[i].effective_weight = 1; | |
231 peer[i].current_weight = 0; | |
6705 | 232 peer[i].max_conns = 0; |
6115 | 233 peer[i].max_fails = 1; |
234 peer[i].fail_timeout = 10; | |
235 *peerp = &peer[i]; | |
236 peerp = &peer[i].next; | |
237 } | |
238 | |
239 us->peer.data = peers; | |
240 | |
241 /* implicitly defined upstream has no backup servers */ | |
242 | |
243 return NGX_OK; | |
244 } | |
245 | |
246 | |
247 ngx_int_t | |
248 ngx_stream_upstream_init_round_robin_peer(ngx_stream_session_t *s, | |
249 ngx_stream_upstream_srv_conf_t *us) | |
250 { | |
251 ngx_uint_t n; | |
252 ngx_stream_upstream_rr_peer_data_t *rrp; | |
253 | |
254 rrp = s->upstream->peer.data; | |
255 | |
256 if (rrp == NULL) { | |
257 rrp = ngx_palloc(s->connection->pool, | |
258 sizeof(ngx_stream_upstream_rr_peer_data_t)); | |
259 if (rrp == NULL) { | |
260 return NGX_ERROR; | |
261 } | |
262 | |
263 s->upstream->peer.data = rrp; | |
264 } | |
265 | |
266 rrp->peers = us->peer.data; | |
267 rrp->current = NULL; | |
6712
fd5c2781460b
Modules compatibility: upstream config field.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6706
diff
changeset
|
268 rrp->config = 0; |
6115 | 269 |
270 n = rrp->peers->number; | |
271 | |
272 if (rrp->peers->next && rrp->peers->next->number > n) { | |
273 n = rrp->peers->next->number; | |
274 } | |
275 | |
276 if (n <= 8 * sizeof(uintptr_t)) { | |
277 rrp->tried = &rrp->data; | |
278 rrp->data = 0; | |
279 | |
280 } else { | |
281 n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t)); | |
282 | |
283 rrp->tried = ngx_pcalloc(s->connection->pool, n * sizeof(uintptr_t)); | |
284 if (rrp->tried == NULL) { | |
285 return NGX_ERROR; | |
286 } | |
287 } | |
288 | |
289 s->upstream->peer.get = ngx_stream_upstream_get_round_robin_peer; | |
290 s->upstream->peer.free = ngx_stream_upstream_free_round_robin_peer; | |
291 s->upstream->peer.tries = ngx_stream_upstream_tries(rrp->peers); | |
292 #if (NGX_STREAM_SSL) | |
293 s->upstream->peer.set_session = | |
294 ngx_stream_upstream_set_round_robin_peer_session; | |
295 s->upstream->peer.save_session = | |
296 ngx_stream_upstream_save_round_robin_peer_session; | |
297 #endif | |
298 | |
299 return NGX_OK; | |
300 } | |
301 | |
302 | |
303 ngx_int_t | |
6643
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
304 ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s, |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
305 ngx_stream_upstream_resolved_t *ur) |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
306 { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
307 u_char *p; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
308 size_t len; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
309 socklen_t socklen; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
310 ngx_uint_t i, n; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
311 struct sockaddr *sockaddr; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
312 ngx_stream_upstream_rr_peer_t *peer, **peerp; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
313 ngx_stream_upstream_rr_peers_t *peers; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
314 ngx_stream_upstream_rr_peer_data_t *rrp; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
315 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
316 rrp = s->upstream->peer.data; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
317 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
318 if (rrp == NULL) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
319 rrp = ngx_palloc(s->connection->pool, |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
320 sizeof(ngx_stream_upstream_rr_peer_data_t)); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
321 if (rrp == NULL) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
322 return NGX_ERROR; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
323 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
324 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
325 s->upstream->peer.data = rrp; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
326 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
327 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
328 peers = ngx_pcalloc(s->connection->pool, |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
329 sizeof(ngx_stream_upstream_rr_peers_t)); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
330 if (peers == NULL) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
331 return NGX_ERROR; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
332 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
333 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
334 peer = ngx_pcalloc(s->connection->pool, |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
335 sizeof(ngx_stream_upstream_rr_peer_t) * ur->naddrs); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
336 if (peer == NULL) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
337 return NGX_ERROR; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
338 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
339 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
340 peers->single = (ur->naddrs == 1); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
341 peers->number = ur->naddrs; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
342 peers->name = &ur->host; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
343 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
344 if (ur->sockaddr) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
345 peer[0].sockaddr = ur->sockaddr; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
346 peer[0].socklen = ur->socklen; |
6785
d1d0dd69a419
Upstream: added the ngx_http_upstream_resolved_t.name field.
Ruslan Ermilov <ru@nginx.com>
parents:
6712
diff
changeset
|
347 peer[0].name = ur->name; |
6643
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
348 peer[0].weight = 1; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
349 peer[0].effective_weight = 1; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
350 peer[0].current_weight = 0; |
6706 | 351 peer[0].max_conns = 0; |
6643
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
352 peer[0].max_fails = 1; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
353 peer[0].fail_timeout = 10; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
354 peers->peer = peer; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
355 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
356 } else { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
357 peerp = &peers->peer; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
358 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
359 for (i = 0; i < ur->naddrs; i++) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
360 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
361 socklen = ur->addrs[i].socklen; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
362 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
363 sockaddr = ngx_palloc(s->connection->pool, socklen); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
364 if (sockaddr == NULL) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
365 return NGX_ERROR; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
366 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
367 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
368 ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
369 ngx_inet_set_port(sockaddr, ur->port); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
370 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
371 p = ngx_pnalloc(s->connection->pool, NGX_SOCKADDR_STRLEN); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
372 if (p == NULL) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
373 return NGX_ERROR; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
374 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
375 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
376 len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
377 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
378 peer[i].sockaddr = sockaddr; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
379 peer[i].socklen = socklen; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
380 peer[i].name.len = len; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
381 peer[i].name.data = p; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
382 peer[i].weight = 1; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
383 peer[i].effective_weight = 1; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
384 peer[i].current_weight = 0; |
6706 | 385 peer[i].max_conns = 0; |
6643
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
386 peer[i].max_fails = 1; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
387 peer[i].fail_timeout = 10; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
388 *peerp = &peer[i]; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
389 peerp = &peer[i].next; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
390 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
391 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
392 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
393 rrp->peers = peers; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
394 rrp->current = NULL; |
6712
fd5c2781460b
Modules compatibility: upstream config field.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6706
diff
changeset
|
395 rrp->config = 0; |
6643
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
396 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
397 if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
398 rrp->tried = &rrp->data; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
399 rrp->data = 0; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
400 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
401 } else { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
402 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
403 / (8 * sizeof(uintptr_t)); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
404 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
405 rrp->tried = ngx_pcalloc(s->connection->pool, n * sizeof(uintptr_t)); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
406 if (rrp->tried == NULL) { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
407 return NGX_ERROR; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
408 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
409 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
410 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
411 s->upstream->peer.get = ngx_stream_upstream_get_round_robin_peer; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
412 s->upstream->peer.free = ngx_stream_upstream_free_round_robin_peer; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
413 s->upstream->peer.tries = ngx_stream_upstream_tries(rrp->peers); |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
414 #if (NGX_STREAM_SSL) |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
415 s->upstream->peer.set_session = ngx_stream_upstream_empty_set_session; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
416 s->upstream->peer.save_session = ngx_stream_upstream_empty_save_session; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
417 #endif |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
418 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
419 return NGX_OK; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
420 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
421 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
422 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
423 ngx_int_t |
6115 | 424 ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) |
425 { | |
426 ngx_stream_upstream_rr_peer_data_t *rrp = data; | |
427 | |
428 ngx_int_t rc; | |
429 ngx_uint_t i, n; | |
430 ngx_stream_upstream_rr_peer_t *peer; | |
431 ngx_stream_upstream_rr_peers_t *peers; | |
432 | |
433 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
434 "get rr peer, try: %ui", pc->tries); | |
435 | |
436 pc->connection = NULL; | |
437 | |
438 peers = rrp->peers; | |
439 ngx_stream_upstream_rr_peers_wlock(peers); | |
440 | |
441 if (peers->single) { | |
442 peer = peers->peer; | |
443 | |
444 if (peer->down) { | |
445 goto failed; | |
446 } | |
447 | |
6705 | 448 if (peer->max_conns && peer->conns >= peer->max_conns) { |
449 goto failed; | |
450 } | |
451 | |
6115 | 452 rrp->current = peer; |
453 | |
454 } else { | |
455 | |
456 /* there are several peers */ | |
457 | |
458 peer = ngx_stream_upstream_get_peer(rrp); | |
459 | |
460 if (peer == NULL) { | |
461 goto failed; | |
462 } | |
463 | |
464 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
465 "get rr peer, current: %p %i", | |
466 peer, peer->current_weight); | |
467 } | |
468 | |
469 pc->sockaddr = peer->sockaddr; | |
470 pc->socklen = peer->socklen; | |
471 pc->name = &peer->name; | |
472 | |
473 peer->conns++; | |
474 | |
475 ngx_stream_upstream_rr_peers_unlock(peers); | |
476 | |
477 return NGX_OK; | |
478 | |
479 failed: | |
480 | |
481 if (peers->next) { | |
482 | |
483 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "backup servers"); | |
484 | |
485 rrp->peers = peers->next; | |
486 | |
487 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) | |
488 / (8 * sizeof(uintptr_t)); | |
489 | |
490 for (i = 0; i < n; i++) { | |
6474 | 491 rrp->tried[i] = 0; |
6115 | 492 } |
493 | |
494 ngx_stream_upstream_rr_peers_unlock(peers); | |
495 | |
496 rc = ngx_stream_upstream_get_round_robin_peer(pc, rrp); | |
497 | |
498 if (rc != NGX_BUSY) { | |
499 return rc; | |
500 } | |
501 | |
502 ngx_stream_upstream_rr_peers_wlock(peers); | |
503 } | |
504 | |
505 ngx_stream_upstream_rr_peers_unlock(peers); | |
506 | |
507 pc->name = peers->name; | |
508 | |
509 return NGX_BUSY; | |
510 } | |
511 | |
512 | |
513 static ngx_stream_upstream_rr_peer_t * | |
514 ngx_stream_upstream_get_peer(ngx_stream_upstream_rr_peer_data_t *rrp) | |
515 { | |
516 time_t now; | |
517 uintptr_t m; | |
518 ngx_int_t total; | |
519 ngx_uint_t i, n, p; | |
520 ngx_stream_upstream_rr_peer_t *peer, *best; | |
521 | |
522 now = ngx_time(); | |
523 | |
524 best = NULL; | |
525 total = 0; | |
526 | |
527 #if (NGX_SUPPRESS_WARN) | |
528 p = 0; | |
529 #endif | |
530 | |
531 for (peer = rrp->peers->peer, i = 0; | |
532 peer; | |
533 peer = peer->next, i++) | |
534 { | |
535 n = i / (8 * sizeof(uintptr_t)); | |
536 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); | |
537 | |
538 if (rrp->tried[n] & m) { | |
539 continue; | |
540 } | |
541 | |
542 if (peer->down) { | |
543 continue; | |
544 } | |
545 | |
546 if (peer->max_fails | |
547 && peer->fails >= peer->max_fails | |
548 && now - peer->checked <= peer->fail_timeout) | |
549 { | |
550 continue; | |
551 } | |
552 | |
6705 | 553 if (peer->max_conns && peer->conns >= peer->max_conns) { |
554 continue; | |
555 } | |
556 | |
6115 | 557 peer->current_weight += peer->effective_weight; |
558 total += peer->effective_weight; | |
559 | |
560 if (peer->effective_weight < peer->weight) { | |
561 peer->effective_weight++; | |
562 } | |
563 | |
564 if (best == NULL || peer->current_weight > best->current_weight) { | |
565 best = peer; | |
566 p = i; | |
567 } | |
568 } | |
569 | |
570 if (best == NULL) { | |
571 return NULL; | |
572 } | |
573 | |
574 rrp->current = best; | |
575 | |
576 n = p / (8 * sizeof(uintptr_t)); | |
577 m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); | |
578 | |
579 rrp->tried[n] |= m; | |
580 | |
581 best->current_weight -= total; | |
582 | |
583 if (now - best->checked > best->fail_timeout) { | |
584 best->checked = now; | |
585 } | |
586 | |
587 return best; | |
588 } | |
589 | |
590 | |
591 void | |
592 ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, | |
593 ngx_uint_t state) | |
594 { | |
595 ngx_stream_upstream_rr_peer_data_t *rrp = data; | |
596 | |
597 time_t now; | |
598 ngx_stream_upstream_rr_peer_t *peer; | |
599 | |
600 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
601 "free rr peer %ui %ui", pc->tries, state); | |
602 | |
603 peer = rrp->current; | |
604 | |
605 ngx_stream_upstream_rr_peers_rlock(rrp->peers); | |
606 ngx_stream_upstream_rr_peer_lock(rrp->peers, peer); | |
607 | |
608 if (rrp->peers->single) { | |
609 peer->conns--; | |
610 | |
611 ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer); | |
612 ngx_stream_upstream_rr_peers_unlock(rrp->peers); | |
613 | |
614 pc->tries = 0; | |
615 return; | |
616 } | |
617 | |
618 if (state & NGX_PEER_FAILED) { | |
619 now = ngx_time(); | |
620 | |
621 peer->fails++; | |
622 peer->accessed = now; | |
623 peer->checked = now; | |
624 | |
625 if (peer->max_fails) { | |
626 peer->effective_weight -= peer->weight / peer->max_fails; | |
6154
cca856715722
Upstream: report to error_log when max_fails is reached.
Ruslan Ermilov <ru@nginx.com>
parents:
6115
diff
changeset
|
627 |
cca856715722
Upstream: report to error_log when max_fails is reached.
Ruslan Ermilov <ru@nginx.com>
parents:
6115
diff
changeset
|
628 if (peer->fails >= peer->max_fails) { |
cca856715722
Upstream: report to error_log when max_fails is reached.
Ruslan Ermilov <ru@nginx.com>
parents:
6115
diff
changeset
|
629 ngx_log_error(NGX_LOG_WARN, pc->log, 0, |
cca856715722
Upstream: report to error_log when max_fails is reached.
Ruslan Ermilov <ru@nginx.com>
parents:
6115
diff
changeset
|
630 "upstream server temporarily disabled"); |
cca856715722
Upstream: report to error_log when max_fails is reached.
Ruslan Ermilov <ru@nginx.com>
parents:
6115
diff
changeset
|
631 } |
6115 | 632 } |
633 | |
634 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
635 "free rr peer failed: %p %i", | |
636 peer, peer->effective_weight); | |
637 | |
638 if (peer->effective_weight < 0) { | |
639 peer->effective_weight = 0; | |
640 } | |
641 | |
642 } else { | |
643 | |
644 /* mark peer live if check passed */ | |
645 | |
646 if (peer->accessed < peer->checked) { | |
647 peer->fails = 0; | |
648 } | |
649 } | |
650 | |
651 peer->conns--; | |
652 | |
653 ngx_stream_upstream_rr_peer_unlock(rrp->peers, peer); | |
654 ngx_stream_upstream_rr_peers_unlock(rrp->peers); | |
655 | |
656 if (pc->tries) { | |
657 pc->tries--; | |
658 } | |
659 } | |
660 | |
661 | |
662 #if (NGX_STREAM_SSL) | |
663 | |
664 static ngx_int_t | |
665 ngx_stream_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc, | |
666 void *data) | |
667 { | |
668 ngx_stream_upstream_rr_peer_data_t *rrp = data; | |
669 | |
670 ngx_int_t rc; | |
671 ngx_ssl_session_t *ssl_session; | |
672 ngx_stream_upstream_rr_peer_t *peer; | |
673 #if (NGX_STREAM_UPSTREAM_ZONE) | |
674 int len; | |
675 #if OPENSSL_VERSION_NUMBER >= 0x0090707fL | |
676 const | |
677 #endif | |
678 u_char *p; | |
679 ngx_stream_upstream_rr_peers_t *peers; | |
680 u_char buf[NGX_SSL_MAX_SESSION_SIZE]; | |
681 #endif | |
682 | |
683 peer = rrp->current; | |
684 | |
685 #if (NGX_STREAM_UPSTREAM_ZONE) | |
686 peers = rrp->peers; | |
687 | |
688 if (peers->shpool) { | |
689 ngx_stream_upstream_rr_peers_rlock(peers); | |
690 ngx_stream_upstream_rr_peer_lock(peers, peer); | |
691 | |
692 if (peer->ssl_session == NULL) { | |
693 ngx_stream_upstream_rr_peer_unlock(peers, peer); | |
694 ngx_stream_upstream_rr_peers_unlock(peers); | |
695 return NGX_OK; | |
696 } | |
697 | |
698 len = peer->ssl_session_len; | |
699 | |
700 ngx_memcpy(buf, peer->ssl_session, len); | |
701 | |
702 ngx_stream_upstream_rr_peer_unlock(peers, peer); | |
703 ngx_stream_upstream_rr_peers_unlock(peers); | |
704 | |
705 p = buf; | |
706 ssl_session = d2i_SSL_SESSION(NULL, &p, len); | |
707 | |
708 rc = ngx_ssl_set_session(pc->connection, ssl_session); | |
709 | |
710 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
711 "set session: %p", ssl_session); | |
712 | |
713 ngx_ssl_free_session(ssl_session); | |
714 | |
715 return rc; | |
716 } | |
717 #endif | |
718 | |
719 ssl_session = peer->ssl_session; | |
720 | |
721 rc = ngx_ssl_set_session(pc->connection, ssl_session); | |
722 | |
723 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
724 "set session: %p", ssl_session); | |
725 | |
726 return rc; | |
727 } | |
728 | |
729 | |
730 static void | |
731 ngx_stream_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc, | |
732 void *data) | |
733 { | |
734 ngx_stream_upstream_rr_peer_data_t *rrp = data; | |
735 | |
736 ngx_ssl_session_t *old_ssl_session, *ssl_session; | |
737 ngx_stream_upstream_rr_peer_t *peer; | |
738 #if (NGX_STREAM_UPSTREAM_ZONE) | |
739 int len; | |
740 u_char *p; | |
741 ngx_stream_upstream_rr_peers_t *peers; | |
742 u_char buf[NGX_SSL_MAX_SESSION_SIZE]; | |
743 #endif | |
744 | |
745 #if (NGX_STREAM_UPSTREAM_ZONE) | |
746 peers = rrp->peers; | |
747 | |
748 if (peers->shpool) { | |
749 | |
750 ssl_session = SSL_get0_session(pc->connection->ssl->connection); | |
751 | |
752 if (ssl_session == NULL) { | |
753 return; | |
754 } | |
755 | |
756 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
757 "save session: %p", ssl_session); | |
758 | |
759 len = i2d_SSL_SESSION(ssl_session, NULL); | |
760 | |
761 /* do not cache too big session */ | |
762 | |
763 if (len > NGX_SSL_MAX_SESSION_SIZE) { | |
764 return; | |
765 } | |
766 | |
767 p = buf; | |
768 (void) i2d_SSL_SESSION(ssl_session, &p); | |
769 | |
770 peer = rrp->current; | |
771 | |
772 ngx_stream_upstream_rr_peers_rlock(peers); | |
773 ngx_stream_upstream_rr_peer_lock(peers, peer); | |
774 | |
775 if (len > peer->ssl_session_len) { | |
776 ngx_shmtx_lock(&peers->shpool->mutex); | |
777 | |
778 if (peer->ssl_session) { | |
779 ngx_slab_free_locked(peers->shpool, peer->ssl_session); | |
780 } | |
781 | |
782 peer->ssl_session = ngx_slab_alloc_locked(peers->shpool, len); | |
783 | |
784 ngx_shmtx_unlock(&peers->shpool->mutex); | |
785 | |
786 if (peer->ssl_session == NULL) { | |
787 peer->ssl_session_len = 0; | |
788 | |
789 ngx_stream_upstream_rr_peer_unlock(peers, peer); | |
790 ngx_stream_upstream_rr_peers_unlock(peers); | |
791 return; | |
792 } | |
793 | |
794 peer->ssl_session_len = len; | |
795 } | |
796 | |
797 ngx_memcpy(peer->ssl_session, buf, len); | |
798 | |
799 ngx_stream_upstream_rr_peer_unlock(peers, peer); | |
800 ngx_stream_upstream_rr_peers_unlock(peers); | |
801 | |
802 return; | |
803 } | |
804 #endif | |
805 | |
806 ssl_session = ngx_ssl_get_session(pc->connection); | |
807 | |
808 if (ssl_session == NULL) { | |
809 return; | |
810 } | |
811 | |
812 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
813 "save session: %p", ssl_session); | |
814 | |
815 peer = rrp->current; | |
816 | |
817 old_ssl_session = peer->ssl_session; | |
818 peer->ssl_session = ssl_session; | |
819 | |
820 if (old_ssl_session) { | |
821 | |
822 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, pc->log, 0, | |
823 "old session: %p", old_ssl_session); | |
824 | |
825 /* TODO: may block */ | |
826 | |
827 ngx_ssl_free_session(old_ssl_session); | |
828 } | |
829 } | |
830 | |
6643
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
831 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
832 static ngx_int_t |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
833 ngx_stream_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data) |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
834 { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
835 return NGX_OK; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
836 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
837 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
838 |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
839 static void |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
840 ngx_stream_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data) |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
841 { |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
842 return; |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
843 } |
9757cffc1e2f
Stream: variables in proxy_pass and proxy_ssl_name.
Vladimir Homutov <vl@nginx.com>
parents:
6474
diff
changeset
|
844 |
6115 | 845 #endif |