Mercurial > hg > nginx
comparison src/core/ngx_inet.c @ 808:eef6d9cc45da
axe ngx_inet_upstream_parse() and ngx_inet_parse_host_port()
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 24 Oct 2006 14:18:35 +0000 |
parents | 472cd9768ac2 |
children | 4d68c486fcb0 |
comparison
equal
deleted
inserted
replaced
807:3095bf59059b | 808:eef6d9cc45da |
---|---|
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 #include <ngx_event_connect.h> | 10 #include <ngx_event_connect.h> |
11 | |
12 | |
13 static char *ngx_inet_parse_host_port(ngx_inet_upstream_t *u); | |
14 | 11 |
15 | 12 |
16 /* | 13 /* |
17 * ngx_sock_ntop() and ngx_inet_ntop() may be implemented as | 14 * ngx_sock_ntop() and ngx_inet_ntop() may be implemented as |
18 * "ngx_sprintf(text, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3])", however, | 15 * "ngx_sprintf(text, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3])", however, |
601 peers->peer[0].uri_separator = ""; | 598 peers->peer[0].uri_separator = ""; |
602 } | 599 } |
603 | 600 |
604 return peers; | 601 return peers; |
605 } | 602 } |
606 | |
607 | |
608 ngx_peers_t * | |
609 ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u) | |
610 { | |
611 char *err; | |
612 u_char *host; | |
613 size_t len; | |
614 in_addr_t in_addr; | |
615 ngx_uint_t i; | |
616 ngx_peers_t *peers; | |
617 struct hostent *h; | |
618 struct sockaddr_in *sin; | |
619 | |
620 err = ngx_inet_parse_host_port(u); | |
621 | |
622 if (err) { | |
623 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
624 "%s in upstream \"%V\"", err, &u->name); | |
625 return NULL; | |
626 } | |
627 | |
628 if (u->default_port) { | |
629 | |
630 if (u->default_port_value == 0) { | |
631 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
632 "no port in upstream \"%V\"", &u->name); | |
633 return NULL; | |
634 } | |
635 | |
636 u->port = u->default_port_value; | |
637 | |
638 u->port_text.data = ngx_palloc(cf->pool, sizeof("65536") - 1); | |
639 if (u->port_text.data == NULL) { | |
640 return NULL; | |
641 } | |
642 | |
643 u->port_text.len = ngx_sprintf(u->port_text.data, "%d", | |
644 u->default_port_value) | |
645 - u->port_text.data; | |
646 | |
647 } else if (u->port) { | |
648 if (u->port == u->default_port_value) { | |
649 u->default_port = 1; | |
650 } | |
651 | |
652 } else { | |
653 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
654 "no port in upstream \"%V\"", &u->name); | |
655 return NULL; | |
656 } | |
657 | |
658 if (u->host.len == 0) { | |
659 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
660 "no host in upstream \"%V\"", &u->name); | |
661 return NULL; | |
662 } | |
663 | |
664 u->port = htons(u->port); | |
665 | |
666 host = ngx_palloc(cf->temp_pool, u->host.len + 1); | |
667 if (host == NULL) { | |
668 return NULL; | |
669 } | |
670 | |
671 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1); | |
672 | |
673 /* AF_INET only */ | |
674 | |
675 in_addr = inet_addr((char *) host); | |
676 | |
677 if (in_addr == INADDR_NONE) { | |
678 h = gethostbyname((char *) host); | |
679 | |
680 if (h == NULL || h->h_addr_list[0] == NULL) { | |
681 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
682 "host %s is not found in upstream \"%V\"", | |
683 host, &u->name); | |
684 return NULL; | |
685 } | |
686 | |
687 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ } | |
688 | |
689 /* MP: ngx_shared_palloc() */ | |
690 | |
691 peers = ngx_pcalloc(cf->pool, | |
692 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1)); | |
693 if (peers == NULL) { | |
694 return NULL; | |
695 } | |
696 | |
697 peers->number = i; | |
698 | |
699 for (i = 0; h->h_addr_list[i] != NULL; i++) { | |
700 | |
701 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)); | |
702 if (sin == NULL) { | |
703 return NULL; | |
704 } | |
705 | |
706 sin->sin_family = AF_INET; | |
707 sin->sin_port = u->port; | |
708 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]); | |
709 | |
710 peers->peer[i].sockaddr = (struct sockaddr *) sin; | |
711 peers->peer[i].socklen = sizeof(struct sockaddr_in); | |
712 | |
713 len = INET_ADDRSTRLEN - 1 + 1 + u->port_text.len; | |
714 | |
715 peers->peer[i].name.data = ngx_palloc(cf->pool, len); | |
716 if (peers->peer[i].name.data == NULL) { | |
717 return NULL; | |
718 } | |
719 | |
720 len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin, | |
721 peers->peer[i].name.data, len); | |
722 | |
723 peers->peer[i].name.data[len++] = ':'; | |
724 | |
725 ngx_memcpy(peers->peer[i].name.data + len, | |
726 u->port_text.data, u->port_text.len); | |
727 | |
728 peers->peer[i].name.len = len + u->port_text.len; | |
729 | |
730 peers->peer[i].uri_separator = ""; | |
731 | |
732 peers->peer[i].weight = NGX_CONF_UNSET_UINT; | |
733 peers->peer[i].max_fails = NGX_CONF_UNSET_UINT; | |
734 peers->peer[i].fail_timeout = NGX_CONF_UNSET; | |
735 } | |
736 | |
737 } else { | |
738 | |
739 /* MP: ngx_shared_palloc() */ | |
740 | |
741 peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)); | |
742 if (peers == NULL) { | |
743 return NULL; | |
744 } | |
745 | |
746 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)); | |
747 if (sin == NULL) { | |
748 return NULL; | |
749 } | |
750 | |
751 peers->number = 1; | |
752 | |
753 sin->sin_family = AF_INET; | |
754 sin->sin_port = u->port; | |
755 sin->sin_addr.s_addr = in_addr; | |
756 | |
757 peers->peer[0].sockaddr = (struct sockaddr *) sin; | |
758 peers->peer[0].socklen = sizeof(struct sockaddr_in); | |
759 | |
760 len = u->host.len + 1 + u->port_text.len; | |
761 | |
762 peers->peer[0].name.len = len; | |
763 | |
764 peers->peer[0].name.data = ngx_palloc(cf->pool, len); | |
765 if (peers->peer[0].name.data == NULL) { | |
766 return NULL; | |
767 } | |
768 | |
769 len = u->host.len; | |
770 | |
771 ngx_memcpy(peers->peer[0].name.data, u->host.data, len); | |
772 | |
773 peers->peer[0].name.data[len++] = ':'; | |
774 | |
775 ngx_memcpy(peers->peer[0].name.data + len, | |
776 u->port_text.data, u->port_text.len); | |
777 | |
778 peers->peer[0].uri_separator = ""; | |
779 } | |
780 | |
781 return peers; | |
782 } | |
783 | |
784 | |
785 static char * | |
786 ngx_inet_parse_host_port(ngx_inet_upstream_t *u) | |
787 { | |
788 size_t i; | |
789 ngx_int_t port; | |
790 ngx_str_t *url; | |
791 | |
792 url = &u->url; | |
793 | |
794 if (u->port_only) { | |
795 i = 0; | |
796 | |
797 } else { | |
798 if (url->data[0] == ':' || url->data[0] == '/') { | |
799 return "invalid host"; | |
800 } | |
801 | |
802 i = 1; | |
803 } | |
804 | |
805 u->host.data = url->data; | |
806 u->host_header = *url; | |
807 | |
808 for ( /* void */ ; i < url->len; i++) { | |
809 | |
810 if (url->data[i] == ':') { | |
811 u->port_text.data = &url->data[i] + 1; | |
812 u->host.len = i; | |
813 | |
814 if (!u->uri_part) { | |
815 u->port_text.len = &url->data[url->len] - u->port_text.data; | |
816 break; | |
817 } | |
818 } | |
819 | |
820 if (url->data[i] == '/') { | |
821 u->uri.data = &url->data[i]; | |
822 u->uri.len = url->len - i; | |
823 u->host_header.len = i; | |
824 | |
825 if (u->host.len == 0) { | |
826 u->host.len = i; | |
827 } | |
828 | |
829 if (u->port_text.data == NULL) { | |
830 u->default_port = 1; | |
831 return NULL; | |
832 } | |
833 | |
834 u->port_text.len = &url->data[i] - u->port_text.data; | |
835 | |
836 if (u->port_text.len == 0) { | |
837 return "invalid port"; | |
838 } | |
839 | |
840 break; | |
841 } | |
842 } | |
843 | |
844 if (u->port_text.data) { | |
845 | |
846 if (u->port_text.len == 0) { | |
847 u->port_text.len = &url->data[i] - u->port_text.data; | |
848 | |
849 if (u->port_text.len == 0) { | |
850 return "invalid port"; | |
851 } | |
852 } | |
853 | |
854 port = ngx_atoi(u->port_text.data, u->port_text.len); | |
855 | |
856 if (port == NGX_ERROR || port < 1 || port > 65536) { | |
857 return "invalid port"; | |
858 } | |
859 | |
860 } else { | |
861 port = ngx_atoi(url->data, url->len); | |
862 | |
863 if (port == NGX_ERROR) { | |
864 u->default_port = 1; | |
865 u->host.len = url->len; | |
866 | |
867 return NULL; | |
868 } | |
869 | |
870 u->port_text = *url; | |
871 u->wildcard = 1; | |
872 } | |
873 | |
874 u->port = (in_port_t) port; | |
875 | |
876 return NULL; | |
877 } |