123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- package dns
- import (
- "context"
- "sync"
- "github.com/sagernet/sing-box/adapter"
- "github.com/sagernet/sing-box/log"
- "github.com/sagernet/sing/common"
- E "github.com/sagernet/sing/common/exceptions"
- )
- type TransportConstructorFunc[T any] func(ctx context.Context, logger log.ContextLogger, tag string, options T) (adapter.DNSTransport, error)
- func RegisterTransport[Options any](registry *TransportRegistry, transportType string, constructor TransportConstructorFunc[Options]) {
- registry.register(transportType, func() any {
- return new(Options)
- }, func(ctx context.Context, logger log.ContextLogger, tag string, rawOptions any) (adapter.DNSTransport, error) {
- var options *Options
- if rawOptions != nil {
- options = rawOptions.(*Options)
- }
- return constructor(ctx, logger, tag, common.PtrValueOrDefault(options))
- })
- }
- var _ adapter.DNSTransportRegistry = (*TransportRegistry)(nil)
- type (
- optionsConstructorFunc func() any
- constructorFunc func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.DNSTransport, error)
- )
- type TransportRegistry struct {
- access sync.Mutex
- optionsType map[string]optionsConstructorFunc
- constructors map[string]constructorFunc
- }
- func NewTransportRegistry() *TransportRegistry {
- return &TransportRegistry{
- optionsType: make(map[string]optionsConstructorFunc),
- constructors: make(map[string]constructorFunc),
- }
- }
- func (r *TransportRegistry) CreateOptions(transportType string) (any, bool) {
- r.access.Lock()
- defer r.access.Unlock()
- optionsConstructor, loaded := r.optionsType[transportType]
- if !loaded {
- return nil, false
- }
- return optionsConstructor(), true
- }
- func (r *TransportRegistry) CreateDNSTransport(ctx context.Context, logger log.ContextLogger, tag string, transportType string, options any) (adapter.DNSTransport, error) {
- r.access.Lock()
- defer r.access.Unlock()
- constructor, loaded := r.constructors[transportType]
- if !loaded {
- return nil, E.New("transport type not found: " + transportType)
- }
- return constructor(ctx, logger, tag, options)
- }
- func (r *TransportRegistry) register(transportType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
- r.access.Lock()
- defer r.access.Unlock()
- r.optionsType[transportType] = optionsConstructor
- r.constructors[transportType] = constructor
- }
|