@@ -8,6 +8,7 @@ package intra
88
99import (
1010 "context"
11+ "net/netip"
1112 "strconv"
1213 "strings"
1314
@@ -24,35 +25,97 @@ import (
2425 "github.com/celzero/firestack/intra/xdns"
2526)
2627
28+ // MakeDoHTransport creates a DNS-over-HTTPS transport for id, dialing via the
29+ // tunnel's proxies. ipcsv, if any, is a csv of IP (or ip:port) addresses of the
30+ // DoH server, used to bypass the system resolver when dialing url.
31+ func MakeDoHTransport (t Tunnel , id , url , ipcsv string ) (dnsx.Transport , error ) {
32+ px , perr := t .internalProxies ()
33+ if perr != nil {
34+ return nil , perr
35+ }
36+ return doh .NewTransport (t .internalCtx (), id , url , csv2slice (ipcsv ), px )
37+ }
38+
39+ // MakeODoHTransport creates an Oblivious-DoH transport for id, dialing via the
40+ // tunnel's proxies. endpoint is the entry / proxy for the ODoH server; resolver
41+ // is the URL of the target ODoH server. epipcsv, if any, is a csv of IP (or
42+ // ip:port) addresses of the endpoint, used to bypass the system resolver.
43+ func MakeODoHTransport (t Tunnel , id , endpoint , resolver , epipcsv string ) (dnsx.Transport , error ) {
44+ px , perr := t .internalProxies ()
45+ if perr != nil {
46+ return nil , perr
47+ }
48+ return doh .NewOdohTransport (t .internalCtx (), id , endpoint , resolver , csv2slice (epipcsv ), px )
49+ }
50+
51+ // MakeDoTTransport creates a DNS-over-TLS transport for id, dialing via the
52+ // tunnel's proxies. ipcsv, if any, is a csv of IP (or ip:port) addresses of the
53+ // DoT server, used to bypass the system resolver.
54+ func MakeDoTTransport (t Tunnel , id , url , ipcsv string ) (dnsx.Transport , error ) {
55+ px , perr := t .internalProxies ()
56+ if perr != nil {
57+ return nil , perr
58+ }
59+ return dns53 .NewTLSTransport (t .internalCtx (), id , url , csv2slice (ipcsv ), px )
60+ }
61+
62+ // MakeDNS53Transport creates a DNS53 (plain DNS over UDP/TCP) transport for id,
63+ // serving from hostOrHostport (a host, host:port, or ip:port), dialing via the
64+ // tunnel's proxies. ipcsv, if any, is a csv of ip or ip:port addresses of the
65+ // server, bypassing the system resolver.
66+ func MakeDNS53Transport (t Tunnel , id , hostOrHostport , ipcsv string ) (dnsx.Transport , error ) {
67+ px , perr := t .internalProxies ()
68+ if perr != nil {
69+ return nil , perr
70+ }
71+ return dns53 .NewTransportFromHostname (t .internalCtx (), id , hostOrHostport , ipcsv , px )
72+ }
73+
74+ // MakeDNS53TransportFrom creates a DNS53 transport for id, serving from ipp,
75+ // dialing via the tunnel's proxies.
76+ func MakeDNS53TransportFrom (t Tunnel , id string , ipp netip.AddrPort ) (dnsx.Transport , error ) {
77+ px , perr := t .internalProxies ()
78+ if perr != nil {
79+ return nil , perr
80+ }
81+ return dns53 .NewTransportFrom (t .internalCtx (), id , ipp , px )
82+ }
83+
84+ // csv2slice splits a comma-separated csv into a slice; returns nil if csv is
85+ // empty (the underlying transports treat nil/empty the same).
86+ func csv2slice (csv string ) (xs []string ) {
87+ if len (csv ) > 0 {
88+ xs = strings .Split (csv , "," )
89+ }
90+ return // nil for empty csv
91+ }
92+
2793// AddDNSProxy creates and adds a DNS53 transport to the tunnel's resolver.
2894func AddDNSProxy (t Tunnel , id , ippcsv string ) error {
29- p , perr := t .internalProxies ()
3095 r , rerr := t .internalResolver ()
31- if rerr != nil || perr != nil {
32- return core . JoinErr ( rerr , perr )
96+ if rerr != nil {
97+ return rerr
3398 }
34- ctx := t .internalCtx ()
3599 specialHostname := protect .HostlessPrefix + id
36- if dns , err := dns53 .NewTransportFromHostname (ctx , id , specialHostname , ippcsv , p ); err != nil {
100+ dns , err := MakeDNS53Transport (t , id , specialHostname , ippcsv )
101+ if err != nil {
37102 return err
38- } else {
39- return addDNSTransport (r , dns )
40103 }
104+ return addDNSTransport (r , dns )
41105}
42106
43- func newSystemDNSProxy (ctx context. Context , p ipn. ProxyProvider , ipcsv string ) (d dnsx.Transport , err error ) {
107+ func newSystemDNSProxy (t Tunnel , ipcsv string ) (d dnsx.Transport , err error ) {
44108 specialHostname := protect .Systemhost // never resolved by ipmap:LookupNetIP
45- return dns53 . NewTransportFromHostname ( ctx , dnsx .System , specialHostname , ipcsv , p )
109+ return MakeDNS53Transport ( t , dnsx .System , specialHostname , ipcsv )
46110}
47111
48112// SetSystemDNS creates and adds a DNS53 transport of the specified IP addresses.
49113func SetSystemDNS (t Tunnel , ipcsvx string ) error {
50114 r , rerr := t .internalResolver ()
51- p , perr := t .internalProxies ()
52- ctx := t .internalCtx ()
115+ _ , perr := t .internalProxies ()
53116 ipcsv := ipcsvx
54117 n := len (ipcsv )
55- if r == nil || p = = nil {
118+ if rerr != nil || perr ! = nil {
56119 log .W ("dns: sys: cannot set system dns; n: %d, errs: %v %v" , n , rerr , perr )
57120 return core .JoinErr (dnsx .ErrAddFailed , rerr , perr )
58121 }
@@ -74,7 +137,7 @@ func SetSystemDNS(t Tunnel, ipcsvx string) error {
74137 }
75138
76139 var ok bool
77- if sdns , err := newSystemDNSProxy (ctx , p , ipcsv ); err == nil {
140+ if sdns , err := newSystemDNSProxy (t , ipcsv ); err == nil {
78141 ok = r .Add (sdns )
79142 } else {
80143 return err
@@ -131,13 +194,11 @@ func AddDefaultTransport(t Tunnel, typ, ippOrUrl, ips string) error {
131194
132195// AddProxyDNS creates and adds a DNS53 transport as defined in Proxy's configuration.
133196func AddProxyDNS (t Tunnel , p x.Proxy ) error {
134- pxr , perr := t .internalProxies ()
135197 r , rerr := t .internalResolver ()
136- if rerr != nil || perr != nil {
137- return core . JoinErr ( rerr , perr )
198+ if rerr != nil {
199+ return rerr
138200 }
139201 pid := p .ID ()
140- ctx := t .internalCtx ()
141202 // TODO: create dns53.NewTransportForProxy() which is self-healing and
142203 // uses updated DNS addresses if p.DNS() has changed/updated
143204 ipOrHostCsv := p .DNS () // may return csv(host:port), csv(ip:port), csv(ips), csv(host)
@@ -152,81 +213,60 @@ func AddProxyDNS(t Tunnel, p x.Proxy) error {
152213 }
153214 first := ipsOrHost [0 ]
154215 ipport , err := xdns .DnsIPPort (first )
155- hostOrHostport := first // could be multiple hostnames or host:ports, but choose the first
156- if err != nil { // use hostname
157- if dns , err := dns53 .NewTransportFromHostname (ctx , pid , hostOrHostport , "" /*ip or ip:port csv*/ , pxr ); err != nil {
158- return err
159- } else {
160- return addDNSTransport (r , dns )
216+ if err != nil { // use hostname
217+ dns , derr := MakeDNS53Transport (t , pid , first , "" /*ip or ip:port csv*/ )
218+ if derr != nil {
219+ return derr
161220 }
162- // use ipports; register with same id as the proxy p
163- } else if dns , err := dns53 .NewTransportFrom (ctx , pid , ipport , pxr ); err != nil {
164- return err
165- } else {
166221 return addDNSTransport (r , dns )
167222 }
223+ // use ipports; register with same id as the proxy p
224+ dns , derr := MakeDNS53TransportFrom (t , pid , ipport )
225+ if derr != nil {
226+ return derr
227+ }
228+ return addDNSTransport (r , dns )
168229}
169230
170231// AddDoHTransport creates and adds a Transport that connects to the specified DoH server.
171232// `url` is the URL of a DoH server (no template, POST-only).
172233func AddDoHTransport (t Tunnel , id , url , ipcsv string ) error {
173- pxr , perr := t .internalProxies ()
174234 r , rerr := t .internalResolver ()
175- if rerr != nil || perr != nil {
176- return core .JoinErr (rerr , perr )
177- }
178- ips := ipcsv
179- ctx := t .internalCtx ()
180- split := []string {}
181- if len (ips ) > 0 {
182- split = strings .Split (ips , "," )
235+ if rerr != nil {
236+ return rerr
183237 }
184- if dns , err := doh .NewTransport (ctx , id , url , split , pxr ); err != nil {
238+ dns , err := MakeDoHTransport (t , id , url , ipcsv )
239+ if err != nil {
185240 return err
186- } else {
187- return addDNSTransport (r , dns )
188241 }
242+ return addDNSTransport (r , dns )
189243}
190244
191245// AddODoHTransport creates and adds a Transport that connects to the specified ODoH server.
192246// `endpoint` is the entry / proxy for the ODoH server, `resolver` is the URL of the target ODoH server.
193247func AddODoHTransport (t Tunnel , id , endpoint , resolver , epipcsv string ) error {
194- pxr , perr := t .internalProxies ()
195248 r , rerr := t .internalResolver ()
196- if rerr != nil || perr != nil {
197- return core .JoinErr (rerr , perr )
198- }
199- epips := epipcsv
200- ctx := t .internalCtx ()
201- split := []string {}
202- if len (epips ) > 0 {
203- split = strings .Split (epips , "," )
249+ if rerr != nil {
250+ return rerr
204251 }
205- if dns , err := doh .NewOdohTransport (ctx , id , endpoint , resolver , split , pxr ); err != nil {
252+ dns , err := MakeODoHTransport (t , id , endpoint , resolver , epipcsv )
253+ if err != nil {
206254 return err
207- } else {
208- return addDNSTransport (r , dns )
209255 }
256+ return addDNSTransport (r , dns )
210257}
211258
212259// AddDoTTransport creates and adds a Transport that connects to the specified DoT server.
213260func AddDoTTransport (t Tunnel , id , url , ipcsv string ) error {
214- pxr , perr := t .internalProxies ()
215261 r , rerr := t .internalResolver ()
216- if rerr != nil || perr != nil {
217- return core .JoinErr (rerr , perr )
218- }
219- ctx := t .internalCtx ()
220- split := []string {}
221- ips := ipcsv
222- if len (ips ) > 0 {
223- split = strings .Split (ips , "," )
262+ if rerr != nil {
263+ return rerr
224264 }
225- if dns , err := dns53 .NewTLSTransport (ctx , id , url , split , pxr ); err != nil {
265+ dns , err := MakeDoTTransport (t , id , url , ipcsv )
266+ if err != nil {
226267 return err
227- } else {
228- return addDNSTransport (r , dns )
229268 }
269+ return addDNSTransport (r , dns )
230270}
231271
232272// AddDNSCryptTransport creates and adds a DNSCrypt transport to the tunnel's resolver.
0 commit comments