Mercurial > hg > nginx-quic
annotate src/core/ngx_md5.c @ 4207:4fc91bae6f83
Better recheck of dead upstream servers.
Previously nginx used to mark backend again as live as soon as fail_timeout
passes (10s by default) since last failure. On the other hand, detecting
dead backend takes up to 60s (proxy_connect_timeout) in typical situation
"backend is down and doesn't respond to any packets". This resulted in
suboptimal behaviour in the above situation (up to 23% of requests were
directed to dead backend with default settings).
More detailed description of the problem may be found here (in Russian):
http://mailman.nginx.org/pipermail/nginx-ru/2011-August/042172.html
Fix is to only allow one request after fail_timeout passes, and
mark backend as "live" only if this request succeeds.
Note that with new code backend will not be marked "live" unless "check"
request is completed, and this may take a while in some specific workloads
(e.g. streaming). This is believed to be acceptable.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 12 Oct 2011 14:22:48 +0000 |
parents | ce1ba4a312d7 |
children | 21167183825d |
rev | line source |
---|---|
3895 | 1 |
2 /* | |
3 * An internal implementation, based on Alexander Peslyak's | |
4 * public domain implementation: | |
5 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 | |
6 * It is not expected to be optimal and is used only | |
7 * if no MD5 implementation was found in system. | |
8 */ | |
9 | |
10 | |
11 #include <ngx_config.h> | |
12 #include <ngx_core.h> | |
13 #include <ngx_md5.h> | |
14 | |
15 | |
16 #if !(NGX_HAVE_MD5) | |
17 | |
18 static const u_char *ngx_md5_body(ngx_md5_t *ctx, const u_char *data, | |
19 size_t size); | |
20 | |
21 | |
22 void | |
23 ngx_md5_init(ngx_md5_t *ctx) | |
24 { | |
25 ctx->a = 0x67452301; | |
26 ctx->b = 0xefcdab89; | |
27 ctx->c = 0x98badcfe; | |
28 ctx->d = 0x10325476; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
29 |
3895 | 30 ctx->bytes = 0; |
31 } | |
32 | |
33 | |
34 void | |
3927
38e6f45c5e3d
make built-in ngx_md5_update() interface consistent with other implemenations
Igor Sysoev <igor@sysoev.ru>
parents:
3900
diff
changeset
|
35 ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size) |
3895 | 36 { |
37 size_t used, free; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
38 |
3941 | 39 used = (size_t) (ctx->bytes & 0x3f); |
3895 | 40 ctx->bytes += size; |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
41 |
3895 | 42 if (used) { |
43 free = 64 - used; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
44 |
3895 | 45 if (size < free) { |
46 ngx_memcpy(&ctx->buffer[used], data, size); | |
47 return; | |
48 } | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
49 |
3927
38e6f45c5e3d
make built-in ngx_md5_update() interface consistent with other implemenations
Igor Sysoev <igor@sysoev.ru>
parents:
3900
diff
changeset
|
50 data = ngx_cpymem(&ctx->buffer[used], data, free); |
3895 | 51 size -= free; |
52 (void) ngx_md5_body(ctx, ctx->buffer, 64); | |
53 } | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
54 |
3895 | 55 if (size >= 64) { |
56 data = ngx_md5_body(ctx, data, size & ~(size_t) 0x3f); | |
57 size &= 0x3f; | |
58 } | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
59 |
3895 | 60 ngx_memcpy(ctx->buffer, data, size); |
61 } | |
62 | |
63 | |
64 void | |
65 ngx_md5_final(u_char result[16], ngx_md5_t *ctx) | |
66 { | |
67 size_t used, free; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
68 |
3941 | 69 used = (size_t) (ctx->bytes & 0x3f); |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
70 |
3895 | 71 ctx->buffer[used++] = 0x80; |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
72 |
3895 | 73 free = 64 - used; |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
74 |
3895 | 75 if (free < 8) { |
76 ngx_memzero(&ctx->buffer[used], free); | |
77 (void) ngx_md5_body(ctx, ctx->buffer, 64); | |
78 used = 0; | |
79 free = 64; | |
80 } | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
81 |
3895 | 82 ngx_memzero(&ctx->buffer[used], free - 8); |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
83 |
3895 | 84 ctx->bytes <<= 3; |
3941 | 85 ctx->buffer[56] = (u_char) ctx->bytes; |
86 ctx->buffer[57] = (u_char) (ctx->bytes >> 8); | |
87 ctx->buffer[58] = (u_char) (ctx->bytes >> 16); | |
88 ctx->buffer[59] = (u_char) (ctx->bytes >> 24); | |
89 ctx->buffer[60] = (u_char) (ctx->bytes >> 32); | |
90 ctx->buffer[61] = (u_char) (ctx->bytes >> 40); | |
91 ctx->buffer[62] = (u_char) (ctx->bytes >> 48); | |
92 ctx->buffer[63] = (u_char) (ctx->bytes >> 56); | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
93 |
3895 | 94 (void) ngx_md5_body(ctx, ctx->buffer, 64); |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
95 |
3941 | 96 result[0] = (u_char) ctx->a; |
97 result[1] = (u_char) (ctx->a >> 8); | |
98 result[2] = (u_char) (ctx->a >> 16); | |
99 result[3] = (u_char) (ctx->a >> 24); | |
100 result[4] = (u_char) ctx->b; | |
101 result[5] = (u_char) (ctx->b >> 8); | |
102 result[6] = (u_char) (ctx->b >> 16); | |
103 result[7] = (u_char) (ctx->b >> 24); | |
104 result[8] = (u_char) ctx->c; | |
105 result[9] = (u_char) (ctx->c >> 8); | |
106 result[10] = (u_char) (ctx->c >> 16); | |
107 result[11] = (u_char) (ctx->c >> 24); | |
108 result[12] = (u_char) ctx->d; | |
109 result[13] = (u_char) (ctx->d >> 8); | |
110 result[14] = (u_char) (ctx->d >> 16); | |
111 result[15] = (u_char) (ctx->d >> 24); | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
112 |
3895 | 113 ngx_memzero(ctx, sizeof(*ctx)); |
114 } | |
115 | |
116 | |
117 /* | |
118 * The basic MD5 functions. | |
119 * | |
120 * F and G are optimized compared to their RFC 1321 definitions for | |
121 * architectures that lack an AND-NOT instruction, just like in | |
122 * Colin Plumb's implementation. | |
123 */ | |
124 | |
125 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) | |
126 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) | |
127 #define H(x, y, z) ((x) ^ (y) ^ (z)) | |
128 #define I(x, y, z) ((y) ^ ((x) | ~(z))) | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
129 |
3895 | 130 /* |
131 * The MD5 transformation for all four rounds. | |
132 */ | |
133 | |
134 #define STEP(f, a, b, c, d, x, t, s) \ | |
135 (a) += f((b), (c), (d)) + (x) + (t); \ | |
136 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ | |
137 (a) += (b) | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
138 |
3895 | 139 /* |
140 * SET() reads 4 input bytes in little-endian byte order and stores them | |
141 * in a properly aligned word in host byte order. | |
142 * | |
143 * The check for little-endian architectures that tolerate unaligned | |
144 * memory accesses is just an optimization. Nothing will break if it | |
145 * does not work. | |
146 */ | |
147 | |
148 #if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) | |
149 | |
150 #define SET(n) (*(uint32_t *) &p[n * 4]) | |
151 #define GET(n) (*(uint32_t *) &p[n * 4]) | |
152 | |
153 #else | |
154 | |
155 #define SET(n) \ | |
156 (block[n] = \ | |
157 (uint32_t) p[n * 4] | \ | |
158 ((uint32_t) p[n * 4 + 1] << 8) | \ | |
159 ((uint32_t) p[n * 4 + 2] << 16) | \ | |
160 ((uint32_t) p[n * 4 + 3] << 24)) | |
161 | |
162 #define GET(n) block[n] | |
163 | |
164 #endif | |
165 | |
166 | |
167 /* | |
168 * This processes one or more 64-byte data blocks, but does not update | |
169 * the bit counters. There are no alignment requirements. | |
170 */ | |
171 | |
172 static const u_char * | |
173 ngx_md5_body(ngx_md5_t *ctx, const u_char *data, size_t size) | |
174 { | |
175 uint32_t a, b, c, d; | |
176 uint32_t saved_a, saved_b, saved_c, saved_d; | |
177 const u_char *p; | |
178 #if !(NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) | |
179 uint32_t block[16]; | |
180 #endif | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
181 |
3895 | 182 p = data; |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
183 |
3895 | 184 a = ctx->a; |
185 b = ctx->b; | |
186 c = ctx->c; | |
187 d = ctx->d; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
188 |
3895 | 189 do { |
190 saved_a = a; | |
191 saved_b = b; | |
192 saved_c = c; | |
193 saved_d = d; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
194 |
3895 | 195 /* Round 1 */ |
196 | |
197 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7); | |
198 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12); | |
199 STEP(F, c, d, a, b, SET(2), 0x242070db, 17); | |
200 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22); | |
201 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7); | |
202 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12); | |
203 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17); | |
204 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22); | |
205 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7); | |
206 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12); | |
207 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17); | |
208 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22); | |
209 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7); | |
210 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12); | |
211 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17); | |
212 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22); | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
213 |
3895 | 214 /* Round 2 */ |
215 | |
216 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5); | |
217 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9); | |
218 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14); | |
219 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20); | |
220 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5); | |
221 STEP(G, d, a, b, c, GET(10), 0x02441453, 9); | |
222 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14); | |
223 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20); | |
224 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5); | |
225 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9); | |
226 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14); | |
227 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20); | |
228 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5); | |
229 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9); | |
230 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14); | |
231 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20); | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
232 |
3895 | 233 /* Round 3 */ |
234 | |
235 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4); | |
236 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11); | |
237 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16); | |
238 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23); | |
239 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4); | |
240 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11); | |
241 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16); | |
242 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23); | |
243 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4); | |
244 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11); | |
245 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16); | |
246 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23); | |
247 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4); | |
248 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11); | |
249 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16); | |
250 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23); | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
251 |
3895 | 252 /* Round 4 */ |
253 | |
254 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6); | |
255 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10); | |
256 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15); | |
257 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21); | |
258 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6); | |
259 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10); | |
260 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15); | |
261 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21); | |
262 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6); | |
263 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10); | |
264 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15); | |
265 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21); | |
266 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6); | |
267 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10); | |
268 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15); | |
269 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21); | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
270 |
3895 | 271 a += saved_a; |
272 b += saved_b; | |
273 c += saved_c; | |
274 d += saved_d; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
275 |
3895 | 276 p += 64; |
277 | |
278 } while (size -= 64); | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
279 |
3895 | 280 ctx->a = a; |
281 ctx->b = b; | |
282 ctx->c = c; | |
283 ctx->d = d; | |
3900
4d5754e2f220
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
3895
diff
changeset
|
284 |
3895 | 285 return p; |
286 } | |
287 | |
288 #endif |