annotate src/http/modules/ngx_http_upstream_ip_hash_module.c @ 6133:af7eba90645d

Win32: shared memory base addresses and remapping. Two mechanisms are implemented to make it possible to store pointers in shared memory on Windows, in particular on Windows Vista and later versions with ASLR: - The ngx_shm_remap() function added to allow remapping of a shared memory zone to the address originally used for it in the master process. While important, it doesn't solve the problem by itself as in many cases it's not possible to use the address because of conflicts with other allocations. - We now create mappings at the same address in all processes by starting mappings at predefined addresses normally unused by newborn processes. These two mechanisms combined allow to use shared memory on Windows almost without problems, including reloads. Based on the patch by Sergey Brester: http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 27 Apr 2015 18:25:42 +0300
parents b6047abf5f30
children f01ab2dbcfdc
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
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
164 ngx_http_upstream_rr_peers_wlock(iphp->rrp.peers);
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,
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
202 "get ip hash peer, hash: %ui %04XA", p, m);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
203
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
204 if (peer->down) {
6108
55dc5f7eb921 Upstream: get rid of questionable micro-optimization in ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
205 goto next;
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
206 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
207
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
208 if (peer->max_fails
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
209 && 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
210 && 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
211 {
6108
55dc5f7eb921 Upstream: get rid of questionable micro-optimization in ip_hash.
Ruslan Ermilov <ru@nginx.com>
parents: 6102
diff changeset
212 goto next;
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
213 }
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
214
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
215 break;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
216
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
217 next:
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
218
5706
a2bf26774cd3 Upstream: fix tries check in ip_hash.
Roman Arutyunyan <arut@nginx.com>
parents: 5486
diff changeset
219 if (++iphp->tries > 20) {
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
220 ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
221 return iphp->get_rr_peer(pc, &iphp->rrp);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
222 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
223 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
224
6100
c44459611d91 Upstream: store peers as a linked list.
Ruslan Ermilov <ru@nginx.com>
parents: 6099
diff changeset
225 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
226
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
227 pc->sockaddr = peer->sockaddr;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
228 pc->socklen = peer->socklen;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
229 pc->name = &peer->name;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
230
6099
6ff0ebd6fbf4 Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents: 5706
diff changeset
231 peer->conns++;
6ff0ebd6fbf4 Upstream: track the number of active connections to upstreams.
Ruslan Ermilov <ru@nginx.com>
parents: 5706
diff changeset
232
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
233 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
234 peer->checked = now;
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
235 }
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
236
6102
3264b7828f72 Upstreams: locking.
Ruslan Ermilov <ru@nginx.com>
parents: 6100
diff changeset
237 ngx_http_upstream_rr_peers_unlock(iphp->rrp.peers);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
238
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
239 iphp->rrp.tried[n] |= m;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
240 iphp->hash = hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
241
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
242 return NGX_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
243 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
244
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
245
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
246 static char *
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
247 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
248 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
249 ngx_http_upstream_srv_conf_t *uscf;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
250
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
251 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
252
5173
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
253 if (uscf->peer.init_upstream) {
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
254 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
255 "load balancing method redefined");
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
256 }
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
257
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
258 uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
259
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
260 uscf->flags = NGX_HTTP_UPSTREAM_CREATE
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
261 |NGX_HTTP_UPSTREAM_WEIGHT
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
262 |NGX_HTTP_UPSTREAM_MAX_FAILS
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
263 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
264 |NGX_HTTP_UPSTREAM_DOWN;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
265
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
266 return NGX_CONF_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
267 }