Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_proxy_module.c @ 8249:90cc7194e993
Upstream: excluded down servers from the next_upstream tries.
Previously, the number of next_upstream tries included servers marked
as "down", resulting in "no live upstreams" with the code 502 instead
of the code derived from an attempt to connect to the last tried "up"
server (ticket #2096).
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Fri, 27 Nov 2020 00:01:20 +0300 |
parents | d63c5373b5ba |
children | da0a85e91587 |
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; |
8178
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 | |
8178
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) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
236 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
237 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
238 |
571 | 239 if (rc == NGX_ERROR) { |
1136 | 240 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
|
241 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
242 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
243 |
1136 | 244 switch (s->mail_state) { |
587 | 245 |
1136 | 246 case ngx_pop3_start: |
247 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
|
248 |
587 | 249 s->connection->log->action = "sending user name to upstream"; |
250 | |
1136 | 251 line.len = sizeof("USER ") - 1 + s->login.len + 2; |
2049 | 252 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 253 if (line.data == NULL) { |
1136 | 254 ngx_mail_proxy_internal_server_error(s); |
527 | 255 return; |
256 } | |
257 | |
1136 | 258 p = ngx_cpymem(line.data, "USER ", sizeof("USER ") - 1); |
259 p = ngx_cpymem(p, s->login.data, s->login.len); | |
260 *p++ = CR; *p = LF; | |
527 | 261 |
1136 | 262 s->mail_state = ngx_pop3_user; |
527 | 263 break; |
264 | |
1136 | 265 case ngx_pop3_user: |
266 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send pass"); | |
527 | 267 |
587 | 268 s->connection->log->action = "sending password to upstream"; |
269 | |
1136 | 270 line.len = sizeof("PASS ") - 1 + s->passwd.len + 2; |
2049 | 271 line.data = ngx_pnalloc(c->pool, line.len); |
501 | 272 if (line.data == NULL) { |
1136 | 273 ngx_mail_proxy_internal_server_error(s); |
527 | 274 return; |
275 } | |
276 | |
1136 | 277 p = ngx_cpymem(line.data, "PASS ", sizeof("PASS ") - 1); |
278 p = ngx_cpymem(p, s->passwd.data, s->passwd.len); | |
527 | 279 *p++ = CR; *p = LF; |
280 | |
1136 | 281 s->mail_state = ngx_pop3_passwd; |
527 | 282 break; |
283 | |
1136 | 284 case ngx_pop3_passwd: |
285 s->connection->read->handler = ngx_mail_proxy_handler; | |
286 s->connection->write->handler = ngx_mail_proxy_handler; | |
287 rev->handler = ngx_mail_proxy_handler; | |
288 c->write->handler = ngx_mail_proxy_handler; | |
663 | 289 |
1136 | 290 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 291 ngx_add_timer(s->connection->read, pcf->timeout); |
292 ngx_del_timer(c->read); | |
293 | |
294 c->log->action = NULL; | |
295 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
296 | |
1136 | 297 ngx_mail_proxy_handler(s->connection->write); |
663 | 298 |
299 return; | |
300 | |
527 | 301 default: |
302 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
303 ngx_str_null(&line); |
527 | 304 #endif |
305 break; | |
306 } | |
307 | |
539 | 308 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
527 | 309 /* |
310 * we treat the incomplete sending as NGX_ERROR | |
311 * because it is very strange here | |
312 */ | |
1136 | 313 ngx_mail_proxy_internal_server_error(s); |
527 | 314 return; |
315 } | |
316 | |
317 s->proxy->buffer->pos = s->proxy->buffer->start; | |
318 s->proxy->buffer->last = s->proxy->buffer->start; | |
319 } | |
320 | |
321 | |
322 static void | |
1136 | 323 ngx_mail_proxy_imap_handler(ngx_event_t *rev) |
527 | 324 { |
539 | 325 u_char *p; |
326 ngx_int_t rc; | |
327 ngx_str_t line; | |
328 ngx_connection_t *c; | |
1136 | 329 ngx_mail_session_t *s; |
330 ngx_mail_proxy_conf_t *pcf; | |
527 | 331 |
1136 | 332 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
333 "mail proxy imap auth handler"); | |
527 | 334 |
335 c = rev->data; | |
336 s = c->data; | |
337 | |
338 if (rev->timedout) { | |
339 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
340 "upstream timed out"); | |
577 | 341 c->timedout = 1; |
1136 | 342 ngx_mail_proxy_internal_server_error(s); |
527 | 343 return; |
344 } | |
345 | |
1136 | 346 rc = ngx_mail_proxy_read_response(s, s->mail_state); |
527 | 347 |
348 if (rc == NGX_AGAIN) { | |
349 return; | |
350 } | |
351 | |
571 | 352 if (rc == NGX_ERROR) { |
1136 | 353 ngx_mail_proxy_upstream_error(s); |
527 | 354 return; |
355 } | |
356 | |
1136 | 357 switch (s->mail_state) { |
527 | 358 |
1136 | 359 case ngx_imap_start: |
360 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
361 "mail proxy send login"); | |
527 | 362 |
1136 | 363 s->connection->log->action = "sending LOGIN command to upstream"; |
587 | 364 |
1136 | 365 line.len = s->tag.len + sizeof("LOGIN ") - 1 |
366 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 367 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 368 if (line.data == NULL) { |
1136 | 369 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
|
370 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
371 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
372 |
1136 | 373 line.len = ngx_sprintf(line.data, "%VLOGIN {%uz}" CRLF, |
374 &s->tag, s->login.len) | |
375 - line.data; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
376 |
1136 | 377 s->mail_state = ngx_imap_login; |
527 | 378 break; |
379 | |
1136 | 380 case ngx_imap_login: |
381 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user"); | |
382 | |
383 s->connection->log->action = "sending user name to upstream"; | |
384 | |
385 line.len = s->login.len + 1 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 386 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 387 if (line.data == NULL) { |
388 ngx_mail_proxy_internal_server_error(s); | |
389 return; | |
390 } | |
391 | |
392 line.len = ngx_sprintf(line.data, "%V {%uz}" CRLF, | |
393 &s->login, s->passwd.len) | |
394 - line.data; | |
395 | |
396 s->mail_state = ngx_imap_user; | |
397 break; | |
398 | |
399 case ngx_imap_user: | |
400 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
401 "mail proxy send passwd"); | |
527 | 402 |
587 | 403 s->connection->log->action = "sending password to upstream"; |
404 | |
1136 | 405 line.len = s->passwd.len + 2; |
2049 | 406 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 407 if (line.data == NULL) { |
1136 | 408 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
|
409 return; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
410 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
411 |
1136 | 412 p = ngx_cpymem(line.data, s->passwd.data, s->passwd.len); |
527 | 413 *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
|
414 |
1136 | 415 s->mail_state = ngx_imap_passwd; |
527 | 416 break; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
417 |
1136 | 418 case ngx_imap_passwd: |
419 s->connection->read->handler = ngx_mail_proxy_handler; | |
420 s->connection->write->handler = ngx_mail_proxy_handler; | |
421 rev->handler = ngx_mail_proxy_handler; | |
422 c->write->handler = ngx_mail_proxy_handler; | |
663 | 423 |
1136 | 424 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 425 ngx_add_timer(s->connection->read, pcf->timeout); |
426 ngx_del_timer(c->read); | |
427 | |
428 c->log->action = NULL; | |
429 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
430 | |
1136 | 431 ngx_mail_proxy_handler(s->connection->write); |
663 | 432 |
433 return; | |
434 | |
527 | 435 default: |
436 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
437 ngx_str_null(&line); |
527 | 438 #endif |
439 break; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
440 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
441 |
539 | 442 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
|
443 /* |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
444 * 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
|
445 * 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
|
446 */ |
1136 | 447 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
|
448 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
449 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
450 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
451 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
|
452 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
|
453 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
454 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
455 |
521 | 456 static void |
1136 | 457 ngx_mail_proxy_smtp_handler(ngx_event_t *rev) |
458 { | |
459 u_char *p; | |
460 ngx_int_t rc; | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
461 ngx_str_t line, auth, encoded; |
2309 | 462 ngx_buf_t *b; |
1136 | 463 ngx_connection_t *c; |
464 ngx_mail_session_t *s; | |
465 ngx_mail_proxy_conf_t *pcf; | |
466 ngx_mail_core_srv_conf_t *cscf; | |
467 | |
468 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
469 "mail proxy smtp auth handler"); | |
470 | |
471 c = rev->data; | |
472 s = c->data; | |
473 | |
474 if (rev->timedout) { | |
475 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
476 "upstream timed out"); | |
477 c->timedout = 1; | |
478 ngx_mail_proxy_internal_server_error(s); | |
479 return; | |
480 } | |
481 | |
482 rc = ngx_mail_proxy_read_response(s, s->mail_state); | |
483 | |
484 if (rc == NGX_AGAIN) { | |
485 return; | |
486 } | |
487 | |
488 if (rc == NGX_ERROR) { | |
489 ngx_mail_proxy_upstream_error(s); | |
490 return; | |
491 } | |
492 | |
493 switch (s->mail_state) { | |
494 | |
495 case ngx_smtp_start: | |
496 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send ehlo"); | |
497 | |
498 s->connection->log->action = "sending HELO/EHLO to upstream"; | |
499 | |
500 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
501 | |
502 line.len = sizeof("HELO ") - 1 + cscf->server_name.len + 2; | |
2049 | 503 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 504 if (line.data == NULL) { |
505 ngx_mail_proxy_internal_server_error(s); | |
506 return; | |
507 } | |
508 | |
509 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
510 | |
511 p = ngx_cpymem(line.data, | |
512 ((s->esmtp || pcf->xclient) ? "EHLO " : "HELO "), | |
513 sizeof("HELO ") - 1); | |
514 | |
515 p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); | |
516 *p++ = CR; *p = LF; | |
517 | |
2309 | 518 if (pcf->xclient) { |
519 s->mail_state = ngx_smtp_helo_xclient; | |
520 | |
521 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
522 s->mail_state = ngx_smtp_helo_from; | |
523 | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
524 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
525 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
526 |
2309 | 527 } else { |
528 s->mail_state = ngx_smtp_helo; | |
529 } | |
1136 | 530 |
531 break; | |
532 | |
2309 | 533 case ngx_smtp_helo_xclient: |
1136 | 534 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
535 "mail proxy send xclient"); | |
536 | |
537 s->connection->log->action = "sending XCLIENT to upstream"; | |
538 | |
2497 | 539 line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" |
1892
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
540 CRLF) - 1 |
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
541 + s->connection->addr_text.len + s->login.len + s->host.len; |
1136 | 542 |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
543 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
544 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
|
545 line.len += sizeof("IPV6:") - 1; |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
546 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
547 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
548 |
2049 | 549 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 550 if (line.data == NULL) { |
551 ngx_mail_proxy_internal_server_error(s); | |
552 return; | |
553 } | |
554 | |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
555 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
|
556 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
557 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
558 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
|
559 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
|
560 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
561 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
562 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
563 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
|
564 s->connection->addr_text.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
565 |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
566 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
|
567 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
568 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
|
569 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
|
570 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
|
571 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
572 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
573 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
|
574 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
|
575 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
576 *p++ = CR; *p++ = LF; |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
577 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
578 line.len = p - line.data; |
2309 | 579 |
2497 | 580 if (s->smtp_helo.len) { |
581 s->mail_state = ngx_smtp_xclient_helo; | |
582 | |
583 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
584 s->mail_state = ngx_smtp_xclient_from; | |
585 | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
586 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
587 s->mail_state = ngx_smtp_xclient_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
588 |
2497 | 589 } else { |
590 s->mail_state = ngx_smtp_xclient; | |
591 } | |
592 | |
593 break; | |
594 | |
595 case ngx_smtp_xclient_helo: | |
596 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
597 "mail proxy send client ehlo"); | |
598 | |
599 s->connection->log->action = "sending client HELO/EHLO to upstream"; | |
600 | |
601 line.len = sizeof("HELO " CRLF) - 1 + s->smtp_helo.len; | |
602 | |
603 line.data = ngx_pnalloc(c->pool, line.len); | |
604 if (line.data == NULL) { | |
605 ngx_mail_proxy_internal_server_error(s); | |
606 return; | |
607 } | |
608 | |
609 line.len = ngx_sprintf(line.data, | |
610 ((s->esmtp) ? "EHLO %V" CRLF : "HELO %V" CRLF), | |
611 &s->smtp_helo) | |
612 - line.data; | |
613 | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
614 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
|
615 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
616 if (s->auth_method == NGX_MAIL_AUTH_NONE) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
617 s->mail_state = ngx_smtp_helo_from; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
618 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
619 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
620 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
621 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
622 } else { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
623 s->mail_state = ngx_smtp_helo; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
624 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
625 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
626 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
627 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
628 case ngx_smtp_helo_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
629 case ngx_smtp_xclient_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
630 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
|
631 "mail proxy send auth"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
632 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
633 s->connection->log->action = "sending AUTH to upstream"; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
634 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
635 if (s->passwd.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
636 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
|
637 "no password available"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
638 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
639 return; |
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 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
642 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
|
643 auth.data = ngx_pnalloc(c->pool, auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
644 if (auth.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
645 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
646 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
647 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
648 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
649 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
|
650 - auth.data; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
651 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
652 line.len = sizeof("AUTH PLAIN " CRLF) - 1 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
653 + ngx_base64_encoded_length(auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
654 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
655 line.data = ngx_pnalloc(c->pool, line.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
656 if (line.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
657 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
658 return; |
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 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
661 encoded.data = ngx_cpymem(line.data, "AUTH PLAIN ", |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
662 sizeof("AUTH PLAIN ") - 1); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
663 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
664 ngx_encode_base64(&encoded, &auth); |
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 p = encoded.data + encoded.len; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
667 *p++ = CR; *p = LF; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
668 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
669 s->mail_state = ngx_smtp_auth_plain; |
2309 | 670 |
671 break; | |
672 | |
673 case ngx_smtp_helo_from: | |
674 case ngx_smtp_xclient_from: | |
675 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
676 "mail proxy send mail from"); | |
677 | |
678 s->connection->log->action = "sending MAIL FROM to upstream"; | |
679 | |
680 line.len = s->smtp_from.len + sizeof(CRLF) - 1; | |
681 line.data = ngx_pnalloc(c->pool, line.len); | |
682 if (line.data == NULL) { | |
683 ngx_mail_proxy_internal_server_error(s); | |
684 return; | |
1136 | 685 } |
686 | |
2309 | 687 p = ngx_cpymem(line.data, s->smtp_from.data, s->smtp_from.len); |
688 *p++ = CR; *p = LF; | |
689 | |
690 s->mail_state = ngx_smtp_from; | |
691 | |
1136 | 692 break; |
693 | |
2309 | 694 case ngx_smtp_from: |
695 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
696 "mail proxy send rcpt to"); | |
697 | |
698 s->connection->log->action = "sending RCPT TO to upstream"; | |
699 | |
700 line.len = s->smtp_to.len + sizeof(CRLF) - 1; | |
701 line.data = ngx_pnalloc(c->pool, line.len); | |
702 if (line.data == NULL) { | |
703 ngx_mail_proxy_internal_server_error(s); | |
704 return; | |
705 } | |
706 | |
707 p = ngx_cpymem(line.data, s->smtp_to.data, s->smtp_to.len); | |
708 *p++ = CR; *p = LF; | |
709 | |
710 s->mail_state = ngx_smtp_to; | |
1136 | 711 |
2309 | 712 break; |
713 | |
714 case ngx_smtp_helo: | |
715 case ngx_smtp_xclient: | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
716 case ngx_smtp_auth_plain: |
2309 | 717 case ngx_smtp_to: |
718 | |
719 b = s->proxy->buffer; | |
1136 | 720 |
2309 | 721 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
|
722 b->pos = b->start; |
2309 | 723 |
724 } else { | |
2440
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
725 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
|
726 b->last = b->start + sizeof(smtp_auth_ok) - 1; |
2309 | 727 } |
728 | |
1136 | 729 s->connection->read->handler = ngx_mail_proxy_handler; |
730 s->connection->write->handler = ngx_mail_proxy_handler; | |
731 rev->handler = ngx_mail_proxy_handler; | |
732 c->write->handler = ngx_mail_proxy_handler; | |
733 | |
734 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
735 ngx_add_timer(s->connection->read, pcf->timeout); | |
736 ngx_del_timer(c->read); | |
737 | |
738 c->log->action = NULL; | |
739 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
740 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
741 if (s->buffer->pos == s->buffer->last) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
742 ngx_mail_proxy_handler(s->connection->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
743 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
744 } else { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
745 ngx_mail_proxy_handler(c->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
746 } |
1136 | 747 |
748 return; | |
749 | |
750 default: | |
751 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
752 ngx_str_null(&line); |
1136 | 753 #endif |
754 break; | |
755 } | |
756 | |
757 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { | |
758 /* | |
759 * we treat the incomplete sending as NGX_ERROR | |
760 * because it is very strange here | |
761 */ | |
762 ngx_mail_proxy_internal_server_error(s); | |
763 return; | |
764 } | |
765 | |
766 s->proxy->buffer->pos = s->proxy->buffer->start; | |
767 s->proxy->buffer->last = s->proxy->buffer->start; | |
768 } | |
769 | |
770 | |
771 static void | |
772 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
|
773 { |
583 | 774 ngx_connection_t *c; |
1136 | 775 ngx_mail_session_t *s; |
583 | 776 |
1136 | 777 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler"); |
583 | 778 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
779 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
583 | 780 c = wev->data; |
781 s = c->data; | |
782 | |
1136 | 783 ngx_mail_proxy_close_session(s); |
583 | 784 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
785 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
786 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
787 |
521 | 788 static ngx_int_t |
1136 | 789 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
|
790 { |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
791 u_char *p, *m; |
857 | 792 ssize_t n; |
793 ngx_buf_t *b; | |
1136 | 794 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
|
795 |
587 | 796 s->connection->log->action = "reading response from upstream"; |
797 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
798 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
|
799 |
539 | 800 n = s->proxy->upstream.connection->recv(s->proxy->upstream.connection, |
801 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
|
802 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
803 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
|
804 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
805 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
806 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
807 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
|
808 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
809 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
810 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
811 b->last += n; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
812 |
3505
c631ef8beaaa
Zimbra IMAP server may return only 4 bytes: "+ \r\n"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
813 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
|
814 return NGX_AGAIN; |
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 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
|
818 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
|
819 *(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
|
820 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
|
821 "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
|
822 b->pos); |
571 | 823 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
|
824 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
825 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
826 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
827 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
828 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
829 p = b->pos; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
830 |
1136 | 831 switch (s->protocol) { |
832 | |
833 case NGX_MAIL_POP3_PROTOCOL: | |
527 | 834 if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') { |
835 return NGX_OK; | |
836 } | |
1136 | 837 break; |
527 | 838 |
1136 | 839 case NGX_MAIL_IMAP_PROTOCOL: |
663 | 840 switch (state) { |
841 | |
842 case ngx_imap_start: | |
527 | 843 if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') { |
844 return NGX_OK; | |
845 } | |
663 | 846 break; |
527 | 847 |
663 | 848 case ngx_imap_login: |
849 case ngx_imap_user: | |
529 | 850 if (p[0] == '+') { |
527 | 851 return NGX_OK; |
852 } | |
663 | 853 break; |
854 | |
855 case ngx_imap_passwd: | |
856 if (ngx_strncmp(p, s->tag.data, s->tag.len) == 0) { | |
857 p += s->tag.len; | |
858 if (p[0] == 'O' && p[1] == 'K') { | |
859 return NGX_OK; | |
860 } | |
861 } | |
862 break; | |
527 | 863 } |
1136 | 864 |
865 break; | |
866 | |
867 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
868 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
869 if (p[3] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
870 /* multiline reply, check if we got last line */ |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
871 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
872 m = b->last - (sizeof(CRLF "200" CRLF) - 1); |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
873 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
874 while (m > p) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
875 if (m[0] == CR && m[1] == LF) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
876 break; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
877 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
878 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
879 m--; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
880 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
881 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
882 if (m <= p || m[5] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
883 return NGX_AGAIN; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
884 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
885 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
886 |
1136 | 887 switch (state) { |
888 | |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
889 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
|
890 if (p[0] == '2' && p[1] == '2' && p[2] == '0') { |
1166 | 891 return NGX_OK; |
892 } | |
893 break; | |
1136 | 894 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
895 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
|
896 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
|
897 case ngx_smtp_helo_from: |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
898 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
|
899 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
|
900 if (p[0] == '2' && p[1] == '5' && p[2] == '0') { |
2309 | 901 return NGX_OK; |
902 } | |
903 break; | |
904 | |
1136 | 905 case ngx_smtp_xclient: |
2309 | 906 case ngx_smtp_xclient_from: |
2497 | 907 case ngx_smtp_xclient_helo: |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
908 case ngx_smtp_xclient_auth: |
2309 | 909 if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') { |
1166 | 910 return NGX_OK; |
911 } | |
912 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
|
913 |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
914 case ngx_smtp_auth_plain: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
915 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
|
916 return NGX_OK; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
917 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
918 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
919 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
920 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
|
921 return NGX_OK; |
1136 | 922 } |
923 | |
1166 | 924 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
925 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
926 |
1136 | 927 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
857 | 928 |
929 if (pcf->pass_error_message == 0) { | |
930 *(b->last - 2) = '\0'; | |
931 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
932 "upstream sent invalid response: \"%s\"", p); | |
933 return NGX_ERROR; | |
934 } | |
935 | |
936 s->out.len = b->last - p - 2; | |
937 s->out.data = p; | |
938 | |
939 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, | |
940 "upstream sent invalid response: \"%V\"", &s->out); | |
941 | |
942 s->out.len = b->last - b->pos; | |
943 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
|
944 |
571 | 945 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
|
946 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
947 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
948 |
521 | 949 static void |
1136 | 950 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
|
951 { |
583 | 952 char *action, *recv_action, *send_action; |
539 | 953 size_t size; |
954 ssize_t n; | |
955 ngx_buf_t *b; | |
583 | 956 ngx_uint_t do_write; |
539 | 957 ngx_connection_t *c, *src, *dst; |
1136 | 958 ngx_mail_session_t *s; |
959 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
|
960 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
961 c = ev->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
962 s = c->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
963 |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
964 if (ev->timedout || c->close) { |
583 | 965 c->log->action = "proxying"; |
966 | |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
967 if (c->close) { |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
968 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
|
969 |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
970 } 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
|
971 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
|
972 "client timed out"); |
577 | 973 c->timedout = 1; |
974 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
975 } else { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
976 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
|
977 "upstream timed out"); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
978 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
979 |
1136 | 980 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
|
981 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
982 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
983 |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
984 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
|
985 if (ev->write) { |
583 | 986 recv_action = "proxying and reading from upstream"; |
987 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
|
988 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
|
989 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
990 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
|
991 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
992 } else { |
583 | 993 recv_action = "proxying and reading from client"; |
994 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
|
995 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
996 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
|
997 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
998 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
999 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1000 } else { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1001 if (ev->write) { |
589 | 1002 recv_action = "proxying and reading from client"; |
1003 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
|
1004 src = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1005 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1006 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1007 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1008 } else { |
589 | 1009 recv_action = "proxying and reading from upstream"; |
1010 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
|
1011 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1012 dst = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1013 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
|
1014 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1015 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1016 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1017 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
|
1018 |
1136 | 1019 ngx_log_debug3(NGX_LOG_DEBUG_MAIL, ev->log, 0, |
6480 | 1020 "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
|
1021 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
|
1022 |
583 | 1023 for ( ;; ) { |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1024 |
583 | 1025 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
|
1026 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1027 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
|
1028 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1029 if (size && dst->write->ready) { |
583 | 1030 c->log->action = send_action; |
1031 | |
539 | 1032 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
|
1033 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1034 if (n == NGX_ERROR) { |
1136 | 1035 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
|
1036 return; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1037 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1038 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1039 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1040 b->pos += n; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1041 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1042 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
|
1043 b->pos = b->start; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1044 b->last = b->start; |
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 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1048 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1049 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1050 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
|
1051 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1052 if (size && src->read->ready) { |
583 | 1053 c->log->action = recv_action; |
1054 | |
539 | 1055 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
|
1056 |
583 | 1057 if (n == NGX_AGAIN || n == 0) { |
1058 break; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1059 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1060 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1061 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1062 do_write = 1; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1063 b->last += n; |
583 | 1064 |
1065 continue; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1066 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1067 |
583 | 1068 if (n == NGX_ERROR) { |
1069 src->read->eof = 1; | |
539 | 1070 } |
418
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 |
583 | 1073 break; |
1074 } | |
1075 | |
1076 c->log->action = "proxying"; | |
1077 | |
1342
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1078 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
|
1079 || (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
|
1080 && 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
|
1081 || (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
|
1082 && s->proxy->upstream.connection->read->eof)) |
583 | 1083 { |
1084 action = c->log->action; | |
1085 c->log->action = NULL; | |
1086 ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done"); | |
1087 c->log->action = action; | |
1088 | |
1136 | 1089 ngx_mail_proxy_close_session(s); |
583 | 1090 return; |
1091 } | |
1092 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1093 if (ngx_handle_write_event(dst->write, 0) != NGX_OK) { |
1136 | 1094 ngx_mail_proxy_close_session(s); |
583 | 1095 return; |
1096 } | |
1097 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1098 if (ngx_handle_read_event(dst->read, 0) != NGX_OK) { |
1136 | 1099 ngx_mail_proxy_close_session(s); |
583 | 1100 return; |
1101 } | |
1102 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1103 if (ngx_handle_write_event(src->write, 0) != NGX_OK) { |
1136 | 1104 ngx_mail_proxy_close_session(s); |
583 | 1105 return; |
1106 } | |
1107 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1108 if (ngx_handle_read_event(src->read, 0) != NGX_OK) { |
1136 | 1109 ngx_mail_proxy_close_session(s); |
583 | 1110 return; |
1111 } | |
1112 | |
1113 if (c == s->connection) { | |
1136 | 1114 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
583 | 1115 ngx_add_timer(c->read, pcf->timeout); |
1116 } | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1117 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1118 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1119 |
521 | 1120 static void |
1136 | 1121 ngx_mail_proxy_upstream_error(ngx_mail_session_t *s) |
857 | 1122 { |
1123 if (s->proxy->upstream.connection) { | |
1136 | 1124 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1125 "close mail proxy connection: %d", | |
857 | 1126 s->proxy->upstream.connection->fd); |
1127 | |
1128 ngx_close_connection(s->proxy->upstream.connection); | |
1129 } | |
1130 | |
1131 if (s->out.len == 0) { | |
1136 | 1132 ngx_mail_session_internal_server_error(s); |
857 | 1133 return; |
1134 } | |
1135 | |
1136 s->quit = 1; | |
1136 | 1137 ngx_mail_send(s->connection->write); |
857 | 1138 } |
1139 | |
1140 | |
1141 static void | |
1136 | 1142 ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s) |
527 | 1143 { |
1144 if (s->proxy->upstream.connection) { | |
1136 | 1145 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1146 "close mail proxy connection: %d", | |
527 | 1147 s->proxy->upstream.connection->fd); |
1148 | |
1149 ngx_close_connection(s->proxy->upstream.connection); | |
1150 } | |
1151 | |
1136 | 1152 ngx_mail_session_internal_server_error(s); |
527 | 1153 } |
1154 | |
1155 | |
1156 static void | |
1136 | 1157 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
|
1158 { |
521 | 1159 if (s->proxy->upstream.connection) { |
1136 | 1160 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1161 "close mail proxy connection: %d", | |
521 | 1162 s->proxy->upstream.connection->fd); |
1163 | |
1164 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
|
1165 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1166 |
1136 | 1167 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
|
1168 } |
521 | 1169 |
1170 | |
1171 static void * | |
1136 | 1172 ngx_mail_proxy_create_conf(ngx_conf_t *cf) |
577 | 1173 { |
1136 | 1174 ngx_mail_proxy_conf_t *pcf; |
577 | 1175 |
1136 | 1176 pcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_proxy_conf_t)); |
521 | 1177 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
|
1178 return NULL; |
521 | 1179 } |
1180 | |
1181 pcf->enable = NGX_CONF_UNSET; | |
857 | 1182 pcf->pass_error_message = NGX_CONF_UNSET; |
1136 | 1183 pcf->xclient = NGX_CONF_UNSET; |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1184 pcf->smtp_auth = NGX_CONF_UNSET; |
539 | 1185 pcf->buffer_size = NGX_CONF_UNSET_SIZE; |
1186 pcf->timeout = NGX_CONF_UNSET_MSEC; | |
521 | 1187 |
1188 return pcf; | |
1189 } | |
1190 | |
1191 | |
1192 static char * | |
1136 | 1193 ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 1194 { |
1136 | 1195 ngx_mail_proxy_conf_t *prev = parent; |
1196 ngx_mail_proxy_conf_t *conf = child; | |
521 | 1197 |
539 | 1198 ngx_conf_merge_value(conf->enable, prev->enable, 0); |
857 | 1199 ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0); |
1136 | 1200 ngx_conf_merge_value(conf->xclient, prev->xclient, 1); |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1201 ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0); |
539 | 1202 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1203 (size_t) ngx_pagesize); | |
1204 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); | |
521 | 1205 |
1206 return NGX_CONF_OK; | |
1207 } |