Upstream: excluded down servers from the next_upstream tries.

Previously, the number of next_upstream tries included servers marked
as "down", resulting in "no live upstreams" with the code 502 instead
of the code derived from an attempt to connect to the last tried "up"
server (ticket #2096).
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index 8e7b4ea..1f15fae 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -10,8 +10,8 @@
 #include <ngx_http.h>
 
 
-#define ngx_http_upstream_tries(p) ((p)->number                               \
-                                    + ((p)->next ? (p)->next->number : 0))
+#define ngx_http_upstream_tries(p) ((p)->tries                                \
+                                    + ((p)->next ? (p)->next->tries : 0))
 
 
 static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer(
@@ -32,7 +32,7 @@
     ngx_http_upstream_srv_conf_t *us)
 {
     ngx_url_t                      u;
-    ngx_uint_t                     i, j, n, w;
+    ngx_uint_t                     i, j, n, w, t;
     ngx_http_upstream_server_t    *server;
     ngx_http_upstream_rr_peer_t   *peer, **peerp;
     ngx_http_upstream_rr_peers_t  *peers, *backup;
@@ -44,6 +44,7 @@
 
         n = 0;
         w = 0;
+        t = 0;
 
         for (i = 0; i < us->servers->nelts; i++) {
             if (server[i].backup) {
@@ -52,6 +53,10 @@
 
             n += server[i].naddrs;
             w += server[i].naddrs * server[i].weight;
+
+            if (!server[i].down) {
+                t += server[i].naddrs;
+            }
         }
 
         if (n == 0) {
@@ -75,6 +80,7 @@
         peers->number = n;
         peers->weighted = (w != n);
         peers->total_weight = w;
+        peers->tries = t;
         peers->name = &us->host;
 
         n = 0;
@@ -110,6 +116,7 @@
 
         n = 0;
         w = 0;
+        t = 0;
 
         for (i = 0; i < us->servers->nelts; i++) {
             if (!server[i].backup) {
@@ -118,6 +125,10 @@
 
             n += server[i].naddrs;
             w += server[i].naddrs * server[i].weight;
+
+            if (!server[i].down) {
+                t += server[i].naddrs;
+            }
         }
 
         if (n == 0) {
@@ -139,6 +150,7 @@
         backup->number = n;
         backup->weighted = (w != n);
         backup->total_weight = w;
+        backup->tries = t;
         backup->name = &us->host;
 
         n = 0;
@@ -214,6 +226,7 @@
     peers->number = n;
     peers->weighted = 0;
     peers->total_weight = n;
+    peers->tries = n;
     peers->name = &us->host;
 
     peerp = &peers->peer;
@@ -332,6 +345,7 @@
 
     peers->single = (ur->naddrs == 1);
     peers->number = ur->naddrs;
+    peers->tries = ur->naddrs;
     peers->name = &ur->host;
 
     if (ur->sockaddr) {
diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h
index 45f258d..922ceaa 100644
--- a/src/http/ngx_http_upstream_round_robin.h
+++ b/src/http/ngx_http_upstream_round_robin.h
@@ -68,6 +68,7 @@
 #endif
 
     ngx_uint_t                      total_weight;
+    ngx_uint_t                      tries;
 
     unsigned                        single:1;
     unsigned                        weighted:1;
diff --git a/src/stream/ngx_stream_upstream_round_robin.c b/src/stream/ngx_stream_upstream_round_robin.c
index c207667..ae3bf37 100644
--- a/src/stream/ngx_stream_upstream_round_robin.c
+++ b/src/stream/ngx_stream_upstream_round_robin.c
@@ -10,8 +10,8 @@
 #include <ngx_stream.h>
 
 
-#define ngx_stream_upstream_tries(p) ((p)->number                             \
-                                      + ((p)->next ? (p)->next->number : 0))
+#define ngx_stream_upstream_tries(p) ((p)->tries                              \
+                                      + ((p)->next ? (p)->next->tries : 0))
 
 
 static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer(
@@ -38,7 +38,7 @@
     ngx_stream_upstream_srv_conf_t *us)
 {
     ngx_url_t                        u;
-    ngx_uint_t                       i, j, n, w;
+    ngx_uint_t                       i, j, n, w, t;
     ngx_stream_upstream_server_t    *server;
     ngx_stream_upstream_rr_peer_t   *peer, **peerp;
     ngx_stream_upstream_rr_peers_t  *peers, *backup;
@@ -50,6 +50,7 @@
 
         n = 0;
         w = 0;
+        t = 0;
 
         for (i = 0; i < us->servers->nelts; i++) {
             if (server[i].backup) {
@@ -58,6 +59,10 @@
 
             n += server[i].naddrs;
             w += server[i].naddrs * server[i].weight;
+
+            if (!server[i].down) {
+                t += server[i].naddrs;
+            }
         }
 
         if (n == 0) {
@@ -81,6 +86,7 @@
         peers->number = n;
         peers->weighted = (w != n);
         peers->total_weight = w;
+        peers->tries = t;
         peers->name = &us->host;
 
         n = 0;
@@ -116,6 +122,7 @@
 
         n = 0;
         w = 0;
+        t = 0;
 
         for (i = 0; i < us->servers->nelts; i++) {
             if (!server[i].backup) {
@@ -124,6 +131,10 @@
 
             n += server[i].naddrs;
             w += server[i].naddrs * server[i].weight;
+
+            if (!server[i].down) {
+                t += server[i].naddrs;
+            }
         }
 
         if (n == 0) {
@@ -145,6 +156,7 @@
         backup->number = n;
         backup->weighted = (w != n);
         backup->total_weight = w;
+        backup->tries = t;
         backup->name = &us->host;
 
         n = 0;
@@ -220,6 +232,7 @@
     peers->number = n;
     peers->weighted = 0;
     peers->total_weight = n;
+    peers->tries = n;
     peers->name = &us->host;
 
     peerp = &peers->peer;
@@ -342,6 +355,7 @@
 
     peers->single = (ur->naddrs == 1);
     peers->number = ur->naddrs;
+    peers->tries = ur->naddrs;
     peers->name = &ur->host;
 
     if (ur->sockaddr) {
diff --git a/src/stream/ngx_stream_upstream_round_robin.h b/src/stream/ngx_stream_upstream_round_robin.h
index 35d9fce..bd96667 100644
--- a/src/stream/ngx_stream_upstream_round_robin.h
+++ b/src/stream/ngx_stream_upstream_round_robin.h
@@ -66,6 +66,7 @@
 #endif
 
     ngx_uint_t                       total_weight;
+    ngx_uint_t                       tries;
 
     unsigned                         single:1;
     unsigned                         weighted:1;