Mercurial > hg > nginx
annotate src/mail/ngx_mail_proxy_module.c @ 7790:da0a85e91587
Mail: added missing event handling after reading data.
If we need to be notified about further events, ngx_handle_read_event()
needs to be called after a read event is processed. Without this,
an event can be removed from the kernel and won't be reported again,
notably when using oneshot event methods, such as eventport on Solaris.
For consistency, existing ngx_handle_read_event() call removed from
ngx_mail_read_command(), as this call only covers one of the code paths
where ngx_mail_read_command() returns NGX_AGAIN. Instead, appropriate
processing added to the callers, covering all code paths where NGX_AGAIN
is returned.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 05 Mar 2021 17:16:17 +0300 |
parents | d63c5373b5ba |
children | 4b8f23a36ebf |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
426
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
426
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
4412 | 4 * Copyright (C) Nginx, Inc. |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
426
diff
changeset
|
5 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
426
diff
changeset
|
6 |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 #include <ngx_event.h> |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
11 #include <ngx_event_connect.h> |
1136 | 12 #include <ngx_mail.h> |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
13 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
14 |
521 | 15 typedef struct { |
16 ngx_flag_t enable; | |
857 | 17 ngx_flag_t pass_error_message; |
1136 | 18 ngx_flag_t xclient; |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
19 ngx_flag_t smtp_auth; |
539 | 20 size_t buffer_size; |
21 ngx_msec_t timeout; | |
1136 | 22 } ngx_mail_proxy_conf_t; |
521 | 23 |
24 | |
1136 | 25 static void ngx_mail_proxy_block_read(ngx_event_t *rev); |
26 static void ngx_mail_proxy_pop3_handler(ngx_event_t *rev); | |
27 static void ngx_mail_proxy_imap_handler(ngx_event_t *rev); | |
28 static void ngx_mail_proxy_smtp_handler(ngx_event_t *rev); | |
29 static void ngx_mail_proxy_dummy_handler(ngx_event_t *ev); | |
30 static ngx_int_t ngx_mail_proxy_read_response(ngx_mail_session_t *s, | |
663 | 31 ngx_uint_t state); |
1136 | 32 static void ngx_mail_proxy_handler(ngx_event_t *ev); |
33 static void ngx_mail_proxy_upstream_error(ngx_mail_session_t *s); | |
34 static void ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s); | |
35 static void ngx_mail_proxy_close_session(ngx_mail_session_t *s); | |
36 static void *ngx_mail_proxy_create_conf(ngx_conf_t *cf); | |
37 static char *ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, | |
521 | 38 void *child); |
39 | |
40 | |
1136 | 41 static ngx_command_t ngx_mail_proxy_commands[] = { |
539 | 42 |
521 | 43 { ngx_string("proxy"), |
1136 | 44 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
521 | 45 ngx_conf_set_flag_slot, |
1136 | 46 NGX_MAIL_SRV_CONF_OFFSET, |
47 offsetof(ngx_mail_proxy_conf_t, enable), | |
521 | 48 NULL }, |
49 | |
539 | 50 { ngx_string("proxy_buffer"), |
1136 | 51 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
539 | 52 ngx_conf_set_size_slot, |
1136 | 53 NGX_MAIL_SRV_CONF_OFFSET, |
54 offsetof(ngx_mail_proxy_conf_t, buffer_size), | |
539 | 55 NULL }, |
56 | |
57 { ngx_string("proxy_timeout"), | |
1136 | 58 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
539 | 59 ngx_conf_set_msec_slot, |
1136 | 60 NGX_MAIL_SRV_CONF_OFFSET, |
61 offsetof(ngx_mail_proxy_conf_t, timeout), | |
539 | 62 NULL }, |
63 | |
857 | 64 { ngx_string("proxy_pass_error_message"), |
4273
e444e8f6538b
Fixed NGX_CONF_TAKE1/NGX_CONF_FLAG misuse.
Sergey Budnevitch <sb@waeme.net>
parents:
3516
diff
changeset
|
65 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
857 | 66 ngx_conf_set_flag_slot, |
1136 | 67 NGX_MAIL_SRV_CONF_OFFSET, |
68 offsetof(ngx_mail_proxy_conf_t, pass_error_message), | |
69 NULL }, | |
70 | |
71 { ngx_string("xclient"), | |
72 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, | |
73 ngx_conf_set_flag_slot, | |
74 NGX_MAIL_SRV_CONF_OFFSET, | |
75 offsetof(ngx_mail_proxy_conf_t, xclient), | |
857 | 76 NULL }, |
77 | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
78 { ngx_string("proxy_smtp_auth"), |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
79 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
80 ngx_conf_set_flag_slot, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
81 NGX_MAIL_SRV_CONF_OFFSET, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
82 offsetof(ngx_mail_proxy_conf_t, smtp_auth), |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
83 NULL }, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
84 |
521 | 85 ngx_null_command |
86 }; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
87 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
88 |
1136 | 89 static ngx_mail_module_t ngx_mail_proxy_module_ctx = { |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1342
diff
changeset
|
90 NULL, /* protocol */ |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1342
diff
changeset
|
91 |
521 | 92 NULL, /* create main configuration */ |
93 NULL, /* init main configuration */ | |
94 | |
1136 | 95 ngx_mail_proxy_create_conf, /* create server configuration */ |
96 ngx_mail_proxy_merge_conf /* merge server configuration */ | |
521 | 97 }; |
98 | |
99 | |
1136 | 100 ngx_module_t ngx_mail_proxy_module = { |
521 | 101 NGX_MODULE_V1, |
1136 | 102 &ngx_mail_proxy_module_ctx, /* module context */ |
103 ngx_mail_proxy_commands, /* module directives */ | |
104 NGX_MAIL_MODULE, /* module type */ | |
541 | 105 NULL, /* init master */ |
521 | 106 NULL, /* init module */ |
541 | 107 NULL, /* init process */ |
108 NULL, /* init thread */ | |
109 NULL, /* exit thread */ | |
110 NULL, /* exit process */ | |
111 NULL, /* exit master */ | |
112 NGX_MODULE_V1_PADDING | |
521 | 113 }; |
114 | |
115 | |
2440
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
116 static u_char smtp_auth_ok[] = "235 2.0.0 OK" CRLF; |
1136 | 117 |
118 | |
521 | 119 void |
3269
f0d596e84634
rename ngx_peer_addr_t to ngx_addr_t
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
120 ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
121 { |
527 | 122 ngx_int_t rc; |
1136 | 123 ngx_mail_proxy_ctx_t *p; |
124 ngx_mail_proxy_conf_t *pcf; | |
125 ngx_mail_core_srv_conf_t *cscf; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
126 |
587 | 127 s->connection->log->action = "connecting to upstream"; |
128 | |
1136 | 129 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
587 | 130 |
1136 | 131 p = ngx_pcalloc(s->connection->pool, sizeof(ngx_mail_proxy_ctx_t)); |
501 | 132 if (p == NULL) { |
1136 | 133 ngx_mail_session_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
134 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
135 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
136 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
137 s->proxy = p; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
138 |
884 | 139 p->upstream.sockaddr = peer->sockaddr; |
140 p->upstream.socklen = peer->socklen; | |
141 p->upstream.name = &peer->name; | |
142 p->upstream.get = ngx_event_get_peer; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
143 p->upstream.log = s->connection->log; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
144 p->upstream.log_error = NGX_ERROR_ERR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
145 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
146 rc = ngx_event_connect_peer(&p->upstream); |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
147 |
543 | 148 if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) { |
1136 | 149 ngx_mail_proxy_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
150 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
151 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
152 |
527 | 153 ngx_add_timer(p->upstream.connection->read, cscf->timeout); |
154 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
155 p->upstream.connection->data = s; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
156 p->upstream.connection->pool = s->connection->pool; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
157 |
1136 | 158 s->connection->read->handler = ngx_mail_proxy_block_read; |
159 p->upstream.connection->write->handler = ngx_mail_proxy_dummy_handler; | |
160 | |
161 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
162 | |
163 s->proxy->buffer = ngx_create_temp_buf(s->connection->pool, | |
164 pcf->buffer_size); | |
165 if (s->proxy->buffer == NULL) { | |
166 ngx_mail_proxy_internal_server_error(s); | |
167 return; | |
168 } | |
169 | |
1981 | 170 s->out.len = 0; |
171 | |
1136 | 172 switch (s->protocol) { |
527 | 173 |
1136 | 174 case NGX_MAIL_POP3_PROTOCOL: |
175 p->upstream.connection->read->handler = ngx_mail_proxy_pop3_handler; | |
176 s->mail_state = ngx_pop3_start; | |
177 break; | |
527 | 178 |
1136 | 179 case NGX_MAIL_IMAP_PROTOCOL: |
180 p->upstream.connection->read->handler = ngx_mail_proxy_imap_handler; | |
181 s->mail_state = ngx_imap_start; | |
182 break; | |
183 | |
184 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
185 p->upstream.connection->read->handler = ngx_mail_proxy_smtp_handler; | |
186 s->mail_state = ngx_smtp_start; | |
187 break; | |
527 | 188 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
189 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
190 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
191 |
521 | 192 static void |
1136 | 193 ngx_mail_proxy_block_read(ngx_event_t *rev) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
194 { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
195 ngx_connection_t *c; |
1136 | 196 ngx_mail_session_t *s; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
197 |
1136 | 198 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy block read"); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
199 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
200 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
201 c = rev->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
202 s = c->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
203 |
1136 | 204 ngx_mail_proxy_close_session(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
205 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
206 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
207 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
208 |
521 | 209 static void |
1136 | 210 ngx_mail_proxy_pop3_handler(ngx_event_t *rev) |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
211 { |
539 | 212 u_char *p; |
213 ngx_int_t rc; | |
214 ngx_str_t line; | |
215 ngx_connection_t *c; | |
1136 | 216 ngx_mail_session_t *s; |
217 ngx_mail_proxy_conf_t *pcf; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
218 |
1136 | 219 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
220 "mail proxy pop3 auth handler"); | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
221 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
222 c = rev->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
223 s = c->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
224 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
225 if (rev->timedout) { |
527 | 226 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
227 "upstream timed out"); | |
577 | 228 c->timedout = 1; |
1136 | 229 ngx_mail_proxy_internal_server_error(s); |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
230 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
231 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
232 |
1136 | 233 rc = ngx_mail_proxy_read_response(s, 0); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
234 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
235 if (rc == NGX_AGAIN) { |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
236 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
237 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
238 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
239 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
240 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
241 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
242 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
243 |
571 | 244 if (rc == NGX_ERROR) { |
1136 | 245 ngx_mail_proxy_upstream_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
246 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
247 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
248 |
1136 | 249 switch (s->mail_state) { |
587 | 250 |
1136 | 251 case ngx_pop3_start: |
252 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user"); | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
253 |
587 | 254 s->connection->log->action = "sending user name to upstream"; |
255 | |
1136 | 256 line.len = sizeof("USER ") - 1 + s->login.len + 2; |
2049 | 257 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 258 if (line.data == NULL) { |
1136 | 259 ngx_mail_proxy_internal_server_error(s); |
527 | 260 return; |
261 } | |
262 | |
1136 | 263 p = ngx_cpymem(line.data, "USER ", sizeof("USER ") - 1); |
264 p = ngx_cpymem(p, s->login.data, s->login.len); | |
265 *p++ = CR; *p = LF; | |
527 | 266 |
1136 | 267 s->mail_state = ngx_pop3_user; |
527 | 268 break; |
269 | |
1136 | 270 case ngx_pop3_user: |
271 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send pass"); | |
527 | 272 |
587 | 273 s->connection->log->action = "sending password to upstream"; |
274 | |
1136 | 275 line.len = sizeof("PASS ") - 1 + s->passwd.len + 2; |
2049 | 276 line.data = ngx_pnalloc(c->pool, line.len); |
501 | 277 if (line.data == NULL) { |
1136 | 278 ngx_mail_proxy_internal_server_error(s); |
527 | 279 return; |
280 } | |
281 | |
1136 | 282 p = ngx_cpymem(line.data, "PASS ", sizeof("PASS ") - 1); |
283 p = ngx_cpymem(p, s->passwd.data, s->passwd.len); | |
527 | 284 *p++ = CR; *p = LF; |
285 | |
1136 | 286 s->mail_state = ngx_pop3_passwd; |
527 | 287 break; |
288 | |
1136 | 289 case ngx_pop3_passwd: |
290 s->connection->read->handler = ngx_mail_proxy_handler; | |
291 s->connection->write->handler = ngx_mail_proxy_handler; | |
292 rev->handler = ngx_mail_proxy_handler; | |
293 c->write->handler = ngx_mail_proxy_handler; | |
663 | 294 |
1136 | 295 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 296 ngx_add_timer(s->connection->read, pcf->timeout); |
297 ngx_del_timer(c->read); | |
298 | |
299 c->log->action = NULL; | |
300 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
301 | |
1136 | 302 ngx_mail_proxy_handler(s->connection->write); |
663 | 303 |
304 return; | |
305 | |
527 | 306 default: |
307 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
308 ngx_str_null(&line); |
527 | 309 #endif |
310 break; | |
311 } | |
312 | |
539 | 313 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
527 | 314 /* |
315 * we treat the incomplete sending as NGX_ERROR | |
316 * because it is very strange here | |
317 */ | |
1136 | 318 ngx_mail_proxy_internal_server_error(s); |
527 | 319 return; |
320 } | |
321 | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
322 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
323 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
324 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
325 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
326 |
527 | 327 s->proxy->buffer->pos = s->proxy->buffer->start; |
328 s->proxy->buffer->last = s->proxy->buffer->start; | |
329 } | |
330 | |
331 | |
332 static void | |
1136 | 333 ngx_mail_proxy_imap_handler(ngx_event_t *rev) |
527 | 334 { |
539 | 335 u_char *p; |
336 ngx_int_t rc; | |
337 ngx_str_t line; | |
338 ngx_connection_t *c; | |
1136 | 339 ngx_mail_session_t *s; |
340 ngx_mail_proxy_conf_t *pcf; | |
527 | 341 |
1136 | 342 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
343 "mail proxy imap auth handler"); | |
527 | 344 |
345 c = rev->data; | |
346 s = c->data; | |
347 | |
348 if (rev->timedout) { | |
349 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
350 "upstream timed out"); | |
577 | 351 c->timedout = 1; |
1136 | 352 ngx_mail_proxy_internal_server_error(s); |
527 | 353 return; |
354 } | |
355 | |
1136 | 356 rc = ngx_mail_proxy_read_response(s, s->mail_state); |
527 | 357 |
358 if (rc == NGX_AGAIN) { | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
359 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
360 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
361 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
362 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
363 |
527 | 364 return; |
365 } | |
366 | |
571 | 367 if (rc == NGX_ERROR) { |
1136 | 368 ngx_mail_proxy_upstream_error(s); |
527 | 369 return; |
370 } | |
371 | |
1136 | 372 switch (s->mail_state) { |
527 | 373 |
1136 | 374 case ngx_imap_start: |
375 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
376 "mail proxy send login"); | |
527 | 377 |
1136 | 378 s->connection->log->action = "sending LOGIN command to upstream"; |
587 | 379 |
1136 | 380 line.len = s->tag.len + sizeof("LOGIN ") - 1 |
381 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 382 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 383 if (line.data == NULL) { |
1136 | 384 ngx_mail_proxy_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
385 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
386 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
387 |
1136 | 388 line.len = ngx_sprintf(line.data, "%VLOGIN {%uz}" CRLF, |
389 &s->tag, s->login.len) | |
390 - line.data; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
391 |
1136 | 392 s->mail_state = ngx_imap_login; |
527 | 393 break; |
394 | |
1136 | 395 case ngx_imap_login: |
396 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user"); | |
397 | |
398 s->connection->log->action = "sending user name to upstream"; | |
399 | |
400 line.len = s->login.len + 1 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 401 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 402 if (line.data == NULL) { |
403 ngx_mail_proxy_internal_server_error(s); | |
404 return; | |
405 } | |
406 | |
407 line.len = ngx_sprintf(line.data, "%V {%uz}" CRLF, | |
408 &s->login, s->passwd.len) | |
409 - line.data; | |
410 | |
411 s->mail_state = ngx_imap_user; | |
412 break; | |
413 | |
414 case ngx_imap_user: | |
415 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
416 "mail proxy send passwd"); | |
527 | 417 |
587 | 418 s->connection->log->action = "sending password to upstream"; |
419 | |
1136 | 420 line.len = s->passwd.len + 2; |
2049 | 421 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 422 if (line.data == NULL) { |
1136 | 423 ngx_mail_proxy_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
424 return; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
425 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
426 |
1136 | 427 p = ngx_cpymem(line.data, s->passwd.data, s->passwd.len); |
527 | 428 *p++ = CR; *p = LF; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
429 |
1136 | 430 s->mail_state = ngx_imap_passwd; |
527 | 431 break; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
432 |
1136 | 433 case ngx_imap_passwd: |
434 s->connection->read->handler = ngx_mail_proxy_handler; | |
435 s->connection->write->handler = ngx_mail_proxy_handler; | |
436 rev->handler = ngx_mail_proxy_handler; | |
437 c->write->handler = ngx_mail_proxy_handler; | |
663 | 438 |
1136 | 439 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 440 ngx_add_timer(s->connection->read, pcf->timeout); |
441 ngx_del_timer(c->read); | |
442 | |
443 c->log->action = NULL; | |
444 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
445 | |
1136 | 446 ngx_mail_proxy_handler(s->connection->write); |
663 | 447 |
448 return; | |
449 | |
527 | 450 default: |
451 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
452 ngx_str_null(&line); |
527 | 453 #endif |
454 break; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
455 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
456 |
539 | 457 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
458 /* |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
459 * we treat the incomplete sending as NGX_ERROR |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
460 * because it is very strange here |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
461 */ |
1136 | 462 ngx_mail_proxy_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
463 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
464 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
465 |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
466 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
467 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
468 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
469 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
470 |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
471 s->proxy->buffer->pos = s->proxy->buffer->start; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
472 s->proxy->buffer->last = s->proxy->buffer->start; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
473 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
474 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
475 |
521 | 476 static void |
1136 | 477 ngx_mail_proxy_smtp_handler(ngx_event_t *rev) |
478 { | |
479 u_char *p; | |
480 ngx_int_t rc; | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
481 ngx_str_t line, auth, encoded; |
2309 | 482 ngx_buf_t *b; |
1136 | 483 ngx_connection_t *c; |
484 ngx_mail_session_t *s; | |
485 ngx_mail_proxy_conf_t *pcf; | |
486 ngx_mail_core_srv_conf_t *cscf; | |
487 | |
488 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
489 "mail proxy smtp auth handler"); | |
490 | |
491 c = rev->data; | |
492 s = c->data; | |
493 | |
494 if (rev->timedout) { | |
495 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
496 "upstream timed out"); | |
497 c->timedout = 1; | |
498 ngx_mail_proxy_internal_server_error(s); | |
499 return; | |
500 } | |
501 | |
502 rc = ngx_mail_proxy_read_response(s, s->mail_state); | |
503 | |
504 if (rc == NGX_AGAIN) { | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
505 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
506 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
507 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
508 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
509 |
1136 | 510 return; |
511 } | |
512 | |
513 if (rc == NGX_ERROR) { | |
514 ngx_mail_proxy_upstream_error(s); | |
515 return; | |
516 } | |
517 | |
518 switch (s->mail_state) { | |
519 | |
520 case ngx_smtp_start: | |
521 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send ehlo"); | |
522 | |
523 s->connection->log->action = "sending HELO/EHLO to upstream"; | |
524 | |
525 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
526 | |
527 line.len = sizeof("HELO ") - 1 + cscf->server_name.len + 2; | |
2049 | 528 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 529 if (line.data == NULL) { |
530 ngx_mail_proxy_internal_server_error(s); | |
531 return; | |
532 } | |
533 | |
534 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
535 | |
536 p = ngx_cpymem(line.data, | |
537 ((s->esmtp || pcf->xclient) ? "EHLO " : "HELO "), | |
538 sizeof("HELO ") - 1); | |
539 | |
540 p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); | |
541 *p++ = CR; *p = LF; | |
542 | |
2309 | 543 if (pcf->xclient) { |
544 s->mail_state = ngx_smtp_helo_xclient; | |
545 | |
546 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
547 s->mail_state = ngx_smtp_helo_from; | |
548 | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
549 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
550 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
551 |
2309 | 552 } else { |
553 s->mail_state = ngx_smtp_helo; | |
554 } | |
1136 | 555 |
556 break; | |
557 | |
2309 | 558 case ngx_smtp_helo_xclient: |
1136 | 559 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
560 "mail proxy send xclient"); | |
561 | |
562 s->connection->log->action = "sending XCLIENT to upstream"; | |
563 | |
2497 | 564 line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" |
1892
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
565 CRLF) - 1 |
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
566 + s->connection->addr_text.len + s->login.len + s->host.len; |
1136 | 567 |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
568 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
569 if (s->connection->sockaddr->sa_family == AF_INET6) { |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
570 line.len += sizeof("IPV6:") - 1; |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
571 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
572 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
573 |
2049 | 574 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 575 if (line.data == NULL) { |
576 ngx_mail_proxy_internal_server_error(s); | |
577 return; | |
578 } | |
579 | |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
580 p = ngx_cpymem(line.data, "XCLIENT ADDR=", sizeof("XCLIENT ADDR=") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
581 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
582 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
583 if (s->connection->sockaddr->sa_family == AF_INET6) { |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
584 p = ngx_cpymem(p, "IPV6:", sizeof("IPV6:") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
585 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
586 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
587 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
588 p = ngx_copy(p, s->connection->addr_text.data, |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
589 s->connection->addr_text.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
590 |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
591 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
592 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
593 if (s->login.len && !pcf->smtp_auth) { |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
594 p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
595 p = ngx_copy(p, s->login.data, s->login.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
596 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
597 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
598 p = ngx_cpymem(p, " NAME=", sizeof(" NAME=") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
599 p = ngx_copy(p, s->host.data, s->host.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
600 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
601 *p++ = CR; *p++ = LF; |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
602 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
603 line.len = p - line.data; |
2309 | 604 |
2497 | 605 if (s->smtp_helo.len) { |
606 s->mail_state = ngx_smtp_xclient_helo; | |
607 | |
608 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
609 s->mail_state = ngx_smtp_xclient_from; | |
610 | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
611 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
612 s->mail_state = ngx_smtp_xclient_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
613 |
2497 | 614 } else { |
615 s->mail_state = ngx_smtp_xclient; | |
616 } | |
617 | |
618 break; | |
619 | |
620 case ngx_smtp_xclient_helo: | |
621 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
622 "mail proxy send client ehlo"); | |
623 | |
624 s->connection->log->action = "sending client HELO/EHLO to upstream"; | |
625 | |
626 line.len = sizeof("HELO " CRLF) - 1 + s->smtp_helo.len; | |
627 | |
628 line.data = ngx_pnalloc(c->pool, line.len); | |
629 if (line.data == NULL) { | |
630 ngx_mail_proxy_internal_server_error(s); | |
631 return; | |
632 } | |
633 | |
634 line.len = ngx_sprintf(line.data, | |
635 ((s->esmtp) ? "EHLO %V" CRLF : "HELO %V" CRLF), | |
636 &s->smtp_helo) | |
637 - line.data; | |
638 | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
639 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
640 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
641 if (s->auth_method == NGX_MAIL_AUTH_NONE) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
642 s->mail_state = ngx_smtp_helo_from; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
643 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
644 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
645 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
646 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
647 } else { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
648 s->mail_state = ngx_smtp_helo; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
649 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
650 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
651 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
652 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
653 case ngx_smtp_helo_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
654 case ngx_smtp_xclient_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
655 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
656 "mail proxy send auth"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
657 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
658 s->connection->log->action = "sending AUTH to upstream"; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
659 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
660 if (s->passwd.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
661 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
662 "no password available"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
663 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
664 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
665 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
666 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
667 auth.len = 1 + s->login.len + 1 + s->passwd.len; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
668 auth.data = ngx_pnalloc(c->pool, auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
669 if (auth.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
670 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
671 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
672 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
673 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
674 auth.len = ngx_sprintf(auth.data, "%Z%V%Z%V", &s->login, &s->passwd) |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
675 - auth.data; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
676 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
677 line.len = sizeof("AUTH PLAIN " CRLF) - 1 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
678 + ngx_base64_encoded_length(auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
679 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
680 line.data = ngx_pnalloc(c->pool, line.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
681 if (line.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
682 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
683 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
684 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
685 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
686 encoded.data = ngx_cpymem(line.data, "AUTH PLAIN ", |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
687 sizeof("AUTH PLAIN ") - 1); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
688 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
689 ngx_encode_base64(&encoded, &auth); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
690 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
691 p = encoded.data + encoded.len; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
692 *p++ = CR; *p = LF; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
693 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
694 s->mail_state = ngx_smtp_auth_plain; |
2309 | 695 |
696 break; | |
697 | |
698 case ngx_smtp_helo_from: | |
699 case ngx_smtp_xclient_from: | |
700 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
701 "mail proxy send mail from"); | |
702 | |
703 s->connection->log->action = "sending MAIL FROM to upstream"; | |
704 | |
705 line.len = s->smtp_from.len + sizeof(CRLF) - 1; | |
706 line.data = ngx_pnalloc(c->pool, line.len); | |
707 if (line.data == NULL) { | |
708 ngx_mail_proxy_internal_server_error(s); | |
709 return; | |
1136 | 710 } |
711 | |
2309 | 712 p = ngx_cpymem(line.data, s->smtp_from.data, s->smtp_from.len); |
713 *p++ = CR; *p = LF; | |
714 | |
715 s->mail_state = ngx_smtp_from; | |
716 | |
1136 | 717 break; |
718 | |
2309 | 719 case ngx_smtp_from: |
720 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
721 "mail proxy send rcpt to"); | |
722 | |
723 s->connection->log->action = "sending RCPT TO to upstream"; | |
724 | |
725 line.len = s->smtp_to.len + sizeof(CRLF) - 1; | |
726 line.data = ngx_pnalloc(c->pool, line.len); | |
727 if (line.data == NULL) { | |
728 ngx_mail_proxy_internal_server_error(s); | |
729 return; | |
730 } | |
731 | |
732 p = ngx_cpymem(line.data, s->smtp_to.data, s->smtp_to.len); | |
733 *p++ = CR; *p = LF; | |
734 | |
735 s->mail_state = ngx_smtp_to; | |
1136 | 736 |
2309 | 737 break; |
738 | |
739 case ngx_smtp_helo: | |
740 case ngx_smtp_xclient: | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
741 case ngx_smtp_auth_plain: |
2309 | 742 case ngx_smtp_to: |
743 | |
744 b = s->proxy->buffer; | |
1136 | 745 |
2309 | 746 if (s->auth_method == NGX_MAIL_AUTH_NONE) { |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
747 b->pos = b->start; |
2309 | 748 |
749 } else { | |
2440
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
750 ngx_memcpy(b->start, smtp_auth_ok, sizeof(smtp_auth_ok) - 1); |
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
751 b->last = b->start + sizeof(smtp_auth_ok) - 1; |
2309 | 752 } |
753 | |
1136 | 754 s->connection->read->handler = ngx_mail_proxy_handler; |
755 s->connection->write->handler = ngx_mail_proxy_handler; | |
756 rev->handler = ngx_mail_proxy_handler; | |
757 c->write->handler = ngx_mail_proxy_handler; | |
758 | |
759 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
760 ngx_add_timer(s->connection->read, pcf->timeout); | |
761 ngx_del_timer(c->read); | |
762 | |
763 c->log->action = NULL; | |
764 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
765 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
766 if (s->buffer->pos == s->buffer->last) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
767 ngx_mail_proxy_handler(s->connection->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
768 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
769 } else { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
770 ngx_mail_proxy_handler(c->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
771 } |
1136 | 772 |
773 return; | |
774 | |
775 default: | |
776 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
777 ngx_str_null(&line); |
1136 | 778 #endif |
779 break; | |
780 } | |
781 | |
782 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { | |
783 /* | |
784 * we treat the incomplete sending as NGX_ERROR | |
785 * because it is very strange here | |
786 */ | |
787 ngx_mail_proxy_internal_server_error(s); | |
788 return; | |
789 } | |
790 | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
791 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
792 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
793 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
794 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
795 |
1136 | 796 s->proxy->buffer->pos = s->proxy->buffer->start; |
797 s->proxy->buffer->last = s->proxy->buffer->start; | |
798 } | |
799 | |
800 | |
801 static void | |
802 ngx_mail_proxy_dummy_handler(ngx_event_t *wev) | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
803 { |
583 | 804 ngx_connection_t *c; |
1136 | 805 ngx_mail_session_t *s; |
583 | 806 |
1136 | 807 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler"); |
583 | 808 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
809 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
583 | 810 c = wev->data; |
811 s = c->data; | |
812 | |
1136 | 813 ngx_mail_proxy_close_session(s); |
583 | 814 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
815 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
816 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
817 |
521 | 818 static ngx_int_t |
1136 | 819 ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
820 { |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
821 u_char *p, *m; |
857 | 822 ssize_t n; |
823 ngx_buf_t *b; | |
1136 | 824 ngx_mail_proxy_conf_t *pcf; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
825 |
587 | 826 s->connection->log->action = "reading response from upstream"; |
827 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
828 b = s->proxy->buffer; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
829 |
539 | 830 n = s->proxy->upstream.connection->recv(s->proxy->upstream.connection, |
831 b->last, b->end - b->last); | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
832 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
833 if (n == NGX_ERROR || n == 0) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
834 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
835 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
836 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
837 if (n == NGX_AGAIN) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
838 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
839 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
840 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
841 b->last += n; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
842 |
3505
c631ef8beaaa
Zimbra IMAP server may return only 4 bytes: "+ \r\n"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
843 if (b->last - b->pos < 4) { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
844 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
845 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
846 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
847 if (*(b->last - 2) != CR || *(b->last - 1) != LF) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
848 if (b->last == b->end) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
849 *(b->last - 1) = '\0'; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
850 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
851 "upstream sent too long response line: \"%s\"", |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
852 b->pos); |
571 | 853 return NGX_ERROR; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
854 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
855 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
856 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
857 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
858 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
859 p = b->pos; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
860 |
1136 | 861 switch (s->protocol) { |
862 | |
863 case NGX_MAIL_POP3_PROTOCOL: | |
527 | 864 if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') { |
865 return NGX_OK; | |
866 } | |
1136 | 867 break; |
527 | 868 |
1136 | 869 case NGX_MAIL_IMAP_PROTOCOL: |
663 | 870 switch (state) { |
871 | |
872 case ngx_imap_start: | |
527 | 873 if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') { |
874 return NGX_OK; | |
875 } | |
663 | 876 break; |
527 | 877 |
663 | 878 case ngx_imap_login: |
879 case ngx_imap_user: | |
529 | 880 if (p[0] == '+') { |
527 | 881 return NGX_OK; |
882 } | |
663 | 883 break; |
884 | |
885 case ngx_imap_passwd: | |
886 if (ngx_strncmp(p, s->tag.data, s->tag.len) == 0) { | |
887 p += s->tag.len; | |
888 if (p[0] == 'O' && p[1] == 'K') { | |
889 return NGX_OK; | |
890 } | |
891 } | |
892 break; | |
527 | 893 } |
1136 | 894 |
895 break; | |
896 | |
897 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
898 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
899 if (p[3] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
900 /* multiline reply, check if we got last line */ |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
901 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
902 m = b->last - (sizeof(CRLF "200" CRLF) - 1); |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
903 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
904 while (m > p) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
905 if (m[0] == CR && m[1] == LF) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
906 break; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
907 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
908 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
909 m--; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
910 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
911 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
912 if (m <= p || m[5] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
913 return NGX_AGAIN; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
914 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
915 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
916 |
1136 | 917 switch (state) { |
918 | |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
919 case ngx_smtp_start: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
920 if (p[0] == '2' && p[1] == '2' && p[2] == '0') { |
1166 | 921 return NGX_OK; |
922 } | |
923 break; | |
1136 | 924 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
925 case ngx_smtp_helo: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
926 case ngx_smtp_helo_xclient: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
927 case ngx_smtp_helo_from: |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
928 case ngx_smtp_helo_auth: |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
929 case ngx_smtp_from: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
930 if (p[0] == '2' && p[1] == '5' && p[2] == '0') { |
2309 | 931 return NGX_OK; |
932 } | |
933 break; | |
934 | |
1136 | 935 case ngx_smtp_xclient: |
2309 | 936 case ngx_smtp_xclient_from: |
2497 | 937 case ngx_smtp_xclient_helo: |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
938 case ngx_smtp_xclient_auth: |
2309 | 939 if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') { |
1166 | 940 return NGX_OK; |
941 } | |
942 break; | |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
943 |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
944 case ngx_smtp_auth_plain: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
945 if (p[0] == '2' && p[1] == '3' && p[2] == '5') { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
946 return NGX_OK; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
947 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
948 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
949 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
950 case ngx_smtp_to: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
951 return NGX_OK; |
1136 | 952 } |
953 | |
1166 | 954 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
955 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
956 |
1136 | 957 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
857 | 958 |
959 if (pcf->pass_error_message == 0) { | |
960 *(b->last - 2) = '\0'; | |
961 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
962 "upstream sent invalid response: \"%s\"", p); | |
963 return NGX_ERROR; | |
964 } | |
965 | |
966 s->out.len = b->last - p - 2; | |
967 s->out.data = p; | |
968 | |
969 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, | |
970 "upstream sent invalid response: \"%V\"", &s->out); | |
971 | |
972 s->out.len = b->last - b->pos; | |
973 s->out.data = b->pos; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
974 |
571 | 975 return NGX_ERROR; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
976 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
977 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
978 |
521 | 979 static void |
1136 | 980 ngx_mail_proxy_handler(ngx_event_t *ev) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
981 { |
583 | 982 char *action, *recv_action, *send_action; |
539 | 983 size_t size; |
984 ssize_t n; | |
985 ngx_buf_t *b; | |
583 | 986 ngx_uint_t do_write; |
539 | 987 ngx_connection_t *c, *src, *dst; |
1136 | 988 ngx_mail_session_t *s; |
989 ngx_mail_proxy_conf_t *pcf; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
990 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
991 c = ev->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
992 s = c->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
993 |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
994 if (ev->timedout || c->close) { |
583 | 995 c->log->action = "proxying"; |
996 | |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
997 if (c->close) { |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
998 ngx_log_error(NGX_LOG_INFO, c->log, 0, "shutdown timeout"); |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
999 |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
1000 } else if (c == s->connection) { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1001 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1002 "client timed out"); |
577 | 1003 c->timedout = 1; |
1004 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1005 } else { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1006 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1007 "upstream timed out"); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1008 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1009 |
1136 | 1010 ngx_mail_proxy_close_session(s); |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1011 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1012 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1013 |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1014 if (c == s->connection) { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1015 if (ev->write) { |
583 | 1016 recv_action = "proxying and reading from upstream"; |
1017 send_action = "proxying and sending to client"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1018 src = s->proxy->upstream.connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1019 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1020 b = s->proxy->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1021 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1022 } else { |
583 | 1023 recv_action = "proxying and reading from client"; |
1024 send_action = "proxying and sending to upstream"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1025 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1026 dst = s->proxy->upstream.connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1027 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1028 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1029 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1030 } else { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1031 if (ev->write) { |
589 | 1032 recv_action = "proxying and reading from client"; |
1033 send_action = "proxying and sending to upstream"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1034 src = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1035 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1036 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1037 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1038 } else { |
589 | 1039 recv_action = "proxying and reading from upstream"; |
1040 send_action = "proxying and sending to client"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1041 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1042 dst = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1043 b = s->proxy->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1044 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1045 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1046 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1047 do_write = ev->write ? 1 : 0; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1048 |
1136 | 1049 ngx_log_debug3(NGX_LOG_DEBUG_MAIL, ev->log, 0, |
6480 | 1050 "mail proxy handler: %ui, #%d > #%d", |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1051 do_write, src->fd, dst->fd); |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1052 |
583 | 1053 for ( ;; ) { |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1054 |
583 | 1055 if (do_write) { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1056 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1057 size = b->last - b->pos; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1058 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1059 if (size && dst->write->ready) { |
583 | 1060 c->log->action = send_action; |
1061 | |
539 | 1062 n = dst->send(dst, b->pos, size); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1063 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1064 if (n == NGX_ERROR) { |
1136 | 1065 ngx_mail_proxy_close_session(s); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1066 return; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1067 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1068 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1069 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1070 b->pos += n; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1071 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1072 if (b->pos == b->last) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1073 b->pos = b->start; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1074 b->last = b->start; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1075 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1076 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1077 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1078 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1079 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1080 size = b->end - b->last; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1081 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1082 if (size && src->read->ready) { |
583 | 1083 c->log->action = recv_action; |
1084 | |
539 | 1085 n = src->recv(src, b->last, size); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1086 |
583 | 1087 if (n == NGX_AGAIN || n == 0) { |
1088 break; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1089 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1090 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1091 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1092 do_write = 1; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1093 b->last += n; |
583 | 1094 |
1095 continue; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1096 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1097 |
583 | 1098 if (n == NGX_ERROR) { |
1099 src->read->eof = 1; | |
539 | 1100 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1101 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1102 |
583 | 1103 break; |
1104 } | |
1105 | |
1106 c->log->action = "proxying"; | |
1107 | |
1342
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1108 if ((s->connection->read->eof && s->buffer->pos == s->buffer->last) |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1109 || (s->proxy->upstream.connection->read->eof |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1110 && s->proxy->buffer->pos == s->proxy->buffer->last) |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1111 || (s->connection->read->eof |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1112 && s->proxy->upstream.connection->read->eof)) |
583 | 1113 { |
1114 action = c->log->action; | |
1115 c->log->action = NULL; | |
1116 ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done"); | |
1117 c->log->action = action; | |
1118 | |
1136 | 1119 ngx_mail_proxy_close_session(s); |
583 | 1120 return; |
1121 } | |
1122 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1123 if (ngx_handle_write_event(dst->write, 0) != NGX_OK) { |
1136 | 1124 ngx_mail_proxy_close_session(s); |
583 | 1125 return; |
1126 } | |
1127 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1128 if (ngx_handle_read_event(dst->read, 0) != NGX_OK) { |
1136 | 1129 ngx_mail_proxy_close_session(s); |
583 | 1130 return; |
1131 } | |
1132 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1133 if (ngx_handle_write_event(src->write, 0) != NGX_OK) { |
1136 | 1134 ngx_mail_proxy_close_session(s); |
583 | 1135 return; |
1136 } | |
1137 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1138 if (ngx_handle_read_event(src->read, 0) != NGX_OK) { |
1136 | 1139 ngx_mail_proxy_close_session(s); |
583 | 1140 return; |
1141 } | |
1142 | |
1143 if (c == s->connection) { | |
1136 | 1144 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
583 | 1145 ngx_add_timer(c->read, pcf->timeout); |
1146 } | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1147 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1148 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1149 |
521 | 1150 static void |
1136 | 1151 ngx_mail_proxy_upstream_error(ngx_mail_session_t *s) |
857 | 1152 { |
1153 if (s->proxy->upstream.connection) { | |
1136 | 1154 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1155 "close mail proxy connection: %d", | |
857 | 1156 s->proxy->upstream.connection->fd); |
1157 | |
1158 ngx_close_connection(s->proxy->upstream.connection); | |
1159 } | |
1160 | |
1161 if (s->out.len == 0) { | |
1136 | 1162 ngx_mail_session_internal_server_error(s); |
857 | 1163 return; |
1164 } | |
1165 | |
1166 s->quit = 1; | |
1136 | 1167 ngx_mail_send(s->connection->write); |
857 | 1168 } |
1169 | |
1170 | |
1171 static void | |
1136 | 1172 ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s) |
527 | 1173 { |
1174 if (s->proxy->upstream.connection) { | |
1136 | 1175 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1176 "close mail proxy connection: %d", | |
527 | 1177 s->proxy->upstream.connection->fd); |
1178 | |
1179 ngx_close_connection(s->proxy->upstream.connection); | |
1180 } | |
1181 | |
1136 | 1182 ngx_mail_session_internal_server_error(s); |
527 | 1183 } |
1184 | |
1185 | |
1186 static void | |
1136 | 1187 ngx_mail_proxy_close_session(ngx_mail_session_t *s) |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1188 { |
521 | 1189 if (s->proxy->upstream.connection) { |
1136 | 1190 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1191 "close mail proxy connection: %d", | |
521 | 1192 s->proxy->upstream.connection->fd); |
1193 | |
1194 ngx_close_connection(s->proxy->upstream.connection); | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1195 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1196 |
1136 | 1197 ngx_mail_close_connection(s->connection); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1198 } |
521 | 1199 |
1200 | |
1201 static void * | |
1136 | 1202 ngx_mail_proxy_create_conf(ngx_conf_t *cf) |
577 | 1203 { |
1136 | 1204 ngx_mail_proxy_conf_t *pcf; |
577 | 1205 |
1136 | 1206 pcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_proxy_conf_t)); |
521 | 1207 if (pcf == NULL) { |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2497
diff
changeset
|
1208 return NULL; |
521 | 1209 } |
1210 | |
1211 pcf->enable = NGX_CONF_UNSET; | |
857 | 1212 pcf->pass_error_message = NGX_CONF_UNSET; |
1136 | 1213 pcf->xclient = NGX_CONF_UNSET; |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1214 pcf->smtp_auth = NGX_CONF_UNSET; |
539 | 1215 pcf->buffer_size = NGX_CONF_UNSET_SIZE; |
1216 pcf->timeout = NGX_CONF_UNSET_MSEC; | |
521 | 1217 |
1218 return pcf; | |
1219 } | |
1220 | |
1221 | |
1222 static char * | |
1136 | 1223 ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 1224 { |
1136 | 1225 ngx_mail_proxy_conf_t *prev = parent; |
1226 ngx_mail_proxy_conf_t *conf = child; | |
521 | 1227 |
539 | 1228 ngx_conf_merge_value(conf->enable, prev->enable, 0); |
857 | 1229 ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0); |
1136 | 1230 ngx_conf_merge_value(conf->xclient, prev->xclient, 1); |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1231 ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0); |
539 | 1232 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1233 (size_t) ngx_pagesize); | |
1234 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); | |
521 | 1235 |
1236 return NGX_CONF_OK; | |
1237 } |