summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2012-09-28 18:28:38 +0000
committerMaxim Dounin <mdounin@mdounin.ru>2012-09-28 18:28:38 +0000
commit6a0f47e0797c8b797c806fab16ffc5bab40c0577 (patch)
tree140ef99d3521f30e2316ab22242eae74724af3b2 /src
parent8be233c8f2a3544195be4a6e97243437cd78df60 (diff)
downloadnginx-6a0f47e0797c8b797c806fab16ffc5bab40c0577.tar.gz
nginx-6a0f47e0797c8b797c806fab16ffc5bab40c0577.tar.bz2
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.
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_resolver.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 178e0831d..dcdbe0cc8 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -88,6 +88,8 @@ static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size);
static void ngx_resolver_free(ngx_resolver_t *r, void *p);
static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
+static in_addr_t *ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src,
+ ngx_uint_t n);
static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
@@ -445,8 +447,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
if (naddrs != 1) {
addr = 0;
- addrs = ngx_resolver_dup(r, rn->u.addrs,
- naddrs * sizeof(in_addr_t));
+ addrs = ngx_resolver_rotate(r, rn->u.addrs, naddrs);
if (addrs == NULL) {
return NGX_ERROR;
}
@@ -2135,6 +2136,28 @@ ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size)
}
+static in_addr_t *
+ngx_resolver_rotate(ngx_resolver_t *r, in_addr_t *src, ngx_uint_t n)
+{
+ void *dst, *p;
+ ngx_uint_t j;
+
+ dst = ngx_resolver_alloc(r, n * sizeof(in_addr_t));
+
+ j = ngx_random() % n;
+
+ if (j == 0) {
+ ngx_memcpy(dst, src, n * sizeof(in_addr_t));
+ return dst;
+ }
+
+ p = ngx_cpymem(dst, &src[j], (n - j) * sizeof(in_addr_t));
+ ngx_memcpy(p, src, j * sizeof(in_addr_t));
+
+ return dst;
+}
+
+
char *
ngx_resolver_strerror(ngx_int_t err)
{