Mercurial > hg > nginx
comparison src/core/ngx_resolver.c @ 4871:c85cefbdaafe
Resolver: cached addresses are returned with random rotation now.
This ensures balancing when working with dynamically resolved upstream
servers with multiple addresses.
Based on patch by Anton Jouline.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 28 Sep 2012 18:28:38 +0000 |
parents | dd63abf20ba7 |
children | 063ac68d89dc |
comparison
equal
deleted
inserted
replaced
4870:8a9b7b4e9f2d | 4871:c85cefbdaafe |
---|---|
86 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size); | 86 static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size); |
87 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size); | 87 static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size); |
88 static void ngx_resolver_free(ngx_resolver_t *r, void *p); | 88 static void ngx_resolver_free(ngx_resolver_t *r, void *p); |
89 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); | 89 static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p); |
90 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); | 90 static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size); |
91 static in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, | |
92 ngx_uint_t n); | |
91 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); | 93 static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len); |
92 | 94 |
93 | 95 |
94 ngx_resolver_t * | 96 ngx_resolver_t * |
95 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) | 97 ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n) |
443 | 445 |
444 /* NGX_RESOLVE_A answer */ | 446 /* NGX_RESOLVE_A answer */ |
445 | 447 |
446 if (naddrs != 1) { | 448 if (naddrs != 1) { |
447 addr = 0; | 449 addr = 0; |
448 addrs = ngx_resolver_dup(r, rn->u.addrs, | 450 addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs); |
449 naddrs * sizeof(in_addr_t)); | |
450 if (addrs == NULL) { | 451 if (addrs == NULL) { |
451 return NGX_ERROR; | 452 return NGX_ERROR; |
452 } | 453 } |
453 | 454 |
454 } else { | 455 } else { |
2133 | 2134 |
2134 return dst; | 2135 return dst; |
2135 } | 2136 } |
2136 | 2137 |
2137 | 2138 |
2139 static in_addr_t * | |
2140 ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n) | |
2141 { | |
2142 void *dst, *p; | |
2143 ngx_uint_t j; | |
2144 | |
2145 dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t)); | |
2146 | |
2147 j = ngx_random() % n; | |
2148 | |
2149 if (j == 0) { | |
2150 ngx_memcpy(dst, src, n * sizeof(in_addr_t)); | |
2151 return dst; | |
2152 } | |
2153 | |
2154 p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t)); | |
2155 ngx_memcpy(p, src, j * sizeof(in_addr_t)); | |
2156 | |
2157 return dst; | |
2158 } | |
2159 | |
2160 | |
2138 char * | 2161 char * |
2139 ngx_resolver_strerror(ngx_int_t err) | 2162 ngx_resolver_strerror(ngx_int_t err) |
2140 { | 2163 { |
2141 static char *errors[] = { | 2164 static char *errors[] = { |
2142 "Format error", /* FORMERR */ | 2165 "Format error", /* FORMERR */ |