|  | @@ -786,17 +786,20 @@ static void ssl_server_add_handshakers(grpc_server_security_connector* sc,
 | 
	
		
			
				|  |  |                           tsi_create_adapter_handshaker(tsi_hs), &sc->base));
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static int ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
 | 
	
		
			
				|  |  | +int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
 | 
	
		
			
				|  |  |    char* allocated_name = nullptr;
 | 
	
		
			
				|  |  |    int r;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  if (strchr(peer_name, ':') != nullptr) {
 | 
	
		
			
				|  |  | -    char* ignored_port;
 | 
	
		
			
				|  |  | -    gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
 | 
	
		
			
				|  |  | -    gpr_free(ignored_port);
 | 
	
		
			
				|  |  | -    peer_name = allocated_name;
 | 
	
		
			
				|  |  | -    if (!peer_name) return 0;
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +  char* ignored_port;
 | 
	
		
			
				|  |  | +  gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
 | 
	
		
			
				|  |  | +  gpr_free(ignored_port);
 | 
	
		
			
				|  |  | +  peer_name = allocated_name;
 | 
	
		
			
				|  |  | +  if (!peer_name) return 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // IPv6 zone-id should not be included in comparisons.
 | 
	
		
			
				|  |  | +  char* const zone_id = strchr(allocated_name, '%');
 | 
	
		
			
				|  |  | +  if (zone_id != nullptr) *zone_id = '\0';
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    r = tsi_ssl_peer_matches_name(peer, peer_name);
 | 
	
		
			
				|  |  |    gpr_free(allocated_name);
 | 
	
		
			
				|  |  |    return r;
 | 
	
	
		
			
				|  | @@ -859,7 +862,7 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc,
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /* Check the peer name if specified. */
 | 
	
		
			
				|  |  | -  if (peer_name != nullptr && !ssl_host_matches_name(peer, peer_name)) {
 | 
	
		
			
				|  |  | +  if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
 | 
	
		
			
				|  |  |      char* msg;
 | 
	
		
			
				|  |  |      gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name);
 | 
	
		
			
				|  |  |      grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
 | 
	
	
		
			
				|  | @@ -968,7 +971,7 @@ static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc,
 | 
	
		
			
				|  |  |        reinterpret_cast<grpc_ssl_channel_security_connector*>(sc);
 | 
	
		
			
				|  |  |    grpc_security_status status = GRPC_SECURITY_ERROR;
 | 
	
		
			
				|  |  |    tsi_peer peer = tsi_shallow_peer_from_ssl_auth_context(auth_context);
 | 
	
		
			
				|  |  | -  if (ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
 | 
	
		
			
				|  |  | +  if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK;
 | 
	
		
			
				|  |  |    /* If the target name was overridden, then the original target_name was
 | 
	
		
			
				|  |  |       'checked' transitively during the previous peer check at the end of the
 | 
	
		
			
				|  |  |       handshake. */
 |