Mercurial > hg > nginx
comparison src/stream/ngx_stream_handler.c @ 6693:3908156a51fa
Stream: phases.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Thu, 15 Sep 2016 14:55:54 +0300 |
parents | 56fc55e32f23 |
children | 893b3313f53c |
comparison
equal
deleted
inserted
replaced
6692:56fc55e32f23 | 6693:3908156a51fa |
---|---|
9 #include <ngx_core.h> | 9 #include <ngx_core.h> |
10 #include <ngx_event.h> | 10 #include <ngx_event.h> |
11 #include <ngx_stream.h> | 11 #include <ngx_stream.h> |
12 | 12 |
13 | 13 |
14 static void ngx_stream_log_session(ngx_stream_session_t *s); | |
14 static void ngx_stream_close_connection(ngx_connection_t *c); | 15 static void ngx_stream_close_connection(ngx_connection_t *c); |
15 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); | 16 static u_char *ngx_stream_log_error(ngx_log_t *log, u_char *buf, size_t len); |
16 static void ngx_stream_proxy_protocol_handler(ngx_event_t *rev); | 17 static void ngx_stream_proxy_protocol_handler(ngx_event_t *rev); |
17 static void ngx_stream_init_session_handler(ngx_event_t *rev); | |
18 | |
19 #if (NGX_STREAM_SSL) | |
20 static void ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); | |
21 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); | |
22 #endif | |
23 | 18 |
24 | 19 |
25 void | 20 void |
26 ngx_stream_init_connection(ngx_connection_t *c) | 21 ngx_stream_init_connection(ngx_connection_t *c) |
27 { | 22 { |
152 len, text, &addr_conf->addr_text); | 147 len, text, &addr_conf->addr_text); |
153 | 148 |
154 c->log->connection = c->number; | 149 c->log->connection = c->number; |
155 c->log->handler = ngx_stream_log_error; | 150 c->log->handler = ngx_stream_log_error; |
156 c->log->data = s; | 151 c->log->data = s; |
157 c->log->action = "initializing connection"; | 152 c->log->action = "initializing session"; |
158 c->log_error = NGX_ERROR_INFO; | 153 c->log_error = NGX_ERROR_INFO; |
159 | 154 |
160 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module); | 155 s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_stream_max_module); |
161 if (s->ctx == NULL) { | 156 if (s->ctx == NULL) { |
162 ngx_stream_close_connection(c); | 157 ngx_stream_close_connection(c); |
177 tp = ngx_timeofday(); | 172 tp = ngx_timeofday(); |
178 s->start_sec = tp->sec; | 173 s->start_sec = tp->sec; |
179 s->start_msec = tp->msec; | 174 s->start_msec = tp->msec; |
180 | 175 |
181 rev = c->read; | 176 rev = c->read; |
182 rev->handler = ngx_stream_init_session_handler; | 177 rev->handler = ngx_stream_session_handler; |
183 | 178 |
184 if (addr_conf->proxy_protocol) { | 179 if (addr_conf->proxy_protocol) { |
185 c->log->action = "reading PROXY protocol"; | 180 c->log->action = "reading PROXY protocol"; |
186 | 181 |
187 rev->handler = ngx_stream_proxy_protocol_handler; | 182 rev->handler = ngx_stream_proxy_protocol_handler; |
277 if (c->recv(c, buf, size) != (ssize_t) size) { | 272 if (c->recv(c, buf, size) != (ssize_t) size) { |
278 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | 273 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); |
279 return; | 274 return; |
280 } | 275 } |
281 | 276 |
282 ngx_stream_init_session_handler(rev); | 277 c->log->action = "initializing session"; |
283 } | 278 |
284 | 279 ngx_stream_session_handler(rev); |
285 | 280 } |
286 static void | 281 |
287 ngx_stream_init_session_handler(ngx_event_t *rev) | 282 |
288 { | 283 void |
289 int tcp_nodelay; | 284 ngx_stream_session_handler(ngx_event_t *rev) |
290 ngx_int_t rc; | 285 { |
291 ngx_connection_t *c; | 286 ngx_connection_t *c; |
292 ngx_stream_session_t *s; | 287 ngx_stream_session_t *s; |
293 ngx_stream_core_srv_conf_t *cscf; | |
294 ngx_stream_core_main_conf_t *cmcf; | |
295 | 288 |
296 c = rev->data; | 289 c = rev->data; |
297 s = c->data; | 290 s = c->data; |
298 | 291 |
299 c->log->action = "initializing session"; | 292 ngx_stream_core_run_phases(s); |
300 | 293 } |
301 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); | |
302 | |
303 if (cmcf->realip_handler) { | |
304 rc = cmcf->realip_handler(s); | |
305 | |
306 if (rc == NGX_ERROR) { | |
307 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
308 return; | |
309 } | |
310 } | |
311 | |
312 if (cmcf->limit_conn_handler) { | |
313 rc = cmcf->limit_conn_handler(s); | |
314 | |
315 if (rc == NGX_ERROR) { | |
316 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
317 return; | |
318 } | |
319 | |
320 if (rc == NGX_ABORT) { | |
321 ngx_stream_finalize_session(s, NGX_STREAM_SERVICE_UNAVAILABLE); | |
322 return; | |
323 } | |
324 } | |
325 | |
326 if (cmcf->access_handler) { | |
327 rc = cmcf->access_handler(s); | |
328 | |
329 if (rc == NGX_ERROR) { | |
330 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
331 return; | |
332 } | |
333 | |
334 if (rc == NGX_ABORT) { | |
335 ngx_stream_finalize_session(s, NGX_STREAM_FORBIDDEN); | |
336 return; | |
337 } | |
338 } | |
339 | |
340 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
341 | |
342 if (c->type == SOCK_STREAM | |
343 && cscf->tcp_nodelay | |
344 && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) | |
345 { | |
346 ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "tcp_nodelay"); | |
347 | |
348 tcp_nodelay = 1; | |
349 | |
350 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, | |
351 (const void *) &tcp_nodelay, sizeof(int)) == -1) | |
352 { | |
353 ngx_connection_error(c, ngx_socket_errno, | |
354 "setsockopt(TCP_NODELAY) failed"); | |
355 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
356 return; | |
357 } | |
358 | |
359 c->tcp_nodelay = NGX_TCP_NODELAY_SET; | |
360 } | |
361 | |
362 | |
363 #if (NGX_STREAM_SSL) | |
364 { | |
365 ngx_stream_ssl_conf_t *sslcf; | |
366 | |
367 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); | |
368 | |
369 if (s->ssl) { | |
370 c->log->action = "SSL handshaking"; | |
371 | |
372 if (sslcf->ssl.ctx == NULL) { | |
373 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
374 "no \"ssl_certificate\" is defined " | |
375 "in server listening on SSL port"); | |
376 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
377 return; | |
378 } | |
379 | |
380 ngx_stream_ssl_init_connection(&sslcf->ssl, c); | |
381 return; | |
382 } | |
383 } | |
384 #endif | |
385 | |
386 c->log->action = "handling client connection"; | |
387 | |
388 cscf->handler(s); | |
389 } | |
390 | |
391 | |
392 #if (NGX_STREAM_SSL) | |
393 | |
394 static void | |
395 ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) | |
396 { | |
397 ngx_stream_session_t *s; | |
398 ngx_stream_ssl_conf_t *sslcf; | |
399 | |
400 s = c->data; | |
401 | |
402 if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { | |
403 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
404 return; | |
405 } | |
406 | |
407 if (ngx_ssl_handshake(c) == NGX_AGAIN) { | |
408 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); | |
409 | |
410 ngx_add_timer(c->read, sslcf->handshake_timeout); | |
411 | |
412 c->ssl->handler = ngx_stream_ssl_handshake_handler; | |
413 | |
414 return; | |
415 } | |
416 | |
417 ngx_stream_ssl_handshake_handler(c); | |
418 } | |
419 | |
420 | |
421 static void | |
422 ngx_stream_ssl_handshake_handler(ngx_connection_t *c) | |
423 { | |
424 ngx_stream_session_t *s; | |
425 ngx_stream_core_srv_conf_t *cscf; | |
426 | |
427 if (!c->ssl->handshaked) { | |
428 ngx_stream_finalize_session(c->data, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
429 return; | |
430 } | |
431 | |
432 if (c->read->timer_set) { | |
433 ngx_del_timer(c->read); | |
434 } | |
435 | |
436 c->log->action = "handling client connection"; | |
437 | |
438 s = c->data; | |
439 | |
440 cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module); | |
441 | |
442 cscf->handler(s); | |
443 } | |
444 | |
445 #endif | |
446 | 294 |
447 | 295 |
448 void | 296 void |
449 ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) | 297 ngx_stream_finalize_session(ngx_stream_session_t *s, ngx_uint_t rc) |
450 { | 298 { |
451 ngx_stream_core_main_conf_t *cmcf; | |
452 | |
453 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, | 299 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, s->connection->log, 0, |
454 "finalize stream session: %i", rc); | 300 "finalize stream session: %i", rc); |
455 | 301 |
456 s->status = rc; | 302 s->status = rc; |
457 | 303 |
304 ngx_stream_log_session(s); | |
305 | |
306 ngx_stream_close_connection(s->connection); | |
307 } | |
308 | |
309 | |
310 static void | |
311 ngx_stream_log_session(ngx_stream_session_t *s) | |
312 { | |
313 ngx_uint_t i, n; | |
314 ngx_stream_handler_pt *log_handler; | |
315 ngx_stream_core_main_conf_t *cmcf; | |
316 | |
458 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); | 317 cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module); |
459 | 318 |
460 if (cmcf->access_log_handler) { | 319 log_handler = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.elts; |
461 (void) cmcf->access_log_handler(s); | 320 n = cmcf->phases[NGX_STREAM_LOG_PHASE].handlers.nelts; |
462 } | 321 |
463 | 322 for (i = 0; i < n; i++) { |
464 ngx_stream_close_connection(s->connection); | 323 log_handler[i](s); |
324 } | |
465 } | 325 } |
466 | 326 |
467 | 327 |
468 static void | 328 static void |
469 ngx_stream_close_connection(ngx_connection_t *c) | 329 ngx_stream_close_connection(ngx_connection_t *c) |