mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-08-19 00:27:38 +08:00
73 lines
1.6 KiB
Go
73 lines
1.6 KiB
Go
package local
|
|
|
|
import (
|
|
"context"
|
|
"net/netip"
|
|
"syscall"
|
|
"time"
|
|
"unsafe"
|
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
|
|
"github.com/miekg/dns"
|
|
)
|
|
|
|
func dnsReadConfig(_ context.Context, _ string) *dnsConfig {
|
|
resStateSize := unsafe.Sizeof(_C_struct___res_state{})
|
|
var state *_C_struct___res_state
|
|
if resStateSize > 0 {
|
|
mem := _C_malloc(resStateSize)
|
|
defer _C_free(mem)
|
|
memSlice := unsafe.Slice((*byte)(mem), resStateSize)
|
|
clear(memSlice)
|
|
state = (*_C_struct___res_state)(unsafe.Pointer(&memSlice[0]))
|
|
}
|
|
if err := ResNinit(state); err != nil {
|
|
return &dnsConfig{
|
|
servers: defaultNS,
|
|
search: dnsDefaultSearch(),
|
|
ndots: 1,
|
|
timeout: 5 * time.Second,
|
|
attempts: 2,
|
|
err: E.Cause(err, "libresolv initialization failed"),
|
|
}
|
|
}
|
|
defer ResNclose(state)
|
|
conf := &dnsConfig{
|
|
ndots: 1,
|
|
timeout: 5 * time.Second,
|
|
attempts: int(state.Retry),
|
|
}
|
|
for i := 0; i < int(state.Nscount); i++ {
|
|
addr := parseRawSockaddr(&state.Nsaddrlist[i])
|
|
if addr.IsValid() {
|
|
conf.servers = append(conf.servers, addr.String())
|
|
}
|
|
}
|
|
for i := 0; ; i++ {
|
|
search := state.Dnsrch[i]
|
|
if search == nil {
|
|
break
|
|
}
|
|
name := dns.Fqdn(GoString(search))
|
|
if name == "" {
|
|
continue
|
|
}
|
|
conf.search = append(conf.search, name)
|
|
}
|
|
return conf
|
|
}
|
|
|
|
func parseRawSockaddr(rawSockaddr *syscall.RawSockaddr) netip.Addr {
|
|
switch rawSockaddr.Family {
|
|
case syscall.AF_INET:
|
|
sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rawSockaddr))
|
|
return netip.AddrFrom4(sa.Addr)
|
|
case syscall.AF_INET6:
|
|
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rawSockaddr))
|
|
return netip.AddrFrom16(sa.Addr)
|
|
default:
|
|
return netip.Addr{}
|
|
}
|
|
}
|