comparison src/http/modules/ngx_http_upstream_ip_hash_module.c @ 678:981b4c44593b NGINX_1_3_2

nginx 1.3.2 *) Change: the "single" parameter of the "keepalive" directive is now ignored. *) Change: SSL compression is now disabled when using all versions of OpenSSL, including ones prior to 1.0.0. *) Feature: it is now possible to use the "ip_hash" directive to balance IPv6 clients. *) Feature: the $status variable can now be used not only in the "log_format" directive. *) Bugfix: a segmentation fault might occur in a worker process on shutdown if the "resolver" directive was used. *) Bugfix: a segmentation fault might occur in a worker process if the ngx_http_mp4_module was used. *) Bugfix: in the ngx_http_mp4_module. *) Bugfix: a segmentation fault might occur in a worker process if conflicting wildcard server names were used. *) Bugfix: nginx might be terminated abnormally on a SIGBUS signal on ARM platform. *) Bugfix: an alert "sendmsg() failed (9: Bad file number)" on HP-UX while reconfiguration.
author Igor Sysoev <http://sysoev.ru>
date Tue, 26 Jun 2012 00:00:00 +0400
parents bfa81a0490a2
children
comparison
equal deleted inserted replaced
677:47f0934d8824 678:981b4c44593b
14 /* the round robin data must be first */ 14 /* the round robin data must be first */
15 ngx_http_upstream_rr_peer_data_t rrp; 15 ngx_http_upstream_rr_peer_data_t rrp;
16 16
17 ngx_uint_t hash; 17 ngx_uint_t hash;
18 18
19 u_char addr[3]; 19 u_char addrlen;
20 u_char *addr;
20 21
21 u_char tries; 22 u_char tries;
22 23
23 ngx_event_get_peer_pt get_rr_peer; 24 ngx_event_get_peer_pt get_rr_peer;
24 } ngx_http_upstream_ip_hash_peer_data_t; 25 } ngx_http_upstream_ip_hash_peer_data_t;
74 NULL, /* exit master */ 75 NULL, /* exit master */
75 NGX_MODULE_V1_PADDING 76 NGX_MODULE_V1_PADDING
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 ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) 84 ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
81 { 85 {
82 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { 86 if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
83 return NGX_ERROR; 87 return NGX_ERROR;
84 } 88 }
91 95
92 static ngx_int_t 96 static ngx_int_t
93 ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r, 97 ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
94 ngx_http_upstream_srv_conf_t *us) 98 ngx_http_upstream_srv_conf_t *us)
95 { 99 {
96 u_char *p;
97 struct sockaddr_in *sin; 100 struct sockaddr_in *sin;
101 #if (NGX_HAVE_INET6)
102 struct sockaddr_in6 *sin6;
103 #endif
98 ngx_http_upstream_ip_hash_peer_data_t *iphp; 104 ngx_http_upstream_ip_hash_peer_data_t *iphp;
99 105
100 iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t)); 106 iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t));
101 if (iphp == NULL) { 107 if (iphp == NULL) {
102 return NGX_ERROR; 108 return NGX_ERROR;
108 return NGX_ERROR; 114 return NGX_ERROR;
109 } 115 }
110 116
111 r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer; 117 r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
112 118
113 /* AF_INET only */ 119 switch (r->connection->sockaddr->sa_family) {
114 120
115 if (r->connection->sockaddr->sa_family == AF_INET) { 121 case AF_INET:
116
117 sin = (struct sockaddr_in *) r->connection->sockaddr; 122 sin = (struct sockaddr_in *) r->connection->sockaddr;
118 p = (u_char *) &sin->sin_addr.s_addr; 123 iphp->addr = (u_char *) &sin->sin_addr.s_addr;
119 iphp->addr[0] = p[0]; 124 iphp->addrlen = 3;
120 iphp->addr[1] = p[1]; 125 break;
121 iphp->addr[2] = p[2]; 126
122 127 #if (NGX_HAVE_INET6)
123 } else { 128 case AF_INET6:
124 iphp->addr[0] = 0; 129 sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
125 iphp->addr[1] = 0; 130 iphp->addr = (u_char *) &sin6->sin6_addr.s6_addr;
126 iphp->addr[2] = 0; 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;
127 } 138 }
128 139
129 iphp->hash = 89; 140 iphp->hash = 89;
130 iphp->tries = 0; 141 iphp->tries = 0;
131 iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer; 142 iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
161 172
162 hash = iphp->hash; 173 hash = iphp->hash;
163 174
164 for ( ;; ) { 175 for ( ;; ) {
165 176
166 for (i = 0; i < 3; i++) { 177 for (i = 0; i < iphp->addrlen; i++) {
167 hash = (hash * 113 + iphp->addr[i]) % 6271; 178 hash = (hash * 113 + iphp->addr[i]) % 6271;
168 } 179 }
169 180
170 if (!iphp->rrp.peers->weighted) { 181 if (!iphp->rrp.peers->weighted) {
171 p = hash % iphp->rrp.peers->number; 182 p = hash % iphp->rrp.peers->number;