package outbounds import ( "net" ) // systemResolver is a PluggableOutbound DNS resolver that resolves hostnames // using the default system DNS server. // Outbounds typically don't require a resolver, as they can do DNS resolution // themselves. However, when using ACL, it's necessary to place a resolver in // front of it in the pipeline (for IP rules to work on domain requests). type systemResolver struct { Next PluggableOutbound } func NewSystemResolver(next PluggableOutbound) PluggableOutbound { return &systemResolver{ Next: next, } } func (r *systemResolver) resolve(reqAddr *AddrEx) { ips, err := net.LookupIP(reqAddr.Host) if err != nil { reqAddr.ResolveInfo = &ResolveInfo{Err: err} return } info := &ResolveInfo{} info.IPv4, info.IPv6 = splitIPv4IPv6(ips) reqAddr.ResolveInfo = info } func (r *systemResolver) TCP(reqAddr *AddrEx) (net.Conn, error) { r.resolve(reqAddr) return r.Next.TCP(reqAddr) } func (r *systemResolver) UDP(reqAddr *AddrEx) (UDPConn, error) { r.resolve(reqAddr) return r.Next.UDP(reqAddr) }