func (sc *SecurityConfig) Equal(other *SecurityConfig) bool {
	switch {
	case sc == nil && other == nil:
		return true
	case (sc != nil) != (other != nil):
		return false
	}
	switch {
	case sc.RootInstanceName != other.RootInstanceName:
		return false
	case sc.RootCertName != other.RootCertName:
		return false
	case sc.IdentityInstanceName != other.IdentityInstanceName:
		return false
	case sc.IdentityCertName != other.IdentityCertName:
		return false
	case sc.RequireClientCert != other.RequireClientCert:
		return false
	default:
		if len(sc.SubjectAltNameMatchers) != len(other.SubjectAltNameMatchers) {
			return false
		}
		for i := 0; i < len(sc.SubjectAltNameMatchers); i++ {
			if !sc.SubjectAltNameMatchers[i].Equal(other.SubjectAltNameMatchers[i]) {
				return false
			}
		}
	}
	return true
}
Equal returns true if sc is equal to other.
package xdsclient
import (
	"context"
	"errors"
	"fmt"
	"regexp"
	"sync"
	"time"
	v2corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
	v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
	"github.com/golang/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/internal/xds/matcher"
	"google.golang.org/grpc/xds/internal/httpfilter"
	"google.golang.org/grpc/xds/internal/xdsclient/load"
	"google.golang.org/grpc"
	"google.golang.org/grpc/internal/backoff"
	"google.golang.org/grpc/internal/buffer"
	"google.golang.org/grpc/internal/grpclog"
	"google.golang.org/grpc/internal/grpcsync"
	"google.golang.org/grpc/keepalive"
	"google.golang.org/grpc/xds/internal"
	"google.golang.org/grpc/xds/internal/version"
	"google.golang.org/grpc/xds/internal/xdsclient/bootstrap"
)
var (
	m = make(map[version.TransportAPI]APIClientBuilder)
)
func RegisterAPIClientBuilder(b APIClientBuilder) {
	m[b.Version()] = b
}
func getAPIClientBuilder(version version.TransportAPI) APIClientBuilder {
	if b, ok := m[version]; ok {
		return b
	}
	return nil
}
type UpdateValidatorFunc func(interface{}) error
type BuildOptions struct {
	Parent UpdateHandler
	Validator UpdateValidatorFunc
	NodeProto proto.Message
	Backoff func(int) time.Duration
	Logger *grpclog.PrefixLogger
}
type APIClientBuilder interface {
	Build(*grpc.ClientConn, BuildOptions) (APIClient, error)
	Version() version.TransportAPI
}
type APIClient interface {
	AddWatch(ResourceType, string)
	RemoveWatch(ResourceType, string)
	reportLoad(ctx context.Context, cc *grpc.ClientConn, opts loadReportingOptions)
	Close()
}
type loadReportingOptions struct {
	loadStore *load.Store
}
type UpdateHandler interface {
	NewListeners(map[string]ListenerUpdateErrTuple, UpdateMetadata)
	NewRouteConfigs(map[string]RouteConfigUpdateErrTuple, UpdateMetadata)
	NewClusters(map[string]ClusterUpdateErrTuple, UpdateMetadata)
	NewEndpoints(map[string]EndpointsUpdateErrTuple, UpdateMetadata)
	NewConnectionError(err error)
}
type ServiceStatus int
const (
	ServiceStatusUnknown ServiceStatus = iota
	ServiceStatusRequested
	ServiceStatusNotExist  
	ServiceStatusACKed
	ServiceStatusNACKed
)
type UpdateErrorMetadata struct {
	Version string
	Err error
	Timestamp time.Time
}
type UpdateMetadata struct {
	Status ServiceStatus
	Version string
	Timestamp time.Time
	ErrState *UpdateErrorMetadata
}
type ListenerUpdate struct {
	RouteConfigName string
	InlineRouteConfig *RouteConfigUpdate
	MaxStreamDuration time.Duration
	HTTPFilters []HTTPFilter
	InboundListenerCfg *InboundListenerConfig
	Raw *anypb.Any
}
type HTTPFilter struct {
	Name string
	Filter httpfilter.Filter
	Config httpfilter.FilterConfig
}
type InboundListenerConfig struct {
	Address string
	Port string
	FilterChains *FilterChainManager
}
type RouteConfigUpdate struct {
	VirtualHosts []*VirtualHost
	Raw *anypb.Any
}
type VirtualHost struct {
	Domains []string
	Routes []*Route
	HTTPFilterConfigOverride map[string]httpfilter.FilterConfig
	RetryConfig              *RetryConfig
}
type RetryConfig struct {
	RetryOn      map[codes.Code]bool
	NumRetries   uint32        
	RetryBackoff RetryBackoff  
}
type RetryBackoff struct {
	BaseInterval time.Duration  
	MaxInterval  time.Duration  
}
type HashPolicyType int
const (
	HashPolicyTypeHeader HashPolicyType = iota
	HashPolicyTypeChannelID
)
type HashPolicy struct {
	HashPolicyType HashPolicyType
	Terminal       bool
	HeaderName        string
	Regex             *regexp.Regexp
	RegexSubstitution string
}
type RouteAction int
const (
	RouteActionUnsupported RouteAction = iota
	RouteActionRoute
	RouteActionNonForwardingAction
)
type Route struct {
	Path   *string
	Prefix *string
	Regex  *regexp.Regexp
	CaseInsensitive bool
	Headers         []*HeaderMatcher
	Fraction        *uint32
	HashPolicies []*HashPolicy
	WeightedClusters map[string]WeightedCluster
	MaxStreamDuration *time.Duration
	HTTPFilterConfigOverride map[string]httpfilter.FilterConfig
	RetryConfig              *RetryConfig
	RouteAction RouteAction
}
type WeightedCluster struct {
	Weight uint32
	HTTPFilterConfigOverride map[string]httpfilter.FilterConfig
}
type HeaderMatcher struct {
	Name         string
	InvertMatch  *bool
	ExactMatch   *string
	RegexMatch   *regexp.Regexp
	PrefixMatch  *string
	SuffixMatch  *string
	RangeMatch   *Int64Range
	PresentMatch *bool
}
type Int64Range struct {
	Start int64
	End   int64
}
type SecurityConfig struct {
	RootInstanceName string
	RootCertName string
	IdentityInstanceName string
	IdentityCertName string
	SubjectAltNameMatchers []matcher.StringMatcher
	RequireClientCert bool
}