Klaus Demo nginx / 3d2fd18
upstream choice modules Igor Sysoev 15 years ago
24 changed file(s) with 1428 addition(s) and 754 deletion(s). Raw diff Collapse all Expand all
254254 HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
255255 fi
256256
257 if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
258 HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_IP_HASH_MODULE"
259 HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS"
260 fi
261
257262 # STUB
258263 #USE_MD5=YES
259264 #HTTP_SRCS="$HTTP_SRCS $HTPP_CACHE_SRCS"
7070 HTTP_EMPTY_GIF=YES
7171 HTTP_BROWSER=YES
7272 HTTP_FLV=NO
73 HTTP_UPSTREAM_IP_HASH=YES
7374
7475 # STUB
7576 HTTP_STUB_STATUS=NO
169170 --without-http_memcached_module) HTTP_MEMCACHED=NO ;;
170171 --without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;;
171172 --without-http_browser_module) HTTP_BROWSER=NO ;;
173 --without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;;
172174
173175 --with-http_perl_module) HTTP_PERL=YES ;;
174176 --with-perl_modules_path=*) NGX_PERL_MODULES="$value" ;;
270272 --without-http_memcached_module disable ngx_http_memcached_module
271273 --without-http_empty_gif_module disable ngx_http_empty_gif_module
272274 --without-http_browser_module disable ngx_http_browser_module
275 --without-http_upstream_ip_hash_module
276 disable ngx_http_upstream_ip_hash_module
273277
274278 --with-http_perl_module enable ngx_http_perl_module
275279 --with-perl_modules_path=PATH set path to the perl modules
269269 src/http/ngx_http_variables.h \
270270 src/http/ngx_http_script.h \
271271 src/http/ngx_http_upstream.h \
272 src/http/ngx_http_upstream_round_robin.h \
272273 src/http/ngx_http_busy_lock.h"
273274
274275 HTTP_SRCS="src/http/ngx_http.c \
284285 src/http/ngx_http_variables.c \
285286 src/http/ngx_http_script.c \
286287 src/http/ngx_http_upstream.c \
288 src/http/ngx_http_upstream_round_robin.c \
287289 src/http/ngx_http_parse_time.c \
288290 src/http/modules/ngx_http_static_module.c \
289291 src/http/modules/ngx_http_index_module.c \
397399 HTTP_FLV_SRCS=src/http/modules/ngx_http_flv_module.c
398400
399401
402 HTTP_UPSTREAM_IP_HASH_MODULE=ngx_http_upstream_ip_hash_module
403 HTTP_UPSTREAM_IP_HASH_SRCS=src/http/modules/ngx_http_upstream_ip_hash_module.c
404
405
400406 IMAP_INCS="src/imap"
401407
402408 IMAP_DEPS="src/imap/ngx_imap.h"
1818 typedef struct ngx_command_s ngx_command_t;
1919 typedef struct ngx_file_s ngx_file_t;
2020 typedef struct ngx_event_s ngx_event_t;
21 typedef struct ngx_peers_s ngx_peers_t;
2221 typedef struct ngx_connection_s ngx_connection_t;
2322
2423 typedef void (*ngx_event_handler_pt)(ngx_event_t *ev);
55
66 #include <ngx_config.h>
77 #include <ngx_core.h>
8 #include <ngx_event.h>
9 #include <ngx_event_connect.h>
108
119
1210 /*
238236
239237 #if (NGX_HAVE_UNIX_DOMAIN)
240238
241 u->type = NGX_PARSE_URL_UNIX;
242
243239 p += 5;
244240 len -= 5;
245241
270266 return NGX_ERROR;
271267 }
272268
273 u->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
274 if (u->peers == NULL) {
269 u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
270 if (u->addrs == NULL) {
275271 return NGX_ERROR;
276272 }
277273
280276 return NGX_ERROR;
281277 }
282278
283 u->peers->number = 1;
279 u->naddrs = 1;
284280
285281 saun->sun_family = AF_UNIX;
286282 (void) ngx_cpystrn((u_char *) saun->sun_path, p, len + 1);
287283
288 u->peers->peer[0].sockaddr = (struct sockaddr *) saun;
289 u->peers->peer[0].socklen = sizeof(struct sockaddr_un);
290 u->peers->peer[0].name.len = len + 5;
291 u->peers->peer[0].name.data = u->url.data;
292 u->peers->peer[0].uri_separator = ":";
284 u->addrs[0].sockaddr = (struct sockaddr *) saun;
285 u->addrs[0].socklen = sizeof(struct sockaddr_un);
286 u->addrs[0].name.len = len + 5;
287 u->addrs[0].name.data = u->url.data;
293288
294289 u->host_header.len = sizeof("localhost") - 1;
295290 u->host_header.data = (u_char *) "localhost";
308303 u->err = "invalid host";
309304 return NGX_ERROR;
310305 }
311
312 u->type = NGX_PARSE_URL_INET;
313306
314307 u->host.data = p;
315308 u->host_header.len = len;
322315 u->host.len = i;
323316
324317 if (!u->uri_part) {
325 u->port.len = &p[len] - u->port.data;
318 u->port.len = len - (i + 1);
326319 break;
327320 }
328321 }
337330 }
338331
339332 if (u->port.data == NULL) {
340 u->default_port = 1;
341 goto port;
333 u->no_port = 1;
334 goto no_port;
342335 }
343336
344337 u->port.len = &p[i] - u->port.data;
374367 port = ngx_atoi(p, len);
375368
376369 if (port == NGX_ERROR) {
377 u->default_port = 1;
378370 u->host.len = len;
379
380 goto port;
371 u->no_port = 1;
372
373 goto no_port;
381374 }
382375
383376 u->port.len = len;
387380
388381 u->portn = (in_port_t) port;
389382
390 port:
383 no_port:
391384
392385 if (u->listen) {
386
393387 if (u->portn == 0) {
394388 if (u->default_portn == 0) {
395389 u->err = "no port";
434428 return NGX_OK;
435429 }
436430
437 if (u->default_port) {
438
439 if (u->upstream) {
440 return NGX_OK;
441 }
442
443 if (u->default_portn == 0) {
431 if (u->no_port) {
432
433 if (u->default_portn == 0 && !u->upstream) {
444434 u->err = "no port";
445435 return NGX_ERROR;
446436 }
454444
455445 u->port.len = ngx_sprintf(u->port.data, "%d", u->portn) - u->port.data;
456446
457 } else if (u->portn) {
458 if (u->portn == u->default_portn) {
459 u->default_port = 1;
460 }
461
462 } else {
447 } else if (u->portn == 0) {
448
463449 u->err = "no port";
464450 return NGX_ERROR;
465451 }
469455 return NGX_ERROR;
470456 }
471457
472 u->peers = ngx_inet_resolve_peer(cf, &u->host, u->portn);
473
474 if (u->peers == NULL) {
475 return NGX_ERROR;
476 }
477
478 if (u->peers == NGX_CONF_ERROR) {
479 u->err = "host not found";
458 if (u->no_resolve) {
459 return NGX_OK;
460 }
461
462 if (ngx_inet_resolve_host(cf, u) != NGX_OK) {
480463 return NGX_ERROR;
481464 }
482465
484467 }
485468
486469
487 ngx_peers_t *
488 ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port)
470 ngx_int_t
471 ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
489472 {
490473 u_char *host;
491474 size_t len;
492475 in_addr_t in_addr;
493476 ngx_uint_t i;
494 ngx_peers_t *peers;
495477 struct hostent *h;
496478 struct sockaddr_in *sin;
497479
498 host = ngx_palloc(cf->temp_pool, name->len + 1);
480 host = ngx_palloc(cf->temp_pool, u->host.len + 1);
499481 if (host == NULL) {
500 return NULL;
501 }
502
503 (void) ngx_cpystrn(host, name->data, name->len + 1);
482 return NGX_ERROR;
483 }
484
485 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
504486
505487 /* AF_INET only */
506488
510492 h = gethostbyname((char *) host);
511493
512494 if (h == NULL || h->h_addr_list[0] == NULL) {
513 return NGX_CONF_ERROR;
514 }
515
516 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
495 u->err = "host not found";
496 return NGX_ERROR;
497 }
498
499 if (u->one_addr == 0) {
500 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
501
502 } else {
503 i = 1;
504 }
517505
518506 /* MP: ngx_shared_palloc() */
519507
520 peers = ngx_pcalloc(cf->pool,
521 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1));
522 if (peers == NULL) {
523 return NULL;
524 }
525
526 peers->number = i;
508 u->addrs = ngx_pcalloc(cf->pool, i * sizeof(ngx_peer_addr_t));
509 if (u->addrs == NULL) {
510 return NGX_ERROR;
511 }
512
513 u->naddrs = i;
527514
528515 for (i = 0; h->h_addr_list[i] != NULL; i++) {
529516
530517 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
531518 if (sin == NULL) {
532 return NULL;
519 return NGX_ERROR;
533520 }
534521
535522 sin->sin_family = AF_INET;
536 sin->sin_port = htons(port);
523 sin->sin_port = htons(u->portn);
537524 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
538525
539 peers->peer[i].sockaddr = (struct sockaddr *) sin;
540 peers->peer[i].socklen = sizeof(struct sockaddr_in);
526 u->addrs[i].sockaddr = (struct sockaddr *) sin;
527 u->addrs[i].socklen = sizeof(struct sockaddr_in);
541528
542529 len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
543530
544 peers->peer[i].name.data = ngx_palloc(cf->pool, len);
545 if (peers->peer[i].name.data == NULL) {
546 return NULL;
531 u->addrs[i].name.data = ngx_palloc(cf->pool, len);
532 if (u->addrs[i].name.data == NULL) {
533 return NGX_ERROR;
547534 }
548535
549536 len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin,
550 peers->peer[i].name.data, len);
551
552 peers->peer[i].name.len =
553 ngx_sprintf(&peers->peer[i].name.data[len],
554 ":%d", port)
555 - peers->peer[i].name.data;
556
557 peers->peer[i].uri_separator = "";
558
559 peers->peer[i].weight = NGX_CONF_UNSET_UINT;
560 peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
561 peers->peer[i].fail_timeout = NGX_CONF_UNSET;
537 u->addrs[i].name.data, len);
538
539 u->addrs[i].name.len = ngx_sprintf(&u->addrs[i].name.data[len],
540 ":%d", u->portn)
541 - u->addrs[i].name.data;
562542 }
563543
564544 } else {
565545
566546 /* MP: ngx_shared_palloc() */
567547
568 peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
569 if (peers == NULL) {
570 return NULL;
548 u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
549 if (u->addrs == NULL) {
550 return NGX_ERROR;
571551 }
572552
573553 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
574554 if (sin == NULL) {
575 return NULL;
576 }
577
578 peers->number = 1;
555 return NGX_ERROR;
556 }
557
558 u->naddrs = 1;
579559
580560 sin->sin_family = AF_INET;
581 sin->sin_port = htons(port);
561 sin->sin_port = htons(u->portn);
582562 sin->sin_addr.s_addr = in_addr;
583563
584 peers->peer[0].sockaddr = (struct sockaddr *) sin;
585 peers->peer[0].socklen = sizeof(struct sockaddr_in);
586
587 peers->peer[0].name.data = ngx_palloc(cf->pool,
588 name->len + sizeof(":65536") - 1);
589 if (peers->peer[0].name.data == NULL) {
590 return NULL;
591 }
592
593 peers->peer[0].name.len = ngx_sprintf(peers->peer[0].name.data, "%V:%d",
594 name, port)
595 - peers->peer[0].name.data;
596
597 peers->peer[0].uri_separator = "";
598 }
599
600 return peers;
564 u->addrs[0].sockaddr = (struct sockaddr *) sin;
565 u->addrs[0].socklen = sizeof(struct sockaddr_in);
566
567 u->addrs[0].name.data = ngx_palloc(cf->pool,
568 u->host.len + sizeof(":65536") - 1);
569 if (u->addrs[0].name.data == NULL) {
570 return NGX_ERROR;
571 }
572
573 u->addrs[0].name.len = ngx_sprintf(u->addrs[0].name.data, "%V:%d",
574 &u->host, u->portn)
575 - u->addrs[0].name.data;
576 }
577
578 return NGX_OK;
601579 }
1111 #include <ngx_core.h>
1212
1313
14 #define NGX_PARSE_URL_INET 1
15 #define NGX_PARSE_URL_UNIX 2
16
17
1814 typedef struct {
19 in_addr_t addr;
20 in_addr_t mask;
15 in_addr_t addr;
16 in_addr_t mask;
2117 } ngx_inet_cidr_t;
2218
2319
24 typedef struct {
25 struct sockaddr *sockaddr;
26 socklen_t socklen;
27
28 ngx_str_t name;
29 char *uri_separator;
30
31 ngx_uint_t current_weight;
32 ngx_uint_t weight;
33
34 ngx_uint_t fails;
35 time_t accessed;
36
37 ngx_uint_t max_fails;
38 time_t fail_timeout;
39
40 #if (NGX_SSL)
41 ngx_ssl_session_t *ssl_session;
42 #endif
43 } ngx_peer_t;
44
45
46 struct ngx_peers_s {
47 ngx_uint_t current;
48
49 ngx_uint_t number;
50 ngx_uint_t last_cached;
51
52 /* ngx_mutex_t *mutex; */
53 ngx_connection_t **cached;
54
55 ngx_peer_t peer[1];
56 };
57
58
5920 typedef union {
60 in_addr_t in_addr;
21 in_addr_t in_addr;
6122 } ngx_url_addr_t;
6223
6324
6425 typedef struct {
65 ngx_int_t type;
26 struct sockaddr *sockaddr;
27 socklen_t socklen;
28 ngx_str_t name;
29 } ngx_peer_addr_t;
6630
67 ngx_peers_t *peers;
6831
69 ngx_str_t url;
70 ngx_str_t host;
71 ngx_str_t host_header;
72 ngx_str_t port;
73 ngx_str_t uri;
32 typedef struct {
33 ngx_int_t type;
7434
75 in_port_t portn;
76 in_port_t default_portn;
35 ngx_str_t url;
36 ngx_str_t host;
37 ngx_str_t host_header;
38 ngx_str_t port;
39 ngx_str_t uri;
7740
78 unsigned listen:1;
79 unsigned uri_part:1;
80 unsigned upstream:1;
41 in_port_t portn;
42 in_port_t default_portn;
8143
82 unsigned default_port:1;
83 unsigned wildcard:1;
44 unsigned listen:1;
45 unsigned uri_part:1;
46 unsigned upstream:1;
47 unsigned no_resolve:1;
48 unsigned one_addr:1;
8449
85 ngx_url_addr_t addr;
50 unsigned wildcard:1;
51 unsigned no_port:1;
8652
87 char *err;
53 ngx_url_addr_t addr;
54
55 ngx_peer_addr_t *addrs;
56 ngx_uint_t naddrs;
57
58 char *err;
8859 } ngx_url_t;
8960
9061
9263 size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
9364 ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
9465 ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
95 ngx_peers_t *ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name,
96 in_port_t port);
66 ngx_int_t ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u);
67
9768
9869
9970 #endif /* _NGX_INET_H_INCLUDED_ */
1313 ngx_event_connect_peer(ngx_peer_connection_t *pc)
1414 {
1515 int rc;
16 ngx_uint_t level, i;
1716 u_int event;
18 time_t now;
1917 ngx_err_t err;
20 ngx_peer_t *peer;
18 ngx_uint_t level;
2119 ngx_socket_t s;
2220 ngx_event_t *rev, *wev;
2321 ngx_connection_t *c;
2422
25 now = ngx_time();
26
27 /* ngx_lock_mutex(pc->peers->mutex); */
28
29 if (pc->peers->last_cached) {
30
31 /* cached connection */
32
33 c = pc->peers->cached[pc->peers->last_cached];
34 pc->peers->last_cached--;
35
36 /* ngx_unlock_mutex(pc->peers->mutex); */
37
38 #if (NGX_THREADS)
39 c->read->lock = c->read->own_lock;
40 c->write->lock = c->write->own_lock;
41 #endif
42
43 pc->connection = c;
44 pc->cached = 1;
45
46 return NGX_OK;
47 }
48
49 pc->cached = 0;
50 pc->connection = NULL;
51
52 if (pc->peers->number == 1) {
53 peer = &pc->peers->peer[0];
54
55 } else {
56
57 /* there are several peers */
58
59 if (pc->tries == pc->peers->number) {
60
61 /* it's a first try - get a current peer */
62
63 for ( ;; ) {
64 pc->cur_peer = pc->peers->current;
65
66 peer = &pc->peers->peer[pc->cur_peer];
67
68 if (peer->max_fails == 0 || peer->fails <= peer->max_fails) {
69 break;
70 }
71
72 if (now - peer->accessed > peer->fail_timeout) {
73 peer->fails = 0;
74 break;
75 }
76
77 pc->peers->current++;
78
79 if (pc->peers->current >= pc->peers->number) {
80 pc->peers->current = 0;
81 }
82
83 pc->tries--;
84
85 if (pc->tries) {
86 continue;
87 }
88
89 goto failed;
90 }
91
92 peer->current_weight--;
93
94 if (peer->current_weight == 0) {
95 peer->current_weight = peer->weight;
96
97 pc->peers->current++;
98
99 if (pc->peers->current >= pc->peers->number) {
100 pc->peers->current = 0;
101 }
102 }
103
104 } else {
105 for ( ;; ) {
106 peer = &pc->peers->peer[pc->cur_peer];
107
108 if (peer->max_fails == 0 || peer->fails <= peer->max_fails) {
109 break;
110 }
111
112 if (now - peer->accessed > peer->fail_timeout) {
113 peer->fails = 0;
114 break;
115 }
116
117 pc->cur_peer++;
118
119 if (pc->cur_peer >= pc->peers->number) {
120 pc->cur_peer = 0;
121 }
122
123 pc->tries--;
124
125 if (pc->tries) {
126 continue;
127 }
128
129 goto failed;
130 }
131
132 peer->current_weight--;
133
134 if (peer->current_weight == 0) {
135 peer->current_weight = peer->weight;
136
137 if (pc->cur_peer == pc->peers->current) {
138 pc->peers->current++;
139
140 if (pc->peers->current >= pc->peers->number) {
141 pc->peers->current = 0;
142 }
143 }
144 }
145 }
146 }
147
148 /* ngx_unlock_mutex(pc->peers->mutex); */
149
150
151 s = ngx_socket(peer->sockaddr->sa_family, SOCK_STREAM, 0);
152
153 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0,
154 "socket %d", s);
23 rc = pc->get(pc, pc->data);
24 if (rc != NGX_OK) {
25 return rc;
26 }
27
28 s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0);
29
30 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s);
15531
15632 if (s == -1) {
15733 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
21086
21187 c->log_error = pc->log_error;
21288
213 if (peer->sockaddr->sa_family != AF_INET) {
89 if (pc->sockaddr->sa_family != AF_INET) {
21490 c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
21591 c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
21692
253129 }
254130
255131 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
256 "connect to %V, fd:%d #%d", &peer->name, s, c->number);
257
258 rc = connect(s, peer->sockaddr, peer->socklen);
132 "connect to %V, fd:%d #%d", pc->name, s, c->number);
133
134 rc = connect(s, pc->sockaddr, pc->socklen);
259135
260136 if (rc == -1) {
261137 err = ngx_socket_errno;
271147 }
272148
273149 ngx_log_error(level, c->log, err, "connect() to %V failed",
274 &peer->name);
150 pc->name);
275151
276152 return NGX_DECLINED;
277153 }
351227 wev->ready = 1;
352228
353229 return NGX_OK;
354
355 failed:
356
357 /* all peers failed, mark them as live for quick recovery */
358
359 for (i = 0; i < pc->peers->number; i++) {
360 pc->peers->peer[i].fails = 0;
361 }
362
363 /* ngx_unlock_mutex(pc->peers->mutex); */
364
365 return NGX_BUSY;
366230 }
367231
368232
369 void
370 ngx_event_connect_peer_failed(ngx_peer_connection_t *pc, ngx_uint_t down)
233 ngx_int_t
234 ngx_event_get_peer(ngx_peer_connection_t *pc, void *data)
371235 {
372 time_t now;
373 ngx_peer_t *peer;
374
375 if (down) {
376 now = ngx_time();
377
378 /* ngx_lock_mutex(pc->peers->mutex); */
379
380 peer = &pc->peers->peer[pc->cur_peer];
381
382 peer->fails++;
383 peer->accessed = now;
384
385 if (peer->current_weight > 1) {
386 peer->current_weight /= 2;
387 }
388
389 /* ngx_unlock_mutex(pc->peers->mutex); */
390 }
391
392 pc->cur_peer++;
393
394 if (pc->cur_peer >= pc->peers->number) {
395 pc->cur_peer = 0;
396 }
397
398 if (pc->tries) {
399 pc->tries--;
400 }
236 return NGX_OK;
401237 }
1212 #include <ngx_event.h>
1313
1414
15 typedef struct {
16 ngx_peers_t *peers;
17 ngx_uint_t cur_peer;
18 ngx_uint_t tries;
15 #define NGX_PEER_KEEPALIVE 1
16 #define NGX_PEER_NEXT 2
17 #define NGX_PEER_FAILED 4
1918
20 ngx_connection_t *connection;
21 #if (NGX_THREADS)
22 ngx_atomic_t *lock;
19
20 typedef struct ngx_peer_connection_s ngx_peer_connection_t;
21
22 typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc,
23 void *data);
24 #if (NGX_SSL)
25 typedef void (*ngx_event_save_peer_pt)(ngx_peer_connection_t *pc, void *data);
26 #endif
27 typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data,
28 ngx_uint_t state);
29
30
31 struct ngx_peer_connection_s {
32 ngx_connection_t *connection;
33
34 struct sockaddr *sockaddr;
35 socklen_t socklen;
36 ngx_str_t *name;
37
38 ngx_uint_t tries;
39
40 ngx_event_get_peer_pt get;
41 ngx_event_free_peer_pt free;
42 void *data;
43
44 #if (NGX_SSL)
45 ngx_ssl_session_t *ssl_session;
46 ngx_event_save_peer_pt save_session;
2347 #endif
2448
25 int rcvbuf;
49 #if (NGX_THREADS)
50 ngx_atomic_t *lock;
51 #endif
2652
27 ngx_log_t *log;
53 int rcvbuf;
2854
29 unsigned cached:1;
30 unsigned log_error:2; /* ngx_connection_log_error_e */
31 } ngx_peer_connection_t;
55 ngx_log_t *log;
56
57 unsigned cached:1;
58 unsigned log_error:2; /* ngx_connection_log_error_e */
59 };
3260
3361
3462 ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc);
35 void ngx_event_connect_peer_failed(ngx_peer_connection_t *pc, ngx_uint_t down);
63 ngx_int_t ngx_event_get_peer(ngx_peer_connection_t *pc, void *data);
64
3665
3766
3867 #endif /* _NGX_EVENT_CONNECT_H_INCLUDED_ */
1111
1212 typedef struct {
1313 ngx_http_upstream_conf_t upstream;
14
15 ngx_http_upstream_srv_conf_t *upstream_peers;
16 ngx_peers_t *peers0;
1714
1815 ngx_str_t index;
1916
120117 static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
121118 void *data);
122119
120 static char *ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf,
121 ngx_command_t *cmd, void *conf);
122 static char *ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
123 ngx_command_t *cmd, void *conf);
124
123125
124126 static ngx_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
125127 { 1, /* version */
309311
310312 { ngx_string("fastcgi_upstream_max_fails"),
311313 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
312 ngx_conf_set_num_slot,
313 NGX_HTTP_LOC_CONF_OFFSET,
314 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.max_fails),
314 ngx_http_fastcgi_upstream_max_fails_unsupported,
315 0,
316 0,
315317 NULL },
316318
317319 { ngx_string("fastcgi_upstream_fail_timeout"),
318320 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
319 ngx_conf_set_sec_slot,
320 NGX_HTTP_LOC_CONF_OFFSET,
321 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.fail_timeout),
321 ngx_http_fastcgi_upstream_fail_timeout_unsupported,
322 0,
323 0,
322324 NULL },
323325
324326 { ngx_string("fastcgi_param"),
410412
411413 u->peer.log = r->connection->log;
412414 u->peer.log_error = NGX_ERROR_ERR;
413 u->peer.peers = flcf->upstream_peers->peers;
414 u->peer.tries = flcf->upstream_peers->peers->number;
415415 #if (NGX_THREADS)
416416 u->peer.lock = &r->connection->lock;
417417 #endif
15461546 conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
15471547 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
15481548
1549 conf->upstream.max_fails = NGX_CONF_UNSET_UINT;
1550 conf->upstream.fail_timeout = NGX_CONF_UNSET;
1551
15521549 conf->upstream.pass_request_headers = NGX_CONF_UNSET;
15531550 conf->upstream.pass_request_body = NGX_CONF_UNSET;
15541551
15721569 uintptr_t *code;
15731570 ngx_str_t *header;
15741571 ngx_uint_t i, j;
1575 ngx_peer_t *peer;
15761572 ngx_array_t hide_headers;
15771573 ngx_keyval_t *src;
15781574 ngx_hash_key_t *hk;
17061702 |NGX_HTTP_UPSTREAM_FT_OFF;
17071703 }
17081704
1709 ngx_conf_merge_uint_value(conf->upstream.max_fails,
1710 prev->upstream.max_fails, 1);
1711
1712 ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
1713 prev->upstream.fail_timeout, 10);
1714
1715 if (conf->upstream_peers) {
1716 peer = conf->upstream_peers->peers->peer;
1717 for (i = 0; i < conf->upstream_peers->peers->number; i++) {
1718 ngx_conf_init_uint_value(peer[i].weight, 1);
1719 peer[i].current_weight = peer[i].weight;
1720 ngx_conf_init_uint_value(peer[i].max_fails,
1721 conf->upstream.max_fails);
1722 ngx_conf_init_value(peer[i].fail_timeout,
1723 conf->upstream.fail_timeout);
1724 }
1725
1726 }
1727
17281705 ngx_conf_merge_path_value(conf->upstream.temp_path,
17291706 prev->upstream.temp_path,
17301707 NGX_HTTP_FASTCGI_TEMP_PATH, 1, 2, 0,
18431820
18441821 peers:
18451822
1846 if (conf->upstream_peers == NULL) {
1847 conf->upstream_peers = prev->upstream_peers;
1823 if (conf->upstream.upstream == NULL) {
1824 conf->upstream.upstream = prev->upstream.upstream;
18481825 conf->upstream.schema = prev->upstream.schema;
18491826 }
18501827
20322009 ngx_memzero(&u, sizeof(ngx_url_t));
20332010
20342011 u.url = value[1];
2035 u.upstream = 1;
2036
2037 lcf->upstream_peers = ngx_http_upstream_add(cf, &u);
2038 if (lcf->upstream_peers == NULL) {
2012 u.no_resolve = 1;
2013
2014 lcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
2015 if (lcf->upstream.upstream == NULL) {
20392016 return NGX_CONF_ERROR;
20402017 }
20412018
20832060
20842061 return NGX_CONF_OK;
20852062 }
2063
2064
2065 static char *
2066 ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf,
2067 ngx_command_t *cmd, void *conf)
2068 {
2069 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2070 "\"fastcgi_upstream_max_fails\" is not supported, "
2071 "use the \"max_fails\" parameter of the \"server\" directive ",
2072 "inside the \"upstream\" block");
2073
2074 return NGX_CONF_ERROR;
2075 }
2076
2077
2078 static char *
2079 ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
2080 ngx_command_t *cmd, void *conf)
2081 {
2082 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2083 "\"fastcgi_upstream_fail_timeout\" is not supported, "
2084 "use the \"fail_timeout\" parameter of the \"server\" directive ",
2085 "inside the \"upstream\" block");
2086
2087 return NGX_CONF_ERROR;
2088 }
1111
1212 typedef struct {
1313 ngx_http_upstream_conf_t upstream;
14 ngx_peers_t *peers;
1514 } ngx_http_memcached_loc_conf_t;
1615
1716
3837 static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd,
3938 void *conf);
4039
40 static char *ngx_http_memcached_upstream_max_fails_unsupported(ngx_conf_t *cf,
41 ngx_command_t *cmd, void *conf);
42 static char *ngx_http_memcached_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
43 ngx_command_t *cmd, void *conf);
44
4145
4246 static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = {
4347 { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
9599
96100 { ngx_string("memcached_upstream_max_fails"),
97101 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
98 ngx_conf_set_num_slot,
99 NGX_HTTP_LOC_CONF_OFFSET,
100 offsetof(ngx_http_memcached_loc_conf_t, upstream.max_fails),
102 ngx_http_memcached_upstream_max_fails_unsupported,
103 0,
104 0,
101105 NULL },
102106
103107 { ngx_string("memcached_upstream_fail_timeout"),
104108 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
105 ngx_conf_set_sec_slot,
106 NGX_HTTP_LOC_CONF_OFFSET,
107 offsetof(ngx_http_memcached_loc_conf_t, upstream.fail_timeout),
109 ngx_http_memcached_upstream_fail_timeout_unsupported,
110 0,
111 0,
108112 NULL },
109113
110114 ngx_null_command
177181
178182 u->peer.log = r->connection->log;
179183 u->peer.log_error = NGX_ERROR_ERR;
180 u->peer.peers = mlcf->peers;
181 u->peer.tries = mlcf->peers->number;
182184 #if (NGX_THREADS)
183185 u->peer.lock = &r->connection->lock;
184186 #endif
510512
511513 conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
512514
513 conf->upstream.max_fails = NGX_CONF_UNSET_UINT;
514 conf->upstream.fail_timeout = NGX_CONF_UNSET;
515
516 /* "fastcgi_cyclic_temp_file" is disabled */
515 /* the hardcoded values */
517516 conf->upstream.cyclic_temp_file = 0;
518
519 /* the hardcoded values */
520517 conf->upstream.buffering = 0;
521518 conf->upstream.ignore_client_abort = 0;
522519 conf->upstream.send_lowat = 0;
539536 ngx_http_memcached_loc_conf_t *prev = parent;
540537 ngx_http_memcached_loc_conf_t *conf = child;
541538
542 ngx_uint_t i;
543
544539 ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
545540 prev->upstream.connect_timeout, 60000);
546541
565560 |NGX_HTTP_UPSTREAM_FT_OFF;
566561 }
567562
568 ngx_conf_merge_uint_value(conf->upstream.max_fails,
569 prev->upstream.max_fails, 1);
570
571 ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
572 prev->upstream.fail_timeout, 10);
573
574 if (conf->peers && conf->peers->number > 1) {
575 for (i = 0; i < conf->peers->number; i++) {
576 conf->peers->peer[i].weight = 1;
577 conf->peers->peer[i].max_fails = conf->upstream.max_fails;
578 conf->peers->peer[i].fail_timeout = conf->upstream.fail_timeout;
579 }
580 }
581
582563 return NGX_CONF_OK;
583564 }
584565
601582 ngx_memzero(&u, sizeof(ngx_url_t));
602583
603584 u.url = value[1];
604 u.uri_part = 1;
605
606 if (ngx_parse_url(cf, &u) != NGX_OK) {
607 if (u.err) {
608 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
609 "%s in \"%V\"", u.err, &u.url);
610 }
611 }
612
613 lcf->peers = u.peers;
585 u.no_resolve = 1;
586 /* u.uri_part = 1; may be used as namespace */
587
588 lcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
589 if (lcf->upstream.upstream == NULL) {
590 return NGX_CONF_ERROR;
591 }
592
614593 lcf->upstream.schema.len = sizeof("memcached://") - 1;
615594 lcf->upstream.schema.data = (u_char *) "memcached://";
616595
626605
627606 return NGX_CONF_OK;
628607 }
608
609
610 static char *
611 ngx_http_memcached_upstream_max_fails_unsupported(ngx_conf_t *cf,
612 ngx_command_t *cmd, void *conf)
613 {
614 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
615 "\"memcached_upstream_max_fails\" is not supported, "
616 "use the \"max_fails\" parameter of the \"server\" directive ",
617 "inside the \"upstream\" block");
618
619 return NGX_CONF_ERROR;
620 }
621
622
623 static char *
624 ngx_http_memcached_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
625 ngx_command_t *cmd, void *conf)
626 {
627 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
628 "\"memcached_upstream_fail_timeout\" is not supported, "
629 "use the \"fail_timeout\" parameter of the \"server\" directive ",
630 "inside the \"upstream\" block");
631
632 return NGX_CONF_ERROR;
633 }
3333
3434 typedef struct {
3535 ngx_http_upstream_conf_t upstream;
36
37 ngx_http_upstream_srv_conf_t *upstream_peers;
3836
3937 ngx_array_t *flushes;
4038 ngx_array_t *body_set_len;
106104
107105 static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
108106
107 static char *ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf,
108 ngx_command_t *cmd, void *conf);
109 static char *ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
110 ngx_command_t *cmd, void *conf);
111
109112
110113 static ngx_conf_post_t ngx_http_proxy_lowat_post =
111114 { ngx_http_proxy_lowat_check };
296299
297300 { ngx_string("proxy_upstream_max_fails"),
298301 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
299 ngx_conf_set_num_slot,
300 NGX_HTTP_LOC_CONF_OFFSET,
301 offsetof(ngx_http_proxy_loc_conf_t, upstream.max_fails),
302 ngx_http_proxy_upstream_max_fails_unsupported,
303 0,
304 0,
302305 NULL },
303306
304307 { ngx_string("proxy_upstream_fail_timeout"),
305308 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
306 ngx_conf_set_sec_slot,
307 NGX_HTTP_LOC_CONF_OFFSET,
308 offsetof(ngx_http_proxy_loc_conf_t, upstream.fail_timeout),
309 ngx_http_proxy_upstream_fail_timeout_unsupported,
310 0,
311 0,
309312 NULL },
310313
311314 { ngx_string("proxy_pass_header"),
418421
419422 u->peer.log = r->connection->log;
420423 u->peer.log_error = NGX_ERROR_ERR;
421 u->peer.peers = plcf->upstream_peers->peers;
422 u->peer.tries = plcf->upstream_peers->peers->number;
423424 #if (NGX_THREADS)
424425 u->peer.lock = &r->connection->lock;
425426 #endif
14971498 conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
14981499 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
14991500
1500 conf->upstream.max_fails = NGX_CONF_UNSET_UINT;
1501 conf->upstream.fail_timeout = NGX_CONF_UNSET;
1502
15031501 conf->upstream.pass_request_headers = NGX_CONF_UNSET;
15041502 conf->upstream.pass_request_body = NGX_CONF_UNSET;
15051503
15261524 uintptr_t *code;
15271525 ngx_str_t *header;
15281526 ngx_uint_t i, j;
1529 ngx_peer_t *peer;
15301527 ngx_array_t hide_headers;
15311528 ngx_keyval_t *src, *s, *h;
15321529 ngx_hash_key_t *hk;
16591656 |NGX_HTTP_UPSTREAM_FT_OFF;
16601657 }
16611658
1662 ngx_conf_merge_uint_value(conf->upstream.max_fails,
1663 prev->upstream.max_fails, 1);
1664
1665 ngx_conf_merge_sec_value(conf->upstream.fail_timeout,
1666 prev->upstream.fail_timeout, 10);
1667
1668 if (conf->upstream_peers) {
1669 peer = conf->upstream_peers->peers->peer;
1670 for (i = 0; i < conf->upstream_peers->peers->number; i++) {
1671 ngx_conf_init_uint_value(peer[i].weight, 1);
1672 peer[i].current_weight = peer[i].weight;
1673 ngx_conf_init_uint_value(peer[i].max_fails,
1674 conf->upstream.max_fails);
1675 ngx_conf_init_value(peer[i].fail_timeout,
1676 conf->upstream.fail_timeout);
1677 }
1678 }
1679
16801659 ngx_conf_merge_path_value(conf->upstream.temp_path,
16811660 prev->upstream.temp_path,
16821661 NGX_HTTP_PROXY_TEMP_PATH, 1, 2, 0,
18331812
18341813 peers:
18351814
1836 if (conf->upstream_peers == NULL) {
1837 conf->upstream_peers = prev->upstream_peers;
1815 if (conf->upstream.upstream == NULL) {
1816 conf->upstream.upstream = prev->upstream.upstream;
18381817
18391818 conf->host_header = prev->host_header;
18401819 conf->port_text = prev->port_text;
21792158 u.url.len = url->len - add;
21802159 u.url.data = url->data + add;
21812160 u.default_portn = port;
2161 u.no_resolve = 1;
21822162 u.uri_part = 1;
2183 u.upstream = 1;
2184
2185 plcf->upstream_peers = ngx_http_upstream_add(cf, &u);
2186 if (plcf->upstream_peers == NULL) {
2163
2164 plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
2165 if (plcf->upstream.upstream == NULL) {
21872166 return NGX_CONF_ERROR;
21882167 }
21892168
23442323
23452324 return NGX_CONF_OK;
23462325 }
2326
2327
2328 static char *
2329 ngx_http_proxy_upstream_max_fails_unsupported(ngx_conf_t *cf,
2330 ngx_command_t *cmd, void *conf)
2331 {
2332 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2333 "\"proxy_upstream_max_fails\" is not supported, "
2334 "use the \"max_fails\" parameter of the \"server\" directive ",
2335 "inside the \"upstream\" block");
2336
2337 return NGX_CONF_ERROR;
2338 }
2339
2340
2341 static char *
2342 ngx_http_proxy_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
2343 ngx_command_t *cmd, void *conf)
2344 {
2345 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2346 "\"proxy_upstream_fail_timeout\" is not supported, "
2347 "use the \"fail_timeout\" parameter of the \"server\" directive ",
2348 "inside the \"upstream\" block");
2349
2350 return NGX_CONF_ERROR;
2351 }
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_http.h>
9
10
11 typedef struct {
12 /* the round robin data must be first */
13 ngx_http_upstream_rr_peer_data_t rrp;
14
15 ngx_uint_t hash;
16
17 /* AF_INET only */
18 u_char addr[3];
19
20 u_char tries;
21
22 ngx_event_get_peer_pt get_rr_peer;
23 } ngx_http_upstream_ip_hash_peer_data_t;
24
25
26 static ngx_int_t ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
27 ngx_http_upstream_srv_conf_t *us);
28 static ngx_int_t ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc,
29 void *data);
30 static char *ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd,
31 void *conf);
32
33
34 static ngx_command_t ngx_http_upstream_ip_hash_commands[] = {
35
36 { ngx_string("ip_hash"),
37 NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
38 ngx_http_upstream_ip_hash,
39 0,
40 0,
41 NULL },
42
43 ngx_null_command
44 };
45
46
47 static ngx_http_module_t ngx_http_upstream_ip_hash_module_ctx = {
48 NULL, /* preconfiguration */
49 NULL, /* postconfiguration */
50
51 NULL, /* create main configuration */
52 NULL, /* init main configuration */
53
54 NULL, /* create server configuration */
55 NULL, /* merge server configuration */
56
57 NULL, /* create location configuration */
58 NULL /* merge location configuration */
59 };
60
61
62 ngx_module_t ngx_http_upstream_ip_hash_module = {
63 NGX_MODULE_V1,
64 &ngx_http_upstream_ip_hash_module_ctx, /* module context */
65 ngx_http_upstream_ip_hash_commands, /* module directives */
66 NGX_HTTP_MODULE, /* module type */
67 NULL, /* init master */
68 NULL, /* init module */
69 NULL, /* init process */
70 NULL, /* init thread */
71 NULL, /* exit thread */
72 NULL, /* exit process */
73 NULL, /* exit master */
74 NGX_MODULE_V1_PADDING
75 };
76
77
78 ngx_int_t
79 ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
80 {
81 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
82 return NGX_ERROR;
83 }
84
85 us->peer.init = ngx_http_upstream_init_ip_hash_peer;
86
87 return NGX_OK;
88 }
89
90
91 static ngx_int_t
92 ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
93 ngx_http_upstream_srv_conf_t *us)
94 {
95 struct sockaddr_in *sin;
96 ngx_http_upstream_ip_hash_peer_data_t *iphp;
97
98 iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t));
99 if (iphp == NULL) {
100 return NGX_ERROR;
101 }
102
103 r->upstream->peer.data = &iphp->rrp;
104
105 if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
106 return NGX_ERROR;
107 }
108
109 r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
110
111 /* AF_INET only */
112 sin = (struct sockaddr_in *) r->connection->sockaddr;
113 iphp->addr[0] = (u_char) ((sin->sin_addr.s_addr >> 24) & 0xff);
114 iphp->addr[1] = (u_char) ((sin->sin_addr.s_addr >> 16) & 0xff);
115 iphp->addr[2] = (u_char) ((sin->sin_addr.s_addr >> 8) & 0xff);
116
117 iphp->hash = 89;
118 iphp->tries = 0;
119 iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
120
121 return NGX_OK;
122 }
123
124
125 static ngx_int_t
126 ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
127 {
128 ngx_http_upstream_ip_hash_peer_data_t *iphp = data;
129
130 time_t now;
131 uintptr_t m;
132 ngx_uint_t i, n, p, hash;
133 ngx_http_upstream_rr_peer_t *peer;
134
135 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
136 "get ip hash peer, try: %ui", pc->tries);
137
138 /* TODO: cached */
139
140 if (iphp->tries > 20 || iphp->rrp.peers->number == 1) {
141 return iphp->get_rr_peer(pc, &iphp->rrp);
142 }
143
144 now = ngx_time();
145
146 pc->cached = 0;
147 pc->connection = NULL;
148
149 hash = iphp->hash;
150
151 for ( ;; ) {
152
153 for (i = 0; i < 3; i++) {
154 hash = (hash * 113 + iphp->addr[i]) % 6271;
155 }
156
157 p = hash % iphp->rrp.peers->number;
158
159 n = p / (8 * sizeof(uintptr_t));
160 m = 1 << p % (8 * sizeof(uintptr_t));
161
162 if (!(iphp->rrp.tried[n] & m)) {
163
164 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
165 "get ip hash peer, hash: %ui %04XA", p, m);
166
167 peer = &iphp->rrp.peers->peer[p];
168
169 /* ngx_lock_mutex(iphp->rrp.peers->mutex); */
170
171 if (!peer->down) {
172
173 if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
174 break;
175 }
176
177 if (now - peer->accessed > peer->fail_timeout) {
178 peer->fails = 0;
179 break;
180 }
181
182 } else {
183 iphp->rrp.tried[n] |= m;
184 }
185
186 /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
187
188 pc->tries--;
189 }
190
191 if (++iphp->tries >= 20) {
192 return iphp->get_rr_peer(pc, &iphp->rrp);
193 }
194 }
195
196 pc->sockaddr = peer->sockaddr;
197 pc->socklen = peer->socklen;
198 pc->name = &peer->name;
199 #if (NGX_SSL)
200 pc->ssl_session = peer->ssl_session;
201 #endif
202
203 /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
204
205 iphp->rrp.tried[n] |= m;
206 iphp->hash = hash;
207
208 return NGX_OK;
209 }
210
211
212 static char *
213 ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
214 {
215 ngx_http_upstream_srv_conf_t *uscf;
216
217 uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
218
219 uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
220
221 uscf->flags = NGX_HTTP_UPSTREAM_CREATE
222 |NGX_HTTP_UPSTREAM_MAX_FAILS
223 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
224 |NGX_HTTP_UPSTREAM_DOWN;
225
226 return NGX_CONF_OK;
227 }
3131 #include <ngx_http_variables.h>
3232 #include <ngx_http_request.h>
3333 #include <ngx_http_upstream.h>
34 #include <ngx_http_upstream_round_robin.h>
3435 #include <ngx_http_config.h>
3536 #include <ngx_http_busy_lock.h>
3637 #include <ngx_http_core_module.h>
24082408 ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
24092409 u_char *buf, size_t len)
24102410 {
2411 u_char *p;
2412 ngx_http_upstream_t *u;
2413 ngx_peer_connection_t *peer;
2411 char *uri_separator;
2412 u_char *p;
2413 ngx_http_upstream_t *u;
24142414
24152415 if (r->server_name.data) {
24162416 p = ngx_snprintf(buf, len, ", server: %V", &r->server_name);
24502450
24512451 u = sr->upstream;
24522452
2453 if (u) {
2454 peer = &u->peer;
2453 if (u && u->peer.name) {
2454
2455 uri_separator = "";
2456
2457 #if (NGX_HAVE_UNIX_DOMAIN)
2458 if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
2459 uri_separator = ":";
2460 }
2461 #endif
24552462
24562463 p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
2457 &u->conf->schema,
2458 &peer->peers->peer[peer->cur_peer].name,
2459 peer->peers->peer[peer->cur_peer].uri_separator,
2460 &u->uri);
2464 &u->conf->schema, u->peer.name,
2465 uri_separator, &u->uri);
24612466 len -= p - buf;
24622467 buf = p;
24632468 }
8686 static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *,
8787 ngx_http_upstream_t *u, ngx_connection_t *c);
8888 static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c);
89 static void ngx_http_upstream_ssl_shutdown(ngx_connection_t *c,
90 ngx_peer_t *peer);
9189 #endif
9290
9391
214212 NULL },
215213
216214 { ngx_string("server"),
217 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
215 NGX_HTTP_UPS_CONF|NGX_CONF_1MORE,
218216 ngx_http_upstream_server,
219217 NGX_HTTP_SRV_CONF_OFFSET,
220218 0,
307305 u->request_bufs = r->request_body->bufs;
308306 }
309307
308 if (u->conf->upstream->peer.init(r, u->conf->upstream) != NGX_OK) {
309 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
310 return;
311 }
312
310313 if (u->create_request(r) != NGX_OK) {
311314 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
312315 return;
313316 }
314
315 u->peer.log = r->connection->log;
316317
317318 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
318319
325326
326327 u->writer.pool = r->pool;
327328
328 if (ngx_array_init(&u->states, r->pool, u->peer.peers->number,
329 if (ngx_array_init(&u->states, r->pool, 1,
329330 sizeof(ngx_http_upstream_state_t))
330331 != NGX_OK)
331332 {
527528 return;
528529 }
529530
530 u->state->peer = &u->peer.peers->peer[u->peer.cur_peer].name;
531 u->state->peer = u->peer.name;
531532
532533 if (rc == NGX_BUSY) {
533534 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
616617 ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
617618 ngx_http_upstream_t *u, ngx_connection_t *c)
618619 {
619 ngx_int_t rc;
620 ngx_peer_t *peer;
620 ngx_int_t rc;
621621
622622 if (ngx_ssl_create_connection(u->conf->ssl, c,
623623 NGX_SSL_BUFFER|NGX_SSL_CLIENT)
631631 c->sendfile = 0;
632632 u->output.sendfile = 0;
633633
634 peer = &u->peer.peers->peer[u->peer.cur_peer];
635
636 if (ngx_ssl_set_session(c, peer->ssl_session) != NGX_OK) {
634 if (ngx_ssl_set_session(c, u->peer.ssl_session) != NGX_OK) {
637635 ngx_http_upstream_finalize_request(r, u,
638636 NGX_HTTP_INTERNAL_SERVER_ERROR);
639637 return;
662660 u = r->upstream;
663661
664662 if (c->ssl->handshaked) {
663
664 u->peer.save_session(&u->peer, u->peer.data);
665665
666666 c->write->handler = ngx_http_upstream_send_request_handler;
667667 c->read->handler = ngx_http_upstream_process_header;
971971 }
972972
973973 n = u->peer.connection->recv(u->peer.connection, u->buffer.last,
974 u->buffer.end - u->buffer.last);
974 u->buffer.end - u->buffer.last);
975975
976976 if (n == NGX_AGAIN) {
977977 #if 0
15841584 ngx_buf_t *b;
15851585 ngx_int_t rc;
15861586 ngx_uint_t do_write;
1587 ngx_connection_t *c, *client;
1587 ngx_connection_t *c, *downstream, *upstream;
15881588 ngx_http_request_t *r;
15891589 ngx_http_upstream_t *u;
15901590 ngx_http_core_loc_conf_t *clcf;
16171617 return;
16181618 }
16191619
1620 client = r->connection;
1620 downstream = r->connection;
1621 upstream = u->peer.connection;
16211622
16221623 b = &u->buffer;
16231624
16321633 if (u->out_bufs || u->busy_bufs) {
16331634 rc = ngx_http_output_filter(r, u->out_bufs);
16341635
1635 if (client->destroyed) {
1636 if (downstream->destroyed) {
16361637 return;
16371638 }
16381639
16481649 if (u->busy_bufs == NULL) {
16491650
16501651 if (u->length == 0
1651 || u->peer.connection->read->eof
1652 || u->peer.connection->read->error)
1652 || upstream->read->eof
1653 || upstream->read->error)
16531654 {
16541655 ngx_http_upstream_finalize_request(r, u, 0);
16551656 return;
16661667 size = u->length;
16671668 }
16681669
1669 if (size && u->peer.connection->read->ready) {
1670
1671 n = u->peer.connection->recv(u->peer.connection, b->last, size);
1670 if (size && upstream->read->ready) {
1671
1672 n = upstream->recv(upstream, b->last, size);
16721673
16731674 if (n == NGX_AGAIN) {
16741675 break;
16891690 break;
16901691 }
16911692
1692 if (client->data == r) {
1693 if (ngx_handle_write_event(client->write, clcf->send_lowat)
1693 if (downstream->data == r) {
1694 if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
16941695 == NGX_ERROR)
16951696 {
16961697 ngx_http_upstream_finalize_request(r, u, 0);
16981699 }
16991700 }
17001701
1701 if (client->write->active) {
1702 ngx_add_timer(client->write, clcf->send_timeout);
1703
1704 } else if (client->write->timer_set) {
1705 ngx_del_timer(client->write);
1706 }
1707
1708 if (ngx_handle_read_event(u->peer.connection->read, 0) == NGX_ERROR) {
1702 if (downstream->write->active) {
1703 ngx_add_timer(downstream->write, clcf->send_timeout);
1704
1705 } else if (downstream->write->timer_set) {
1706 ngx_del_timer(downstream->write);
1707 }
1708
1709 if (ngx_handle_read_event(upstream->read, 0) == NGX_ERROR) {
17091710 ngx_http_upstream_finalize_request(r, u, 0);
17101711 return;
17111712 }
17121713
1713 if (u->peer.connection->read->active) {
1714 ngx_add_timer(u->peer.connection->read, u->conf->read_timeout);
1715
1716 } else if (u->peer.connection->read->timer_set) {
1717 ngx_del_timer(u->peer.connection->read);
1714 if (upstream->read->active) {
1715 ngx_add_timer(upstream->read, u->conf->read_timeout);
1716
1717 } else if (upstream->read->timer_set) {
1718 ngx_del_timer(upstream->read);
17181719 }
17191720 }
17201721
19211922 ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
19221923 ngx_uint_t ft_type)
19231924 {
1924 ngx_uint_t status, down;
1925 ngx_uint_t status, state;
19251926
19261927 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1927 "http next upstream, %xD", ft_type);
1928 "http next upstream, %xi", ft_type);
19281929
19291930 #if 0
19301931 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
19311932 #endif
19321933
19331934 if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
1934 down = 0;
1935 state = NGX_PEER_NEXT;
19351936 } else {
1936 down = 1;
1937 }
1938
1939 ngx_event_connect_peer_failed(&u->peer, down);
1937 state = NGX_PEER_FAILED;
1938 }
1939
1940 u->peer.free(&u->peer, u->peer.data, state);
19401941
19411942 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
19421943 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
20022003 "close http upstream connection: %d",
20032004 u->peer.connection->fd);
20042005 #if (NGX_HTTP_SSL)
2006
20052007 if (u->peer.connection->ssl) {
2006 ngx_http_upstream_ssl_shutdown(u->peer.connection,
2007 &u->peer.peers->peer[u->peer.cur_peer]);
2008 u->peer.connection->ssl->no_wait_shutdown = 1;
2009 u->peer.connection->ssl->no_send_shutdown = 1;
2010
2011 (void) ngx_ssl_shutdown(u->peer.connection);
20082012 }
20092013 #endif
2014
20102015 ngx_close_connection(u->peer.connection);
20112016 }
20122017
20532058
20542059 u->finalize_request(r, rc);
20552060
2061 u->peer.free(&u->peer, u->peer.data, 0);
2062
20562063 if (u->peer.connection) {
2064
2065 #if (NGX_HTTP_SSL)
2066
2067 /* TODO: do not shutdown persistent connection */
2068
2069 if (u->peer.connection->ssl) {
2070
2071 /*
2072 * We send the "close notify" shutdown alert to the upstream only
2073 * and do not wait its "close notify" shutdown alert.
2074 * It is acceptable according to the TLS standard.
2075 */
2076
2077 u->peer.connection->ssl->no_wait_shutdown = 1;
2078
2079 (void) ngx_ssl_shutdown(u->peer.connection);
2080 }
2081 #endif
2082
20572083 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
20582084 "close http upstream connection: %d",
20592085 u->peer.connection->fd);
2060 #if (NGX_HTTP_SSL)
2061
2062 /* TODO: do not shutdown persistent connection */
2063
2064 if (u->peer.connection->ssl) {
2065 ngx_http_upstream_ssl_shutdown(u->peer.connection,
2066 &u->peer.peers->peer[u->peer.cur_peer]);
2067 }
2068 #endif
2086
20692087 ngx_close_connection(u->peer.connection);
20702088 }
20712089
21042122 }
21052123
21062124
2107 #if (NGX_HTTP_SSL)
2108
2109 static void
2110 ngx_http_upstream_ssl_shutdown(ngx_connection_t *c, ngx_peer_t *peer)
2111 {
2112 /* lock peer mutex */
2113
2114 if (peer->ssl_session) {
2115 ngx_ssl_free_session(peer->ssl_session);
2116 }
2117
2118 peer->ssl_session = ngx_ssl_get_session(c);
2119
2120 /* unlock peer mutex */
2121
2122 /*
2123 * We send the "close notify" shutdown alert to the upstream only
2124 * and do not wait its "close notify" shutdown alert.
2125 * It is acceptable according to the TLS standard.
2126 */
2127
2128 c->ssl->no_wait_shutdown = 1;
2129
2130 (void) ngx_ssl_shutdown(c);
2131 }
2132
2133 #endif
2134
2135
21362125 static ngx_int_t
21372126 ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
21382127 ngx_uint_t offset)
25942583 static char *
25952584 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
25962585 {
2597 char *rv;
2598 void *mconf;
2599 ngx_str_t *value;
2600 ngx_url_t u;
2601 ngx_uint_t i, j, m, n;
2602 ngx_conf_t pcf;
2603 ngx_peers_t **peers;
2604 ngx_http_module_t *module;
2605 ngx_http_conf_ctx_t *ctx;
2606 ngx_http_upstream_srv_conf_t *uscf;
2586 char *rv;
2587 void *mconf;
2588 ngx_str_t *value;
2589 ngx_url_t u;
2590 ngx_uint_t m;
2591 ngx_conf_t pcf;
2592 ngx_http_module_t *module;
2593 ngx_http_conf_ctx_t *ctx, *http_ctx;
2594 ngx_http_upstream_srv_conf_t *uscf;
2595
2596 ngx_memzero(&u, sizeof(ngx_url_t));
2597
2598 value = cf->args->elts;
2599 u.host = value[1];
2600 u.upstream = 1;
2601 u.no_resolve = 1;
2602
2603 uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
2604 |NGX_HTTP_UPSTREAM_WEIGHT
2605 |NGX_HTTP_UPSTREAM_MAX_FAILS
2606 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
2607 |NGX_HTTP_UPSTREAM_DOWN
2608 |NGX_HTTP_UPSTREAM_BACKUP);
2609 if (uscf == NULL) {
2610 return NGX_CONF_ERROR;
2611 }
2612
26072613
26082614 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
26092615 if (ctx == NULL) {
26102616 return NGX_CONF_ERROR;
26112617 }
26122618
2613 ngx_memzero(&u, sizeof(ngx_url_t));
2614
2615 value = cf->args->elts;
2616 u.host = value[1];
2617
2618 uscf = ngx_http_upstream_add(cf, &u);
2619 if (uscf == NULL) {
2620 return NGX_CONF_ERROR;
2621 }
2619 http_ctx = cf->ctx;
2620 ctx->main_conf = http_ctx->main_conf;
26222621
26232622 /* the upstream{}'s srv_conf */
26242623
26292628
26302629 ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf;
26312630
2631 uscf->srv_conf = ctx->srv_conf;
2632
26322633
26332634 /* the upstream{}'s loc_conf */
26342635
26432644 }
26442645
26452646 module = ngx_modules[m]->ctx;
2647
2648 if (module->create_srv_conf) {
2649 mconf = module->create_srv_conf(cf);
2650 if (mconf == NULL) {
2651 return NGX_CONF_ERROR;
2652 }
2653
2654 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
2655 }
26462656
26472657 if (module->create_loc_conf) {
26482658 mconf = module->create_loc_conf(cf);
26752685 return NGX_CONF_ERROR;
26762686 }
26772687
2678 peers = uscf->servers->elts;
2679
2680 if (uscf->servers->nelts == 1) {
2681 uscf->peers = peers[0];
2682 }
2683
2684 n = 0;
2685
2686 for (i = 0; i < uscf->servers->nelts; i++) {
2687 n += peers[i]->number;
2688 }
2689
2690 uscf->peers = ngx_pcalloc(cf->pool,
2691 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (n - 1));
2692 if (uscf->peers == NULL) {
2693 return NGX_CONF_ERROR;
2694 }
2695
2696 uscf->peers->number = n;
2697
2698 n = 0;
2699
2700 for (i = 0; i < uscf->servers->nelts; i++) {
2701 for (j = 0; j < peers[i]->number; j++) {
2702 uscf->peers->peer[n++] = peers[i]->peer[j];
2703 }
2704 }
2705
27062688 return rv;
27072689 }
27082690
27122694 {
27132695 ngx_http_upstream_srv_conf_t *uscf = conf;
27142696
2715 ngx_str_t *value;
2716 ngx_url_t u;
2717 ngx_int_t weight;
2718 ngx_uint_t i;
2719 ngx_peers_t **peers;
2697 time_t fail_timeout;
2698 ngx_str_t *value, s;
2699 ngx_url_t u;
2700 ngx_int_t weight, max_fails;
2701 ngx_uint_t i;
2702 ngx_http_upstream_server_t *us;
27202703
27212704 if (uscf->servers == NULL) {
2722 uscf->servers = ngx_array_create(cf->pool, 4, sizeof(ngx_peers_t *));
2705 uscf->servers = ngx_array_create(cf->pool, 4,
2706 sizeof(ngx_http_upstream_server_t));
27232707 if (uscf->servers == NULL) {
27242708 return NGX_CONF_ERROR;
27252709 }
27262710 }
27272711
2728 peers = ngx_array_push(uscf->servers);
2729 if (peers == NULL) {
2712 us = ngx_array_push(uscf->servers);
2713 if (us == NULL) {
27302714 return NGX_CONF_ERROR;
27312715 }
2716
2717 ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
27322718
27332719 value = cf->args->elts;
27342720
27472733 }
27482734
27492735 weight = 1;
2750
2751 if (cf->args->nelts == 3) {
2752
2753 value = &value[2];
2754
2755 if (ngx_strncmp(value->data, "weight=", 7) == 0) {
2756
2757 weight = ngx_atoi(&value->data[7], value->len - 7);
2736 max_fails = 1;
2737 fail_timeout = 10;
2738
2739 for (i = 2; i < cf->args->nelts; i++) {
2740
2741 if (ngx_strncmp(value[i].data, "weight=", 7) == 0) {
2742
2743 if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) {
2744 goto invalid;
2745 }
2746
2747 weight = ngx_atoi(&value[i].data[7], value[i].len - 7);
27582748
27592749 if (weight == NGX_ERROR || weight == 0) {
27602750 goto invalid;
27612751 }
27622752
2763 } else {
2764 goto invalid;
2765 }
2766 }
2767
2768 for (i = 0; i < u.peers->number; i++) {
2769 u.peers->peer[i].weight = weight;
2770 u.peers->peer[i].current_weight = weight;
2771 u.peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
2772 u.peers->peer[i].fail_timeout = NGX_CONF_UNSET;
2773 }
2774
2775 *peers = u.peers;
2753 continue;
2754 }
2755
2756 if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
2757
2758 if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) {
2759 goto invalid;
2760 }
2761
2762 max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10);
2763
2764 if (max_fails == NGX_ERROR) {
2765 goto invalid;
2766 }
2767
2768 continue;
2769 }
2770
2771 if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) {
2772
2773 if (!(uscf->flags & NGX_HTTP_UPSTREAM_FAIL_TIMEOUT)) {
2774 goto invalid;
2775 }
2776
2777 s.len = value[i].len - 13;
2778 s.data = &value[i].data[13];
2779
2780 fail_timeout = ngx_parse_time(&s, 1);
2781
2782 if (fail_timeout < 0) {
2783 goto invalid;
2784 }
2785
2786 continue;
2787 }
2788
2789 if (ngx_strncmp(value[i].data, "down", 4) == 0) {
2790
2791 if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
2792 goto invalid;
2793 }
2794
2795 us->down = 1;
2796
2797 continue;
2798 }
2799
2800 goto invalid;
2801 }
2802
2803 us->addrs = u.addrs;
2804 us->naddrs = u.naddrs;
2805 us->weight = weight;
2806 us->max_fails = max_fails;
2807 us->fail_timeout = fail_timeout;
27762808
27772809 return NGX_CONF_OK;
27782810
27792811 invalid:
27802812
2781 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", value);
2813 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2814 "invalid parameter \"%V\"", &value[i]);
27822815
27832816 return NGX_CONF_ERROR;
27842817 }
27852818
27862819
27872820 ngx_http_upstream_srv_conf_t *
2788 ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u)
2821 ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
27892822 {
27902823 ngx_uint_t i;
2824 ngx_http_upstream_server_t *us;
27912825 ngx_http_upstream_srv_conf_t *uscf, **uscfp;
27922826 ngx_http_upstream_main_conf_t *umcf;
27932827
2794 if (u->upstream) {
2828 if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) {
2829
27952830 if (ngx_parse_url(cf, u) != NGX_OK) {
27962831 if (u->err) {
27972832 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
28002835
28012836 return NULL;
28022837 }
2803
2804 if (u->peers) {
2805 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
2806 if (uscf == NULL) {
2807 return NULL;
2808 }
2809
2810 uscf->peers = u->peers;
2811
2812 return uscf;
2813 }
28142838 }
28152839
28162840 umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
28182842 uscfp = umcf->upstreams.elts;
28192843
28202844 for (i = 0; i < umcf->upstreams.nelts; i++) {
2821 if (uscfp[i]->host.len != u->host.len) {
2845 if (uscfp[i]->host.len != u->host.len
2846 || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
2847 != 0)
2848 {
28222849 continue;
28232850 }
28242851
2825 if (ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
2826 == 0)
2852 if ((flags & NGX_HTTP_UPSTREAM_CREATE)
2853 && (uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE))
28272854 {
2828 return uscfp[i];
2829 }
2855 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2856 "duplicate upstream \"%V\"", &u->host);
2857 return NULL;
2858 }
2859
2860 if (uscfp[i]->port == 0 && u->portn && !u->no_port) {
2861 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
2862 "upstream \"%V\" port %d is ignored",
2863 &u->host, u->portn);
2864 }
2865
2866 return uscfp[i];
28302867 }
28312868
28322869 uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
28342871 return NULL;
28352872 }
28362873
2874 uscf->flags = flags;
28372875 uscf->host = u->host;
28382876 uscf->file_name = cf->conf_file->file.name;
28392877 uscf->line = cf->conf_file->line;
2840 uscf->port = u->default_portn;
2878 uscf->port = u->portn;
2879
2880 if (u->naddrs == 1) {
2881 uscf->servers = ngx_array_create(cf->pool, 1,
2882 sizeof(ngx_http_upstream_server_t));
2883 if (uscf->servers == NULL) {
2884 return NGX_CONF_ERROR;
2885 }
2886
2887 us = ngx_array_push(uscf->servers);
2888 if (us == NULL) {
2889 return NGX_CONF_ERROR;
2890 }
2891
2892 ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
2893
2894 us->addrs = u->addrs;
2895 us->naddrs = u->naddrs;
2896 }
28412897
28422898 uscfp = ngx_array_push(&umcf->upstreams);
28432899 if (uscfp == NULL) {
28802936 ngx_array_t headers_in;
28812937 ngx_hash_key_t *hk;
28822938 ngx_hash_init_t hash;
2939 ngx_http_upstream_init_pt init;
28832940 ngx_http_upstream_header_t *header;
28842941 ngx_http_upstream_srv_conf_t **uscfp;
28852942
28862943 uscfp = umcf->upstreams.elts;
28872944
28882945 for (i = 0; i < umcf->upstreams.nelts; i++) {
2889 if (uscfp[i]->peers) {
2890 continue;
2891 }
2892
2893 uscfp[i]->peers = ngx_inet_resolve_peer(cf, &uscfp[i]->host,
2894 uscfp[i]->port);
2895 if (uscfp[i]->peers == NULL) {
2946
2947 init = uscfp[i]->peer.init_upstream ? uscfp[i]->peer.init_upstream:
2948 ngx_http_upstream_init_round_robin;
2949
2950 if (init(cf, uscfp[i]) != NGX_OK) {
28962951 return NGX_CONF_ERROR;
28972952 }
2898
2899 if (uscfp[i]->peers == NGX_CONF_ERROR) {
2900 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
2901 "upstream host \"%V\" is not found in %s:%ui",
2902 &uscfp[i]->host, uscfp[i]->file_name.data,
2903 uscfp[i]->line);
2904 return NGX_CONF_ERROR;
2905 }
2906 }
2907
2953 }
2954
2955
2956 /* upstream_headers_in_hash */
29082957
29092958 if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
29102959 != NGX_OK)
4343 typedef struct {
4444 ngx_hash_t headers_in_hash;
4545 ngx_array_t upstreams;
46 /* ngx_http_upstream_srv_conf_t */
46 /* ngx_http_upstream_srv_conf_t */
4747 } ngx_http_upstream_main_conf_t;
4848
49
50 typedef struct {
51 ngx_peers_t *peers;
52
53 ngx_array_t *servers;
54
49 typedef struct ngx_http_upstream_srv_conf_s ngx_http_upstream_srv_conf_t;
50
51 typedef ngx_int_t (*ngx_http_upstream_init_pt)(ngx_conf_t *cf,
52 ngx_http_upstream_srv_conf_t *us);
53 typedef ngx_int_t (*ngx_http_upstream_init_peer_pt)(ngx_http_request_t *r,
54 ngx_http_upstream_srv_conf_t *us);
55
56
57 typedef struct {
58 ngx_http_upstream_init_pt init_upstream;
59 ngx_http_upstream_init_peer_pt init;
60 void *data;
61 } ngx_http_upstream_peer_t;
62
63
64 typedef struct {
65 ngx_peer_addr_t *addrs;
66 ngx_uint_t naddrs;
67 ngx_uint_t weight;
68 ngx_uint_t max_fails;
69 time_t fail_timeout;
70
71 unsigned down:1;
72 unsigned backup:1;
73 } ngx_http_upstream_server_t;
74
75
76 #define NGX_HTTP_UPSTREAM_CREATE 0x0001
77 #define NGX_HTTP_UPSTREAM_WEIGHT 0x0002
78 #define NGX_HTTP_UPSTREAM_MAX_FAILS 0x0004
79 #define NGX_HTTP_UPSTREAM_FAIL_TIMEOUT 0x0008
80 #define NGX_HTTP_UPSTREAM_DOWN 0x0010
81 #define NGX_HTTP_UPSTREAM_BACKUP 0x0020
82
83
84 struct ngx_http_upstream_srv_conf_s {
85 ngx_http_upstream_peer_t peer;
86 void **srv_conf;
87
88 ngx_array_t *servers; /* ngx_http_upstream_server_t */
89
90 ngx_uint_t flags;
5591 ngx_str_t host;
5692 ngx_str_t file_name;
5793 ngx_uint_t line;
5894 in_port_t port;
59 } ngx_http_upstream_srv_conf_t;
60
61
62 typedef struct {
95 };
96
97
98 typedef struct {
99 ngx_http_upstream_srv_conf_t *upstream;
100
63101 ngx_msec_t connect_timeout;
64102 ngx_msec_t send_timeout;
65103 ngx_msec_t read_timeout;
77115 size_t temp_file_write_size_conf;
78116
79117 ngx_uint_t next_upstream;
80 ngx_uint_t max_fails;
81
82 time_t fail_timeout;
83118
84119 ngx_bufs_t bufs;
85120
212247
213248 void ngx_http_upstream_init(ngx_http_request_t *r);
214249 ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
215 ngx_url_t *u);
250 ngx_url_t *u, ngx_uint_t flags);
251
252
253 #define ngx_http_conf_upstream_srv_conf(uscf, module) \
254 uscf->srv_conf[module.ctx_index]
216255
217256
218257 extern ngx_module_t ngx_http_upstream_module;
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #include <ngx_config.h>
7 #include <ngx_core.h>
8 #include <ngx_http.h>
9
10
11 ngx_int_t
12 ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
13 ngx_http_upstream_srv_conf_t *us)
14 {
15 ngx_url_t u;
16 ngx_uint_t i, j, n;
17 ngx_http_upstream_server_t *server;
18 ngx_http_upstream_rr_peers_t *peers;
19
20 us->peer.init = ngx_http_upstream_init_round_robin_peer;
21
22 if (us->servers) {
23 n = 0;
24 server = us->servers->elts;
25
26 for (i = 0; i < us->servers->nelts; i++) {
27 n += server[i].naddrs;
28 }
29
30 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
31 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
32 if (peers == NULL) {
33 return NGX_ERROR;
34 }
35
36 peers->number = n;
37 peers->name = &us->host;
38
39 n = 0;
40
41 for (i = 0; i < us->servers->nelts; i++) {
42 for (j = 0; j < server[i].naddrs; j++) {
43 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;
44 peers->peer[n].socklen = server[i].addrs[j].socklen;
45 peers->peer[n].name = server[i].addrs[j].name;
46 peers->peer[n].weight = server[i].weight;
47 peers->peer[n].current_weight = server[i].weight;
48 peers->peer[n].max_fails = server[i].max_fails;
49 peers->peer[n].fail_timeout = server[i].fail_timeout;
50 peers->peer[n].down = server[i].down;
51 n++;
52 }
53 }
54
55 us->peer.data = peers;
56
57 return NGX_OK;
58 }
59
60
61 /* an upstream implicitly defined by proxy_pass, etc. */
62
63 ngx_memzero(&u, sizeof(ngx_url_t));
64
65 u.host = us->host;
66 u.portn = us->port;
67
68 if (ngx_inet_resolve_host(cf, &u) != NGX_OK) {
69 if (u.err) {
70 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
71 "%s in upstream host \"%V\" is not found in %s:%ui",
72 u.err, &us->host, us->file_name.data, us->line);
73 }
74
75 return NGX_ERROR;
76 }
77
78 n = u.naddrs;
79
80 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
81 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
82 if (peers == NULL) {
83 return NGX_ERROR;
84 }
85
86 peers->number = n;
87 peers->name = &us->host;
88
89 n = 0;
90
91 for (i = 0; i < u.naddrs; i++) {
92 peers->peer[n].sockaddr = u.addrs[i].sockaddr;
93 peers->peer[n].socklen = u.addrs[i].socklen;
94 peers->peer[n].name = u.addrs[i].name;
95 peers->peer[n].weight = 1;
96 peers->peer[n].current_weight = 1;
97 peers->peer[n].max_fails = 1;
98 peers->peer[n].fail_timeout = 10;
99 n++;
100 }
101
102 us->peer.data = peers;
103
104 return NGX_OK;
105 }
106
107
108 ngx_int_t
109 ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
110 ngx_http_upstream_srv_conf_t *us)
111 {
112 ngx_uint_t n;
113 ngx_http_upstream_rr_peer_data_t *rrp;
114
115 rrp = r->upstream->peer.data;
116
117 if (rrp == NULL) {
118 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t));
119 if (rrp == NULL) {
120 return NGX_ERROR;
121 }
122
123 r->upstream->peer.data = rrp;
124 }
125
126 rrp->peers = us->peer.data;
127 rrp->current = 0;
128
129 if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
130 rrp->tried = &rrp->data;
131 rrp->data = 0;
132
133 } else {
134 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
135 / (8 * sizeof(uintptr_t));
136
137 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
138 if (rrp->tried == NULL) {
139 return NGX_ERROR;
140 }
141 }
142
143 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
144 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
145 r->upstream->peer.tries = rrp->peers->number;
146 #if (NGX_HTTP_SSL)
147 r->upstream->peer.save_session = ngx_http_upstream_save_round_robin_peer;
148 #endif
149
150 return NGX_OK;
151 }
152
153
154 ngx_int_t
155 ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
156 {
157 ngx_http_upstream_rr_peer_data_t *rrp = data;
158
159 time_t now;
160 uintptr_t m;
161 ngx_uint_t i, n;
162 ngx_connection_t *c;
163 ngx_http_upstream_rr_peer_t *peer;
164
165 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
166 "get rr peer, try: %ui", pc->tries);
167
168 now = ngx_time();
169
170 /* ngx_lock_mutex(rrp->peers->mutex); */
171
172 if (rrp->peers->last_cached) {
173
174 /* cached connection */
175
176 c = rrp->peers->cached[rrp->peers->last_cached];
177 rrp->peers->last_cached--;
178
179 /* ngx_unlock_mutex(ppr->peers->mutex); */
180
181 #if (NGX_THREADS)
182 c->read->lock = c->read->own_lock;
183 c->write->lock = c->write->own_lock;
184 #endif
185
186 pc->connection = c;
187 pc->cached = 1;
188
189 return NGX_OK;
190 }
191
192 pc->cached = 0;
193 pc->connection = NULL;
194
195 if (rrp->peers->number == 1) {
196 peer = &rrp->peers->peer[0];
197
198 } else {
199
200 /* there are several peers */
201
202 if (pc->tries == rrp->peers->number) {
203
204 /* it's a first try - get a current peer */
205
206 for ( ;; ) {
207 rrp->current = rrp->peers->current;
208
209 n = rrp->current / (8 * sizeof(uintptr_t));
210 m = 1 << rrp->current % (8 * sizeof(uintptr_t));
211
212 if (!(rrp->tried[n] & m)) {
213 peer = &rrp->peers->peer[rrp->current];
214
215 if (!peer->down) {
216
217 if (peer->max_fails == 0
218 || peer->fails < peer->max_fails)
219 {
220 break;
221 }
222
223 if (now - peer->accessed > peer->fail_timeout) {
224 peer->fails = 0;
225 break;
226 }
227
228 } else {
229 rrp->tried[n] |= m;
230 }
231
232 pc->tries--;
233 }
234
235 rrp->peers->current++;
236
237 if (rrp->peers->current >= rrp->peers->number) {
238 rrp->peers->current = 0;
239 }
240
241 if (pc->tries) {
242 continue;
243 }
244
245 goto failed;
246 }
247
248 peer->current_weight--;
249
250 if (peer->current_weight == 0) {
251 peer->current_weight = peer->weight;
252
253 rrp->peers->current++;
254
255 if (rrp->peers->current >= rrp->peers->number) {
256 rrp->peers->current = 0;
257 }
258 }
259
260 } else {
261 for ( ;; ) {
262 n = rrp->current / (8 * sizeof(uintptr_t));
263 m = 1 << rrp->current % (8 * sizeof(uintptr_t));
264
265 if (!(rrp->tried[n] & m)) {
266
267 peer = &rrp->peers->peer[rrp->current];
268
269 if (!peer->down) {
270
271 if (peer->max_fails == 0
272 || peer->fails < peer->max_fails)
273 {
274 break;
275 }
276
277 if (now - peer->accessed > peer->fail_timeout) {
278 peer->fails = 0;
279 break;
280 }
281
282 } else {
283 rrp->tried[n] |= m;
284 }
285
286 pc->tries--;
287 }
288
289 rrp->current++;
290
291 if (rrp->current >= rrp->peers->number) {
292 rrp->current = 0;
293 }
294
295 if (pc->tries) {
296 continue;
297 }
298
299 goto failed;
300 }
301
302 peer->current_weight--;
303
304 if (peer->current_weight == 0) {
305 peer->current_weight = peer->weight;
306
307 if (rrp->current == rrp->peers->current) {
308 rrp->peers->current++;
309
310 if (rrp->peers->current >= rrp->peers->number) {
311 rrp->peers->current = 0;
312 }
313 }
314 }
315 }
316
317 rrp->tried[n] |= m;
318 }
319
320 pc->sockaddr = peer->sockaddr;
321 pc->socklen = peer->socklen;
322 pc->name = &peer->name;
323 #if (NGX_SSL)
324 pc->ssl_session = peer->ssl_session;
325 #endif
326
327 /* ngx_unlock_mutex(rrp->peers->mutex); */
328
329 return NGX_OK;
330
331 failed:
332
333 /* all peers failed, mark them as live for quick recovery */
334
335 for (i = 0; i < rrp->peers->number; i++) {
336 rrp->peers->peer[i].fails = 0;
337 }
338
339 /* ngx_unlock_mutex(rrp->peers->mutex); */
340
341 pc->name = rrp->peers->name;
342
343 return NGX_BUSY;
344 }
345
346
347 void
348 ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
349 ngx_uint_t state)
350 {
351 ngx_http_upstream_rr_peer_data_t *rrp = data;
352
353 time_t now;
354 ngx_http_upstream_rr_peer_t *peer;
355
356 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
357 "free rr peer %ui %ui", pc->tries, state);
358
359 if (state == 0 && pc->tries == 0) {
360 return;
361 }
362
363 /* TODO: NGX_PEER_KEEPALIVE */
364
365 if (rrp->peers->number == 1) {
366 pc->tries = 0;
367 return;
368 }
369
370 if (state & NGX_PEER_FAILED) {
371 now = ngx_time();
372
373 peer = &rrp->peers->peer[rrp->current];
374
375 /* ngx_lock_mutex(rrp->peers->mutex); */
376
377 peer->fails++;
378 peer->accessed = now;
379
380 if (peer->current_weight > 1) {
381 peer->current_weight /= 2;
382 }
383
384 /* ngx_unlock_mutex(rrp->peers->mutex); */
385 }
386
387 rrp->current++;
388
389 if (rrp->current >= rrp->peers->number) {
390 rrp->current = 0;
391 }
392
393 if (pc->tries) {
394 pc->tries--;
395 }
396
397 /* ngx_unlock_mutex(rrp->peers->mutex); */
398 }
399
400
401 #if (NGX_HTTP_SSL)
402
403 void
404 ngx_http_upstream_save_round_robin_peer(ngx_peer_connection_t *pc, void *data)
405 {
406 ngx_http_upstream_rr_peer_data_t *rrp = data;
407
408 ngx_ssl_session_t *ssl_session;
409 ngx_http_upstream_rr_peer_t *peer;
410
411 ssl_session = ngx_ssl_get_session(pc->connection);
412
413 if (ssl_session == NULL) {
414 return;
415 }
416
417 peer = &rrp->peers->peer[rrp->current];
418
419 /* ngx_lock_mutex(rrp->peers->mutex); */
420 peer->ssl_session = ssl_session;
421 /* ngx_unlock_mutex(rrp->peers->mutex); */
422
423 if (pc->ssl_session) {
424 /* TODO: may block */
425 ngx_ssl_free_session(pc->ssl_session);
426 }
427 }
428
429 #endif
0
1 /*
2 * Copyright (C) Igor Sysoev
3 */
4
5
6 #ifndef _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
7 #define _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
8
9
10 #include <ngx_config.h>
11 #include <ngx_core.h>
12 #include <ngx_http.h>
13
14
15 typedef struct {
16 struct sockaddr *sockaddr;
17 socklen_t socklen;
18 ngx_str_t name;
19
20 ngx_uint_t current_weight;
21 ngx_uint_t weight;
22
23 ngx_uint_t fails;
24 time_t accessed;
25
26 ngx_uint_t max_fails;
27 time_t fail_timeout;
28
29 ngx_uint_t down; /* unsigned down:1; */
30
31 #if (NGX_SSL)
32 ngx_ssl_session_t *ssl_session;
33 #endif
34 } ngx_http_upstream_rr_peer_t;
35
36
37 typedef struct {
38 ngx_uint_t current;
39
40 ngx_uint_t number;
41 ngx_uint_t last_cached;
42
43 /* ngx_mutex_t *mutex; */
44 ngx_connection_t **cached;
45
46 ngx_str_t *name;
47
48 ngx_http_upstream_rr_peer_t peer[1];
49 } ngx_http_upstream_rr_peers_t;
50
51
52 typedef struct {
53 ngx_http_upstream_rr_peers_t *peers;
54 ngx_uint_t current;
55 uintptr_t *tried;
56 uintptr_t data;
57 } ngx_http_upstream_rr_peer_data_t;
58
59
60 ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
61 ngx_http_upstream_srv_conf_t *us);
62 ngx_int_t ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
63 ngx_http_upstream_srv_conf_t *us);
64 ngx_int_t ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc,
65 void *data);
66 void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
67 void *data, ngx_uint_t state);
68
69 #if (NGX_HTTP_SSL)
70 void ngx_http_upstream_save_round_robin_peer(ngx_peer_connection_t *pc,
71 void *data);
72 #endif
73
74
75
76 #endif /* _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */
265265
266266
267267 /* STUB */
268 void ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peers_t *peers);
268 void ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peer_addr_t *peer);
269269 void ngx_imap_auth_http_init(ngx_imap_session_t *s);
270270 /**/
271271
1111
1212
1313 typedef struct {
14 ngx_peers_t *peers;
14 ngx_peer_addr_t *peer;
1515
1616 ngx_msec_t timeout;
1717
174174
175175 ngx_imap_set_ctx(s, ctx, ngx_imap_auth_http_module);
176176
177 ctx->peer.peers = ahcf->peers;
177 ctx->peer.sockaddr = ahcf->peer->sockaddr;
178 ctx->peer.socklen = ahcf->peer->socklen;
179 ctx->peer.name = &ahcf->peer->name;
180 ctx->peer.get = ngx_event_get_peer;
178181 ctx->peer.log = s->connection->log;
179182 ctx->peer.log_error = NGX_ERROR_ERR;
180183
228231
229232 if (wev->timedout) {
230233 ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
231 "auth http server %V timed out",
232 &ctx->peer.peers->peer[0].name);
234 "auth http server %V timed out", ctx->peer.name);
233235 ngx_close_connection(ctx->peer.connection);
234236 ngx_destroy_pool(ctx->pool);
235237 ngx_imap_session_internal_server_error(s);
292294
293295 if (rev->timedout) {
294296 ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
295 "auth http server %V timed out",
296 &ctx->peer.peers->peer[0].name);
297 "auth http server %V timed out", ctx->peer.name);
297298 ngx_close_connection(ctx->peer.connection);
298299 ngx_destroy_pool(ctx->pool);
299300 ngx_imap_session_internal_server_error(s);
412413
413414 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
414415 "auth http server &V sent invalid response",
415 &ctx->peer.peers->peer[0].name);
416 ctx->peer.name);
416417 ngx_close_connection(ctx->peer.connection);
417418 ngx_destroy_pool(ctx->pool);
418419 ngx_imap_session_internal_server_error(s);
446447 time_t timer;
447448 size_t len, size;
448449 ngx_int_t rc, port, n;
449 ngx_peers_t *peers;
450 ngx_peer_addr_t *peer;
450451 struct sockaddr_in *sin;
451452
452453 ngx_log_debug0(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
661662 if (ctx->addr.len == 0 || ctx->port.len == 0) {
662663 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
663664 "auth http server %V did not send server or port",
664 &ctx->peer.peers->peer[0].name);
665 ctx->peer.name);
665666 ngx_destroy_pool(ctx->pool);
666667 ngx_imap_session_internal_server_error(s);
667668 return;
670671 if (s->passwd.data == NULL) {
671672 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
672673 "auth http server %V did not send password",
673 &ctx->peer.peers->peer[0].name);
674 ctx->peer.name);
674675 ngx_destroy_pool(ctx->pool);
675676 ngx_imap_session_internal_server_error(s);
676677 return;
677678 }
678679
679 peers = ngx_pcalloc(s->connection->pool, sizeof(ngx_peers_t));
680 if (peers == NULL) {
680 peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_peer_addr_t));
681 if (peer == NULL) {
681682 ngx_destroy_pool(ctx->pool);
682683 ngx_imap_session_internal_server_error(s);
683684 return;
697698 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
698699 "auth http server %V sent invalid server "
699700 "port:\"%V\"",
700 &ctx->peer.peers->peer[0].name, &ctx->port);
701 ctx->peer.name, &ctx->port);
701702 ngx_destroy_pool(ctx->pool);
702703 ngx_imap_session_internal_server_error(s);
703704 return;
711712 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
712713 "auth http server %V sent invalid server "
713714 "address:\"%V\"",
714 &ctx->peer.peers->peer[0].name, &ctx->addr);
715 ctx->peer.name, &ctx->addr);
715716 ngx_destroy_pool(ctx->pool);
716717 ngx_imap_session_internal_server_error(s);
717718 return;
718719 }
719720
720 peers->number = 1;
721
722 peers->peer[0].sockaddr = (struct sockaddr *) sin;
723 peers->peer[0].socklen = sizeof(struct sockaddr_in);
721 peer->sockaddr = (struct sockaddr *) sin;
722 peer->socklen = sizeof(struct sockaddr_in);
724723
725724 len = ctx->addr.len + 1 + ctx->port.len;
726725
727 peers->peer[0].name.len = len;
728
729 peers->peer[0].name.data = ngx_palloc(s->connection->pool, len);
730 if (peers->peer[0].name.data == NULL) {
726 peer->name.len = len;
727
728 peer->name.data = ngx_palloc(s->connection->pool, len);
729 if (peer->name.data == NULL) {
731730 ngx_destroy_pool(ctx->pool);
732731 ngx_imap_session_internal_server_error(s);
733732 return;
735734
736735 len = ctx->addr.len;
737736
738 ngx_memcpy(peers->peer[0].name.data, ctx->addr.data, len);
739
740 peers->peer[0].name.data[len++] = ':';
741
742 ngx_memcpy(peers->peer[0].name.data + len,
743 ctx->port.data, ctx->port.len);
744
745 peers->peer[0].uri_separator = "";
737 ngx_memcpy(peer->name.data, ctx->addr.data, len);
738
739 peer->name.data[len++] = ':';
740
741 ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);
746742
747743 ngx_destroy_pool(ctx->pool);
748 ngx_imap_proxy_init(s, peers);
744 ngx_imap_proxy_init(s, peer);
749745
750746 return;
751747 }
758754
759755 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
760756 "auth http server %V sent invalid header in response",
761 &ctx->peer.peers->peer[0].name);
757 ctx->peer.name);
762758 ngx_close_connection(ctx->peer.connection);
763759 ngx_destroy_pool(ctx->pool);
764760 ngx_imap_session_internal_server_error(s);
12411237 ngx_uint_t i;
12421238 ngx_table_elt_t *header;
12431239
1244 if (conf->peers == NULL) {
1245 conf->peers = prev->peers;
1240 if (conf->peer == NULL) {
1241 conf->peer = prev->peer;
12461242 conf->host_header = prev->host_header;
12471243 conf->uri = prev->uri;
12481244 }
12961292 u.url = value[1];
12971293 u.default_portn = 80;
12981294 u.uri_part = 1;
1295 u.one_addr = 1;
12991296
13001297 if (ngx_parse_url(cf, &u) != NGX_OK) {
13011298 if (u.err) {
13041301 }
13051302 }
13061303
1307 ahcf->peers = u.peers;
1308 ahcf->peers->number = 1;
1304 ahcf->peer = u.addrs;
13091305
13101306 ahcf->host_header = u.host_header;
13111307 ahcf->uri = u.uri;
12781278 return p;
12791279 }
12801280
1281 p = ngx_snprintf(buf, len, ", upstream: %V",
1282 &s->proxy->upstream.peers->peer[0].name);
1281 p = ngx_snprintf(buf, len, ", upstream: %V", s->proxy->upstream.name);
12831282
12841283 return p;
12851284 }
9393
9494
9595 void
96 ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peers_t *peers)
96 ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peer_addr_t *peer)
9797 {
9898 int keepalive;
9999 ngx_int_t rc;
124124
125125 s->proxy = p;
126126
127 p->upstream.peers = peers;
127 p->upstream.sockaddr = peer->sockaddr;
128 p->upstream.socklen = peer->socklen;
129 p->upstream.name = &peer->name;
130 p->upstream.get = ngx_event_get_peer;
128131 p->upstream.log = s->connection->log;
129132 p->upstream.log_error = NGX_ERROR_ERR;
130133
99
1010
1111 typedef struct {
12 ngx_peers_t *peers;
12 ngx_peer_addr_t *peers;
13 ngx_uint_t npeers;
1314 } ngx_http_mysql_test_conf_t;
1415
1516
9394 m->passwd = &ngx_mysql_passwd;
9495 m->database = &ngx_mysql_database;
9596
97 /* STUB */
98 m->peer.sockaddr = mtcf->peers[0].sockaddr;
99 m->peer.socklen = mtcf->peers[0].socklen;
100 m->peer.name = &mtcf->peers[0].name;
101 m->peer.tries = mtcf->npeers;
102 m->peer.get = ngx_event_get_peer;
103 /**/
96104 m->peer.log = r->connection->log;
97105 m->peer.log_error = NGX_ERROR_ERR;
98 m->peer.peers = mtcf->peers;
99 m->peer.tries = mtcf->peers->number;
100106
101107 rc = ngx_mysql_connect(m);
102108
189195 return NGX_CONF_ERROR;
190196 }
191197
192 mtcf->peers = u.peers;
198 mtcf->peers = u.addrs;
199 mtcf->npeers = u.naddrs;
193200
194201 return NGX_CONF_OK;
195202 }
149149
150150 if (rev->timedout) {
151151 ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
152 "mysql server %V timed out",
153 &m->peer.peers->peer[0].name);
152 "mysql server %V timed out", m->peer.name);
154153
155154 ngx_mysql_close(m, NGX_ERROR);
156155 return;
182181 if (ngx_m24toh(gr1->pktlen) > n - 4) {
183182 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
184183 "mysql server %V sent incomplete greeting packet",
185 &m->peer.peers->peer[0].name);
184 m->peer.name);
186185
187186 ngx_mysql_close(m, NGX_ERROR);
188187 return;
191190 if (gr1->protocol < 10) {
192191 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
193192 "mysql server %V sent unsupported protocol version %ud",
194 &m->peer.peers->peer[0].name, gr1->protocol);
193 m->peer.name, gr1->protocol);
195194
196195 ngx_mysql_close(m, NGX_ERROR);
197196 return;
272271 if (n < (ssize_t) len) {
273272 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
274273 "the incomplete packet was sent to mysql server %V",
275 &m->peer.peers->peer[0].name);
274 m->peer.name);
276275
277276 ngx_mysql_close(m, NGX_ERROR);
278277 return;
328327 if (len > n - 4) {
329328 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
330329 "mysql server %V sent incomplete response packet",
331 &m->peer.peers->peer[0].name);
330 m->peer.name);
332331
333332 ngx_mysql_close(m, NGX_ERROR);
334333 return;
352351
353352 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
354353 "mysql server %V sent error (%ud): \"%V\"",
355 &m->peer.peers->peer[0].name, ngx_m16toh(epkt->code), &msg);
354 m->peer.name, ngx_m16toh(epkt->code), &msg);
356355
357356 ngx_mysql_close(m, NGX_ERROR);
358357 }
375374 if (n < (ssize_t) m->query.len) {
376375 ngx_log_error(NGX_LOG_ERR, m->peer.log, 0,
377376 "the incomplete packet was sent to mysql server %V",
378 &m->peer.peers->peer[0].name);
377 m->peer.name);
379378
380379 ngx_mysql_close(m, NGX_ERROR);
381380 return NGX_OK;
426425 if (len > n - 4) {
427426 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
428427 "mysql server %V sent incomplete response packet",
429 &m->peer.peers->peer[0].name);
428 m->peer.name);
430429
431430 ngx_mysql_close(m, NGX_ERROR);
432431 return;
450449
451450 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
452451 "mysql server %V sent error (%ud): \"%V\"",
453 &m->peer.peers->peer[0].name, ngx_m16toh(epkt->code), &msg);
452 m->peer.name, ngx_m16toh(epkt->code), &msg);
454453
455454 ngx_mysql_close(m, NGX_ERROR);
456455 }