mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-01-30 20:56:54 +00:00
73 lines
2.3 KiB
Go
73 lines
2.3 KiB
Go
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
|
|
}
|