comparison src/http/ngx_http_request.c @ 5605:3a72b1805c52

Added server-side support for PROXY protocol v1 (ticket #355). Client address specified in the PROXY protocol header is now saved in the $proxy_protocol_addr variable and can be used in the realip module. This is currently not implemented for mail.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 17 Mar 2014 17:41:24 +0400
parents 188481078faf
children e0aa54a4357e
comparison
equal deleted inserted replaced
5604:22d485944c20 5605:3a72b1805c52
341 rev->handler = ngx_http_ssl_handshake; 341 rev->handler = ngx_http_ssl_handshake;
342 } 342 }
343 } 343 }
344 #endif 344 #endif
345 345
346 if (hc->addr_conf->proxy_protocol) {
347 hc->proxy_protocol = 1;
348 c->log->action = "reading PROXY protocol";
349 }
350
346 if (rev->ready) { 351 if (rev->ready) {
347 /* the deferred accept(), rtsig, aio, iocp */ 352 /* the deferred accept(), rtsig, aio, iocp */
348 353
349 if (ngx_use_accept_mutex) { 354 if (ngx_use_accept_mutex) {
350 ngx_post_event(rev, &ngx_posted_events); 355 ngx_post_event(rev, &ngx_posted_events);
366 371
367 372
368 static void 373 static void
369 ngx_http_wait_request_handler(ngx_event_t *rev) 374 ngx_http_wait_request_handler(ngx_event_t *rev)
370 { 375 {
376 u_char *p;
371 size_t size; 377 size_t size;
372 ssize_t n; 378 ssize_t n;
373 ngx_buf_t *b; 379 ngx_buf_t *b;
374 ngx_connection_t *c; 380 ngx_connection_t *c;
375 ngx_http_connection_t *hc; 381 ngx_http_connection_t *hc;
455 ngx_http_close_connection(c); 461 ngx_http_close_connection(c);
456 return; 462 return;
457 } 463 }
458 464
459 b->last += n; 465 b->last += n;
466
467 if (hc->proxy_protocol) {
468 hc->proxy_protocol = 0;
469
470 p = ngx_proxy_protocol_parse(c, b->pos, b->last);
471
472 if (p == NULL) {
473 ngx_http_close_connection(c);
474 return;
475 }
476
477 b->pos = p;
478
479 if (b->pos == b->last) {
480 c->log->action = "waiting for request";
481 b->pos = b->start;
482 b->last = b->start;
483 ngx_post_event(rev, &ngx_posted_events);
484 return;
485 }
486 }
460 487
461 c->log->action = "reading client request line"; 488 c->log->action = "reading client request line";
462 489
463 ngx_reusable_connection(c, 0); 490 ngx_reusable_connection(c, 0);
464 491
587 #if (NGX_HTTP_SSL) 614 #if (NGX_HTTP_SSL)
588 615
589 static void 616 static void
590 ngx_http_ssl_handshake(ngx_event_t *rev) 617 ngx_http_ssl_handshake(ngx_event_t *rev)
591 { 618 {
592 u_char buf[1]; 619 u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
620 size_t size;
593 ssize_t n; 621 ssize_t n;
594 ngx_err_t err; 622 ngx_err_t err;
595 ngx_int_t rc; 623 ngx_int_t rc;
596 ngx_connection_t *c; 624 ngx_connection_t *c;
597 ngx_http_connection_t *hc; 625 ngx_http_connection_t *hc;
598 ngx_http_ssl_srv_conf_t *sscf; 626 ngx_http_ssl_srv_conf_t *sscf;
599 627
600 c = rev->data; 628 c = rev->data;
629 hc = c->data;
601 630
602 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, 631 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
603 "http check ssl handshake"); 632 "http check ssl handshake");
604 633
605 if (rev->timedout) { 634 if (rev->timedout) {
611 if (c->close) { 640 if (c->close) {
612 ngx_http_close_connection(c); 641 ngx_http_close_connection(c);
613 return; 642 return;
614 } 643 }
615 644
616 n = recv(c->fd, (char *) buf, 1, MSG_PEEK); 645 size = hc->proxy_protocol ? sizeof(buf) : 1;
646
647 n = recv(c->fd, (char *) buf, size, MSG_PEEK);
617 648
618 err = ngx_socket_errno; 649 err = ngx_socket_errno;
619 650
620 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n); 651 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n);
621 652
636 667
637 ngx_connection_error(c, err, "recv() failed"); 668 ngx_connection_error(c, err, "recv() failed");
638 ngx_http_close_connection(c); 669 ngx_http_close_connection(c);
639 670
640 return; 671 return;
672 }
673
674 if (hc->proxy_protocol) {
675 hc->proxy_protocol = 0;
676
677 p = ngx_proxy_protocol_parse(c, buf, buf + n);
678
679 if (p == NULL) {
680 ngx_http_close_connection(c);
681 return;
682 }
683
684 size = p - buf;
685
686 if (c->recv(c, buf, size) != (ssize_t) size) {
687 ngx_http_close_connection(c);
688 return;
689 }
690
691 c->log->action = "SSL handshaking";
692
693 if (n == (ssize_t) size) {
694 ngx_post_event(rev, &ngx_posted_events);
695 return;
696 }
697
698 n = 1;
699 buf[0] = *p;
641 } 700 }
642 701
643 if (n == 1) { 702 if (n == 1) {
644 if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { 703 if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {
645 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, 704 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
646 "https ssl handshake: 0x%02Xd", buf[0]); 705 "https ssl handshake: 0x%02Xd", buf[0]);
647 706
648 hc = c->data;
649 sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, 707 sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
650 ngx_http_ssl_module); 708 ngx_http_ssl_module);
651 709
652 if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER) 710 if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
653 != NGX_OK) 711 != NGX_OK)