| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- 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{}
- }
- }
|