comparison src/mail/ngx_mail_smtp_handler.c @ 366:babd3d9efb62 NGINX_0_6_27

nginx 0.6.27 *) Change: now by default the rtsig method is not built on Linux 2.6.18+. *) Change: now a request method is not changed while redirection to a named location via an "error_page" directive. *) Feature: the "resolver" and "resolver_timeout" directives in SMTP proxy. *) Feature: the "post_action" directive supports named locations. *) Bugfix: a segmentation fault occurred in worker process, if a request was redirected from proxy, FastCGI, or memcached location to static named locations. *) Bugfix: browsers did not repeat SSL handshake if there is no valid client certificate in first handshake. Thanks to Alexander V. Inyukhin. *) Bugfix: if response code 495-497 was redirected via an "error_page" directive without code change, then nginx tried to allocate too many memory. *) Bugfix: memory leak in long-lived non buffered connections. *) Bugfix: memory leak in resolver. *) Bugfix: a segmentation fault occurred in worker process, if a request was redirected from proxy, FastCGI, or memcached location to static named locations. *) Bugfix: in the $proxy_host and $proxy_port variables caching. Thanks to Sergey Bochenkov. *) Bugfix: a "proxy_pass" directive with variables used incorrectly the same port as in another "proxy_pass" directive with the same host name and without variables. Thanks to Sergey Bochenkov. *) Bugfix: an alert "sendmsg() failed (9: Bad file descriptor)" on some 64-bit platforms while reconfiguration. *) Bugfix: a segmentation fault occurred in worker process, if empty stub block was used second time in SSI. *) Bugfix: in copying URI part contained escaped symbols into arguments.
author Igor Sysoev <http://sysoev.ru>
date Wed, 12 Mar 2008 00:00:00 +0300
parents 9121a0a91f47
children 984bb0b1399b
comparison
equal deleted inserted replaced
365:9b0140fa1132 366:babd3d9efb62
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 #include <ngx_mail.h> 10 #include <ngx_mail.h>
11 #include <ngx_mail_smtp_module.h> 11 #include <ngx_mail_smtp_module.h>
12 12
13 13
14 static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx);
15 static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx);
16 static void ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c);
14 static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev); 17 static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev);
15 static ngx_int_t ngx_mail_smtp_create_buffer(ngx_mail_session_t *s, 18 static ngx_int_t ngx_mail_smtp_create_buffer(ngx_mail_session_t *s,
16 ngx_connection_t *c); 19 ngx_connection_t *c);
17 20
18 static ngx_int_t ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c); 21 static ngx_int_t ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c);
38 "503 5.5.0 Improper use of SMTP command pipelining" CRLF; 41 "503 5.5.0 Improper use of SMTP command pipelining" CRLF;
39 static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF; 42 static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF;
40 static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF; 43 static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF;
41 44
42 45
46 static ngx_str_t smtp_unavailable = ngx_string("[UNAVAILABLE]");
47 static ngx_str_t smtp_tempunavail = ngx_string("[TEMPUNAVAIL]");
48
49
43 void 50 void
44 ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c) 51 ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
52 {
53 struct sockaddr_in *sin;
54 ngx_resolver_ctx_t *ctx;
55 ngx_mail_core_srv_conf_t *cscf;
56
57 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
58
59 if (cscf->resolver == NULL) {
60 s->host = smtp_unavailable;
61 ngx_mail_smtp_greeting(s, c);
62 return;
63 }
64
65 c->log->action = "in resolving client address";
66
67 ctx = ngx_resolve_start(cscf->resolver, NULL);
68 if (ctx == NULL) {
69 ngx_mail_close_connection(c);
70 return;
71 }
72
73 /* AF_INET only */
74
75 sin = (struct sockaddr_in *) c->sockaddr;
76
77 ctx->addr = sin->sin_addr.s_addr;
78 ctx->handler = ngx_mail_smtp_resolve_addr_handler;
79 ctx->data = s;
80 ctx->timeout = cscf->resolver_timeout;
81
82 if (ngx_resolve_addr(ctx) != NGX_OK) {
83 ngx_mail_close_connection(c);
84 }
85 }
86
87
88 static void
89 ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx)
90 {
91 ngx_connection_t *c;
92 ngx_mail_session_t *s;
93 ngx_mail_core_srv_conf_t *cscf;
94
95 s = ctx->data;
96 c = s->connection;
97
98 if (ctx->state) {
99 ngx_log_error(NGX_LOG_ERR, c->log, 0,
100 "%V could not be resolved (%i: %s)",
101 &c->addr_text, ctx->state,
102 ngx_resolver_strerror(ctx->state));
103
104 if (ctx->state == NGX_RESOLVE_NXDOMAIN) {
105 s->host = smtp_unavailable;
106
107 } else {
108 s->host = smtp_tempunavail;
109 }
110
111 ngx_resolve_addr_done(ctx);
112
113 ngx_mail_smtp_greeting(s, s->connection);
114
115 return;
116 }
117
118 c->log->action = "in resolving client hostname";
119
120 s->host.data = ngx_pstrdup(c->pool, &ctx->name);
121 if (s->host.data == NULL) {
122 ngx_resolve_addr_done(ctx);
123 ngx_mail_close_connection(c);
124 return;
125 }
126
127 s->host.len = ctx->name.len;
128
129 ngx_resolve_addr_done(ctx);
130
131 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
132 "address resolved: %V", &s->host);
133
134 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
135
136 ctx = ngx_resolve_start(cscf->resolver, NULL);
137 if (ctx == NULL) {
138 ngx_mail_close_connection(c);
139 return;
140 }
141
142 ctx->name = s->host;
143 ctx->type = NGX_RESOLVE_A;
144 ctx->handler = ngx_mail_smtp_resolve_name_handler;
145 ctx->data = s;
146 ctx->timeout = cscf->resolver_timeout;
147
148 if (ngx_resolve_name(ctx) != NGX_OK) {
149 ngx_mail_close_connection(c);
150 }
151 }
152
153
154 static void
155 ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx)
156 {
157 in_addr_t addr;
158 ngx_uint_t i;
159 ngx_connection_t *c;
160 struct sockaddr_in *sin;
161 ngx_mail_session_t *s;
162
163 s = ctx->data;
164 c = s->connection;
165
166 if (ctx->state) {
167 ngx_log_error(NGX_LOG_ERR, c->log, 0,
168 "%V could not be resolved (%i: %s)",
169 &ctx->name, ctx->state,
170 ngx_resolver_strerror(ctx->state));
171
172 if (ctx->state == NGX_RESOLVE_NXDOMAIN) {
173 s->host = smtp_unavailable;
174
175 } else {
176 s->host = smtp_tempunavail;
177 }
178
179 } else {
180
181 /* AF_INET only */
182
183 sin = (struct sockaddr_in *) c->sockaddr;
184
185 for (i = 0; i < ctx->naddrs; i++) {
186
187 addr = ctx->addrs[i];
188
189 ngx_log_debug4(NGX_LOG_DEBUG_MAIL, c->log, 0,
190 "name was resolved to %ud.%ud.%ud.%ud",
191 (ntohl(addr) >> 24) & 0xff,
192 (ntohl(addr) >> 16) & 0xff,
193 (ntohl(addr) >> 8) & 0xff,
194 ntohl(addr) & 0xff);
195
196 if (addr == sin->sin_addr.s_addr) {
197 goto found;
198 }
199 }
200
201 s->host = smtp_unavailable;
202 }
203
204 found:
205
206 ngx_resolve_name_done(ctx);
207
208 ngx_mail_smtp_greeting(s, c);
209 }
210
211
212 static void
213 ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c)
45 { 214 {
46 ngx_msec_t timeout; 215 ngx_msec_t timeout;
47 ngx_mail_core_srv_conf_t *cscf; 216 ngx_mail_core_srv_conf_t *cscf;
48 ngx_mail_smtp_srv_conf_t *sscf; 217 ngx_mail_smtp_srv_conf_t *sscf;
218
219 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
220 "smtp greeting for \"%V\"", &s->host);
49 221
50 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); 222 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
51 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); 223 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
52 224
53 timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout; 225 timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout;