Mercurial > hg > nginx
comparison src/http/modules/ngx_http_upstream_hash_module.c @ 6148:bf8b6534db3a
Upstream hash: consistency across little/big endianness.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Mon, 18 May 2015 16:05:44 +0300 |
parents | b6047abf5f30 |
children | 52367732bcbc |
comparison
equal
deleted
inserted
replaced
6147:74b6ef56ea56 | 6148:bf8b6534db3a |
---|---|
275 static ngx_int_t | 275 static ngx_int_t |
276 ngx_http_upstream_init_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) | 276 ngx_http_upstream_init_chash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) |
277 { | 277 { |
278 u_char *host, *port, c; | 278 u_char *host, *port, c; |
279 size_t host_len, port_len, size; | 279 size_t host_len, port_len, size; |
280 uint32_t hash, base_hash, prev_hash; | 280 uint32_t hash, base_hash; |
281 ngx_str_t *server; | 281 ngx_str_t *server; |
282 ngx_uint_t npoints, i, j; | 282 ngx_uint_t npoints, i, j; |
283 ngx_http_upstream_rr_peer_t *peer; | 283 ngx_http_upstream_rr_peer_t *peer; |
284 ngx_http_upstream_rr_peers_t *peers; | 284 ngx_http_upstream_rr_peers_t *peers; |
285 ngx_http_upstream_chash_points_t *points; | 285 ngx_http_upstream_chash_points_t *points; |
286 ngx_http_upstream_hash_srv_conf_t *hcf; | 286 ngx_http_upstream_hash_srv_conf_t *hcf; |
287 union { | |
288 uint32_t value; | |
289 u_char byte[4]; | |
290 } prev_hash; | |
287 | 291 |
288 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { | 292 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { |
289 return NGX_ERROR; | 293 return NGX_ERROR; |
290 } | 294 } |
291 | 295 |
348 ngx_crc32_init(base_hash); | 352 ngx_crc32_init(base_hash); |
349 ngx_crc32_update(&base_hash, host, host_len); | 353 ngx_crc32_update(&base_hash, host, host_len); |
350 ngx_crc32_update(&base_hash, (u_char *) "", 1); | 354 ngx_crc32_update(&base_hash, (u_char *) "", 1); |
351 ngx_crc32_update(&base_hash, port, port_len); | 355 ngx_crc32_update(&base_hash, port, port_len); |
352 | 356 |
353 prev_hash = 0; | 357 prev_hash.value = 0; |
354 npoints = peer->weight * 160; | 358 npoints = peer->weight * 160; |
355 | 359 |
356 for (j = 0; j < npoints; j++) { | 360 for (j = 0; j < npoints; j++) { |
357 hash = base_hash; | 361 hash = base_hash; |
358 | 362 |
359 ngx_crc32_update(&hash, (u_char *) &prev_hash, sizeof(uint32_t)); | 363 ngx_crc32_update(&hash, prev_hash.byte, 4); |
360 ngx_crc32_final(hash); | 364 ngx_crc32_final(hash); |
361 | 365 |
362 points->point[points->number].hash = hash; | 366 points->point[points->number].hash = hash; |
363 points->point[points->number].server = server; | 367 points->point[points->number].server = server; |
364 points->number++; | 368 points->number++; |
365 | 369 |
366 prev_hash = hash; | 370 #if (NGX_HAVE_LITTLE_ENDIAN) |
371 prev_hash.value = hash; | |
372 #else | |
373 prev_hash.byte[0] = (u_char) (hash & 0xff); | |
374 prev_hash.byte[1] = (u_char) ((hash >> 8) & 0xff); | |
375 prev_hash.byte[2] = (u_char) ((hash >> 16) & 0xff); | |
376 prev_hash.byte[3] = (u_char) ((hash >> 24) & 0xff); | |
377 #endif | |
367 } | 378 } |
368 } | 379 } |
369 | 380 |
370 ngx_qsort(points->point, | 381 ngx_qsort(points->point, |
371 points->number, | 382 points->number, |