~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/http/modules/ngx_http_upstream_ip_hash_module.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
15
16
 
16
17
    ngx_uint_t                         hash;
17
18
 
18
 
    /* AF_INET only */
19
 
    u_char                             addr[3];
 
19
    u_char                             addrlen;
 
20
    u_char                            *addr;
20
21
 
21
22
    u_char                             tries;
22
23
 
76
77
};
77
78
 
78
79
 
79
 
ngx_int_t
 
80
static u_char ngx_http_upstream_ip_hash_pseudo_addr[3];
 
81
 
 
82
 
 
83
static ngx_int_t
80
84
ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
81
85
{
82
86
    if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
93
97
ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
94
98
    ngx_http_upstream_srv_conf_t *us)
95
99
{
96
 
    u_char                                 *p;
97
100
    struct sockaddr_in                     *sin;
 
101
#if (NGX_HAVE_INET6)
 
102
    struct sockaddr_in6                    *sin6;
 
103
#endif
98
104
    ngx_http_upstream_ip_hash_peer_data_t  *iphp;
99
105
 
100
106
    iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t));
110
116
 
111
117
    r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
112
118
 
113
 
    /* AF_INET only */
114
 
    sin = (struct sockaddr_in *) r->connection->sockaddr;
115
 
    p = (u_char *) &sin->sin_addr.s_addr;
116
 
    iphp->addr[0] = p[0];
117
 
    iphp->addr[1] = p[1];
118
 
    iphp->addr[2] = p[2];
 
119
    switch (r->connection->sockaddr->sa_family) {
 
120
 
 
121
    case AF_INET:
 
122
        sin = (struct sockaddr_in *) r->connection->sockaddr;
 
123
        iphp->addr = (u_char *) &sin->sin_addr.s_addr;
 
124
        iphp->addrlen = 3;
 
125
        break;
 
126
 
 
127
#if (NGX_HAVE_INET6)
 
128
    case AF_INET6:
 
129
        sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
 
130
        iphp->addr = (u_char *) &sin6->sin6_addr.s6_addr;
 
131
        iphp->addrlen = 16;
 
132
        break;
 
133
#endif
 
134
 
 
135
    default:
 
136
        iphp->addr = ngx_http_upstream_ip_hash_pseudo_addr;
 
137
        iphp->addrlen = 3;
 
138
    }
119
139
 
120
140
    iphp->hash = 89;
121
141
    iphp->tries = 0;
131
151
    ngx_http_upstream_ip_hash_peer_data_t  *iphp = data;
132
152
 
133
153
    time_t                        now;
 
154
    ngx_int_t                     w;
134
155
    uintptr_t                     m;
135
156
    ngx_uint_t                    i, n, p, hash;
136
157
    ngx_http_upstream_rr_peer_t  *peer;
153
174
 
154
175
    for ( ;; ) {
155
176
 
156
 
        for (i = 0; i < 3; i++) {
 
177
        for (i = 0; i < iphp->addrlen; i++) {
157
178
            hash = (hash * 113 + iphp->addr[i]) % 6271;
158
179
        }
159
180
 
160
 
        p = hash % iphp->rrp.peers->number;
 
181
        if (!iphp->rrp.peers->weighted) {
 
182
            p = hash % iphp->rrp.peers->number;
 
183
 
 
184
        } else {
 
185
            w = hash % iphp->rrp.peers->total_weight;
 
186
 
 
187
            for (i = 0; i < iphp->rrp.peers->number; i++) {
 
188
                w -= iphp->rrp.peers->peer[i].weight;
 
189
                if (w < 0) {
 
190
                    break;
 
191
                }
 
192
            }
 
193
 
 
194
            p = i;
 
195
        }
161
196
 
162
197
        n = p / (8 * sizeof(uintptr_t));
163
198
        m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
177
212
                    break;
178
213
                }
179
214
 
180
 
                if (now - peer->accessed > peer->fail_timeout) {
181
 
                    peer->fails = 0;
 
215
                if (now - peer->checked > peer->fail_timeout) {
 
216
                    peer->checked = now;
182
217
                    break;
183
218
                }
184
219
            }
217
252
 
218
253
    uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
219
254
 
 
255
    if (uscf->peer.init_upstream) {
 
256
        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
 
257
                           "load balancing method redefined");
 
258
    }
 
259
 
220
260
    uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
221
261
 
222
262
    uscf->flags = NGX_HTTP_UPSTREAM_CREATE
 
263
                  |NGX_HTTP_UPSTREAM_WEIGHT
223
264
                  |NGX_HTTP_UPSTREAM_MAX_FAILS
224
265
                  |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
225
266
                  |NGX_HTTP_UPSTREAM_DOWN;