Files
opera-proxy/resolver/factory.go
T

82 lines
1.6 KiB
Go
Raw Normal View History

2025-08-12 19:38:17 +03:00
package resolver
import (
2026-01-08 22:38:17 +02:00
"crypto/tls"
"crypto/x509"
2025-08-12 19:38:17 +03:00
"errors"
"net"
2026-01-08 22:53:27 +02:00
"net/http"
2025-08-12 19:38:17 +03:00
"net/url"
"strings"
2026-01-08 22:53:27 +02:00
"time"
2025-08-12 19:38:17 +03:00
"github.com/ncruces/go-dns"
)
2026-01-08 22:38:17 +02:00
func FromURL(u string, caPool *x509.CertPool) (*net.Resolver, error) {
2025-09-24 00:32:48 +03:00
begin:
2025-08-12 19:38:17 +03:00
parsed, err := url.Parse(u)
if err != nil {
return nil, err
}
2025-08-16 02:52:52 +03:00
host := parsed.Hostname()
port := parsed.Port()
2025-09-23 23:37:29 +03:00
switch scheme := strings.ToLower(parsed.Scheme); scheme {
2025-09-24 00:32:48 +03:00
case "":
switch {
case strings.HasPrefix(u, "//"):
u = "dns:" + u
default:
u = "dns://" + u
}
goto begin
case "udp", "dns":
2025-08-12 19:38:17 +03:00
if port == "" {
port = "53"
}
return NewPlainResolver(net.JoinHostPort(host, port)), nil
case "tcp":
if port == "" {
port = "53"
}
return NewTCPResolver(net.JoinHostPort(host, port)), nil
2025-09-23 23:37:29 +03:00
case "http", "https", "doh":
2025-08-16 02:52:52 +03:00
if port == "" {
2025-09-23 23:37:29 +03:00
if scheme == "http" {
port = "80"
} else {
port = "443"
}
}
if scheme == "doh" {
parsed.Scheme = "https"
u = parsed.String()
2025-08-16 02:52:52 +03:00
}
2026-01-08 22:53:27 +02:00
return dns.NewDoHResolver(u,
dns.DoHAddresses(net.JoinHostPort(host, port)),
dns.DoHTransport(&http.Transport{
MaxIdleConns: http.DefaultMaxIdleConnsPerHost,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ForceAttemptHTTP2: true,
TLSClientConfig: &tls.Config{
RootCAs: caPool,
},
}),
)
2025-09-23 23:37:29 +03:00
case "tls", "dot":
2025-08-12 19:38:17 +03:00
if port == "" {
port = "853"
}
2025-08-16 02:52:52 +03:00
hp := net.JoinHostPort(host, port)
2026-01-08 22:38:17 +02:00
return dns.NewDoTResolver(hp,
dns.DoTAddresses(hp),
dns.DoTConfig(&tls.Config{
RootCAs: caPool,
}),
)
2025-08-12 19:38:17 +03:00
default:
return nil, errors.New("not implemented")
}
}