2023-03-25 04:03:23 +00:00
|
|
|
package fakeip
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"net/netip"
|
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/sagernet/sing-box/adapter"
|
|
|
|
"github.com/sagernet/sing-dns"
|
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
|
|
"github.com/sagernet/sing/common/logger"
|
2024-11-09 13:16:11 +00:00
|
|
|
"github.com/sagernet/sing/service"
|
2023-03-25 04:03:23 +00:00
|
|
|
|
|
|
|
mDNS "github.com/miekg/dns"
|
|
|
|
)
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
var (
|
|
|
|
_ dns.Transport = (*Transport)(nil)
|
|
|
|
_ adapter.FakeIPTransport = (*Transport)(nil)
|
|
|
|
)
|
2023-03-25 04:03:23 +00:00
|
|
|
|
|
|
|
func init() {
|
2024-02-09 10:37:25 +00:00
|
|
|
dns.RegisterTransport([]string{"fakeip"}, func(options dns.TransportOptions) (dns.Transport, error) {
|
|
|
|
return NewTransport(options)
|
|
|
|
})
|
2023-03-25 04:03:23 +00:00
|
|
|
}
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
type Transport struct {
|
2023-03-25 04:03:23 +00:00
|
|
|
name string
|
|
|
|
router adapter.Router
|
|
|
|
store adapter.FakeIPStore
|
|
|
|
logger logger.ContextLogger
|
|
|
|
}
|
|
|
|
|
2024-02-09 10:37:25 +00:00
|
|
|
func NewTransport(options dns.TransportOptions) (*Transport, error) {
|
2024-11-09 13:16:11 +00:00
|
|
|
router := service.FromContext[adapter.Router](options.Context)
|
2023-03-25 04:03:23 +00:00
|
|
|
if router == nil {
|
|
|
|
return nil, E.New("missing router in context")
|
|
|
|
}
|
2023-06-10 08:26:40 +00:00
|
|
|
return &Transport{
|
2024-02-09 10:37:25 +00:00
|
|
|
name: options.Name,
|
2023-03-25 04:03:23 +00:00
|
|
|
router: router,
|
2024-02-09 10:37:25 +00:00
|
|
|
logger: options.Logger,
|
2023-03-25 04:03:23 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
func (s *Transport) Name() string {
|
2023-03-25 04:03:23 +00:00
|
|
|
return s.name
|
|
|
|
}
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
func (s *Transport) Start() error {
|
2023-03-25 04:03:23 +00:00
|
|
|
s.store = s.router.FakeIPStore()
|
|
|
|
if s.store == nil {
|
|
|
|
return E.New("fakeip not enabled")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-08-24 13:52:38 +00:00
|
|
|
func (s *Transport) Reset() {
|
|
|
|
}
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
func (s *Transport) Close() error {
|
2023-03-25 04:03:23 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
func (s *Transport) Raw() bool {
|
2023-03-25 04:03:23 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
func (s *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
2023-03-25 04:03:23 +00:00
|
|
|
return nil, os.ErrInvalid
|
|
|
|
}
|
|
|
|
|
2023-06-10 08:26:40 +00:00
|
|
|
func (s *Transport) Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error) {
|
2023-03-25 04:03:23 +00:00
|
|
|
var addresses []netip.Addr
|
|
|
|
if strategy != dns.DomainStrategyUseIPv6 {
|
2023-07-11 06:05:14 +00:00
|
|
|
inet4Address, err := s.store.Create(domain, false)
|
2023-03-25 04:03:23 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
addresses = append(addresses, inet4Address)
|
|
|
|
}
|
|
|
|
if strategy != dns.DomainStrategyUseIPv4 {
|
2023-07-11 06:05:14 +00:00
|
|
|
inet6Address, err := s.store.Create(domain, true)
|
2023-03-25 04:03:23 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
addresses = append(addresses, inet6Address)
|
|
|
|
}
|
|
|
|
return addresses, nil
|
|
|
|
}
|
2023-06-10 08:26:40 +00:00
|
|
|
|
|
|
|
func (s *Transport) Store() adapter.FakeIPStore {
|
|
|
|
return s.store
|
|
|
|
}
|