|  | @@ -57,11 +57,11 @@ bool grpc_parse_unix(const grpc_uri *uri,
 | 
	
		
			
				|  |  |    struct sockaddr_un *un = (struct sockaddr_un *)resolved_addr->addr;
 | 
	
		
			
				|  |  |    const size_t maxlen = sizeof(un->sun_path);
 | 
	
		
			
				|  |  |    const size_t path_len = strnlen(uri->path, maxlen);
 | 
	
		
			
				|  |  | -  if (path_len == maxlen) return 0;
 | 
	
		
			
				|  |  | +  if (path_len == maxlen) return false;
 | 
	
		
			
				|  |  |    un->sun_family = AF_UNIX;
 | 
	
		
			
				|  |  |    strcpy(un->sun_path, uri->path);
 | 
	
		
			
				|  |  |    resolved_addr->len = sizeof(*un);
 | 
	
		
			
				|  |  | -  return 1;
 | 
	
		
			
				|  |  | +  return true;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #else /* GRPC_HAVE_UNIX_SOCKET */
 | 
	
	
		
			
				|  | @@ -73,74 +73,65 @@ bool grpc_parse_unix(const grpc_uri *uri,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #endif /* GRPC_HAVE_UNIX_SOCKET */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -bool grpc_parse_ipv4(const grpc_uri *uri,
 | 
	
		
			
				|  |  | -                     grpc_resolved_address *resolved_addr) {
 | 
	
		
			
				|  |  | -  if (strcmp("ipv4", uri->scheme) != 0) {
 | 
	
		
			
				|  |  | -    gpr_log(GPR_ERROR, "Expected 'ipv4' scheme, got '%s'", uri->scheme);
 | 
	
		
			
				|  |  | -    return false;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  const char *host_port = uri->path;
 | 
	
		
			
				|  |  | +bool grpc_parse_ipv4_hostport(const char *hostport, grpc_resolved_address *addr,
 | 
	
		
			
				|  |  | +                              bool log_errors) {
 | 
	
		
			
				|  |  | +  bool success = false;
 | 
	
		
			
				|  |  | +  // Split host and port.
 | 
	
		
			
				|  |  |    char *host;
 | 
	
		
			
				|  |  |    char *port;
 | 
	
		
			
				|  |  | -  int port_num;
 | 
	
		
			
				|  |  | -  bool result = false;
 | 
	
		
			
				|  |  | -  struct sockaddr_in *in = (struct sockaddr_in *)resolved_addr->addr;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (*host_port == '/') ++host_port;
 | 
	
		
			
				|  |  | -  if (!gpr_split_host_port(host_port, &host, &port)) {
 | 
	
		
			
				|  |  | -    return false;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  memset(resolved_addr, 0, sizeof(grpc_resolved_address));
 | 
	
		
			
				|  |  | -  resolved_addr->len = sizeof(struct sockaddr_in);
 | 
	
		
			
				|  |  | +  if (!gpr_split_host_port(hostport, &host, &port)) return false;
 | 
	
		
			
				|  |  | +  // Parse IP address.
 | 
	
		
			
				|  |  | +  memset(addr, 0, sizeof(*addr));
 | 
	
		
			
				|  |  | +  addr->len = sizeof(struct sockaddr_in);
 | 
	
		
			
				|  |  | +  struct sockaddr_in *in = (struct sockaddr_in *)addr->addr;
 | 
	
		
			
				|  |  |    in->sin_family = AF_INET;
 | 
	
		
			
				|  |  |    if (inet_pton(AF_INET, host, &in->sin_addr) == 0) {
 | 
	
		
			
				|  |  | -    gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host);
 | 
	
		
			
				|  |  | +    if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 address: '%s'", host);
 | 
	
		
			
				|  |  |      goto done;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (port != NULL) {
 | 
	
		
			
				|  |  | -    if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
 | 
	
		
			
				|  |  | -        port_num > 65535) {
 | 
	
		
			
				|  |  | -      gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port);
 | 
	
		
			
				|  |  | -      goto done;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    in->sin_port = htons((uint16_t)port_num);
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    gpr_log(GPR_ERROR, "no port given for ipv4 scheme");
 | 
	
		
			
				|  |  | +  // Parse port.
 | 
	
		
			
				|  |  | +  if (port == NULL) {
 | 
	
		
			
				|  |  | +    if (log_errors) gpr_log(GPR_ERROR, "no port given for ipv4 scheme");
 | 
	
		
			
				|  |  |      goto done;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  result = true;
 | 
	
		
			
				|  |  | +  int port_num;
 | 
	
		
			
				|  |  | +  if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) {
 | 
	
		
			
				|  |  | +    if (log_errors) gpr_log(GPR_ERROR, "invalid ipv4 port: '%s'", port);
 | 
	
		
			
				|  |  | +    goto done;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  in->sin_port = htons((uint16_t)port_num);
 | 
	
		
			
				|  |  | +  success = true;
 | 
	
		
			
				|  |  |  done:
 | 
	
		
			
				|  |  |    gpr_free(host);
 | 
	
		
			
				|  |  |    gpr_free(port);
 | 
	
		
			
				|  |  | -  return result;
 | 
	
		
			
				|  |  | +  return success;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -bool grpc_parse_ipv6(const grpc_uri *uri,
 | 
	
		
			
				|  |  | +bool grpc_parse_ipv4(const grpc_uri *uri,
 | 
	
		
			
				|  |  |                       grpc_resolved_address *resolved_addr) {
 | 
	
		
			
				|  |  | -  if (strcmp("ipv6", uri->scheme) != 0) {
 | 
	
		
			
				|  |  | -    gpr_log(GPR_ERROR, "Expected 'ipv6' scheme, got '%s'", uri->scheme);
 | 
	
		
			
				|  |  | +  if (strcmp("ipv4", uri->scheme) != 0) {
 | 
	
		
			
				|  |  | +    gpr_log(GPR_ERROR, "Expected 'ipv4' scheme, got '%s'", uri->scheme);
 | 
	
		
			
				|  |  |      return false;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    const char *host_port = uri->path;
 | 
	
		
			
				|  |  | -  char *host;
 | 
	
		
			
				|  |  | -  char *port;
 | 
	
		
			
				|  |  | -  int port_num;
 | 
	
		
			
				|  |  | -  int result = 0;
 | 
	
		
			
				|  |  | -  struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)resolved_addr->addr;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    if (*host_port == '/') ++host_port;
 | 
	
		
			
				|  |  | -  if (!gpr_split_host_port(host_port, &host, &port)) {
 | 
	
		
			
				|  |  | -    return 0;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +  return grpc_parse_ipv4_hostport(host_port, resolved_addr,
 | 
	
		
			
				|  |  | +                                  true /* log_errors */);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  memset(in6, 0, sizeof(*in6));
 | 
	
		
			
				|  |  | -  resolved_addr->len = sizeof(*in6);
 | 
	
		
			
				|  |  | +bool grpc_parse_ipv6_hostport(const char *hostport, grpc_resolved_address *addr,
 | 
	
		
			
				|  |  | +                              bool log_errors) {
 | 
	
		
			
				|  |  | +  bool success = false;
 | 
	
		
			
				|  |  | +  // Split host and port.
 | 
	
		
			
				|  |  | +  char *host;
 | 
	
		
			
				|  |  | +  char *port;
 | 
	
		
			
				|  |  | +  if (!gpr_split_host_port(hostport, &host, &port)) return false;
 | 
	
		
			
				|  |  | +  // Parse IP address.
 | 
	
		
			
				|  |  | +  memset(addr, 0, sizeof(*addr));
 | 
	
		
			
				|  |  | +  addr->len = sizeof(struct sockaddr_in6);
 | 
	
		
			
				|  |  | +  struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr->addr;
 | 
	
		
			
				|  |  |    in6->sin6_family = AF_INET6;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  /* Handle the RFC6874 syntax for IPv6 zone identifiers. */
 | 
	
		
			
				|  |  | +  // Handle the RFC6874 syntax for IPv6 zone identifiers.
 | 
	
		
			
				|  |  |    char *host_end = (char *)gpr_memrchr(host, '%', strlen(host));
 | 
	
		
			
				|  |  |    if (host_end != NULL) {
 | 
	
		
			
				|  |  |      GPR_ASSERT(host_end >= host);
 | 
	
	
		
			
				|  | @@ -159,7 +150,7 @@ bool grpc_parse_ipv6(const grpc_uri *uri,
 | 
	
		
			
				|  |  |        gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1);
 | 
	
		
			
				|  |  |        goto done;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    // Handle "sin6_scope_id" being type "u_long". See grpc issue ##10027.
 | 
	
		
			
				|  |  | +    // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027.
 | 
	
		
			
				|  |  |      in6->sin6_scope_id = sin6_scope_id;
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  |      if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
 | 
	
	
		
			
				|  | @@ -167,24 +158,34 @@ bool grpc_parse_ipv6(const grpc_uri *uri,
 | 
	
		
			
				|  |  |        goto done;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  if (port != NULL) {
 | 
	
		
			
				|  |  | -    if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 ||
 | 
	
		
			
				|  |  | -        port_num > 65535) {
 | 
	
		
			
				|  |  | -      gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port);
 | 
	
		
			
				|  |  | -      goto done;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    in6->sin6_port = htons((uint16_t)port_num);
 | 
	
		
			
				|  |  | -  } else {
 | 
	
		
			
				|  |  | -    gpr_log(GPR_ERROR, "no port given for ipv6 scheme");
 | 
	
		
			
				|  |  | +  // Parse port.
 | 
	
		
			
				|  |  | +  if (port == NULL) {
 | 
	
		
			
				|  |  | +    if (log_errors) gpr_log(GPR_ERROR, "no port given for ipv6 scheme");
 | 
	
		
			
				|  |  |      goto done;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -  result = 1;
 | 
	
		
			
				|  |  | +  int port_num;
 | 
	
		
			
				|  |  | +  if (sscanf(port, "%d", &port_num) != 1 || port_num < 0 || port_num > 65535) {
 | 
	
		
			
				|  |  | +    if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 port: '%s'", port);
 | 
	
		
			
				|  |  | +    goto done;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  in6->sin6_port = htons((uint16_t)port_num);
 | 
	
		
			
				|  |  | +  success = true;
 | 
	
		
			
				|  |  |  done:
 | 
	
		
			
				|  |  |    gpr_free(host);
 | 
	
		
			
				|  |  |    gpr_free(port);
 | 
	
		
			
				|  |  | -  return result;
 | 
	
		
			
				|  |  | +  return success;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +bool grpc_parse_ipv6(const grpc_uri *uri,
 | 
	
		
			
				|  |  | +                     grpc_resolved_address *resolved_addr) {
 | 
	
		
			
				|  |  | +  if (strcmp("ipv6", uri->scheme) != 0) {
 | 
	
		
			
				|  |  | +    gpr_log(GPR_ERROR, "Expected 'ipv6' scheme, got '%s'", uri->scheme);
 | 
	
		
			
				|  |  | +    return false;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  const char *host_port = uri->path;
 | 
	
		
			
				|  |  | +  if (*host_port == '/') ++host_port;
 | 
	
		
			
				|  |  | +  return grpc_parse_ipv6_hostport(host_port, resolved_addr,
 | 
	
		
			
				|  |  | +                                  true /* log_errors */);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  bool grpc_parse_uri(const grpc_uri *uri, grpc_resolved_address *resolved_addr) {
 |