annotate src/http/modules/ngx_http_upstream_ip_hash_module.c @ 4615:adcd60233817

Added r->state reset on fastcgi/scgi/uwsgi request start. Failing to do so results in problems if 400 or 414 requests are redirected to fastcgi/scgi/uwsgi upstream, as well as after invalid headers got from upstream. This was already fixed for proxy in r3478, but fastcgi (the only affected protocol at that time) was missed. Reported by Matthieu Tourne.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 11 May 2012 13:09:24 +0000
parents d620f497c50f
children 382c523d253a 0141b4aec0e4
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
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19 u_char addr[3];
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
21 u_char tries;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
23 ngx_event_get_peer_pt get_rr_peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24 } ngx_http_upstream_ip_hash_peer_data_t;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
25
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 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
28 ngx_http_upstream_srv_conf_t *us);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
29 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
30 void *data);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31 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
32 void *conf);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33
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 static ngx_command_t ngx_http_upstream_ip_hash_commands[] = {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
37 { ngx_string("ip_hash"),
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38 NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39 ngx_http_upstream_ip_hash,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
40 0,
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 NULL },
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
43
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
44 ngx_null_command
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45 };
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 static ngx_http_module_t ngx_http_upstream_ip_hash_module_ctx = {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
49 NULL, /* preconfiguration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
50 NULL, /* postconfiguration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
51
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52 NULL, /* create main configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
53 NULL, /* init main configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
55 NULL, /* create server configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
56 NULL, /* merge server configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
57
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58 NULL, /* create location configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59 NULL /* merge location configuration */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60 };
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 ngx_module_t ngx_http_upstream_ip_hash_module = {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 NGX_MODULE_V1,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65 &ngx_http_upstream_ip_hash_module_ctx, /* module context */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66 ngx_http_upstream_ip_hash_commands, /* module directives */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67 NGX_HTTP_MODULE, /* module type */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 NULL, /* init master */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 NULL, /* init module */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 NULL, /* init process */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
71 NULL, /* init thread */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
72 NULL, /* exit thread */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
73 NULL, /* exit process */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 NULL, /* exit master */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
75 NGX_MODULE_V1_PADDING
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76 };
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 ngx_int_t
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
80 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
81 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
82 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
83 return NGX_ERROR;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84 }
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 us->peer.init = ngx_http_upstream_init_ip_hash_peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88 return NGX_OK;
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
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 static ngx_int_t
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93 ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94 ngx_http_upstream_srv_conf_t *us)
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
95 {
1144
324a5a3fe27f ip_hash used wrong byte order
Igor Sysoev <igor@sysoev.ru>
parents: 1129
diff changeset
96 u_char *p;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
97 struct sockaddr_in *sin;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
98 ngx_http_upstream_ip_hash_peer_data_t *iphp;
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 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
101 if (iphp == NULL) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
102 return NGX_ERROR;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
103 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
104
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
105 r->upstream->peer.data = &iphp->rrp;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
106
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
107 if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
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.get = ngx_http_upstream_get_ip_hash_peer;
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 /* AF_INET only */
2512
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
114
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
115 if (r->connection->sockaddr->sa_family == AF_INET) {
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
116
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
117 sin = (struct sockaddr_in *) r->connection->sockaddr;
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
118 p = (u_char *) &sin->sin_addr.s_addr;
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
119 iphp->addr[0] = p[0];
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
120 iphp->addr[1] = p[1];
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
121 iphp->addr[2] = p[2];
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
122
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
123 } else {
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
124 iphp->addr[0] = 0;
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
125 iphp->addr[1] = 0;
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
126 iphp->addr[2] = 0;
2e91aecb9e57 a prelimiary IPv6 support, HTTP listen
Igor Sysoev <igor@sysoev.ru>
parents: 1418
diff changeset
127 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
128
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
129 iphp->hash = 89;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
130 iphp->tries = 0;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
131 iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
132
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
133 return NGX_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
134 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
135
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
136
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
137 static ngx_int_t
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
138 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
139 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
140 ngx_http_upstream_ip_hash_peer_data_t *iphp = data;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
141
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
142 time_t now;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
143 uintptr_t m;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
144 ngx_uint_t i, n, p, hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
145 ngx_http_upstream_rr_peer_t *peer;
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 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
148 "get ip hash peer, try: %ui", pc->tries);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
149
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
150 /* TODO: cached */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
151
1418
acb1f441e7b2 update ip_hash to "backup" option
Igor Sysoev <igor@sysoev.ru>
parents: 1417
diff changeset
152 if (iphp->tries > 20 || iphp->rrp.peers->single) {
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
153 return iphp->get_rr_peer(pc, &iphp->rrp);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
154 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
155
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
156 now = ngx_time();
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
157
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
158 pc->cached = 0;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
159 pc->connection = NULL;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
160
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
161 hash = iphp->hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
162
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
163 for ( ;; ) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
164
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
165 for (i = 0; i < 3; i++) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
166 hash = (hash * 113 + iphp->addr[i]) % 6271;
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
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
169 p = hash % iphp->rrp.peers->number;
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 n = p / (8 * sizeof(uintptr_t));
1416
ad2311c943a3 fix ip_hash on 64-bit platform
Igor Sysoev <igor@sysoev.ru>
parents: 1284
diff changeset
172 m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
173
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
174 if (!(iphp->rrp.tried[n] & m)) {
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 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
177 "get ip hash peer, hash: %ui %04XA", p, m);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
178
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
179 peer = &iphp->rrp.peers->peer[p];
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
180
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
181 /* ngx_lock_mutex(iphp->rrp.peers->mutex); */
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 if (!peer->down) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
184
1025
f88651afad40 style fix: remove tabs
Igor Sysoev <igor@sysoev.ru>
parents: 884
diff changeset
185 if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
f88651afad40 style fix: remove tabs
Igor Sysoev <igor@sysoev.ru>
parents: 884
diff changeset
186 break;
f88651afad40 style fix: remove tabs
Igor Sysoev <igor@sysoev.ru>
parents: 884
diff changeset
187 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
188
4207
4fc91bae6f83 Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents: 2512
diff changeset
189 if (now - peer->checked > peer->fail_timeout) {
4fc91bae6f83 Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents: 2512
diff changeset
190 peer->checked = now;
1025
f88651afad40 style fix: remove tabs
Igor Sysoev <igor@sysoev.ru>
parents: 884
diff changeset
191 break;
f88651afad40 style fix: remove tabs
Igor Sysoev <igor@sysoev.ru>
parents: 884
diff changeset
192 }
1129
44f7e6f36b8c avoid endless loop
Igor Sysoev <igor@sysoev.ru>
parents: 1025
diff changeset
193 }
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
194
1129
44f7e6f36b8c avoid endless loop
Igor Sysoev <igor@sysoev.ru>
parents: 1025
diff changeset
195 iphp->rrp.tried[n] |= m;
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 /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
198
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
199 pc->tries--;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
200 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
201
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
202 if (++iphp->tries >= 20) {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
203 return iphp->get_rr_peer(pc, &iphp->rrp);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
204 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
205 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
206
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
207 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
208
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
209 pc->sockaddr = peer->sockaddr;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
210 pc->socklen = peer->socklen;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
211 pc->name = &peer->name;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
212
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
213 /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
214
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
215 iphp->rrp.tried[n] |= m;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
216 iphp->hash = hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
217
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
218 return NGX_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
219 }
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
220
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
221
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
222 static char *
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
223 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
224 {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
225 ngx_http_upstream_srv_conf_t *uscf;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
226
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
227 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
228
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
229 uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
230
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
231 uscf->flags = NGX_HTTP_UPSTREAM_CREATE
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
232 |NGX_HTTP_UPSTREAM_MAX_FAILS
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
233 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
234 |NGX_HTTP_UPSTREAM_DOWN;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
235
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
236 return NGX_CONF_OK;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
237 }