@@ -2,6 +2,8 @@ package dns
22
33import (
44 "context"
5+ "strconv"
6+
57 "github.com/xtls/xray-core/common/errors"
68 "github.com/xtls/xray-core/common/net"
79 "github.com/xtls/xray-core/common/strmatcher"
@@ -31,7 +33,15 @@ func NewStaticHosts(hosts []*Config_HostMapping) (*StaticHosts, error) {
3133 ips := make ([]net.Address , 0 , len (mapping .Ip )+ 1 )
3234 switch {
3335 case len (mapping .ProxiedDomain ) > 0 :
34- ips = append (ips , net .DomainAddress (mapping .ProxiedDomain ))
36+ if mapping .ProxiedDomain [0 ] == '#' {
37+ rcode , err := strconv .Atoi (mapping .ProxiedDomain [1 :])
38+ if err != nil {
39+ return nil , err
40+ }
41+ ips = append (ips , dns .RCodeError (rcode ))
42+ } else {
43+ ips = append (ips , net .DomainAddress (mapping .ProxiedDomain ))
44+ }
3545 case len (mapping .Ip ) > 0 :
3646 for _ , ip := range mapping .Ip {
3747 addr := net .IPAddress (ip )
@@ -58,38 +68,51 @@ func filterIP(ips []net.Address, option dns.IPOption) []net.Address {
5868 return filtered
5969}
6070
61- func (h * StaticHosts ) lookupInternal (domain string ) []net.Address {
71+ func (h * StaticHosts ) lookupInternal (domain string ) ( []net.Address , error ) {
6272 ips := make ([]net.Address , 0 )
6373 found := false
6474 for _ , id := range h .matchers .Match (domain ) {
75+ for _ , v := range h .ips [id ] {
76+ if err , ok := v .(dns.RCodeError ); ok {
77+ if uint16 (err ) == 0 {
78+ return nil , dns .ErrEmptyResponse
79+ }
80+ return nil , err
81+ }
82+ }
6583 ips = append (ips , h .ips [id ]... )
6684 found = true
6785 }
6886 if ! found {
69- return nil
87+ return nil , nil
7088 }
71- return ips
89+ return ips , nil
7290}
7391
74- func (h * StaticHosts ) lookup (domain string , option dns.IPOption , maxDepth int ) []net.Address {
75- switch addrs := h .lookupInternal (domain ); {
92+ func (h * StaticHosts ) lookup (domain string , option dns.IPOption , maxDepth int ) ([]net.Address , error ) {
93+ switch addrs , err := h .lookupInternal (domain ); {
94+ case err != nil :
95+ return nil , err
7696 case len (addrs ) == 0 : // Not recorded in static hosts, return nil
77- return addrs
97+ return addrs , nil
7898 case len (addrs ) == 1 && addrs [0 ].Family ().IsDomain (): // Try to unwrap domain
7999 errors .LogDebug (context .Background (), "found replaced domain: " , domain , " -> " , addrs [0 ].Domain (), ". Try to unwrap it" )
80100 if maxDepth > 0 {
81- unwrapped := h .lookup (addrs [0 ].Domain (), option , maxDepth - 1 )
101+ unwrapped , err := h .lookup (addrs [0 ].Domain (), option , maxDepth - 1 )
102+ if err != nil {
103+ return nil , err
104+ }
82105 if unwrapped != nil {
83- return unwrapped
106+ return unwrapped , nil
84107 }
85108 }
86- return addrs
109+ return addrs , nil
87110 default : // IP record found, return a non-nil IP array
88- return filterIP (addrs , option )
111+ return filterIP (addrs , option ), nil
89112 }
90113}
91114
92115// Lookup returns IP addresses or proxied domain for the given domain, if exists in this StaticHosts.
93- func (h * StaticHosts ) Lookup (domain string , option dns.IPOption ) []net.Address {
116+ func (h * StaticHosts ) Lookup (domain string , option dns.IPOption ) ( []net.Address , error ) {
94117 return h .lookup (domain , option , 5 )
95118}
0 commit comments