comparison src/mail/ngx_mail_handler.c @ 7794:12ea1de7d87c

Mail: parsing of the PROXY protocol from clients. Activated with the "proxy_protocol" parameter of the "listen" directive. Obtained information is passed to the auth_http script in Proxy-Protocol-Addr, Proxy-Protocol-Port, Proxy-Protocol-Server-Addr, and Proxy-Protocol-Server-Port headers.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 05 Mar 2021 17:16:24 +0300
parents adee10c7fac8
children ef4bdbbce57e
comparison
equal deleted inserted replaced
7793:44ebeeceb70e 7794:12ea1de7d87c
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 #include <ngx_event.h> 10 #include <ngx_event.h>
11 #include <ngx_mail.h> 11 #include <ngx_mail.h>
12 12
13 13
14 static void ngx_mail_proxy_protocol_handler(ngx_event_t *rev);
14 static void ngx_mail_init_session_handler(ngx_event_t *rev); 15 static void ngx_mail_init_session_handler(ngx_event_t *rev);
15 static void ngx_mail_init_session(ngx_connection_t *c); 16 static void ngx_mail_init_session(ngx_connection_t *c);
16 17
17 #if (NGX_MAIL_SSL) 18 #if (NGX_MAIL_SSL)
18 static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); 19 static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
166 c->log_error = NGX_ERROR_INFO; 167 c->log_error = NGX_ERROR_INFO;
167 168
168 rev = c->read; 169 rev = c->read;
169 rev->handler = ngx_mail_init_session_handler; 170 rev->handler = ngx_mail_init_session_handler;
170 171
172 if (addr_conf->proxy_protocol) {
173 c->log->action = "reading PROXY protocol";
174
175 rev->handler = ngx_mail_proxy_protocol_handler;
176
177 if (!rev->ready) {
178 ngx_add_timer(rev, cscf->timeout);
179
180 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
181 ngx_mail_close_connection(c);
182 }
183
184 return;
185 }
186 }
187
171 if (ngx_use_accept_mutex) { 188 if (ngx_use_accept_mutex) {
172 ngx_post_event(rev, &ngx_posted_events); 189 ngx_post_event(rev, &ngx_posted_events);
173 return; 190 return;
174 } 191 }
175 192
176 rev->handler(rev); 193 rev->handler(rev);
194 }
195
196
197 static void
198 ngx_mail_proxy_protocol_handler(ngx_event_t *rev)
199 {
200 u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER];
201 size_t size;
202 ssize_t n;
203 ngx_err_t err;
204 ngx_connection_t *c;
205 ngx_mail_session_t *s;
206 ngx_mail_core_srv_conf_t *cscf;
207
208 c = rev->data;
209 s = c->data;
210
211 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0,
212 "mail PROXY protocol handler");
213
214 if (rev->timedout) {
215 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
216 c->timedout = 1;
217 ngx_mail_close_connection(c);
218 return;
219 }
220
221 n = recv(c->fd, (char *) buf, sizeof(buf), MSG_PEEK);
222
223 err = ngx_socket_errno;
224
225 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "recv(): %z", n);
226
227 if (n == -1) {
228 if (err == NGX_EAGAIN) {
229 rev->ready = 0;
230
231 if (!rev->timer_set) {
232 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
233 ngx_add_timer(rev, cscf->timeout);
234 }
235
236 if (ngx_handle_read_event(rev, 0) != NGX_OK) {
237 ngx_mail_close_connection(c);
238 }
239
240 return;
241 }
242
243 ngx_connection_error(c, err, "recv() failed");
244
245 ngx_mail_close_connection(c);
246 return;
247 }
248
249 p = ngx_proxy_protocol_read(c, buf, buf + n);
250
251 if (p == NULL) {
252 ngx_mail_close_connection(c);
253 return;
254 }
255
256 size = p - buf;
257
258 if (c->recv(c, buf, size) != (ssize_t) size) {
259 ngx_mail_close_connection(c);
260 return;
261 }
262
263 ngx_mail_init_session_handler(rev);
177 } 264 }
178 265
179 266
180 static void 267 static void
181 ngx_mail_init_session_handler(ngx_event_t *rev) 268 ngx_mail_init_session_handler(ngx_event_t *rev)
240 327
241 if (ngx_ssl_handshake(c) == NGX_AGAIN) { 328 if (ngx_ssl_handshake(c) == NGX_AGAIN) {
242 329
243 s = c->data; 330 s = c->data;
244 331
245 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); 332 if (!c->read->timer_set) {
246 333 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
247 ngx_add_timer(c->read, cscf->timeout); 334 ngx_add_timer(c->read, cscf->timeout);
335 }
248 336
249 c->ssl->handler = ngx_mail_ssl_handshake_handler; 337 c->ssl->handler = ngx_mail_ssl_handshake_handler;
250 338
251 return; 339 return;
252 } 340 }