annotate src/http/modules/ngx_http_upstream_ip_hash_module.c @ 6075:7fcfe113827d stable-1.6

Fixed possible buffer overrun in "too long header line" logging. Additionally, ellipsis now always added to make it clear that the header logged is incomplete. Reported by Daniil Bondarev.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 08 Oct 2014 17:16:04 +0400
parents 741aa3fde496
children a2bf26774cd3
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
1418
acb1f441e7b2 update ip_hash to "backup" option
Igor Sysoev <igor@sysoev.ru>
parents: 1417
diff changeset
164 if (iphp->tries > 20 || iphp->rrp.peers->single) {
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
165 return iphp->get_rr_peer(pc, &iphp->rrp);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
166 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
167
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
168 now = ngx_time();
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 pc->cached = 0;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
171 pc->connection = NULL;
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 hash = iphp->hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
174
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
175 for ( ;; ) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
176
5359
2fda9065d0f4 Win32: Borland C compatibility fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents: 5173
diff changeset
177 for (i = 0; i < (ngx_uint_t) iphp->addrlen; i++) {
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
178 hash = (hash * 113 + iphp->addr[i]) % 6271;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
179 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
180
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
181 if (!iphp->rrp.peers->weighted) {
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
182 p = hash % iphp->rrp.peers->number;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
183
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
184 } else {
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
185 w = hash % iphp->rrp.peers->total_weight;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
186
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
187 for (i = 0; i < iphp->rrp.peers->number; i++) {
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
188 w -= iphp->rrp.peers->peer[i].weight;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
189 if (w < 0) {
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
190 break;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
191 }
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
192 }
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
193
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
194 p = i;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
195 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
196
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
197 n = p / (8 * sizeof(uintptr_t));
1416
ad2311c943a3 fix ip_hash on 64-bit platform
Igor Sysoev <igor@sysoev.ru>
parents: 1284
diff changeset
198 m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
199
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
200 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
201 goto next;
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
202 }
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 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
205 "get ip hash peer, hash: %ui %04XA", p, m);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
206
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
207 peer = &iphp->rrp.peers->peer[p];
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
208
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
209 /* ngx_lock_mutex(iphp->rrp.peers->mutex); */
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->down) {
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
212 goto next_try;
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
213 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
214
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
215 if (peer->max_fails
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
216 && 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
217 && 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
218 {
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
219 goto next_try;
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
220 }
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
221
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
222 break;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
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 next_try:
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
225
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
226 iphp->rrp.tried[n] |= m;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
227
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
228 /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
229
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
230 pc->tries--;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
231
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
232 next:
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
233
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
234 if (++iphp->tries >= 20) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
235 return iphp->get_rr_peer(pc, &iphp->rrp);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
236 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
237 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
238
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
239 iphp->rrp.current = p;
b23a80f9a7b8 set current peer to use it in ngx_http_upstream_free_round_robin_peer()
Igor Sysoev <igor@sysoev.ru>
parents: 1416
diff changeset
240
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
241 pc->sockaddr = peer->sockaddr;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
242 pc->socklen = peer->socklen;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
243 pc->name = &peer->name;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
244
5486
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
245 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
246 peer->checked = now;
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
247 }
741aa3fde496 Upstream: simplified peer selection loop in the "ip_hash" module.
Vladimir Homutov <vl@nginx.com>
parents: 5359
diff changeset
248
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
249 /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
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 iphp->rrp.tried[n] |= m;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
252 iphp->hash = hash;
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 return NGX_OK;
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
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
257
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
258 static char *
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
259 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
260 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
261 ngx_http_upstream_srv_conf_t *uscf;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
262
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
263 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
264
5173
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
265 if (uscf->peer.init_upstream) {
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
266 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
267 "load balancing method redefined");
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
268 }
5373be93c0be Upstream: warn if multiple non-stackable balancers are installed.
Ruslan Ermilov <ru@nginx.com>
parents: 4695
diff changeset
269
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
270 uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
271
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
272 uscf->flags = NGX_HTTP_UPSTREAM_CREATE
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
273 |NGX_HTTP_UPSTREAM_WEIGHT
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
274 |NGX_HTTP_UPSTREAM_MAX_FAILS
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
275 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
276 |NGX_HTTP_UPSTREAM_DOWN;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
277
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
278 return NGX_CONF_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
279 }