@@ -36,34 +36,33 @@ typedef struct {
3636 struct sockaddr_storage raddr ;
3737} request_t ;
3838
39- // Very very basic hostname parsing.
40- // Note: Performs basic checks to see if last digit is non-alpha.
41- // Non-alpha hostnames are assumed to be IP addresses. e.g. foo.1
42- // Returns non-zero on success, zero on failure.
43- static int hostname_from_uri (const char * uri ,
44- char * hostname , int hostname_len ) {
45- if (strncmp (uri , "https://" , 8 ) != 0 ) { return 0 ; } // not https://
46- uri += 8 ;
47- const char * end = uri ;
48- while (* end && * end != '/' ) { end ++ ; }
49- if (end - uri >= hostname_len ) {
50- return 0 ;
51- }
52- if (end == uri ) { return 0 ; } // empty string.
53- if (!isalpha (* (end - 1 ))) { return 0 ; } // last digit non-alpha.
54-
55- // If using basic authentication in URL, chop off prefix.
56- char * tmp = strchr (uri , '@' );
57- if (tmp ) {
58- tmp ++ ;
59- if (tmp < end ) {
60- uri = tmp ;
39+ static int is_ipv4_address (char * str ) {
40+ struct in6_addr addr ;
41+ return inet_pton (AF_INET , str , & addr ) == 1 ;
42+ }
43+
44+ static int hostname_from_url (const char * url_in ,
45+ char * hostname , const size_t hostname_len ) {
46+ int res = 0 ;
47+ CURLU * url = curl_url ();
48+ if (url != NULL ) {
49+ CURLUcode rc = curl_url_set (url , CURLUPART_URL , url_in , 0 );
50+ if (rc == CURLUE_OK ) {
51+ char * host = NULL ;
52+ rc = curl_url_get (url , CURLUPART_HOST , & host , 0 );
53+ const size_t host_len = strlen (host );
54+ if (rc == CURLUE_OK && host_len < hostname_len &&
55+ host [0 ] != '[' && host [host_len - 1 ] != ']' && // skip IPv6 address
56+ !is_ipv4_address (host )) {
57+ strncpy (hostname , host , hostname_len - 1 ); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
58+ hostname [hostname_len - 1 ] = '\0' ;
59+ res = 1 ; // success
60+ }
61+ curl_free (host );
6162 }
63+ curl_url_cleanup (url );
6264 }
63-
64- strncpy (hostname , uri , end - uri ); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
65- hostname [end - uri ] = 0 ;
66- return 1 ;
65+ return res ;
6766}
6867
6968static void signal_shutdown_cb (struct ev_loop * loop ,
@@ -298,9 +297,9 @@ int main(int argc, char *argv[]) {
298297 logging_flush_init (loop );
299298
300299 dns_poller_t dns_poller ;
301- char hostname [255 ]; // Domain names shouldn't exceed 253 chars.
300+ char hostname [255 ] = { 0 } ; // Domain names shouldn't exceed 253 chars.
302301 if (!proxy_supports_name_resolution (opt .curl_proxy )) {
303- if (hostname_from_uri (opt .resolver_url , hostname , 254 )) {
302+ if (hostname_from_url (opt .resolver_url , hostname , sizeof ( hostname ) )) {
304303 app .using_dns_poller = 1 ;
305304 dns_poller_init (& dns_poller , loop , opt .bootstrap_dns ,
306305 opt .bootstrap_dns_polling_interval , hostname ,
0 commit comments