transport_registry.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package dns
  2. import (
  3. "context"
  4. "sync"
  5. "github.com/sagernet/sing-box/adapter"
  6. "github.com/sagernet/sing-box/log"
  7. "github.com/sagernet/sing/common"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. )
  10. type TransportConstructorFunc[T any] func(ctx context.Context, logger log.ContextLogger, tag string, options T) (adapter.DNSTransport, error)
  11. func RegisterTransport[Options any](registry *TransportRegistry, transportType string, constructor TransportConstructorFunc[Options]) {
  12. registry.register(transportType, func() any {
  13. return new(Options)
  14. }, func(ctx context.Context, logger log.ContextLogger, tag string, rawOptions any) (adapter.DNSTransport, error) {
  15. var options *Options
  16. if rawOptions != nil {
  17. options = rawOptions.(*Options)
  18. }
  19. return constructor(ctx, logger, tag, common.PtrValueOrDefault(options))
  20. })
  21. }
  22. var _ adapter.DNSTransportRegistry = (*TransportRegistry)(nil)
  23. type (
  24. optionsConstructorFunc func() any
  25. constructorFunc func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.DNSTransport, error)
  26. )
  27. type TransportRegistry struct {
  28. access sync.Mutex
  29. optionsType map[string]optionsConstructorFunc
  30. constructors map[string]constructorFunc
  31. }
  32. func NewTransportRegistry() *TransportRegistry {
  33. return &TransportRegistry{
  34. optionsType: make(map[string]optionsConstructorFunc),
  35. constructors: make(map[string]constructorFunc),
  36. }
  37. }
  38. func (r *TransportRegistry) CreateOptions(transportType string) (any, bool) {
  39. r.access.Lock()
  40. defer r.access.Unlock()
  41. optionsConstructor, loaded := r.optionsType[transportType]
  42. if !loaded {
  43. return nil, false
  44. }
  45. return optionsConstructor(), true
  46. }
  47. func (r *TransportRegistry) CreateDNSTransport(ctx context.Context, logger log.ContextLogger, tag string, transportType string, options any) (adapter.DNSTransport, error) {
  48. r.access.Lock()
  49. defer r.access.Unlock()
  50. constructor, loaded := r.constructors[transportType]
  51. if !loaded {
  52. return nil, E.New("transport type not found: " + transportType)
  53. }
  54. return constructor(ctx, logger, tag, options)
  55. }
  56. func (r *TransportRegistry) register(transportType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
  57. r.access.Lock()
  58. defer r.access.Unlock()
  59. r.optionsType[transportType] = optionsConstructor
  60. r.constructors[transportType] = constructor
  61. }