comparison src/core/ngx_inet.c @ 694:88a1b4797f2e NGINX_1_3_10

nginx 1.3.10 *) Change: domain names specified in configuration file are now resolved to IPv6 addresses as well as IPv4 ones. *) Change: now if the "include" directive with mask is used on Unix systems, included files are sorted in alphabetical order. *) Change: the "add_header" directive adds headers to 201 responses. *) Feature: the "geo" directive now supports IPv6 addresses in CIDR notation. *) Feature: the "flush" and "gzip" parameters of the "access_log" directive. *) Feature: variables support in the "auth_basic" directive. *) Bugfix: nginx could not be built with the ngx_http_perl_module in some cases. *) Bugfix: a segmentation fault might occur in a worker process if the ngx_http_xslt_module was used. *) Bugfix: nginx could not be built on MacOSX in some cases. Thanks to Piotr Sikora. *) Bugfix: the "limit_rate" directive with high rates might result in truncated responses on 32-bit platforms. Thanks to Alexey Antropov. *) Bugfix: a segmentation fault might occur in a worker process if the "if" directive was used. Thanks to Piotr Sikora. *) Bugfix: a "100 Continue" response was issued with "413 Request Entity Too Large" responses. *) Bugfix: the "image_filter", "image_filter_jpeg_quality" and "image_filter_sharpen" directives might be inherited incorrectly. Thanks to Ian Babrou. *) Bugfix: "crypt_r() failed" errors might appear if the "auth_basic" directive was used on Linux. *) Bugfix: in backup servers handling. Thanks to Thomas Chen. *) Bugfix: proxied HEAD requests might return incorrect response if the "gzip" directive was used.
author Igor Sysoev <http://sysoev.ru>
date Tue, 25 Dec 2012 00:00:00 +0400
parents bfa81a0490a2
children
comparison
equal deleted inserted replaced
693:cfd4279acc6e 694:88a1b4797f2e
463 463
464 /* 464 /*
465 * prevent MSVC8 warning: 465 * prevent MSVC8 warning:
466 * potentially uninitialized local variable 'inaddr6' used 466 * potentially uninitialized local variable 'inaddr6' used
467 */ 467 */
468 ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr)); 468 ngx_memzero(&inaddr6, sizeof(struct in6_addr));
469 #endif 469 #endif
470 470
471 inaddr = ngx_inet_addr(text, len); 471 inaddr = ngx_inet_addr(text, len);
472 472
473 if (inaddr != INADDR_NONE) { 473 if (inaddr != INADDR_NONE) {
609 609
610 610
611 static ngx_int_t 611 static ngx_int_t
612 ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u) 612 ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
613 { 613 {
614 u_char *p, *host, *port, *last, *uri, *args; 614 u_char *p, *host, *port, *last, *uri, *args;
615 size_t len; 615 size_t len;
616 ngx_int_t n; 616 ngx_int_t n;
617 struct hostent *h; 617 struct sockaddr_in *sin;
618 struct sockaddr_in *sin; 618 #if (NGX_HAVE_INET6)
619 struct sockaddr_in6 *sin6;
620 #endif
619 621
620 u->socklen = sizeof(struct sockaddr_in); 622 u->socklen = sizeof(struct sockaddr_in);
621 sin = (struct sockaddr_in *) &u->sockaddr; 623 sin = (struct sockaddr_in *) &u->sockaddr;
622 sin->sin_family = AF_INET; 624 sin->sin_family = AF_INET;
623 625
703 } 705 }
704 } 706 }
705 } 707 }
706 708
707 u->no_port = 1; 709 u->no_port = 1;
710
711 if (!u->no_resolve) {
712 u->port = u->default_port;
713 sin->sin_port = htons(u->default_port);
714 }
708 } 715 }
709 716
710 len = last - host; 717 len = last - host;
711 718
712 if (len == 0) { 719 if (len == 0) {
713 u->err = "no host"; 720 u->err = "no host";
714 return NGX_ERROR; 721 return NGX_ERROR;
715 } 722 }
716 723
717 if (len == 1 && *host == '*') {
718 len = 0;
719 }
720
721 u->host.len = len; 724 u->host.len = len;
722 u->host.data = host; 725 u->host.data = host;
723 726
727 if (u->listen && len == 1 && *host == '*') {
728 sin->sin_addr.s_addr = INADDR_ANY;
729 u->wildcard = 1;
730 return NGX_OK;
731 }
732
733 sin->sin_addr.s_addr = ngx_inet_addr(host, len);
734
735 if (sin->sin_addr.s_addr != INADDR_NONE) {
736
737 if (sin->sin_addr.s_addr == INADDR_ANY) {
738 u->wildcard = 1;
739 }
740
741 u->naddrs = 1;
742
743 u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
744 if (u->addrs == NULL) {
745 return NGX_ERROR;
746 }
747
748 sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
749 if (sin == NULL) {
750 return NGX_ERROR;
751 }
752
753 ngx_memcpy(sin, u->sockaddr, sizeof(struct sockaddr_in));
754
755 u->addrs[0].sockaddr = (struct sockaddr *) sin;
756 u->addrs[0].socklen = sizeof(struct sockaddr_in);
757
758 p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
759 if (p == NULL) {
760 return NGX_ERROR;
761 }
762
763 u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
764 &u->host, u->port) - p;
765 u->addrs[0].name.data = p;
766
767 return NGX_OK;
768 }
769
724 if (u->no_resolve) { 770 if (u->no_resolve) {
725 return NGX_OK; 771 return NGX_OK;
726 } 772 }
727 773
728 if (len) { 774 if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
729 sin->sin_addr.s_addr = ngx_inet_addr(host, len); 775 return NGX_ERROR;
730 776 }
731 if (sin->sin_addr.s_addr == INADDR_NONE) { 777
732 p = ngx_alloc(++len, pool->log); 778 u->family = u->addrs[0].sockaddr->sa_family;
733 if (p == NULL) { 779 u->socklen = u->addrs[0].socklen;
734 return NGX_ERROR; 780 ngx_memcpy(u->sockaddr, u->addrs[0].sockaddr, u->addrs[0].socklen);
735 } 781
736 782 switch (u->family) {
737 (void) ngx_cpystrn(p, host, len); 783
738 784 #if (NGX_HAVE_INET6)
739 h = gethostbyname((const char *) p); 785 case AF_INET6:
740 786 sin6 = (struct sockaddr_in6 *) &u->sockaddr;
741 ngx_free(p); 787
742 788 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
743 if (h == NULL || h->h_addr_list[0] == NULL) { 789 u->wildcard = 1;
744 u->err = "host not found"; 790 }
745 return NGX_ERROR; 791
746 } 792 break;
747 793 #endif
748 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[0]); 794
749 } 795 default: /* AF_INET */
796 sin = (struct sockaddr_in *) &u->sockaddr;
750 797
751 if (sin->sin_addr.s_addr == INADDR_ANY) { 798 if (sin->sin_addr.s_addr == INADDR_ANY) {
752 u->wildcard = 1; 799 u->wildcard = 1;
753 } 800 }
754 801
755 } else { 802 break;
756 sin->sin_addr.s_addr = INADDR_ANY; 803 }
757 u->wildcard = 1; 804
758 } 805 return NGX_OK;
759
760 if (u->no_port) {
761 u->port = u->default_port;
762 sin->sin_port = htons(u->default_port);
763 }
764
765 if (u->listen) {
766 return NGX_OK;
767 }
768
769 return ngx_inet_resolve_host(pool, u);
770 } 806 }
771 807
772 808
773 static ngx_int_t 809 static ngx_int_t
774 ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u) 810 ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
830 u->port_text.len = len; 866 u->port_text.len = len;
831 u->port_text.data = port; 867 u->port_text.data = port;
832 868
833 } else { 869 } else {
834 u->no_port = 1; 870 u->no_port = 1;
871
872 if (!u->no_resolve) {
873 u->port = u->default_port;
874 sin6->sin6_port = htons(u->default_port);
875 }
835 } 876 }
836 } 877 }
837 878
838 len = p - host; 879 len = p - host;
839 880
850 return NGX_ERROR; 891 return NGX_ERROR;
851 } 892 }
852 893
853 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 894 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
854 u->wildcard = 1; 895 u->wildcard = 1;
855 }
856
857 if (u->no_port) {
858 u->port = u->default_port;
859 sin6->sin6_port = htons(u->default_port);
860 } 896 }
861 897
862 u->family = AF_INET6; 898 u->family = AF_INET6;
863 u->naddrs = 1; 899 u->naddrs = 1;
864 900
895 return NGX_ERROR; 931 return NGX_ERROR;
896 932
897 #endif 933 #endif
898 } 934 }
899 935
936
937 #if (NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6)
938
939 ngx_int_t
940 ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
941 {
942 u_char *p, *host;
943 size_t len;
944 in_port_t port;
945 ngx_uint_t i;
946 struct addrinfo hints, *res, *rp;
947 struct sockaddr_in *sin;
948 struct sockaddr_in6 *sin6;
949
950 port = htons(u->port);
951
952 host = ngx_alloc(u->host.len + 1, pool->log);
953 if (host == NULL) {
954 return NGX_ERROR;
955 }
956
957 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
958
959 ngx_memzero(&hints, sizeof(struct addrinfo));
960 hints.ai_family = AF_UNSPEC;
961 hints.ai_socktype = SOCK_STREAM;
962
963 if (getaddrinfo((char *) host, NULL, &hints, &res) != 0) {
964 u->err = "host not found";
965 ngx_free(host);
966 return NGX_ERROR;
967 }
968
969 ngx_free(host);
970
971 for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) {
972
973 switch (rp->ai_family) {
974
975 case AF_INET:
976 case AF_INET6:
977 break;
978
979 default:
980 continue;
981 }
982
983 i++;
984 }
985
986 if (i == 0) {
987 u->err = "host not found";
988 goto failed;
989 }
990
991 /* MP: ngx_shared_palloc() */
992
993 u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
994 if (u->addrs == NULL) {
995 goto failed;
996 }
997
998 u->naddrs = i;
999
1000 i = 0;
1001
1002 /* AF_INET addresses first */
1003
1004 for (rp = res; rp != NULL; rp = rp->ai_next) {
1005
1006 if (rp->ai_family != AF_INET) {
1007 continue;
1008 }
1009
1010 sin = ngx_pcalloc(pool, rp->ai_addrlen);
1011 if (sin == NULL) {
1012 goto failed;
1013 }
1014
1015 ngx_memcpy(sin, rp->ai_addr, rp->ai_addrlen);
1016
1017 sin->sin_port = port;
1018
1019 u->addrs[i].sockaddr = (struct sockaddr *) sin;
1020 u->addrs[i].socklen = rp->ai_addrlen;
1021
1022 len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
1023
1024 p = ngx_pnalloc(pool, len);
1025 if (p == NULL) {
1026 goto failed;
1027 }
1028
1029 len = ngx_sock_ntop((struct sockaddr *) sin, p, len, 1);
1030
1031 u->addrs[i].name.len = len;
1032 u->addrs[i].name.data = p;
1033
1034 i++;
1035 }
1036
1037 for (rp = res; rp != NULL; rp = rp->ai_next) {
1038
1039 if (rp->ai_family != AF_INET6) {
1040 continue;
1041 }
1042
1043 sin6 = ngx_pcalloc(pool, rp->ai_addrlen);
1044 if (sin6 == NULL) {
1045 goto failed;
1046 }
1047
1048 ngx_memcpy(sin6, rp->ai_addr, rp->ai_addrlen);
1049
1050 sin6->sin6_port = port;
1051
1052 u->addrs[i].sockaddr = (struct sockaddr *) sin6;
1053 u->addrs[i].socklen = rp->ai_addrlen;
1054
1055 len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
1056
1057 p = ngx_pnalloc(pool, len);
1058 if (p == NULL) {
1059 goto failed;
1060 }
1061
1062 len = ngx_sock_ntop((struct sockaddr *) sin6, p, len, 1);
1063
1064 u->addrs[i].name.len = len;
1065 u->addrs[i].name.data = p;
1066
1067 i++;
1068 }
1069
1070 freeaddrinfo(res);
1071 return NGX_OK;
1072
1073 failed:
1074
1075 freeaddrinfo(res);
1076 return NGX_ERROR;
1077 }
1078
1079 #else /* !NGX_HAVE_GETADDRINFO || !NGX_HAVE_INET6 */
900 1080
901 ngx_int_t 1081 ngx_int_t
902 ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u) 1082 ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
903 { 1083 {
904 u_char *p, *host; 1084 u_char *p, *host;
930 if (h == NULL || h->h_addr_list[0] == NULL) { 1110 if (h == NULL || h->h_addr_list[0] == NULL) {
931 u->err = "host not found"; 1111 u->err = "host not found";
932 return NGX_ERROR; 1112 return NGX_ERROR;
933 } 1113 }
934 1114
935 if (u->one_addr == 0) { 1115 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
936 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
937
938 } else {
939 i = 1;
940 }
941 1116
942 /* MP: ngx_shared_palloc() */ 1117 /* MP: ngx_shared_palloc() */
943 1118
944 u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t)); 1119 u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
945 if (u->addrs == NULL) { 1120 if (u->addrs == NULL) {
1008 u->addrs[0].name.data = p; 1183 u->addrs[0].name.data = p;
1009 } 1184 }
1010 1185
1011 return NGX_OK; 1186 return NGX_OK;
1012 } 1187 }
1188
1189 #endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */