Mercurial > hg > nginx-mail
comparison src/mail/ngx_mail_core_module.c @ 570:9773720b845e
Merge with 0.8.16.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 26 Sep 2009 01:25:07 +0400 |
parents | 1e91f9968443 f39b9e29530d |
children |
comparison
equal
deleted
inserted
replaced
511:1e91f9968443 | 570:9773720b845e |
---|---|
118 { | 118 { |
119 ngx_mail_core_main_conf_t *cmcf; | 119 ngx_mail_core_main_conf_t *cmcf; |
120 | 120 |
121 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t)); | 121 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t)); |
122 if (cmcf == NULL) { | 122 if (cmcf == NULL) { |
123 return NGX_CONF_ERROR; | 123 return NULL; |
124 } | 124 } |
125 | 125 |
126 if (ngx_array_init(&cmcf->servers, cf->pool, 4, | 126 if (ngx_array_init(&cmcf->servers, cf->pool, 4, |
127 sizeof(ngx_mail_core_srv_conf_t *)) | 127 sizeof(ngx_mail_core_srv_conf_t *)) |
128 != NGX_OK) | 128 != NGX_OK) |
129 { | 129 { |
130 return NGX_CONF_ERROR; | 130 return NULL; |
131 } | 131 } |
132 | 132 |
133 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) | 133 if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) |
134 != NGX_OK) | 134 != NGX_OK) |
135 { | 135 { |
136 return NGX_CONF_ERROR; | 136 return NULL; |
137 } | 137 } |
138 | 138 |
139 return cmcf; | 139 return cmcf; |
140 } | 140 } |
141 | 141 |
272 | 272 |
273 return rv; | 273 return rv; |
274 } | 274 } |
275 | 275 |
276 | 276 |
277 /* AF_INET only */ | |
278 | |
279 static char * | 277 static char * |
280 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 278 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
281 { | 279 { |
282 ngx_mail_core_srv_conf_t *cscf = conf; | 280 ngx_mail_core_srv_conf_t *cscf = conf; |
283 | 281 |
282 size_t len, off; | |
283 in_port_t port; | |
284 ngx_str_t *value; | 284 ngx_str_t *value; |
285 ngx_url_t u; | 285 ngx_url_t u; |
286 ngx_uint_t i, m; | 286 ngx_uint_t i, m; |
287 ngx_mail_listen_t *imls; | 287 struct sockaddr *sa; |
288 ngx_mail_listen_t *ls; | |
288 ngx_mail_module_t *module; | 289 ngx_mail_module_t *module; |
290 struct sockaddr_in *sin; | |
289 ngx_mail_core_main_conf_t *cmcf; | 291 ngx_mail_core_main_conf_t *cmcf; |
292 #if (NGX_HAVE_INET6) | |
293 struct sockaddr_in6 *sin6; | |
294 #endif | |
290 | 295 |
291 value = cf->args->elts; | 296 value = cf->args->elts; |
292 | 297 |
293 ngx_memzero(&u, sizeof(ngx_url_t)); | 298 ngx_memzero(&u, sizeof(ngx_url_t)); |
294 | 299 |
303 } | 308 } |
304 | 309 |
305 return NGX_CONF_ERROR; | 310 return NGX_CONF_ERROR; |
306 } | 311 } |
307 | 312 |
308 if (u.family != AF_INET) { | |
309 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "listen supports IPv4 only"); | |
310 return NGX_CONF_ERROR; | |
311 } | |
312 | |
313 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); | 313 cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); |
314 | 314 |
315 imls = cmcf->listen.elts; | 315 ls = cmcf->listen.elts; |
316 | 316 |
317 for (i = 0; i < cmcf->listen.nelts; i++) { | 317 for (i = 0; i < cmcf->listen.nelts; i++) { |
318 | 318 |
319 if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { | 319 sa = (struct sockaddr *) ls[i].sockaddr; |
320 | |
321 if (sa->sa_family != u.family) { | |
322 continue; | |
323 } | |
324 | |
325 switch (sa->sa_family) { | |
326 | |
327 #if (NGX_HAVE_INET6) | |
328 case AF_INET6: | |
329 off = offsetof(struct sockaddr_in6, sin6_addr); | |
330 len = 16; | |
331 sin6 = (struct sockaddr_in6 *) sa; | |
332 port = sin6->sin6_port; | |
333 break; | |
334 #endif | |
335 | |
336 default: /* AF_INET */ | |
337 off = offsetof(struct sockaddr_in, sin_addr); | |
338 len = 4; | |
339 sin = (struct sockaddr_in *) sa; | |
340 port = sin->sin_port; | |
341 break; | |
342 } | |
343 | |
344 if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) { | |
345 continue; | |
346 } | |
347 | |
348 if (port != u.port) { | |
320 continue; | 349 continue; |
321 } | 350 } |
322 | 351 |
323 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 352 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
324 "duplicate \"%V\" address and port pair", &u.url); | 353 "duplicate \"%V\" address and port pair", &u.url); |
325 return NGX_CONF_ERROR; | 354 return NGX_CONF_ERROR; |
326 } | 355 } |
327 | 356 |
328 imls = ngx_array_push(&cmcf->listen); | 357 ls = ngx_array_push(&cmcf->listen); |
329 if (imls == NULL) { | 358 if (ls == NULL) { |
330 return NGX_CONF_ERROR; | 359 return NGX_CONF_ERROR; |
331 } | 360 } |
332 | 361 |
333 ngx_memzero(imls, sizeof(ngx_mail_listen_t)); | 362 ngx_memzero(ls, sizeof(ngx_mail_listen_t)); |
334 | 363 |
335 imls->addr = u.addr.in_addr; | 364 ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen); |
336 imls->port = u.port; | 365 |
337 imls->family = u.family; | 366 ls->socklen = u.socklen; |
338 imls->ctx = cf->ctx; | 367 ls->wildcard = u.wildcard; |
368 ls->ctx = cf->ctx; | |
339 | 369 |
340 for (m = 0; ngx_modules[m]; m++) { | 370 for (m = 0; ngx_modules[m]; m++) { |
341 if (ngx_modules[m]->type != NGX_MAIL_MODULE) { | 371 if (ngx_modules[m]->type != NGX_MAIL_MODULE) { |
342 continue; | 372 continue; |
343 } | 373 } |
357 } | 387 } |
358 | 388 |
359 for (i = 2; i < cf->args->nelts; i++) { | 389 for (i = 2; i < cf->args->nelts; i++) { |
360 | 390 |
361 if (ngx_strcmp(value[i].data, "bind") == 0) { | 391 if (ngx_strcmp(value[i].data, "bind") == 0) { |
362 imls->bind = 1; | 392 ls->bind = 1; |
363 continue; | 393 continue; |
394 } | |
395 | |
396 if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { | |
397 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) | |
398 struct sockaddr *sa; | |
399 u_char buf[NGX_SOCKADDR_STRLEN]; | |
400 | |
401 sa = (struct sockaddr *) ls->sockaddr; | |
402 | |
403 if (sa->sa_family == AF_INET6) { | |
404 | |
405 if (ngx_strcmp(&value[i].data[10], "n") == 0) { | |
406 ls->ipv6only = 1; | |
407 | |
408 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) { | |
409 ls->ipv6only = 2; | |
410 | |
411 } else { | |
412 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
413 "invalid ipv6only flags \"%s\"", | |
414 &value[i].data[9]); | |
415 return NGX_CONF_ERROR; | |
416 } | |
417 | |
418 ls->bind = 1; | |
419 | |
420 } else { | |
421 len = ngx_sock_ntop(sa, buf, NGX_SOCKADDR_STRLEN, 1); | |
422 | |
423 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
424 "ipv6only is not supported " | |
425 "on addr \"%*s\", ignored", len, buf); | |
426 } | |
427 | |
428 continue; | |
429 #else | |
430 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
431 "bind ipv6only is not supported " | |
432 "on this platform"); | |
433 return NGX_CONF_ERROR; | |
434 #endif | |
364 } | 435 } |
365 | 436 |
366 if (ngx_strcmp(value[i].data, "ssl") == 0) { | 437 if (ngx_strcmp(value[i].data, "ssl") == 0) { |
367 #if (NGX_MAIL_SSL) | 438 #if (NGX_MAIL_SSL) |
368 imls->ssl = 1; | 439 ls->ssl = 1; |
369 continue; | 440 continue; |
370 #else | 441 #else |
371 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 442 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
372 "the \"ssl\" parameter requires " | 443 "the \"ssl\" parameter requires " |
373 "ngx_mail_ssl_module"); | 444 "ngx_mail_ssl_module"); |