annotate src/http/modules/ngx_http_upstream_ip_hash_module.c @ 7732:59e1c73fe02b

SSL: ssl_reject_handshake directive (ticket #195). In some cases it might be needed to reject SSL handshake based on SNI server name provided, for example, to make sure an invalid certificate is not returned to clients trying to contact a name-based virtual server without SSL configured. Previously, a "ssl_ciphers aNULL;" was used for this. This workaround, however, is not compatible with TLSv1.3, in particular, when using BoringSSL, where it is not possible to configure TLSv1.3 ciphers at all. With this change, the ssl_reject_handshake directive is introduced, which instructs nginx to reject SSL handshakes with an "unrecognized_name" alert in a particular server block. For example, to reject handshake with names other than example.com, one can use the following configuration: server { listen 443 ssl; ssl_reject_handshake on; } server { listen 443 ssl; server_name example.com; ssl_certificate example.com.crt; ssl_certificate_key example.com.key; } The following configuration can be used to reject all SSL handshakes without SNI server name provided: server { listen 443 ssl; ssl_reject_handshake on; } server { listen 443 ssl; server_name ~^; ssl_certificate example.crt; ssl_certificate_key example.key; } Additionally, the ssl_reject_handshake directive makes configuring certificates for the default server block optional. If no certificates are configured in the default server for a given listening socket, certificates must be defined in all non-default server blocks with the listening socket in question.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 22 Oct 2020 18:02:28 +0300
parents ed599ea6c1f1
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
2 /*
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
4412
d620f497c50f Copyright updated.
Maxim Konovalov <maxim@nginx.com>
parents: 4207
diff changeset
4 * Copyright (C) Nginx, Inc.
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
5 */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #include <ngx_config.h>
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #include <ngx_core.h>
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10 #include <ngx_http.h>
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
12
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 typedef struct {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
14 /* the round robin data must be first */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
15 ngx_http_upstream_rr_peer_data_t rrp;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
16
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
17 ngx_uint_t hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18
4695
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
19 u_char addrlen;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
20 u_char *addr;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
21
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22 u_char tries;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
23
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24 ngx_event_get_peer_pt get_rr_peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
25 } ngx_http_upstream_ip_hash_peer_data_t;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
26
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
27
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
28 static ngx_int_t ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
29 ngx_http_upstream_srv_conf_t *us);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
30 static ngx_int_t ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31 void *data);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32 static char *ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33 void *conf);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
34
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
35
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36 static ngx_command_t ngx_http_upstream_ip_hash_commands[] = {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
37
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38 { ngx_string("ip_hash"),
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39 NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
40 ngx_http_upstream_ip_hash,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
41 0,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
42 0,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
43 NULL },
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
44
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45 ngx_null_command
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
46 };
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
47
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
48
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
49 static ngx_http_module_t ngx_http_upstream_ip_hash_module_ctx = {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
50 NULL, /* preconfiguration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
51 NULL, /* postconfiguration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
53 NULL, /* create main configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54 NULL, /* init main configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
55
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
56 NULL, /* create server configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
57 NULL, /* merge server configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59 NULL, /* create location configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60 NULL /* merge location configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
61 };
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
62
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
63
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 ngx_module_t ngx_http_upstream_ip_hash_module = {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65 NGX_MODULE_V1,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66 &ngx_http_upstream_ip_hash_module_ctx, /* module context */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67 ngx_http_upstream_ip_hash_commands, /* module directives */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 NGX_HTTP_MODULE, /* module type */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 NULL, /* init master */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 NULL, /* init module */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
71 NULL, /* init process */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
72 NULL, /* init thread */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
73 NULL, /* exit thread */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 NULL, /* exit process */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
75 NULL, /* exit master */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76 NGX_MODULE_V1_PADDING
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77 };
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
78
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
79
4695
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
80 static u_char ngx_http_upstream_ip_hash_pseudo_addr[3];
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
81
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
82
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
83 static ngx_int_t
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84 ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
85 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
86 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87 return NGX_ERROR;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
89
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
90 us->peer.init = ngx_http_upstream_init_ip_hash_peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
91
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
92 return NGX_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
95
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
96 static ngx_int_t
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
97 ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
98 ngx_http_upstream_srv_conf_t *us)
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
99 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
100 struct sockaddr_in *sin;
4695
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
101 #if (NGX_HAVE_INET6)
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
102 struct sockaddr_in6 *sin6;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
103 #endif
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
104 ngx_http_upstream_ip_hash_peer_data_t *iphp;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
105
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
106 iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t));
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
107 if (iphp == NULL) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
108 return NGX_ERROR;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
109 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
110
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111 r->upstream->peer.data = &iphp->rrp;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
112
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
113 if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
114 return NGX_ERROR;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
115 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
116
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
117 r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
118
4695
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
119 switch (r->connection->sockaddr->sa_family) {
2512
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
120
4695
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
121 case AF_INET:
2512
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
122 sin = (struct sockaddr_in *) r->connection->sockaddr;
4695
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
123 iphp->addr = (u_char *) &sin->sin_addr.s_addr;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
124 iphp->addrlen = 3;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
125 break;
2512
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
126
4695
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
127 #if (NGX_HAVE_INET6)
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
128 case AF_INET6:
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
129 sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
130 iphp->addr = (u_char *) &sin6->sin6_addr.s6_addr;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
131 iphp->addrlen = 16;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
132 break;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
133 #endif
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
134
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
135 default:
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
136 iphp->addr = ngx_http_upstream_ip_hash_pseudo_addr;
441b2941a506 Added IPv6 support to ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 4655
diff changeset
137 iphp->addrlen = 3;
2512
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
138 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
139
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
140 iphp->hash = 89;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
141 iphp->tries = 0;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
142 iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
143
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
144 return NGX_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
145 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
146
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
147
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
148 static ngx_int_t
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
149 ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
150 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
151 ngx_http_upstream_ip_hash_peer_data_t *iphp = data;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
152
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
153 time_t now;
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
154 ngx_int_t w;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
155 uintptr_t m;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
156 ngx_uint_t i, n, p, hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
157 ngx_http_upstream_rr_peer_t *peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
158
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
159 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
160 "get ip hash peer, try: %ui", pc->tries);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
161
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
162 /* TODO: cached */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
163
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6705
diff changeset
164 ngx_http_upstream_rr_peers_rlock(iphp->rrp.peers);
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
165
1418
acb1f441e7b2 update ip_hash to "backup" option
Igor Sysoev <igor@sysoev.ru>
parents: 1417
diff changeset
166 if (iphp->tries > 20 || iphp->rrp.peers->single) {
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
167 ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
168 return iphp->get_rr_peer(pc, &iphp->rrp);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
169 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
170
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
171 now = ngx_time();
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
172
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
173 pc->cached = 0;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
174 pc->connection = NULL;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
175
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
176 hash = iphp->hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
177
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
178 for ( ;; ) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
179
5359
2fda9065d0f4 Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 5173
diff changeset
180 for (i = 0; i < (ngx_uint_t) iphp->addrlen; i++) {
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
181 hash = (hash * 113 + iphp->addr[i]) % 6271;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
182 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
183
6121
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6108
diff changeset
184 w = hash % iphp->rrp.peers->total_weight;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6108
diff changeset
185 peer = iphp->rrp.peers->peer;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6108
diff changeset
186 p = 0;
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
187
6121
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6108
diff changeset
188 while (w >= peer->weight) {
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6108
diff changeset
189 w -= peer->weight;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6108
diff changeset
190 peer = peer->next;
b6047abf5f30 Upstream: simplified ip_hash and hash peer selection code.
Ruslan Ermilov <ru@nginx.com>
parents: 6108
diff changeset
191 p++;
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
192 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
193
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
194 n = p / (8 * sizeof(uintptr_t));
1416
ad2311c943a3 fix ip_hash on 64-bit platform
Igor Sysoev <igor@sysoev.ru>
parents: 1284
diff changeset
195 m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
196
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
197 if (iphp->rrp.tried[n] & m) {
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
198 goto next;
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
199 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
200
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
201 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
6480
f01ab2dbcfdc Fixed logging.
Sergey Kandaurov <pluknet@nginx.com>
parents: 6121
diff changeset
202 "get ip hash peer, hash: %ui %04XL", p, (uint64_t) m);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
203
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6705
diff changeset
204 ngx_http_upstream_rr_peer_lock(iphp->rrp.peers, peer);
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6705
diff changeset
205
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
206 if (peer->down) {
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6705
diff changeset
207 ngx_http_upstream_rr_peer_unlock(iphp->rrp.peers, peer);
6108
55dc5f7eb921 Upstream: get rid of questionable micro-optimization in ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
208 goto next;
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
209 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
210
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
211 if (peer->max_fails
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
212 && peer->fails >= peer->max_fails
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
213 && now - peer->checked <= peer->fail_timeout)
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
214 {
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6705
diff changeset
215 ngx_http_upstream_rr_peer_unlock(iphp->rrp.peers, peer);
6108
55dc5f7eb921 Upstream: get rid of questionable micro-optimization in ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
216 goto next;
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
217 }
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
218
6705
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6480
diff changeset
219 if (peer->max_conns && peer->conns >= peer->max_conns) {
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6705
diff changeset
220 ngx_http_upstream_rr_peer_unlock(iphp->rrp.peers, peer);
6705
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6480
diff changeset
221 goto next;
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6480
diff changeset
222 }
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6480
diff changeset
223
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
224 break;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
225
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
226 next:
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
227
5706
a2bf26774cd3 Upstream: fix tries check in ip_hash.
Roman Arutyunyan <arut@nginx.com>
parents: 5486
diff changeset
228 if (++iphp->tries > 20) {
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
229 ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
230 return iphp->get_rr_peer(pc, &iphp->rrp);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
231 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
232 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
233
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
234 iphp->rrp.current = peer;
1417
b23a80f9a7b8 set current peer to use it in ngx_http_upstream_free_round_robin_peer()
Igor Sysoev <igor@sysoev.ru>
parents: 1416
diff changeset
235
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
236 pc->sockaddr = peer->sockaddr;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
237 pc->socklen = peer->socklen;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
238 pc->name = &peer->name;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
239
6099
6ff0ebd6fbf4 Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents: 5706
diff changeset
240 peer->conns++;
6ff0ebd6fbf4 Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents: 5706
diff changeset
241
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
242 if (now - peer->checked > peer->fail_timeout) {
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
243 peer->checked = now;
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
244 }
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
245
7300
ed599ea6c1f1 Upstream: improved peer selection concurrency for hash and ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6705
diff changeset
246 ngx_http_upstream_rr_peer_unlock(iphp->rrp.peers, peer);
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
247 ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
248
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
249 iphp->rrp.tried[n] |= m;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
250 iphp->hash = hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
251
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
252 return NGX_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
253 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
254
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
255
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
256 static char *
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
257 ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
258 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
259 ngx_http_upstream_srv_conf_t *uscf;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
260
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
261 uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
262
5173
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
263 if (uscf->peer.init_upstream) {
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
264 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
265 "load balancing method redefined");
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
266 }
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
267
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
268 uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
269
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
270 uscf->flags = NGX_HTTP_UPSTREAM_CREATE
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
271 |NGX_HTTP_UPSTREAM_WEIGHT
6705
29bf0dbc0a77 Upstream: max_conns.
Ruslan Ermilov <ru@nginx.com>
parents: 6480
diff changeset
272 |NGX_HTTP_UPSTREAM_MAX_CONNS
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
273 |NGX_HTTP_UPSTREAM_MAX_FAILS
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
274 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
275 |NGX_HTTP_UPSTREAM_DOWN;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
276
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
277 return NGX_CONF_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
278 }