mirror of
https://github.com/nginx/nginx.git
synced 2025-06-13 06:12:44 +08:00
Merged with the default branch.
This commit is contained in:
commit
02b52e4c0b
1
.hgtags
1
.hgtags
@ -457,3 +457,4 @@ dc0cc425fa63a80315f6efb68697cadb6626cdf2 release-1.19.4
|
||||
8e5b068f761cd512d10c9671fbde0b568c1fd08b release-1.19.5
|
||||
f618488eb769e0ed74ef0d93cd118d2ad79ef94d release-1.19.6
|
||||
3fa6e2095a7a51acc630517e1c27a7b7ac41f7b3 release-1.19.7
|
||||
8c65d21464aaa5923775f80c32474adc7a320068 release-1.19.8
|
||||
|
@ -48,4 +48,6 @@ default: build
|
||||
|
||||
clean:
|
||||
rm -rf Makefile $NGX_OBJS
|
||||
|
||||
.PHONY: default clean
|
||||
END
|
||||
|
@ -215,4 +215,6 @@ upgrade:
|
||||
test -f $NGX_PID_PATH.oldbin
|
||||
|
||||
kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
|
||||
|
||||
.PHONY: build install modules upgrade
|
||||
END
|
||||
|
@ -1037,6 +1037,12 @@ if [ $MAIL != NO ]; then
|
||||
ngx_module_srcs=src/mail/ngx_mail_proxy_module.c
|
||||
|
||||
. auto/module
|
||||
|
||||
ngx_module_name=ngx_mail_realip_module
|
||||
ngx_module_deps=
|
||||
ngx_module_srcs=src/mail/ngx_mail_realip_module.c
|
||||
|
||||
. auto/module
|
||||
fi
|
||||
|
||||
|
||||
|
56
auto/unix
56
auto/unix
@ -727,17 +727,33 @@ ngx_feature_test="char buf[1]; struct iovec vec[1]; ssize_t n;
|
||||
. auto/feature
|
||||
|
||||
|
||||
ngx_feature="sys_nerr"
|
||||
ngx_feature_name="NGX_SYS_NERR"
|
||||
ngx_feature_run=value
|
||||
ngx_feature_incs='#include <errno.h>
|
||||
#include <stdio.h>'
|
||||
# strerrordesc_np(), introduced in glibc 2.32
|
||||
|
||||
ngx_feature="strerrordesc_np()"
|
||||
ngx_feature_name="NGX_HAVE_STRERRORDESC_NP"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs='#include <string.h>'
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test='printf("%d", sys_nerr);'
|
||||
ngx_feature_test="char *p; p = strerrordesc_np(0);
|
||||
if (p == NULL) return 1"
|
||||
. auto/feature
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
ngx_feature="sys_nerr"
|
||||
ngx_feature_name="NGX_SYS_NERR"
|
||||
ngx_feature_run=value
|
||||
ngx_feature_incs='#include <errno.h>
|
||||
#include <stdio.h>'
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test='printf("%d", sys_nerr);'
|
||||
. auto/feature
|
||||
fi
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
# Cygiwn defines _sys_nerr
|
||||
@ -753,34 +769,6 @@ if [ $ngx_found = no ]; then
|
||||
fi
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
# Solaris has no sys_nerr
|
||||
ngx_feature='maximum errno'
|
||||
ngx_feature_name=NGX_SYS_NERR
|
||||
ngx_feature_run=value
|
||||
ngx_feature_incs='#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>'
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test='int n;
|
||||
char *p;
|
||||
for (n = 1; n < 1000; n++) {
|
||||
errno = 0;
|
||||
p = strerror(n);
|
||||
if (errno == EINVAL
|
||||
|| p == NULL
|
||||
|| strncmp(p, "Unknown error", 13) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("%d", n);'
|
||||
. auto/feature
|
||||
fi
|
||||
|
||||
|
||||
ngx_feature="localtime_r()"
|
||||
ngx_feature_name="NGX_HAVE_LOCALTIME_R"
|
||||
ngx_feature_run=no
|
||||
|
@ -2414,26 +2414,26 @@ syn keyword ngxDirectiveThirdParty contained ip2proxy_usage_type
|
||||
|
||||
" highlight
|
||||
|
||||
hi link ngxComment Comment
|
||||
hi link ngxParamComment Comment
|
||||
hi link ngxListenComment Comment
|
||||
hi link ngxVariable Identifier
|
||||
hi link ngxVariableString PreProc
|
||||
hi link ngxString String
|
||||
hi link ngxListenString String
|
||||
hi def link ngxComment Comment
|
||||
hi def link ngxParamComment Comment
|
||||
hi def link ngxListenComment Comment
|
||||
hi def link ngxVariable Identifier
|
||||
hi def link ngxVariableString PreProc
|
||||
hi def link ngxString String
|
||||
hi def link ngxListenString String
|
||||
|
||||
hi link ngxBoolean Boolean
|
||||
hi link ngxDirectiveBlock Statement
|
||||
hi link ngxDirectiveImportant Type
|
||||
hi link ngxDirectiveListen Type
|
||||
hi link ngxDirectiveControl Keyword
|
||||
hi link ngxDirectiveError Constant
|
||||
hi link ngxDirectiveDeprecated Error
|
||||
hi link ngxDirective Identifier
|
||||
hi link ngxDirectiveThirdParty Special
|
||||
hi link ngxDirectiveThirdPartyDeprecated Error
|
||||
hi def link ngxBoolean Boolean
|
||||
hi def link ngxDirectiveBlock Statement
|
||||
hi def link ngxDirectiveImportant Type
|
||||
hi def link ngxDirectiveListen Type
|
||||
hi def link ngxDirectiveControl Keyword
|
||||
hi def link ngxDirectiveError Constant
|
||||
hi def link ngxDirectiveDeprecated Error
|
||||
hi def link ngxDirective Identifier
|
||||
hi def link ngxDirectiveThirdParty Special
|
||||
hi def link ngxDirectiveThirdPartyDeprecated Error
|
||||
|
||||
hi link ngxListenOptions Keyword
|
||||
hi link ngxListenOptionsDeprecated Error
|
||||
hi def link ngxListenOptions Keyword
|
||||
hi def link ngxListenOptionsDeprecated Error
|
||||
|
||||
let b:current_syntax = "nginx"
|
||||
|
@ -5,6 +5,68 @@
|
||||
<change_log title="nginx">
|
||||
|
||||
|
||||
<changes ver="1.19.8" date="2021-03-09">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
в директиве proxy_cookie_flags теперь
|
||||
флаги можно задавать с помощью переменных.
|
||||
</para>
|
||||
<para lang="en">
|
||||
flags in the "proxy_cookie_flags" directive
|
||||
can now contain variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
параметр proxy_protocol в директиве listen,
|
||||
директивы proxy_protocol и set_real_ip_from
|
||||
в почтовом прокси-сервере.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_protocol" parameter of the "listen" directive,
|
||||
the "proxy_protocol" and "set_real_ip_from" directives
|
||||
in mail proxy.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
HTTP/2-соединения сразу закрывались
|
||||
при использовании "keepalive_timeout 0";
|
||||
ошибка появилась в 1.19.7.
|
||||
</para>
|
||||
<para lang="en">
|
||||
HTTP/2 connections were immediately closed
|
||||
when using "keepalive_timeout 0";
|
||||
the bug had appeared in 1.19.7.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
некоторые ошибки логгировались как неизвестные,
|
||||
если nginx был собран с glibc 2.32.
|
||||
</para>
|
||||
<para lang="en">
|
||||
some errors were logged as unknown
|
||||
if nginx was built with glibc 2.32.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
в методе обработки соединений eventport.
|
||||
</para>
|
||||
<para lang="en">
|
||||
in the eventport method.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.19.7" date="2021-02-16">
|
||||
|
||||
<change type="change">
|
||||
|
@ -6,7 +6,7 @@ TEMP = tmp
|
||||
|
||||
CC = cl
|
||||
OBJS = objs.msvc8
|
||||
OPENSSL = openssl-1.1.1i
|
||||
OPENSSL = openssl-1.1.1j
|
||||
ZLIB = zlib-1.2.11
|
||||
PCRE = pcre-8.44
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1019007
|
||||
#define NGINX_VERSION "1.19.7"
|
||||
#define nginx_version 1019008
|
||||
#define NGINX_VERSION "1.19.8"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
|
@ -338,7 +338,7 @@ ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rev->oneshot && !rev->ready) {
|
||||
if (rev->oneshot && rev->ready) {
|
||||
if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ static time_t ngx_ssl_parse_time(
|
||||
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||
const
|
||||
#endif
|
||||
ASN1_TIME *asn1time);
|
||||
ASN1_TIME *asn1time, ngx_log_t *log);
|
||||
|
||||
static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
|
||||
static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
@ -1014,26 +1014,52 @@ ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
|
||||
|
||||
c = ngx_ssl_get_connection(ssl_conn);
|
||||
|
||||
if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
cert = X509_STORE_CTX_get_current_cert(x509_store);
|
||||
err = X509_STORE_CTX_get_error(x509_store);
|
||||
depth = X509_STORE_CTX_get_error_depth(x509_store);
|
||||
|
||||
sname = X509_get_subject_name(cert);
|
||||
subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)";
|
||||
|
||||
if (sname) {
|
||||
subject = X509_NAME_oneline(sname, NULL, 0);
|
||||
if (subject == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
||||
"X509_NAME_oneline() failed");
|
||||
}
|
||||
|
||||
} else {
|
||||
subject = NULL;
|
||||
}
|
||||
|
||||
iname = X509_get_issuer_name(cert);
|
||||
issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)";
|
||||
|
||||
if (iname) {
|
||||
issuer = X509_NAME_oneline(iname, NULL, 0);
|
||||
if (issuer == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0,
|
||||
"X509_NAME_oneline() failed");
|
||||
}
|
||||
|
||||
} else {
|
||||
issuer = NULL;
|
||||
}
|
||||
|
||||
ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"verify:%d, error:%d, depth:%d, "
|
||||
"subject:\"%s\", issuer:\"%s\"",
|
||||
ok, err, depth, subject, issuer);
|
||||
ok, err, depth,
|
||||
subject ? subject : "(none)",
|
||||
issuer ? issuer : "(none)");
|
||||
|
||||
if (sname) {
|
||||
if (subject) {
|
||||
OPENSSL_free(subject);
|
||||
}
|
||||
|
||||
if (iname) {
|
||||
if (issuer) {
|
||||
OPENSSL_free(issuer);
|
||||
}
|
||||
#endif
|
||||
@ -1948,6 +1974,10 @@ ngx_ssl_handshake_log(ngx_connection_t *c)
|
||||
#endif
|
||||
SSL_CIPHER *cipher;
|
||||
|
||||
if (!(c->log->log_level & NGX_LOG_DEBUG_EVENT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
cipher = SSL_get_current_cipher(c->ssl->connection);
|
||||
|
||||
if (cipher) {
|
||||
@ -4802,11 +4832,13 @@ ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@ -4854,11 +4886,13 @@ ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_print_ex() failed");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@ -4907,6 +4941,11 @@ ngx_ssl_get_subject_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
|
||||
}
|
||||
|
||||
p = X509_NAME_oneline(name, NULL, 0);
|
||||
if (p == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (len = 0; p[len]; len++) { /* void */ }
|
||||
|
||||
@ -4950,6 +4989,11 @@ ngx_ssl_get_issuer_dn_legacy(ngx_connection_t *c, ngx_pool_t *pool,
|
||||
}
|
||||
|
||||
p = X509_NAME_oneline(name, NULL, 0);
|
||||
if (p == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_NAME_oneline() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (len = 0; p[len]; len++) { /* void */ }
|
||||
|
||||
@ -4986,6 +5030,7 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -5024,6 +5069,7 @@ ngx_ssl_get_fingerprint(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||
}
|
||||
|
||||
if (!X509_digest(cert, EVP_sha1(), buf, &len)) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "X509_digest() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -5097,6 +5143,7 @@ ngx_ssl_get_client_v_start(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -5141,6 +5188,7 @@ ngx_ssl_get_client_v_end(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
|
||||
X509_free(cert);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -5183,9 +5231,9 @@ ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||
end = ngx_ssl_parse_time(X509_get0_notAfter(cert));
|
||||
end = ngx_ssl_parse_time(X509_get0_notAfter(cert), c->log);
|
||||
#else
|
||||
end = ngx_ssl_parse_time(X509_get_notAfter(cert));
|
||||
end = ngx_ssl_parse_time(X509_get_notAfter(cert), c->log);
|
||||
#endif
|
||||
|
||||
if (end == (time_t) NGX_ERROR) {
|
||||
@ -5220,7 +5268,7 @@ ngx_ssl_parse_time(
|
||||
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||
const
|
||||
#endif
|
||||
ASN1_TIME *asn1time)
|
||||
ASN1_TIME *asn1time, ngx_log_t *log)
|
||||
{
|
||||
BIO *bio;
|
||||
char *value;
|
||||
@ -5236,6 +5284,7 @@ ngx_ssl_parse_time(
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "BIO_new() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
@ -4841,9 +4841,9 @@ ngx_http_grpc_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ typedef struct {
|
||||
#endif
|
||||
} cookie;
|
||||
|
||||
ngx_uint_t flags;
|
||||
ngx_array_t flags_values;
|
||||
ngx_uint_t regex;
|
||||
} ngx_http_proxy_cookie_flags_t;
|
||||
|
||||
@ -2916,12 +2916,14 @@ static ngx_int_t
|
||||
ngx_http_proxy_rewrite_cookie_flags(ngx_http_request_t *r, ngx_array_t *attrs,
|
||||
ngx_array_t *flags)
|
||||
{
|
||||
ngx_str_t pattern;
|
||||
ngx_str_t pattern, value;
|
||||
#if (NGX_PCRE)
|
||||
ngx_int_t rc;
|
||||
#endif
|
||||
ngx_uint_t i;
|
||||
ngx_uint_t i, m, f, nelts;
|
||||
ngx_keyval_t *attr;
|
||||
ngx_conf_bitmask_t *mask;
|
||||
ngx_http_complex_value_t *flags_values;
|
||||
ngx_http_proxy_cookie_flags_t *pcf;
|
||||
|
||||
attr = attrs->elts;
|
||||
@ -2965,7 +2967,47 @@ ngx_http_proxy_rewrite_cookie_flags(ngx_http_request_t *r, ngx_array_t *attrs,
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
return ngx_http_proxy_edit_cookie_flags(r, attrs, pcf[i].flags);
|
||||
nelts = pcf[i].flags_values.nelts;
|
||||
flags_values = pcf[i].flags_values.elts;
|
||||
|
||||
mask = ngx_http_proxy_cookie_flags_masks;
|
||||
f = 0;
|
||||
|
||||
for (i = 0; i < nelts; i++) {
|
||||
|
||||
if (ngx_http_complex_value(r, &flags_values[i], &value) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (value.len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (m = 0; mask[m].name.len != 0; m++) {
|
||||
|
||||
if (mask[m].name.len != value.len
|
||||
|| ngx_strncasecmp(mask[m].name.data, value.data, value.len)
|
||||
!= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
f |= mask[m].mask;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (mask[m].name.len == 0) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"invalid proxy_cookie_flags flag \"%V\"", &value);
|
||||
}
|
||||
}
|
||||
|
||||
if (f == 0) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
return ngx_http_proxy_edit_cookie_flags(r, attrs, f);
|
||||
}
|
||||
|
||||
|
||||
@ -4514,8 +4556,8 @@ ngx_http_proxy_cookie_flags(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_http_proxy_loc_conf_t *plcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_uint_t i, m;
|
||||
ngx_conf_bitmask_t *mask;
|
||||
ngx_uint_t i;
|
||||
ngx_http_complex_value_t *cv;
|
||||
ngx_http_proxy_cookie_flags_t *pcf;
|
||||
ngx_http_compile_complex_value_t ccv;
|
||||
#if (NGX_PCRE)
|
||||
@ -4599,32 +4641,27 @@ ngx_http_proxy_cookie_flags(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
}
|
||||
|
||||
mask = ngx_http_proxy_cookie_flags_masks;
|
||||
pcf->flags = 0;
|
||||
if (ngx_array_init(&pcf->flags_values, cf->pool, cf->args->nelts - 2,
|
||||
sizeof(ngx_http_complex_value_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 2; i < cf->args->nelts; i++) {
|
||||
for (m = 0; mask[m].name.len != 0; m++) {
|
||||
|
||||
if (mask[m].name.len != value[i].len
|
||||
|| ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pcf->flags & mask[m].mask) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"duplicate parameter \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
pcf->flags |= mask[m].mask;
|
||||
|
||||
break;
|
||||
cv = ngx_array_push(&pcf->flags_values);
|
||||
if (cv == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (mask[m].name.len == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[i]);
|
||||
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
|
||||
|
||||
ccv.cf = cf;
|
||||
ccv.value = &value[i];
|
||||
ccv.complex_value = cv;
|
||||
|
||||
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
@ -4876,9 +4913,9 @@ ngx_http_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1307,9 +1307,9 @@ ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2398,9 +2398,9 @@ ngx_http_uwsgi_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -238,6 +238,7 @@ ngx_http_v2_init(ngx_event_t *rev)
|
||||
ngx_http_v2_srv_conf_t *h2scf;
|
||||
ngx_http_v2_main_conf_t *h2mcf;
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
c = rev->data;
|
||||
hc = c->data;
|
||||
@ -325,8 +326,10 @@ ngx_http_v2_init(ngx_event_t *rev)
|
||||
rev->handler = ngx_http_v2_read_handler;
|
||||
c->write->handler = ngx_http_v2_write_handler;
|
||||
|
||||
if (c->read->timer_set) {
|
||||
ngx_del_timer(c->read);
|
||||
if (!rev->timer_set) {
|
||||
cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
ngx_add_timer(rev, cscf->client_header_timeout);
|
||||
}
|
||||
|
||||
c->idle = 1;
|
||||
|
@ -405,6 +405,7 @@ ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
|
||||
#if (NGX_MAIL_SSL)
|
||||
addrs[i].conf.ssl = addr[i].opt.ssl;
|
||||
#endif
|
||||
addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||
addrs[i].conf.addr_text = addr[i].opt.addr_text;
|
||||
}
|
||||
|
||||
@ -439,6 +440,7 @@ ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
|
||||
#if (NGX_MAIL_SSL)
|
||||
addrs6[i].conf.ssl = addr[i].opt.ssl;
|
||||
#endif
|
||||
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||
addrs6[i].conf.addr_text = addr[i].opt.addr_text;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ typedef struct {
|
||||
unsigned ipv6only:1;
|
||||
#endif
|
||||
unsigned so_keepalive:2;
|
||||
unsigned proxy_protocol:1;
|
||||
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
|
||||
int tcp_keepidle;
|
||||
int tcp_keepintvl;
|
||||
@ -55,7 +56,8 @@ typedef struct {
|
||||
typedef struct {
|
||||
ngx_mail_conf_ctx_t *ctx;
|
||||
ngx_str_t addr_text;
|
||||
ngx_uint_t ssl; /* unsigned ssl:1; */
|
||||
unsigned ssl:1;
|
||||
unsigned proxy_protocol:1;
|
||||
} ngx_mail_addr_conf_t;
|
||||
|
||||
typedef struct {
|
||||
@ -176,6 +178,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
ngx_peer_connection_t upstream;
|
||||
ngx_buf_t *buffer;
|
||||
ngx_uint_t proxy_protocol; /* unsigned proxy_protocol:1; */
|
||||
} ngx_mail_proxy_ctx_t;
|
||||
|
||||
|
||||
@ -197,6 +200,7 @@ typedef struct {
|
||||
|
||||
ngx_uint_t mail_state;
|
||||
|
||||
unsigned ssl:1;
|
||||
unsigned protocol:3;
|
||||
unsigned blocked:1;
|
||||
unsigned quit:1;
|
||||
@ -405,6 +409,7 @@ char *ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
/* STUB */
|
||||
void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer);
|
||||
void ngx_mail_auth_http_init(ngx_mail_session_t *s);
|
||||
ngx_int_t ngx_mail_realip_handler(ngx_mail_session_t *s);
|
||||
/**/
|
||||
|
||||
|
||||
|
@ -1224,22 +1224,49 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
||||
+ sizeof("Client-IP: ") - 1 + s->connection->addr_text.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Client-Host: ") - 1 + s->host.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-From: ") - 1 + s->smtp_from.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-To: ") - 1 + s->smtp_to.len + sizeof(CRLF) - 1
|
||||
#if (NGX_MAIL_SSL)
|
||||
+ sizeof("Auth-SSL: on" CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Verify: ") - 1 + verify.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Subject: ") - 1 + subject.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Issuer: ") - 1 + issuer.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Serial: ") - 1 + serial.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Fingerprint: ") - 1 + fingerprint.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Cert: ") - 1 + cert.len + sizeof(CRLF) - 1
|
||||
#endif
|
||||
+ ahcf->header.len
|
||||
+ sizeof(CRLF) - 1;
|
||||
|
||||
if (c->proxy_protocol) {
|
||||
len += sizeof("Proxy-Protocol-Addr: ") - 1
|
||||
+ c->proxy_protocol->src_addr.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Proxy-Protocol-Port: ") - 1
|
||||
+ sizeof("65535") - 1 + sizeof(CRLF) - 1
|
||||
+ sizeof("Proxy-Protocol-Server-Addr: ") - 1
|
||||
+ c->proxy_protocol->dst_addr.len + sizeof(CRLF) - 1
|
||||
+ sizeof("Proxy-Protocol-Server-Port: ") - 1
|
||||
+ sizeof("65535") - 1 + sizeof(CRLF) - 1;
|
||||
}
|
||||
|
||||
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||
len += sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-From: ") - 1 + s->smtp_from.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SMTP-To: ") - 1 + s->smtp_to.len
|
||||
+ sizeof(CRLF) - 1;
|
||||
}
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
|
||||
if (c->ssl) {
|
||||
len += sizeof("Auth-SSL: on" CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Verify: ") - 1 + verify.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Subject: ") - 1 + subject.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Issuer: ") - 1 + issuer.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Serial: ") - 1 + serial.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Fingerprint: ") - 1 + fingerprint.len
|
||||
+ sizeof(CRLF) - 1
|
||||
+ sizeof("Auth-SSL-Cert: ") - 1 + cert.len
|
||||
+ sizeof(CRLF) - 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
b = ngx_create_temp_buf(pool, len);
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
@ -1298,6 +1325,26 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
if (c->proxy_protocol) {
|
||||
b->last = ngx_cpymem(b->last, "Proxy-Protocol-Addr: ",
|
||||
sizeof("Proxy-Protocol-Addr: ") - 1);
|
||||
b->last = ngx_copy(b->last, c->proxy_protocol->src_addr.data,
|
||||
c->proxy_protocol->src_addr.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
b->last = ngx_sprintf(b->last, "Proxy-Protocol-Port: %d" CRLF,
|
||||
c->proxy_protocol->src_port);
|
||||
|
||||
b->last = ngx_cpymem(b->last, "Proxy-Protocol-Server-Addr: ",
|
||||
sizeof("Proxy-Protocol-Server-Addr: ") - 1);
|
||||
b->last = ngx_copy(b->last, c->proxy_protocol->dst_addr.data,
|
||||
c->proxy_protocol->dst_addr.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
b->last = ngx_sprintf(b->last, "Proxy-Protocol-Server-Port: %d" CRLF,
|
||||
c->proxy_protocol->dst_port);
|
||||
}
|
||||
|
||||
if (s->auth_method == NGX_MAIL_AUTH_NONE) {
|
||||
|
||||
/* HELO, MAIL FROM, and RCPT TO can't contain CRLF, no need to escape */
|
||||
|
@ -548,6 +548,11 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ngx_strcmp(value[i].data, "proxy_protocol") == 0) {
|
||||
ls->proxy_protocol = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the invalid \"%V\" parameter", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <ngx_mail.h>
|
||||
|
||||
|
||||
static void ngx_mail_proxy_protocol_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_init_session_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_init_session(ngx_connection_t *c);
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
@ -26,6 +28,7 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_event_t *rev;
|
||||
ngx_mail_port_t *port;
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_in *sin;
|
||||
@ -129,6 +132,10 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
||||
s->main_conf = addr_conf->ctx->main_conf;
|
||||
s->srv_conf = addr_conf->ctx->srv_conf;
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
s->ssl = addr_conf->ssl;
|
||||
#endif
|
||||
|
||||
s->addr_text = &addr_conf->addr_text;
|
||||
|
||||
c->data = s;
|
||||
@ -159,13 +166,125 @@ ngx_mail_init_connection(ngx_connection_t *c)
|
||||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
|
||||
rev = c->read;
|
||||
rev->handler = ngx_mail_init_session_handler;
|
||||
|
||||
if (addr_conf->proxy_protocol) {
|
||||
c->log->action = "reading PROXY protocol";
|
||||
|
||||
rev->handler = ngx_mail_proxy_protocol_handler;
|
||||
|
||||
if (!rev->ready) {
|
||||
ngx_add_timer(rev, cscf->timeout);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_use_accept_mutex) {
|
||||
ngx_post_event(rev, &ngx_posted_events);
|
||||
return;
|
||||
}
|
||||
|
||||
rev->handler(rev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_mail_proxy_protocol_handler(ngx_event_t *rev)
|
||||
{
|
||||
u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_session_t *s;
|
||||
ngx_mail_core_srv_conf_t *cscf;
|
||||
|
||||
c = rev->data;
|
||||
s = c->data;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||
"mail PROXY protocol handler");
|
||||
|
||||
if (rev->timedout) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
|
||||
c->timedout = 1;
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK);
|
||||
|
||||
err = ngx_socket_errno;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "recv(): %z", n);
|
||||
|
||||
if (n == -1) {
|
||||
if (err == NGX_EAGAIN) {
|
||||
rev->ready = 0;
|
||||
|
||||
if (!rev->timer_set) {
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
ngx_add_timer(rev, cscf->timeout);
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_connection_error(c, err, "recv() failed");
|
||||
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
p = ngx_proxy_protocol_read(c, buf, buf + n);
|
||||
|
||||
if (p == NULL) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
size = p - buf;
|
||||
|
||||
if (c->recv(c, buf, size) != (ssize_t) size) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_mail_realip_handler(s) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_init_session_handler(rev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_mail_init_session_handler(ngx_event_t *rev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_session_t *s;
|
||||
|
||||
c = rev->data;
|
||||
s = c->data;
|
||||
|
||||
#if (NGX_MAIL_SSL)
|
||||
{
|
||||
ngx_mail_ssl_conf_t *sslcf;
|
||||
|
||||
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
||||
|
||||
if (sslcf->enable || addr_conf->ssl) {
|
||||
if (sslcf->enable || s->ssl) {
|
||||
c->log->action = "SSL handshaking";
|
||||
|
||||
ngx_mail_ssl_init_connection(&sslcf->ssl, c);
|
||||
@ -215,9 +334,10 @@ ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
|
||||
|
||||
s = c->data;
|
||||
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
|
||||
ngx_add_timer(c->read, cscf->timeout);
|
||||
if (!c->read->timer_set) {
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
ngx_add_timer(c->read, cscf->timeout);
|
||||
}
|
||||
|
||||
c->ssl->handler = ngx_mail_ssl_handshake_handler;
|
||||
|
||||
@ -338,6 +458,8 @@ ngx_mail_init_session(ngx_connection_t *c)
|
||||
|
||||
s = c->data;
|
||||
|
||||
c->log->action = "sending client greeting line";
|
||||
|
||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||
|
||||
s->protocol = cscf->protocol->type;
|
||||
@ -722,11 +844,6 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
|
||||
}
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (s->buffer->pos == s->buffer->last) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
@ -123,6 +123,12 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
|
||||
if (s->out.len) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap send handler busy");
|
||||
s->blocked = 1;
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -130,7 +136,16 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
|
||||
|
||||
rc = ngx_mail_read_command(s, c);
|
||||
|
||||
if (rc == NGX_AGAIN || rc == NGX_ERROR) {
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -293,6 +308,11 @@ ngx_mail_imap_auth_state(ngx_event_t *rev)
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_send(c->write);
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,12 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
|
||||
if (s->out.len) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 send handler busy");
|
||||
s->blocked = 1;
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -145,7 +151,16 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
|
||||
|
||||
rc = ngx_mail_read_command(s, c);
|
||||
|
||||
if (rc == NGX_AGAIN || rc == NGX_ERROR) {
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -275,6 +290,11 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
|
||||
s->arg_start = s->buffer->start;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_send(c->write);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ typedef struct {
|
||||
ngx_flag_t pass_error_message;
|
||||
ngx_flag_t xclient;
|
||||
ngx_flag_t smtp_auth;
|
||||
ngx_flag_t proxy_protocol;
|
||||
size_t buffer_size;
|
||||
ngx_msec_t timeout;
|
||||
} ngx_mail_proxy_conf_t;
|
||||
@ -26,7 +27,8 @@ static void ngx_mail_proxy_block_read(ngx_event_t *rev);
|
||||
static void ngx_mail_proxy_pop3_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_proxy_imap_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_proxy_smtp_handler(ngx_event_t *rev);
|
||||
static void ngx_mail_proxy_dummy_handler(ngx_event_t *ev);
|
||||
static void ngx_mail_proxy_write_handler(ngx_event_t *wev);
|
||||
static ngx_int_t ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s);
|
||||
static ngx_int_t ngx_mail_proxy_read_response(ngx_mail_session_t *s,
|
||||
ngx_uint_t state);
|
||||
static void ngx_mail_proxy_handler(ngx_event_t *ev);
|
||||
@ -82,6 +84,13 @@ static ngx_command_t ngx_mail_proxy_commands[] = {
|
||||
offsetof(ngx_mail_proxy_conf_t, smtp_auth),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_protocol"),
|
||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_MAIL_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_mail_proxy_conf_t, proxy_protocol),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@ -156,7 +165,7 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
|
||||
p->upstream.connection->pool = s->connection->pool;
|
||||
|
||||
s->connection->read->handler = ngx_mail_proxy_block_read;
|
||||
p->upstream.connection->write->handler = ngx_mail_proxy_dummy_handler;
|
||||
p->upstream.connection->write->handler = ngx_mail_proxy_write_handler;
|
||||
|
||||
pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
|
||||
|
||||
@ -167,6 +176,8 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->proxy_protocol = pcf->proxy_protocol;
|
||||
|
||||
s->out.len = 0;
|
||||
|
||||
switch (s->protocol) {
|
||||
@ -186,6 +197,12 @@ ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
|
||||
s->mail_state = ngx_smtp_start;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_proxy_write_handler(p->upstream.connection->write);
|
||||
}
|
||||
|
||||
|
||||
@ -230,9 +247,25 @@ ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy pop3 busy");
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_mail_proxy_read_response(s, 0);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -314,6 +347,11 @@ ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->buffer->pos = s->proxy->buffer->start;
|
||||
s->proxy->buffer->last = s->proxy->buffer->start;
|
||||
}
|
||||
@ -343,9 +381,25 @@ ngx_mail_proxy_imap_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy imap busy");
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_mail_proxy_read_response(s, s->mail_state);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -448,6 +502,11 @@ ngx_mail_proxy_imap_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->buffer->pos = s->proxy->buffer->start;
|
||||
s->proxy->buffer->last = s->proxy->buffer->start;
|
||||
}
|
||||
@ -479,9 +538,25 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy smtp busy");
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_mail_proxy_read_response(s, s->mail_state);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -763,25 +838,103 @@ ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->buffer->pos = s->proxy->buffer->start;
|
||||
s->proxy->buffer->last = s->proxy->buffer->start;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_mail_proxy_dummy_handler(ngx_event_t *wev)
|
||||
ngx_mail_proxy_write_handler(ngx_event_t *wev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_session_t *s;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler");
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy write handler");
|
||||
|
||||
c = wev->data;
|
||||
s = c->data;
|
||||
|
||||
if (s->proxy->proxy_protocol) {
|
||||
if (ngx_mail_proxy_send_proxy_protocol(s) != NGX_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
s->proxy->proxy_protocol = 0;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
|
||||
c = wev->data;
|
||||
s = c->data;
|
||||
|
||||
ngx_mail_proxy_close_session(s);
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
}
|
||||
|
||||
if (c->read->ready) {
|
||||
ngx_post_event(c->read, &ngx_posted_events);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s)
|
||||
{
|
||||
u_char *p;
|
||||
ssize_t n, size;
|
||||
ngx_connection_t *c;
|
||||
u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
|
||||
|
||||
s->connection->log->action = "sending PROXY protocol header to upstream";
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
|
||||
"mail proxy send PROXY protocol header");
|
||||
|
||||
p = ngx_proxy_protocol_write(s->connection, buf,
|
||||
buf + NGX_PROXY_PROTOCOL_MAX_HEADER);
|
||||
if (p == NULL) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
c = s->proxy->upstream.connection;
|
||||
|
||||
size = p - buf;
|
||||
|
||||
n = c->send(c, buf, size);
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (n != size) {
|
||||
|
||||
/*
|
||||
* PROXY protocol specification:
|
||||
* The sender must always ensure that the header
|
||||
* is sent at once, so that the transport layer
|
||||
* maintains atomicity along the path to the receiver.
|
||||
*/
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||
"could not send PROXY protocol header at once");
|
||||
|
||||
ngx_mail_proxy_internal_server_error(s);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1182,6 +1335,7 @@ ngx_mail_proxy_create_conf(ngx_conf_t *cf)
|
||||
pcf->pass_error_message = NGX_CONF_UNSET;
|
||||
pcf->xclient = NGX_CONF_UNSET;
|
||||
pcf->smtp_auth = NGX_CONF_UNSET;
|
||||
pcf->proxy_protocol = NGX_CONF_UNSET;
|
||||
pcf->buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
pcf->timeout = NGX_CONF_UNSET_MSEC;
|
||||
|
||||
@ -1199,6 +1353,7 @@ ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0);
|
||||
ngx_conf_merge_value(conf->xclient, prev->xclient, 1);
|
||||
ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0);
|
||||
ngx_conf_merge_value(conf->proxy_protocol, prev->proxy_protocol, 0);
|
||||
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
|
||||
(size_t) ngx_pagesize);
|
||||
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000);
|
||||
|
269
src/mail/ngx_mail_realip_module.c
Normal file
269
src/mail/ngx_mail_realip_module.c
Normal file
@ -0,0 +1,269 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_mail.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *from; /* array of ngx_cidr_t */
|
||||
} ngx_mail_realip_srv_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_mail_realip_set_addr(ngx_mail_session_t *s,
|
||||
ngx_addr_t *addr);
|
||||
static char *ngx_mail_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static void *ngx_mail_realip_create_srv_conf(ngx_conf_t *cf);
|
||||
static char *ngx_mail_realip_merge_srv_conf(ngx_conf_t *cf, void *parent,
|
||||
void *child);
|
||||
|
||||
|
||||
static ngx_command_t ngx_mail_realip_commands[] = {
|
||||
|
||||
{ ngx_string("set_real_ip_from"),
|
||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_mail_realip_from,
|
||||
NGX_MAIL_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_mail_module_t ngx_mail_realip_module_ctx = {
|
||||
NULL, /* protocol */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
ngx_mail_realip_create_srv_conf, /* create server configuration */
|
||||
ngx_mail_realip_merge_srv_conf /* merge server configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_mail_realip_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_mail_realip_module_ctx, /* module context */
|
||||
ngx_mail_realip_commands, /* module directives */
|
||||
NGX_MAIL_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_mail_realip_handler(ngx_mail_session_t *s)
|
||||
{
|
||||
ngx_addr_t addr;
|
||||
ngx_connection_t *c;
|
||||
ngx_mail_realip_srv_conf_t *rscf;
|
||||
|
||||
rscf = ngx_mail_get_module_srv_conf(s, ngx_mail_realip_module);
|
||||
|
||||
if (rscf->from == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
c = s->connection;
|
||||
|
||||
if (c->proxy_protocol == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_cidr_match(c->sockaddr, rscf->from) != NGX_OK) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_parse_addr(c->pool, &addr, c->proxy_protocol->src_addr.data,
|
||||
c->proxy_protocol->src_addr.len)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_inet_set_port(addr.sockaddr, c->proxy_protocol->src_port);
|
||||
|
||||
return ngx_mail_realip_set_addr(s, &addr);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_mail_realip_set_addr(ngx_mail_session_t *s, ngx_addr_t *addr)
|
||||
{
|
||||
size_t len;
|
||||
u_char *p;
|
||||
u_char text[NGX_SOCKADDR_STRLEN];
|
||||
ngx_connection_t *c;
|
||||
|
||||
c = s->connection;
|
||||
|
||||
len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text,
|
||||
NGX_SOCKADDR_STRLEN, 0);
|
||||
if (len == 0) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_pnalloc(c->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(p, text, len);
|
||||
|
||||
c->sockaddr = addr->sockaddr;
|
||||
c->socklen = addr->socklen;
|
||||
c->addr_text.len = len;
|
||||
c->addr_text.data = p;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_mail_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_mail_realip_srv_conf_t *rscf = conf;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_cidr_t c, *cidr;
|
||||
ngx_uint_t i;
|
||||
struct sockaddr_in *sin;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (rscf->from == NULL) {
|
||||
rscf->from = ngx_array_create(cf->pool, 2,
|
||||
sizeof(ngx_cidr_t));
|
||||
if (rscf->from == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr = ngx_array_push(rscf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cidr->family = AF_UNIX;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rc = ngx_ptocidr(&value[1], &c);
|
||||
|
||||
if (rc != NGX_ERROR) {
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless",
|
||||
&value[1]);
|
||||
}
|
||||
|
||||
cidr = ngx_array_push(rscf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*cidr = c;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
u.host = value[1];
|
||||
|
||||
if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in set_real_ip_from \"%V\"",
|
||||
u.err, &u.host);
|
||||
}
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cidr = ngx_array_push_n(rscf->from, u.naddrs);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
|
||||
|
||||
for (i = 0; i < u.naddrs; i++) {
|
||||
cidr[i].family = u.addrs[i].sockaddr->sa_family;
|
||||
|
||||
switch (cidr[i].family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in6.addr = sin6->sin6_addr;
|
||||
ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in.addr = sin->sin_addr.s_addr;
|
||||
cidr[i].u.in.mask = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_mail_realip_create_srv_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_mail_realip_srv_conf_t *conf;
|
||||
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_realip_srv_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->from = NULL;
|
||||
*/
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_mail_realip_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
{
|
||||
ngx_mail_realip_srv_conf_t *prev = parent;
|
||||
ngx_mail_realip_srv_conf_t *conf = child;
|
||||
|
||||
if (conf->from == NULL) {
|
||||
conf->from = prev->from;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
@ -449,6 +449,12 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
|
||||
if (s->out.len) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp send handler busy");
|
||||
s->blocked = 1;
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -456,7 +462,16 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
|
||||
|
||||
rc = ngx_mail_read_command(s, c);
|
||||
|
||||
if (rc == NGX_AGAIN || rc == NGX_ERROR) {
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -568,6 +583,11 @@ ngx_mail_smtp_auth_state(ngx_event_t *rev)
|
||||
s->arg_start = s->buffer->pos;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||
ngx_mail_session_internal_server_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_mail_send(c->write);
|
||||
}
|
||||
}
|
||||
|
@ -682,7 +682,7 @@ ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
@ -9,6 +9,49 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
static ngx_str_t ngx_unknown_error = ngx_string("Unknown error");
|
||||
|
||||
|
||||
#if (NGX_HAVE_STRERRORDESC_NP)
|
||||
|
||||
/*
|
||||
* The strerrordesc_np() function, introduced in glibc 2.32, is
|
||||
* async-signal-safe. This makes it possible to use it directly,
|
||||
* without copying error messages.
|
||||
*/
|
||||
|
||||
|
||||
u_char *
|
||||
ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
|
||||
{
|
||||
size_t len;
|
||||
const char *msg;
|
||||
|
||||
msg = strerrordesc_np(err);
|
||||
|
||||
if (msg == NULL) {
|
||||
msg = (char *) ngx_unknown_error.data;
|
||||
len = ngx_unknown_error.len;
|
||||
|
||||
} else {
|
||||
len = ngx_strlen(msg);
|
||||
}
|
||||
|
||||
size = ngx_min(size, len);
|
||||
|
||||
return ngx_cpymem(errstr, msg, size);
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_strerror_init(void)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* The strerror() messages are copied because:
|
||||
*
|
||||
@ -26,7 +69,8 @@
|
||||
|
||||
|
||||
static ngx_str_t *ngx_sys_errlist;
|
||||
static ngx_str_t ngx_unknown_error = ngx_string("Unknown error");
|
||||
static ngx_err_t ngx_first_error;
|
||||
static ngx_err_t ngx_last_error;
|
||||
|
||||
|
||||
u_char *
|
||||
@ -34,8 +78,13 @@ ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
|
||||
{
|
||||
ngx_str_t *msg;
|
||||
|
||||
msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
|
||||
&ngx_unknown_error;
|
||||
if (err >= ngx_first_error && err < ngx_last_error) {
|
||||
msg = &ngx_sys_errlist[err - ngx_first_error];
|
||||
|
||||
} else {
|
||||
msg = &ngx_unknown_error;
|
||||
}
|
||||
|
||||
size = ngx_min(size, msg->len);
|
||||
|
||||
return ngx_cpymem(errstr, msg->data, size);
|
||||
@ -50,20 +99,92 @@ ngx_strerror_init(void)
|
||||
size_t len;
|
||||
ngx_err_t err;
|
||||
|
||||
#if (NGX_SYS_NERR)
|
||||
ngx_first_error = 0;
|
||||
ngx_last_error = NGX_SYS_NERR;
|
||||
|
||||
#elif (EPERM > 1000 && EPERM < 0x7fffffff - 1000)
|
||||
|
||||
/*
|
||||
* If number of errors is not known, and EPERM error code has large
|
||||
* but reasonable value, guess possible error codes based on the error
|
||||
* messages returned by strerror(), starting from EPERM. Notably,
|
||||
* this covers GNU/Hurd, where errors start at 0x40000001.
|
||||
*/
|
||||
|
||||
for (err = EPERM; err > EPERM - 1000; err--) {
|
||||
ngx_set_errno(0);
|
||||
msg = strerror(err);
|
||||
|
||||
if (errno == EINVAL
|
||||
|| msg == NULL
|
||||
|| strncmp(msg, "Unknown error", 13) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_first_error = err;
|
||||
}
|
||||
|
||||
for (err = EPERM; err < EPERM + 1000; err++) {
|
||||
ngx_set_errno(0);
|
||||
msg = strerror(err);
|
||||
|
||||
if (errno == EINVAL
|
||||
|| msg == NULL
|
||||
|| strncmp(msg, "Unknown error", 13) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_last_error = err + 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* If number of errors is not known, guess it based on the error
|
||||
* messages returned by strerror().
|
||||
*/
|
||||
|
||||
ngx_first_error = 0;
|
||||
|
||||
for (err = 0; err < 1000; err++) {
|
||||
ngx_set_errno(0);
|
||||
msg = strerror(err);
|
||||
|
||||
if (errno == EINVAL
|
||||
|| msg == NULL
|
||||
|| strncmp(msg, "Unknown error", 13) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_last_error = err + 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ngx_strerror() is not ready to work at this stage, therefore,
|
||||
* malloc() is used and possible errors are logged using strerror().
|
||||
*/
|
||||
|
||||
len = NGX_SYS_NERR * sizeof(ngx_str_t);
|
||||
len = (ngx_last_error - ngx_first_error) * sizeof(ngx_str_t);
|
||||
|
||||
ngx_sys_errlist = malloc(len);
|
||||
if (ngx_sys_errlist == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (err = 0; err < NGX_SYS_NERR; err++) {
|
||||
for (err = ngx_first_error; err < ngx_last_error; err++) {
|
||||
msg = strerror(err);
|
||||
|
||||
if (msg == NULL) {
|
||||
ngx_sys_errlist[err - ngx_first_error] = ngx_unknown_error;
|
||||
continue;
|
||||
}
|
||||
|
||||
len = ngx_strlen(msg);
|
||||
|
||||
p = malloc(len);
|
||||
@ -72,8 +193,8 @@ ngx_strerror_init(void)
|
||||
}
|
||||
|
||||
ngx_memcpy(p, msg, len);
|
||||
ngx_sys_errlist[err].len = len;
|
||||
ngx_sys_errlist[err].data = p;
|
||||
ngx_sys_errlist[err - ngx_first_error].len = len;
|
||||
ngx_sys_errlist[err - ngx_first_error].data = p;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
@ -85,3 +206,5 @@ failed:
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1026,9 +1026,9 @@ ngx_stream_proxy_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1061,9 +1061,9 @@ ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#ifndef SSL_CONF_FLAG_FILE
|
||||
return "is not supported on this platform";
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NGX_CONF_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user