Mercurial > hg > nginx-vendor-current
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 */ |