Mercurial > hg > nginx
comparison src/http/modules/ngx_http_upstream_ip_hash_module.c @ 4695:441b2941a506
Added IPv6 support to ip_hash.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Tue, 19 Jun 2012 12:36:54 +0000 |
parents | 382c523d253a |
children | 5373be93c0be |
comparison
equal
deleted
inserted
replaced
4694:5b5c07dee156 | 4695:441b2941a506 |
---|---|
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; |