Mercurial > hg > nginx-quic
annotate src/core/ngx_hash.c @ 6133:af7eba90645d
Win32: shared memory base addresses and remapping.
Two mechanisms are implemented to make it possible to store pointers
in shared memory on Windows, in particular on Windows Vista and later
versions with ASLR:
- The ngx_shm_remap() function added to allow remapping of a shared memory
zone to the address originally used for it in the master process. While
important, it doesn't solve the problem by itself as in many cases it's
not possible to use the address because of conflicts with other
allocations.
- We now create mappings at the same address in all processes by starting
mappings at predefined addresses normally unused by newborn processes.
These two mechanisms combined allow to use shared memory on Windows
almost without problems, including reloads.
Based on the patch by Sergey Brester:
http://mailman.nginx.org/pipermail/nginx-devel/2015-April/006836.html
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 27 Apr 2015 18:25:42 +0300 |
parents | f961c719fb09 |
children | ddf35e019a80 |
rev | line source |
---|---|
507 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
507 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 | |
11 | |
589 | 12 void * |
13 ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len) | |
14 { | |
15 ngx_uint_t i; | |
16 ngx_hash_elt_t *elt; | |
17 | |
18 #if 0 | |
2155 | 19 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "hf:\"%*s\"", len, name); |
589 | 20 #endif |
21 | |
22 elt = hash->buckets[key % hash->size]; | |
23 | |
24 if (elt == NULL) { | |
25 return NULL; | |
26 } | |
27 | |
28 while (elt->value) { | |
29 if (len != (size_t) elt->len) { | |
30 goto next; | |
31 } | |
32 | |
33 for (i = 0; i < len; i++) { | |
34 if (name[i] != elt->name[i]) { | |
35 goto next; | |
36 } | |
37 } | |
38 | |
39 return elt->value; | |
40 | |
41 next: | |
42 | |
43 elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len, | |
44 sizeof(void *)); | |
45 continue; | |
46 } | |
47 | |
48 return NULL; | |
49 } | |
50 | |
51 | |
52 void * | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
53 ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len) |
589 | 54 { |
55 void *value; | |
56 ngx_uint_t i, n, key; | |
57 | |
58 #if 0 | |
2155 | 59 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wch:\"%*s\"", len, name); |
589 | 60 #endif |
61 | |
62 n = len; | |
63 | |
64 while (n) { | |
65 if (name[n - 1] == '.') { | |
66 break; | |
67 } | |
68 | |
69 n--; | |
70 } | |
71 | |
72 key = 0; | |
73 | |
74 for (i = n; i < len; i++) { | |
75 key = ngx_hash(key, name[i]); | |
76 } | |
77 | |
78 #if 0 | |
79 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key); | |
80 #endif | |
81 | |
82 value = ngx_hash_find(&hwc->hash, key, &name[n], len - n); | |
83 | |
2149 | 84 #if 0 |
85 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "value:\"%p\"", value); | |
86 #endif | |
87 | |
589 | 88 if (value) { |
591 | 89 |
90 /* | |
91 * the 2 low bits of value have the special meaning: | |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
92 * 00 - value is data pointer for both "example.com" |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
93 * and "*.example.com"; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
94 * 01 - value is data pointer for "*.example.com" only; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
95 * 10 - value is pointer to wildcard hash allowing |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
96 * both "example.com" and "*.example.com"; |
591 | 97 * 11 - value is pointer to wildcard hash allowing |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
98 * "*.example.com" only. |
591 | 99 */ |
100 | |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
101 if ((uintptr_t) value & 2) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
102 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
103 if (n == 0) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
104 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
105 /* "example.com" */ |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
106 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
107 if ((uintptr_t) value & 1) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
108 return NULL; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
109 } |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
110 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
111 hwc = (ngx_hash_wildcard_t *) |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
112 ((uintptr_t) value & (uintptr_t) ~3); |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
113 return hwc->value; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
114 } |
591 | 115 |
116 hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3); | |
117 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
118 value = ngx_hash_find_wc_head(hwc, name, n - 1); |
589 | 119 |
120 if (value) { | |
121 return value; | |
122 } | |
123 | |
124 return hwc->value; | |
125 } | |
126 | |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
127 if ((uintptr_t) value & 1) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
128 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
129 if (n == 0) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
130 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
131 /* "example.com" */ |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
132 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
133 return NULL; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
134 } |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
135 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
136 return (void *) ((uintptr_t) value & (uintptr_t) ~3); |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
137 } |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
138 |
589 | 139 return value; |
140 } | |
141 | |
142 return hwc->value; | |
143 } | |
144 | |
145 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
146 void * |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
147 ngx_hash_find_wc_tail(ngx_hash_wildcard_t *hwc, u_char *name, size_t len) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
148 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
149 void *value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
150 ngx_uint_t i, key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
151 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
152 #if 0 |
2155 | 153 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wct:\"%*s\"", len, name); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
154 #endif |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
155 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
156 key = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
157 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
158 for (i = 0; i < len; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
159 if (name[i] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
160 break; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
161 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
162 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
163 key = ngx_hash(key, name[i]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
164 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
165 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
166 if (i == len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
167 return NULL; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
168 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
169 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
170 #if 0 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
171 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
172 #endif |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
173 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
174 value = ngx_hash_find(&hwc->hash, key, name, i); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
175 |
2155 | 176 #if 0 |
177 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "value:\"%p\"", value); | |
178 #endif | |
179 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
180 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
181 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
182 /* |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
183 * the 2 low bits of value have the special meaning: |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
184 * 00 - value is data pointer; |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
185 * 11 - value is pointer to wildcard hash allowing "example.*". |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
186 */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
187 |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
188 if ((uintptr_t) value & 2) { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
189 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
190 i++; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
191 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
192 hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
193 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
194 value = ngx_hash_find_wc_tail(hwc, &name[i], len - i); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
195 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
196 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
197 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
198 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
199 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
200 return hwc->value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
201 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
202 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
203 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
204 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
205 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
206 return hwc->value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
207 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
208 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
209 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
210 void * |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
211 ngx_hash_find_combined(ngx_hash_combined_t *hash, ngx_uint_t key, u_char *name, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
212 size_t len) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
213 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
214 void *value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
215 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
216 if (hash->hash.buckets) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
217 value = ngx_hash_find(&hash->hash, key, name, len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
218 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
219 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
220 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
221 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
222 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
223 |
2195 | 224 if (len == 0) { |
225 return NULL; | |
226 } | |
227 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
228 if (hash->wc_head && hash->wc_head->hash.buckets) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
229 value = ngx_hash_find_wc_head(hash->wc_head, name, len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
230 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
231 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
232 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
233 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
234 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
235 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
236 if (hash->wc_tail && hash->wc_tail->hash.buckets) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
237 value = ngx_hash_find_wc_tail(hash->wc_tail, name, len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
238 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
239 if (value) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
240 return value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
241 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
242 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
243 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
244 return NULL; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
245 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
246 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
247 |
589 | 248 #define NGX_HASH_ELT_SIZE(name) \ |
3510
4c70bbdfd076
allow hash key values more than 255 bytes, it does not actually increase mean
Igor Sysoev <igor@sysoev.ru>
parents:
3118
diff
changeset
|
249 (sizeof(void *) + ngx_align((name)->key.len + 2, sizeof(void *))) |
589 | 250 |
507 | 251 ngx_int_t |
589 | 252 ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts) |
253 { | |
254 u_char *elts; | |
595 | 255 size_t len; |
256 u_short *test; | |
589 | 257 ngx_uint_t i, n, key, size, start, bucket_size; |
258 ngx_hash_elt_t *elt, **buckets; | |
259 | |
260 for (n = 0; n < nelts; n++) { | |
261 if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *)) | |
262 { | |
263 ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0, | |
595 | 264 "could not build the %s, you should " |
589 | 265 "increase %s_bucket_size: %i", |
266 hinit->name, hinit->name, hinit->bucket_size); | |
267 return NGX_ERROR; | |
268 } | |
269 } | |
270 | |
595 | 271 test = ngx_alloc(hinit->max_size * sizeof(u_short), hinit->pool->log); |
589 | 272 if (test == NULL) { |
273 return NGX_ERROR; | |
274 } | |
275 | |
631 | 276 bucket_size = hinit->bucket_size - sizeof(void *); |
277 | |
746 | 278 start = nelts / (bucket_size / (2 * sizeof(void *))); |
589 | 279 start = start ? start : 1; |
280 | |
4404
840f3e768ef8
Fixed division by zero exception in ngx_hash_init().
Valentin Bartenev <vbart@nginx.com>
parents:
3510
diff
changeset
|
281 if (hinit->max_size > 10000 && nelts && hinit->max_size / nelts < 100) { |
631 | 282 start = hinit->max_size - 1000; |
283 } | |
589 | 284 |
5636
54f847c88cf7
Core: fixed hash to actually try max_size.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5635
diff
changeset
|
285 for (size = start; size <= hinit->max_size; size++) { |
589 | 286 |
595 | 287 ngx_memzero(test, size * sizeof(u_short)); |
589 | 288 |
289 for (n = 0; n < nelts; n++) { | |
290 if (names[n].key.data == NULL) { | |
291 continue; | |
292 } | |
293 | |
294 key = names[n].key_hash % size; | |
595 | 295 test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); |
589 | 296 |
297 #if 0 | |
298 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
299 "%ui: %ui %ui \"%V\"", | |
300 size, key, test[key], &names[n].key); | |
301 #endif | |
302 | |
595 | 303 if (test[key] > (u_short) bucket_size) { |
589 | 304 goto next; |
305 } | |
306 } | |
307 | |
308 goto found; | |
309 | |
310 next: | |
311 | |
312 continue; | |
313 } | |
314 | |
5985
f961c719fb09
Core: fixed potential buffer overrun when initializing hash.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5870
diff
changeset
|
315 size = hinit->max_size; |
5870
5e72578e6503
Core: fixed buffer overrun when hash max_size reached.
Yichun Zhang <agentzh@gmail.com>
parents:
5636
diff
changeset
|
316 |
5635
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
317 ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0, |
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
318 "could not build optimal %s, you should increase " |
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
319 "either %s_max_size: %i or %s_bucket_size: %i; " |
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
320 "ignoring %s_bucket_size", |
589 | 321 hinit->name, hinit->name, hinit->max_size, |
5635
c348dea081fb
Core: hash now ignores bucket_size if it hits max_size limit.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4689
diff
changeset
|
322 hinit->name, hinit->bucket_size, hinit->name); |
589 | 323 |
324 found: | |
325 | |
326 for (i = 0; i < size; i++) { | |
327 test[i] = sizeof(void *); | |
328 } | |
329 | |
330 for (n = 0; n < nelts; n++) { | |
331 if (names[n].key.data == NULL) { | |
332 continue; | |
333 } | |
334 | |
335 key = names[n].key_hash % size; | |
595 | 336 test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); |
589 | 337 } |
338 | |
339 len = 0; | |
340 | |
341 for (i = 0; i < size; i++) { | |
342 if (test[i] == sizeof(void *)) { | |
343 continue; | |
344 } | |
345 | |
595 | 346 test[i] = (u_short) (ngx_align(test[i], ngx_cacheline_size)); |
589 | 347 |
348 len += test[i]; | |
349 } | |
350 | |
351 if (hinit->hash == NULL) { | |
352 hinit->hash = ngx_pcalloc(hinit->pool, sizeof(ngx_hash_wildcard_t) | |
353 + size * sizeof(ngx_hash_elt_t *)); | |
354 if (hinit->hash == NULL) { | |
355 ngx_free(test); | |
356 return NGX_ERROR; | |
357 } | |
358 | |
359 buckets = (ngx_hash_elt_t **) | |
360 ((u_char *) hinit->hash + sizeof(ngx_hash_wildcard_t)); | |
361 | |
362 } else { | |
363 buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *)); | |
364 if (buckets == NULL) { | |
365 ngx_free(test); | |
366 return NGX_ERROR; | |
367 } | |
368 } | |
369 | |
370 elts = ngx_palloc(hinit->pool, len + ngx_cacheline_size); | |
371 if (elts == NULL) { | |
372 ngx_free(test); | |
373 return NGX_ERROR; | |
374 } | |
375 | |
376 elts = ngx_align_ptr(elts, ngx_cacheline_size); | |
377 | |
378 for (i = 0; i < size; i++) { | |
379 if (test[i] == sizeof(void *)) { | |
380 continue; | |
381 } | |
382 | |
383 buckets[i] = (ngx_hash_elt_t *) elts; | |
384 elts += test[i]; | |
385 | |
386 } | |
387 | |
388 for (i = 0; i < size; i++) { | |
389 test[i] = 0; | |
390 } | |
391 | |
392 for (n = 0; n < nelts; n++) { | |
393 if (names[n].key.data == NULL) { | |
394 continue; | |
395 } | |
396 | |
397 key = names[n].key_hash % size; | |
398 elt = (ngx_hash_elt_t *) ((u_char *) buckets[key] + test[key]); | |
399 | |
400 elt->value = names[n].value; | |
3510
4c70bbdfd076
allow hash key values more than 255 bytes, it does not actually increase mean
Igor Sysoev <igor@sysoev.ru>
parents:
3118
diff
changeset
|
401 elt->len = (u_short) names[n].key.len; |
589 | 402 |
2135 | 403 ngx_strlow(elt->name, names[n].key.data, names[n].key.len); |
589 | 404 |
595 | 405 test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n])); |
589 | 406 } |
407 | |
408 for (i = 0; i < size; i++) { | |
409 if (buckets[i] == NULL) { | |
410 continue; | |
411 } | |
412 | |
413 elt = (ngx_hash_elt_t *) ((u_char *) buckets[i] + test[i]); | |
414 | |
415 elt->value = NULL; | |
416 } | |
417 | |
418 ngx_free(test); | |
419 | |
420 hinit->hash->buckets = buckets; | |
421 hinit->hash->size = size; | |
422 | |
423 #if 0 | |
424 | |
425 for (i = 0; i < size; i++) { | |
426 ngx_str_t val; | |
427 ngx_uint_t key; | |
428 | |
429 elt = buckets[i]; | |
430 | |
431 if (elt == NULL) { | |
432 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
433 "%ui: NULL", i); | |
434 continue; | |
435 } | |
436 | |
437 while (elt->value) { | |
438 val.len = elt->len; | |
439 val.data = &elt->name[0]; | |
440 | |
441 key = hinit->key(val.data, val.len); | |
442 | |
443 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
444 "%ui: %p \"%V\" %ui", i, elt, &val, key); | |
445 | |
446 elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len, | |
447 sizeof(void *)); | |
448 } | |
449 } | |
450 | |
451 #endif | |
452 | |
453 return NGX_OK; | |
454 } | |
455 | |
456 | |
457 ngx_int_t | |
458 ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, | |
459 ngx_uint_t nelts) | |
460 { | |
593 | 461 size_t len, dot_len; |
591 | 462 ngx_uint_t i, n, dot; |
589 | 463 ngx_array_t curr_names, next_names; |
464 ngx_hash_key_t *name, *next_name; | |
465 ngx_hash_init_t h; | |
466 ngx_hash_wildcard_t *wdc; | |
467 | |
468 if (ngx_array_init(&curr_names, hinit->temp_pool, nelts, | |
469 sizeof(ngx_hash_key_t)) | |
470 != NGX_OK) | |
471 { | |
472 return NGX_ERROR; | |
473 } | |
474 | |
475 if (ngx_array_init(&next_names, hinit->temp_pool, nelts, | |
476 sizeof(ngx_hash_key_t)) | |
477 != NGX_OK) | |
478 { | |
479 return NGX_ERROR; | |
480 } | |
481 | |
482 for (n = 0; n < nelts; n = i) { | |
483 | |
484 #if 0 | |
485 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
486 "wc0: \"%V\"", &names[n].key); | |
487 #endif | |
488 | |
591 | 489 dot = 0; |
490 | |
589 | 491 for (len = 0; len < names[n].key.len; len++) { |
492 if (names[n].key.data[len] == '.') { | |
591 | 493 dot = 1; |
589 | 494 break; |
495 } | |
496 } | |
497 | |
498 name = ngx_array_push(&curr_names); | |
499 if (name == NULL) { | |
500 return NGX_ERROR; | |
501 } | |
502 | |
591 | 503 name->key.len = len; |
589 | 504 name->key.data = names[n].key.data; |
505 name->key_hash = hinit->key(name->key.data, name->key.len); | |
506 name->value = names[n].value; | |
507 | |
508 #if 0 | |
509 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
593 | 510 "wc1: \"%V\" %ui", &name->key, dot); |
589 | 511 #endif |
512 | |
593 | 513 dot_len = len + 1; |
514 | |
591 | 515 if (dot) { |
516 len++; | |
517 } | |
518 | |
589 | 519 next_names.nelts = 0; |
520 | |
521 if (names[n].key.len != len) { | |
522 next_name = ngx_array_push(&next_names); | |
523 if (next_name == NULL) { | |
524 return NGX_ERROR; | |
525 } | |
526 | |
527 next_name->key.len = names[n].key.len - len; | |
528 next_name->key.data = names[n].key.data + len; | |
3118 | 529 next_name->key_hash = 0; |
589 | 530 next_name->value = names[n].value; |
531 | |
532 #if 0 | |
533 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
534 "wc2: \"%V\"", &next_name->key); | |
535 #endif | |
536 } | |
537 | |
538 for (i = n + 1; i < nelts; i++) { | |
539 if (ngx_strncmp(names[n].key.data, names[i].key.data, len) != 0) { | |
540 break; | |
541 } | |
542 | |
593 | 543 if (!dot |
544 && names[i].key.len > len | |
545 && names[i].key.data[len] != '.') | |
546 { | |
547 break; | |
548 } | |
549 | |
589 | 550 next_name = ngx_array_push(&next_names); |
551 if (next_name == NULL) { | |
552 return NGX_ERROR; | |
553 } | |
554 | |
593 | 555 next_name->key.len = names[i].key.len - dot_len; |
556 next_name->key.data = names[i].key.data + dot_len; | |
3118 | 557 next_name->key_hash = 0; |
589 | 558 next_name->value = names[i].value; |
559 | |
560 #if 0 | |
561 ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0, | |
591 | 562 "wc3: \"%V\"", &next_name->key); |
589 | 563 #endif |
564 } | |
565 | |
566 if (next_names.nelts) { | |
593 | 567 |
589 | 568 h = *hinit; |
569 h.hash = NULL; | |
570 | |
571 if (ngx_hash_wildcard_init(&h, (ngx_hash_key_t *) next_names.elts, | |
572 next_names.nelts) | |
573 != NGX_OK) | |
574 { | |
575 return NGX_ERROR; | |
576 } | |
577 | |
578 wdc = (ngx_hash_wildcard_t *) h.hash; | |
579 | |
580 if (names[n].key.len == len) { | |
581 wdc->value = names[n].value; | |
582 } | |
583 | |
2502
23706c19fab8
fix r2169 for .def.com and .abc.def.com case
Igor Sysoev <igor@sysoev.ru>
parents:
2195
diff
changeset
|
584 name->value = (void *) ((uintptr_t) wdc | (dot ? 3 : 2)); |
2168
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
585 |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
586 } else if (dot) { |
80924319ba05
fix the case when unset domain.tld was matched by *.domain.tld
Igor Sysoev <igor@sysoev.ru>
parents:
2155
diff
changeset
|
587 name->value = (void *) ((uintptr_t) name->value | 1); |
589 | 588 } |
589 } | |
590 | |
591 if (ngx_hash_init(hinit, (ngx_hash_key_t *) curr_names.elts, | |
592 curr_names.nelts) | |
593 != NGX_OK) | |
594 { | |
595 return NGX_ERROR; | |
596 } | |
597 | |
598 return NGX_OK; | |
599 } | |
600 | |
601 | |
602 ngx_uint_t | |
603 ngx_hash_key(u_char *data, size_t len) | |
604 { | |
605 ngx_uint_t i, key; | |
606 | |
607 key = 0; | |
608 | |
609 for (i = 0; i < len; i++) { | |
610 key = ngx_hash(key, data[i]); | |
611 } | |
612 | |
613 return key; | |
614 } | |
615 | |
616 | |
617 ngx_uint_t | |
618 ngx_hash_key_lc(u_char *data, size_t len) | |
619 { | |
620 ngx_uint_t i, key; | |
621 | |
622 key = 0; | |
623 | |
624 for (i = 0; i < len; i++) { | |
625 key = ngx_hash(key, ngx_tolower(data[i])); | |
626 } | |
627 | |
628 return key; | |
629 } | |
630 | |
631 | |
2136 | 632 ngx_uint_t |
633 ngx_hash_strlow(u_char *dst, u_char *src, size_t n) | |
634 { | |
635 ngx_uint_t key; | |
636 | |
637 key = 0; | |
638 | |
639 while (n--) { | |
640 *dst = ngx_tolower(*src); | |
641 key = ngx_hash(key, *dst); | |
642 dst++; | |
643 src++; | |
644 } | |
645 | |
646 return key; | |
647 } | |
648 | |
649 | |
589 | 650 ngx_int_t |
593 | 651 ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type) |
652 { | |
653 ngx_uint_t asize; | |
654 | |
655 if (type == NGX_HASH_SMALL) { | |
656 asize = 4; | |
657 ha->hsize = 107; | |
658 | |
659 } else { | |
660 asize = NGX_HASH_LARGE_ASIZE; | |
661 ha->hsize = NGX_HASH_LARGE_HSIZE; | |
662 } | |
663 | |
664 if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t)) | |
665 != NGX_OK) | |
666 { | |
667 return NGX_ERROR; | |
668 } | |
669 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
670 if (ngx_array_init(&ha->dns_wc_head, ha->temp_pool, asize, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
671 sizeof(ngx_hash_key_t)) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
672 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
673 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
674 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
675 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
676 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
677 if (ngx_array_init(&ha->dns_wc_tail, ha->temp_pool, asize, |
593 | 678 sizeof(ngx_hash_key_t)) |
679 != NGX_OK) | |
680 { | |
681 return NGX_ERROR; | |
682 } | |
683 | |
684 ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize); | |
685 if (ha->keys_hash == NULL) { | |
686 return NGX_ERROR; | |
687 } | |
688 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
689 ha->dns_wc_head_hash = ngx_pcalloc(ha->temp_pool, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
690 sizeof(ngx_array_t) * ha->hsize); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
691 if (ha->dns_wc_head_hash == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
692 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
693 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
694 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
695 ha->dns_wc_tail_hash = ngx_pcalloc(ha->temp_pool, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
696 sizeof(ngx_array_t) * ha->hsize); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
697 if (ha->dns_wc_tail_hash == NULL) { |
593 | 698 return NGX_ERROR; |
699 } | |
700 | |
701 return NGX_OK; | |
702 } | |
703 | |
704 | |
705 ngx_int_t | |
706 ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value, | |
707 ngx_uint_t flags) | |
708 { | |
709 size_t len; | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
710 u_char *p; |
593 | 711 ngx_str_t *name; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
712 ngx_uint_t i, k, n, skip, last; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
713 ngx_array_t *keys, *hwc; |
593 | 714 ngx_hash_key_t *hk; |
715 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
716 last = key->len; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
717 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
718 if (flags & NGX_HASH_WILDCARD_KEY) { |
593 | 719 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
720 /* |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
721 * supported wildcards: |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
722 * "*.example.com", ".example.com", and "www.example.*" |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
723 */ |
593 | 724 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
725 n = 0; |
593 | 726 |
727 for (i = 0; i < key->len; i++) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
728 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
729 if (key->data[i] == '*') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
730 if (++n > 1) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
731 return NGX_DECLINED; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
732 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
733 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
734 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
735 if (key->data[i] == '.' && key->data[i + 1] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
736 return NGX_DECLINED; |
597 | 737 } |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
738 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
739 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
740 if (key->len > 1 && key->data[0] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
741 skip = 1; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
742 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
743 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
744 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
745 if (key->len > 2) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
746 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
747 if (key->data[0] == '*' && key->data[1] == '.') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
748 skip = 2; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
749 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
750 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
751 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
752 if (key->data[i - 2] == '.' && key->data[i - 1] == '*') { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
753 skip = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
754 last -= 2; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
755 goto wildcard; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
756 } |
593 | 757 } |
758 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
759 if (n) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
760 return NGX_DECLINED; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
761 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
762 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
763 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
764 /* exact hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
765 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
766 k = 0; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
767 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
768 for (i = 0; i < last; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
769 if (!(flags & NGX_HASH_READONLY_KEY)) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
770 key->data[i] = ngx_tolower(key->data[i]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
771 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
772 k = ngx_hash(k, key->data[i]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
773 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
774 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
775 k %= ha->hsize; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
776 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
777 /* check conflicts in exact hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
778 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
779 name = ha->keys_hash[k].elts; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
780 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
781 if (name) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
782 for (i = 0; i < ha->keys_hash[k].nelts; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
783 if (last != name[i].len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
784 continue; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
785 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
786 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
787 if (ngx_strncmp(key->data, name[i].data, last) == 0) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
788 return NGX_BUSY; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
789 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
790 } |
593 | 791 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
792 } else { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
793 if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4, |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
794 sizeof(ngx_str_t)) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
795 != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
796 { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
797 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
798 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
799 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
800 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
801 name = ngx_array_push(&ha->keys_hash[k]); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
802 if (name == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
803 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
804 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
805 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
806 *name = *key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
807 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
808 hk = ngx_array_push(&ha->keys); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
809 if (hk == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
810 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
811 } |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
812 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
813 hk->key = *key; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
814 hk->key_hash = ngx_hash_key(key->data, last); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
815 hk->value = value; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
816 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
817 return NGX_OK; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
818 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
819 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
820 wildcard: |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
821 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
822 /* wildcard hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
823 |
2136 | 824 k = ngx_hash_strlow(&key->data[skip], &key->data[skip], last - skip); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
825 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
826 k %= ha->hsize; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
827 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
828 if (skip == 1) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
829 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
830 /* check conflicts in exact hash for ".example.com" */ |
593 | 831 |
832 name = ha->keys_hash[k].elts; | |
833 | |
834 if (name) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
835 len = last - skip; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
836 |
593 | 837 for (i = 0; i < ha->keys_hash[k].nelts; i++) { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
838 if (len != name[i].len) { |
593 | 839 continue; |
840 } | |
841 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
842 if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) { |
593 | 843 return NGX_BUSY; |
844 } | |
845 } | |
846 | |
847 } else { | |
848 if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4, | |
849 sizeof(ngx_str_t)) | |
850 != NGX_OK) | |
851 { | |
852 return NGX_ERROR; | |
853 } | |
854 } | |
855 | |
856 name = ngx_array_push(&ha->keys_hash[k]); | |
857 if (name == NULL) { | |
858 return NGX_ERROR; | |
859 } | |
860 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
861 name->len = last - 1; |
2049 | 862 name->data = ngx_pnalloc(ha->temp_pool, name->len); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
863 if (name->data == NULL) { |
593 | 864 return NGX_ERROR; |
865 } | |
866 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
867 ngx_memcpy(name->data, &key->data[1], name->len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
868 } |
593 | 869 |
870 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
871 if (skip) { |
593 | 872 |
873 /* | |
874 * convert "*.example.com" to "com.example.\0" | |
875 * and ".example.com" to "com.example\0" | |
876 */ | |
877 | |
2049 | 878 p = ngx_pnalloc(ha->temp_pool, last); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
879 if (p == NULL) { |
619 | 880 return NGX_ERROR; |
881 } | |
882 | |
593 | 883 len = 0; |
884 n = 0; | |
885 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
886 for (i = last - 1; i; i--) { |
593 | 887 if (key->data[i] == '.') { |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
888 ngx_memcpy(&p[n], &key->data[i + 1], len); |
593 | 889 n += len; |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
890 p[n++] = '.'; |
593 | 891 len = 0; |
892 continue; | |
893 } | |
894 | |
895 len++; | |
896 } | |
897 | |
898 if (len) { | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
899 ngx_memcpy(&p[n], &key->data[1], len); |
593 | 900 n += len; |
901 } | |
902 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
903 p[n] = '\0'; |
619 | 904 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
905 hwc = &ha->dns_wc_head; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
906 keys = &ha->dns_wc_head_hash[k]; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
907 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
908 } else { |
619 | 909 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
910 /* convert "www.example.*" to "www.example\0" */ |
619 | 911 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
912 last++; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
913 |
2049 | 914 p = ngx_pnalloc(ha->temp_pool, last); |
1415
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
915 if (p == NULL) { |
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
916 return NGX_ERROR; |
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
917 } |
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
918 |
1492 | 919 ngx_cpystrn(p, key->data, last); |
1415
d83687d29853
fix trailing wildcard when two or more listen used in one server
Igor Sysoev <igor@sysoev.ru>
parents:
1253
diff
changeset
|
920 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
921 hwc = &ha->dns_wc_tail; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
922 keys = &ha->dns_wc_tail_hash[k]; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
923 } |
593 | 924 |
925 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
926 /* check conflicts in wildcard hash */ |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
927 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
928 name = keys->elts; |
593 | 929 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
930 if (name) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
931 len = last - skip; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
932 |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
933 for (i = 0; i < keys->nelts; i++) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
934 if (len != name[i].len) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
935 continue; |
593 | 936 } |
937 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
938 if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
939 return NGX_BUSY; |
593 | 940 } |
941 } | |
942 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
943 } else { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
944 if (ngx_array_init(keys, ha->temp_pool, 4, sizeof(ngx_str_t)) != NGX_OK) |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
945 { |
593 | 946 return NGX_ERROR; |
947 } | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
948 } |
593 | 949 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
950 name = ngx_array_push(keys); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
951 if (name == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
952 return NGX_ERROR; |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
953 } |
619 | 954 |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
955 name->len = last - skip; |
2049 | 956 name->data = ngx_pnalloc(ha->temp_pool, name->len); |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
957 if (name->data == NULL) { |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
958 return NGX_ERROR; |
593 | 959 } |
960 | |
1253
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
961 ngx_memcpy(name->data, key->data + skip, name->len); |
8ef04207c84f
the "www.example.*" wildcard hash support
Igor Sysoev <igor@sysoev.ru>
parents:
746
diff
changeset
|
962 |
4689
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
963 |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
964 /* add to wildcard hash */ |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
965 |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
966 hk = ngx_array_push(hwc); |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
967 if (hk == NULL) { |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
968 return NGX_ERROR; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
969 } |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
970 |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
971 hk->key.len = last - 1; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
972 hk->key.data = p; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
973 hk->key_hash = 0; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
974 hk->value = value; |
d2ed9fee092b
Fixed handling of conflicting wildcard server names.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
975 |
593 | 976 return NGX_OK; |
977 } |