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,