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 }