Mercurial > hg > nginx-quic
annotate src/core/ngx_module.c @ 8456:c72d8839f427
Mail: fixed SMTP pipelining to send the response immediately.
Previously, if there were some pipelined SMTP data in the buffer when
a proxied connection with the backend was established, nginx called
ngx_mail_proxy_handler() to send these data, and not tried to send the
response to the last command. In most cases, this response was later sent
along with the response to the pipelined command, but if for some reason
client decides to wait for the response before finishing the next command
this might result in a connection hang.
Fix is to always call ngx_mail_proxy_handler() to send the response, and
additionally post an event to send the pipelined data if needed.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 19 May 2021 03:13:12 +0300 |
parents | 3600bbfb43e3 |
children |
rev | line source |
---|---|
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
1 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
2 /* |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
4 * Copyright (C) Maxim Dounin |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
5 * Copyright (C) Nginx, Inc. |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
6 */ |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
7 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
8 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
9 #include <ngx_config.h> |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
10 #include <ngx_core.h> |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
11 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
12 |
6383 | 13 #define NGX_MAX_DYNAMIC_MODULES 128 |
14 | |
15 | |
16 static ngx_uint_t ngx_module_index(ngx_cycle_t *cycle); | |
17 static ngx_uint_t ngx_module_ctx_index(ngx_cycle_t *cycle, ngx_uint_t type, | |
18 ngx_uint_t index); | |
19 | |
20 | |
21 ngx_uint_t ngx_max_module; | |
22 static ngx_uint_t ngx_modules_n; | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
23 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
24 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
25 ngx_int_t |
6429
3600bbfb43e3
Fixed compilation with -Wmissing-prototypes.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6417
diff
changeset
|
26 ngx_preinit_modules(void) |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
27 { |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
28 ngx_uint_t i; |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
29 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
30 for (i = 0; ngx_modules[i]; i++) { |
6383 | 31 ngx_modules[i]->index = i; |
32 ngx_modules[i]->name = ngx_module_names[i]; | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
33 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
34 |
6383 | 35 ngx_modules_n = i; |
36 ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES; | |
37 | |
38 return NGX_OK; | |
39 } | |
40 | |
41 | |
42 ngx_int_t | |
43 ngx_cycle_modules(ngx_cycle_t *cycle) | |
44 { | |
45 /* | |
46 * create a list of modules to be used for this cycle, | |
47 * copy static modules to it | |
48 */ | |
49 | |
50 cycle->modules = ngx_pcalloc(cycle->pool, (ngx_max_module + 1) | |
51 * sizeof(ngx_module_t *)); | |
52 if (cycle->modules == NULL) { | |
53 return NGX_ERROR; | |
54 } | |
55 | |
56 ngx_memcpy(cycle->modules, ngx_modules, | |
57 ngx_modules_n * sizeof(ngx_module_t *)); | |
58 | |
59 cycle->modules_n = ngx_modules_n; | |
60 | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
61 return NGX_OK; |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
62 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
63 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
64 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
65 ngx_int_t |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
66 ngx_init_modules(ngx_cycle_t *cycle) |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
67 { |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
68 ngx_uint_t i; |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
69 |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
70 for (i = 0; cycle->modules[i]; i++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
71 if (cycle->modules[i]->init_module) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
72 if (cycle->modules[i]->init_module(cycle) != NGX_OK) { |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
73 return NGX_ERROR; |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
74 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
75 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
76 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
77 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
78 return NGX_OK; |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
79 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
80 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
81 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
82 ngx_int_t |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
83 ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type) |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
84 { |
6383 | 85 ngx_uint_t i, next, max; |
86 ngx_module_t *module; | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
87 |
6383 | 88 next = 0; |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
89 max = 0; |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
90 |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
91 /* count appropriate modules, set up their indices */ |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
92 |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6378
diff
changeset
|
93 for (i = 0; cycle->modules[i]; i++) { |
6383 | 94 module = cycle->modules[i]; |
95 | |
96 if (module->type != type) { | |
97 continue; | |
98 } | |
99 | |
100 if (module->ctx_index != NGX_MODULE_UNSET_INDEX) { | |
101 | |
102 /* if ctx_index was assigned, preserve it */ | |
103 | |
104 if (module->ctx_index > max) { | |
105 max = module->ctx_index; | |
106 } | |
107 | |
108 if (module->ctx_index == next) { | |
109 next++; | |
110 } | |
111 | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
112 continue; |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
113 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
114 |
6383 | 115 /* search for some free index */ |
116 | |
117 module->ctx_index = ngx_module_ctx_index(cycle, type, next); | |
118 | |
119 if (module->ctx_index > max) { | |
120 max = module->ctx_index; | |
121 } | |
122 | |
123 next = module->ctx_index + 1; | |
124 } | |
125 | |
126 /* | |
127 * make sure the number returned is big enough for previous | |
128 * cycle as well, else there will be problems if the number | |
129 * will be stored in a global variable (as it's used to be) | |
130 * and we'll have to roll back to the previous cycle | |
131 */ | |
132 | |
133 if (cycle->old_cycle && cycle->old_cycle->modules) { | |
134 | |
135 for (i = 0; cycle->old_cycle->modules[i]; i++) { | |
136 module = cycle->old_cycle->modules[i]; | |
137 | |
138 if (module->type != type) { | |
139 continue; | |
140 } | |
141 | |
142 if (module->ctx_index > max) { | |
143 max = module->ctx_index; | |
144 } | |
145 } | |
146 } | |
147 | |
148 /* prevent loading of additional modules */ | |
149 | |
150 cycle->modules_used = 1; | |
151 | |
152 return max + 1; | |
153 } | |
154 | |
155 | |
156 ngx_int_t | |
157 ngx_add_module(ngx_conf_t *cf, ngx_str_t *file, ngx_module_t *module, | |
158 char **order) | |
159 { | |
160 void *rv; | |
161 ngx_uint_t i, m, before; | |
162 ngx_core_module_t *core_module; | |
163 | |
164 if (cf->cycle->modules_n >= ngx_max_module) { | |
165 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
166 "too many modules loaded"); | |
167 return NGX_ERROR; | |
168 } | |
169 | |
170 if (module->version != nginx_version) { | |
171 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
172 "module \"%V\" version %ui instead of %ui", | |
6394
5fe617f38222
Dynamic modules: fixed a version mismatch message (ticket #898).
Ruslan Ermilov <ru@nginx.com>
parents:
6383
diff
changeset
|
173 file, module->version, (ngx_uint_t) nginx_version); |
6383 | 174 return NGX_ERROR; |
175 } | |
176 | |
177 if (ngx_strcmp(module->signature, NGX_MODULE_SIGNATURE) != 0) { | |
178 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
179 "module \"%V\" is not binary compatible", | |
180 file); | |
181 return NGX_ERROR; | |
182 } | |
183 | |
184 for (m = 0; cf->cycle->modules[m]; m++) { | |
185 if (ngx_strcmp(cf->cycle->modules[m]->name, module->name) == 0) { | |
186 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
187 "module \"%s\" is already loaded", | |
188 module->name); | |
189 return NGX_ERROR; | |
190 } | |
191 } | |
192 | |
193 /* | |
194 * if the module wasn't previously loaded, assign an index | |
195 */ | |
196 | |
197 if (module->index == NGX_MODULE_UNSET_INDEX) { | |
198 module->index = ngx_module_index(cf->cycle); | |
199 | |
200 if (module->index >= ngx_max_module) { | |
201 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
202 "too many modules loaded"); | |
203 return NGX_ERROR; | |
204 } | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
205 } |
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
206 |
6383 | 207 /* |
208 * put the module into the cycle->modules array | |
209 */ | |
210 | |
211 before = cf->cycle->modules_n; | |
212 | |
213 if (order) { | |
214 for (i = 0; order[i]; i++) { | |
215 if (ngx_strcmp(order[i], module->name) == 0) { | |
216 i++; | |
217 break; | |
218 } | |
219 } | |
220 | |
221 for ( /* void */ ; order[i]; i++) { | |
222 | |
223 #if 0 | |
224 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0, | |
225 "module: %s before %s", | |
226 module->name, order[i]); | |
227 #endif | |
228 | |
229 for (m = 0; m < before; m++) { | |
230 if (ngx_strcmp(cf->cycle->modules[m]->name, order[i]) == 0) { | |
231 | |
232 ngx_log_debug3(NGX_LOG_DEBUG_CORE, cf->log, 0, | |
233 "module: %s before %s:%i", | |
234 module->name, order[i], m); | |
235 | |
236 before = m; | |
237 break; | |
238 } | |
239 } | |
240 } | |
241 } | |
242 | |
243 /* put the module before modules[before] */ | |
244 | |
245 if (before != cf->cycle->modules_n) { | |
246 ngx_memmove(&cf->cycle->modules[before + 1], | |
247 &cf->cycle->modules[before], | |
248 (cf->cycle->modules_n - before) * sizeof(ngx_module_t *)); | |
249 } | |
250 | |
251 cf->cycle->modules[before] = module; | |
252 cf->cycle->modules_n++; | |
253 | |
254 if (module->type == NGX_CORE_MODULE) { | |
255 | |
256 /* | |
257 * we are smart enough to initialize core modules; | |
258 * other modules are expected to be loaded before | |
259 * initialization - e.g., http modules must be loaded | |
260 * before http{} block | |
261 */ | |
262 | |
263 core_module = module->ctx; | |
264 | |
265 if (core_module->create_conf) { | |
266 rv = core_module->create_conf(cf->cycle); | |
267 if (rv == NULL) { | |
268 return NGX_ERROR; | |
269 } | |
270 | |
271 cf->cycle->conf_ctx[module->index] = rv; | |
272 } | |
273 } | |
274 | |
275 return NGX_OK; | |
6378
0f203a2af17c
Dynamic modules: moved module-related stuff to separate files.
Maxim Dounin <mdounin@mdounin.ru>
parents:
diff
changeset
|
276 } |
6383 | 277 |
278 | |
279 static ngx_uint_t | |
280 ngx_module_index(ngx_cycle_t *cycle) | |
281 { | |
282 ngx_uint_t i, index; | |
283 ngx_module_t *module; | |
284 | |
285 index = 0; | |
286 | |
287 again: | |
288 | |
289 /* find an unused index */ | |
290 | |
291 for (i = 0; cycle->modules[i]; i++) { | |
292 module = cycle->modules[i]; | |
293 | |
294 if (module->index == index) { | |
295 index++; | |
296 goto again; | |
297 } | |
298 } | |
299 | |
300 /* check previous cycle */ | |
301 | |
302 if (cycle->old_cycle && cycle->old_cycle->modules) { | |
303 | |
304 for (i = 0; cycle->old_cycle->modules[i]; i++) { | |
305 module = cycle->old_cycle->modules[i]; | |
306 | |
307 if (module->index == index) { | |
308 index++; | |
309 goto again; | |
310 } | |
311 } | |
312 } | |
313 | |
314 return index; | |
315 } | |
316 | |
317 | |
318 static ngx_uint_t | |
319 ngx_module_ctx_index(ngx_cycle_t *cycle, ngx_uint_t type, ngx_uint_t index) | |
320 { | |
321 ngx_uint_t i; | |
322 ngx_module_t *module; | |
323 | |
324 again: | |
325 | |
326 /* find an unused ctx_index */ | |
327 | |
328 for (i = 0; cycle->modules[i]; i++) { | |
329 module = cycle->modules[i]; | |
330 | |
331 if (module->type != type) { | |
332 continue; | |
333 } | |
334 | |
335 if (module->ctx_index == index) { | |
336 index++; | |
337 goto again; | |
338 } | |
339 } | |
340 | |
341 /* check previous cycle */ | |
342 | |
343 if (cycle->old_cycle && cycle->old_cycle->modules) { | |
344 | |
345 for (i = 0; cycle->old_cycle->modules[i]; i++) { | |
346 module = cycle->old_cycle->modules[i]; | |
347 | |
348 if (module->type != type) { | |
349 continue; | |
350 } | |
351 | |
352 if (module->ctx_index == index) { | |
353 index++; | |
354 goto again; | |
355 } | |
356 } | |
357 } | |
358 | |
359 return index; | |
360 } |