comparison src/imap/ngx_imap.c @ 641:5e8fb59c18c1 release-0.3.42

nginx-0.3.42-RELEASE import *) Feature: the "bind" option of the "listen" directive in IMAP/POP3 proxy. *) Bugfix: if the same capture in the "rewrite" directive was used more then once. *) Bugfix: the $sent_http_content_type, $sent_http_content_length, $sent_http_last_modified, $sent_http_connection, $sent_http_keep_alive, and $sent_http_transfer_encoding variables were not written to access log. *) Bugfix: the $sent_http_cache_control returned value of the single "Cache-Control" response header line.
author Igor Sysoev <igor@sysoev.ru>
date Wed, 26 Apr 2006 09:52:47 +0000
parents 4d9ea73a627a
children
comparison
equal deleted inserted replaced
640:5fd31c2fe4a8 641:5e8fb59c18c1
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 #include <ngx_imap.h> 10 #include <ngx_imap.h>
11 11
12 12
13 static char *ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); 13 static char *ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
14 static int ngx_libc_cdecl ngx_imap_cmp_conf_in_addrs(const void *one,
15 const void *two);
14 16
15 17
16 ngx_uint_t ngx_imap_max_module; 18 ngx_uint_t ngx_imap_max_module;
17 19
18 20
54 56
55 static char * 57 static char *
56 ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 58 ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
57 { 59 {
58 char *rv; 60 char *rv;
59 ngx_uint_t m, mi, s; 61 u_char *text;
62 size_t len;
63 ngx_uint_t i, a, l, m, mi, s, p, last, bind_all, done;
60 ngx_conf_t pcf; 64 ngx_conf_t pcf;
65 ngx_array_t in_ports;
66 ngx_listening_t *ls;
67 ngx_imap_listen_t *imls;
61 ngx_imap_module_t *module; 68 ngx_imap_module_t *module;
69 ngx_imap_in_port_t *imip;
62 ngx_imap_conf_ctx_t *ctx; 70 ngx_imap_conf_ctx_t *ctx;
71 ngx_imap_conf_in_port_t *in_port;
72 ngx_imap_conf_in_addr_t *in_addr;
63 ngx_imap_core_srv_conf_t **cscfp; 73 ngx_imap_core_srv_conf_t **cscfp;
64 ngx_imap_core_main_conf_t *cmcf; 74 ngx_imap_core_main_conf_t *cmcf;
65 75
66 /* the main imap context */ 76 /* the main imap context */
67 77
189 199
190 /* imap{}'s cf->ctx was needed while the configuration merging */ 200 /* imap{}'s cf->ctx was needed while the configuration merging */
191 201
192 *cf = pcf; 202 *cf = pcf;
193 203
204
205 if (ngx_array_init(&in_ports, cf->temp_pool, 4,
206 sizeof(ngx_imap_conf_in_port_t))
207 != NGX_OK)
208 {
209 return NGX_CONF_ERROR;
210 }
211
212 imls = cmcf->listen.elts;
213
214 for (l = 0; l < cmcf->listen.nelts; l++) {
215
216 /* AF_INET only */
217
218 in_port = in_ports.elts;
219 for (p = 0; p < in_ports.nelts; p++) {
220 if (in_port[p].port == imls[l].port) {
221 in_port = &in_port[p];
222 goto found;
223 }
224 }
225
226 in_port = ngx_array_push(&in_ports);
227 if (in_port == NULL) {
228 return NGX_CONF_ERROR;
229 }
230
231 in_port->port = imls[l].port;
232
233 if (ngx_array_init(&in_port->addrs, cf->temp_pool, 2,
234 sizeof(ngx_imap_conf_in_addr_t))
235 != NGX_OK)
236 {
237 return NGX_CONF_ERROR;
238 }
239
240 found:
241
242 in_addr = ngx_array_push(&in_port->addrs);
243 if (in_addr == NULL) {
244 return NGX_CONF_ERROR;
245 }
246
247 in_addr->addr = imls[l].addr;
248 in_addr->ctx = imls[l].ctx;
249 in_addr->bind = imls[l].bind;
250 }
251
252 /* optimize the lists of ports and addresses */
253
254 /* AF_INET only */
255
256 in_port = in_ports.elts;
257 for (p = 0; p < in_ports.nelts; p++) {
258
259 ngx_qsort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts,
260 sizeof(ngx_imap_conf_in_addr_t), ngx_imap_cmp_conf_in_addrs);
261
262 in_addr = in_port[p].addrs.elts;
263 last = in_port[p].addrs.nelts;
264
265 /*
266 * if there is the binding to the "*:port" then we need to bind()
267 * to the "*:port" only and ignore the other bindings
268 */
269
270 if (in_addr[last - 1].addr == INADDR_ANY) {
271 in_addr[last - 1].bind = 1;
272 bind_all = 0;
273
274 } else {
275 bind_all = 1;
276 }
277
278 for (a = 0; a < last; /* void */ ) {
279
280 if (!bind_all && !in_addr[a].bind) {
281 a++;
282 continue;
283 }
284
285 ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr,
286 in_port[p].port);
287 if (ls == NULL) {
288 return NGX_CONF_ERROR;
289 }
290
291 ls->backlog = -1;
292 ls->rcvbuf = -1;
293 ls->sndbuf = -1;
294
295 ls->addr_ntop = 1;
296 ls->handler = ngx_imap_init_connection;
297 ls->pool_size = 256;
298
299 /* STUB */
300 ls->log = *cf->cycle->new_log;
301 ls->log.data = &ls->addr_text;
302 ls->log.handler = ngx_accept_log_error;
303 /**/
304
305 imip = ngx_palloc(cf->pool, sizeof(ngx_imap_in_port_t));
306 if (imip == NULL) {
307 return NGX_CONF_ERROR;
308 }
309
310 ls->servers = imip;
311
312 in_addr = in_port[p].addrs.elts;
313
314 if (in_addr[a].bind && in_addr[a].addr != INADDR_ANY) {
315 imip->naddrs = 1;
316 done = 0;
317
318 } else if (in_port[p].addrs.nelts > 1
319 && in_addr[last - 1].addr == INADDR_ANY)
320 {
321 imip->naddrs = last;
322 done = 1;
323
324 } else {
325 imip->naddrs = 1;
326 done = 0;
327 }
328
329 #if 0
330 ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
331 "%ui: %V %d %ui %ui",
332 a, &ls->addr_text, in_addr[a].bind,
333 imip->naddrs, last);
334 #endif
335
336 imip->addrs = ngx_pcalloc(cf->pool,
337 imip->naddrs * sizeof(ngx_imap_in_addr_t));
338 if (imip->addrs == NULL) {
339 return NGX_CONF_ERROR;
340 }
341
342 for (i = 0; i < imip->naddrs; i++) {
343 imip->addrs[i].addr = in_addr[i].addr;
344 imip->addrs[i].ctx = in_addr[i].ctx;
345
346 text = ngx_palloc(cf->pool,
347 INET_ADDRSTRLEN - 1 + sizeof(":65535") - 1);
348 if (text == NULL) {
349 return NGX_CONF_ERROR;
350 }
351
352 len = ngx_inet_ntop(AF_INET, &in_addr[i].addr, text,
353 INET_ADDRSTRLEN);
354
355 len = ngx_sprintf(text + len, ":%d", in_port[p].port) - text;
356
357 imip->addrs[i].addr_text.len = len;
358 imip->addrs[i].addr_text.data = text;
359 }
360
361 if (done) {
362 break;
363 }
364
365 in_addr++;
366 in_port[p].addrs.elts = in_addr;
367 last--;
368
369 a = 0;
370 }
371 }
372
194 return NGX_CONF_OK; 373 return NGX_CONF_OK;
195 } 374 }
375
376
377 static int ngx_libc_cdecl
378 ngx_imap_cmp_conf_in_addrs(const void *one, const void *two)
379 {
380 ngx_imap_conf_in_addr_t *first, *second;
381
382 first = (ngx_imap_conf_in_addr_t *) one;
383 second = (ngx_imap_conf_in_addr_t *) two;
384
385 if (first->addr == INADDR_ANY) {
386 /* the INADDR_ANY must be the last resort, shift it to the end */
387 return 1;
388 }
389
390 if (first->bind && !second->bind) {
391 /* shift explicit bind()ed addresses to the start */
392 return -1;
393 }
394
395 if (!first->bind && second->bind) {
396 /* shift explicit bind()ed addresses to the start */
397 return 1;
398 }
399
400 /* do not sort by default */
401
402 return 0;
403 }