Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dns): support DoH, DoT, DoH3, DoQ #649

Merged
merged 28 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ffaa0a3
chore: define more DNS scheme
EkkoG Sep 24, 2024
de0850d
feat: support DoT
EkkoG Sep 24, 2024
fd8ca88
feat: support DoH
EkkoG Sep 24, 2024
f0ef835
feat: support DoH3
EkkoG Sep 24, 2024
9261ec1
chore: change DoH3 scheme to h3
EkkoG Sep 24, 2024
0bef80f
chore: DoH3 scheme support both h3 and http3
EkkoG Sep 24, 2024
1643f71
fix: tcp+udp scheme broken and change control flow to switch when sen…
EkkoG Sep 25, 2024
4fbd640
chore: make DNS scheme http3 as a h3 alias
EkkoG Sep 25, 2024
8350725
fix: DoH3 fake addr issue
EkkoG Sep 25, 2024
31c24df
fix: udp+tcp alias to h3
EkkoG Sep 25, 2024
3a01eee
chore: remove DNS quic scheme since it not be implemented yet
EkkoG Sep 25, 2024
bd5e41d
Revert "chore: remove DNS quic scheme since it not be implemented yet"
EkkoG Sep 25, 2024
3aaa67a
feat: support DoQ
EkkoG Sep 25, 2024
203506d
refactor: add streamDNS func for DoT, tcp, DoQ
EkkoG Sep 26, 2024
b483825
fix: DoQ msg id issue
EkkoG Sep 26, 2024
c89819e
chore: remove stream interface, use io.ReadWriter instead
EkkoG Sep 26, 2024
850bf64
Fix: set DoH req's SNI and HTTP host to avoid certificate verify fail…
EkkoG Sep 26, 2024
78af443
refactor: more clear send request function name
EkkoG Sep 26, 2024
103f60b
refactor: avoid convert []byte to string when send http request
EkkoG Sep 27, 2024
db89298
feat: support custom DoH/DoH3 url path
EkkoG Sep 27, 2024
4c5a462
feat: disable redirect when use HTTP DNS
EkkoG Sep 27, 2024
d9ad712
fix: error when DNS request over proxy
EkkoG Sep 27, 2024
bfa975d
feat(dns): set id to 0 when DoH and DoH3 for cache friendly
EkkoG Oct 8, 2024
a0ccbc3
feat(dns): reuse connection for DoH/DoH3/DoQ
EkkoG Oct 8, 2024
e01ce62
chore: remove unused code
EkkoG Oct 8, 2024
60d45a3
chore(dns): add comment for create new QUIC connection
EkkoG Oct 8, 2024
54185ee
fix(doh): problems with not recreating a new one when the client is n…
EkkoG Oct 9, 2024
d9ecac6
fix(dns): concurrent map writes
EkkoG Oct 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion component/dns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func New(dns *config.Dns, opt *NewOption) (s *Dns, err error) {

func (s *Dns) CheckUpstreamsFormat() error {
for _, upstream := range s.upstream {
_, _, _, err := ParseRawUpstream(upstream.Raw)
_, _, _, _, err := ParseRawUpstream(upstream.Raw)
if err != nil {
return err
}
Expand Down
41 changes: 33 additions & 8 deletions component/dns/upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ const (
UpstreamScheme_UDP UpstreamScheme = "udp"
UpstreamScheme_TCP_UDP UpstreamScheme = "tcp+udp"
upstreamScheme_TCP_UDP_Alias UpstreamScheme = "udp+tcp"
UpstreamScheme_TLS UpstreamScheme = "tls"
UpstreamScheme_QUIC UpstreamScheme = "quic"
UpstreamScheme_HTTPS UpstreamScheme = "https"
upstreamScheme_H3_Alias UpstreamScheme = "http3"
UpstreamScheme_H3 UpstreamScheme = "h3"
)

func (s UpstreamScheme) ContainsTcp() bool {
Expand All @@ -42,8 +47,9 @@ func (s UpstreamScheme) ContainsTcp() bool {
}
}

func ParseRawUpstream(raw *url.URL) (scheme UpstreamScheme, hostname string, port uint16, err error) {
func ParseRawUpstream(raw *url.URL) (scheme UpstreamScheme, hostname string, port uint16, path string, err error) {
var __port string
var __path string
switch scheme = UpstreamScheme(raw.Scheme); scheme {
case upstreamScheme_TCP_UDP_Alias:
scheme = UpstreamScheme_TCP_UDP
Expand All @@ -53,27 +59,45 @@ func ParseRawUpstream(raw *url.URL) (scheme UpstreamScheme, hostname string, por
if __port == "" {
__port = "53"
}
case upstreamScheme_H3_Alias:
scheme = UpstreamScheme_H3
fallthrough
case UpstreamScheme_HTTPS, UpstreamScheme_H3:
__port = raw.Port()
if __port == "" {
__port = "443"
}
__path = raw.Path
if __path == "" {
__path = "/dns-query"
}
case UpstreamScheme_QUIC, UpstreamScheme_TLS:
__port = raw.Port()
if __port == "" {
__port = "853"
}
default:
return "", "", 0, fmt.Errorf("unexpected scheme: %v", raw.Scheme)
return "", "", 0, "", fmt.Errorf("unexpected scheme: %v", raw.Scheme)
}
_port, err := strconv.ParseUint(__port, 10, 16)
if err != nil {
return "", "", 0, fmt.Errorf("failed to parse dns_upstream port: %v", err)
return "", "", 0, "", fmt.Errorf("failed to parse dns_upstream port: %v", err)
}
port = uint16(_port)
hostname = raw.Hostname()
return scheme, hostname, port, nil
return scheme, hostname, port, __path, nil
}

type Upstream struct {
Scheme UpstreamScheme
Hostname string
Port uint16
Path string
*netutils.Ip46
}

func NewUpstream(ctx context.Context, upstream *url.URL, resolverNetwork string) (up *Upstream, err error) {
scheme, hostname, port, err := ParseRawUpstream(upstream)
scheme, hostname, port, path, err := ParseRawUpstream(upstream)
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrFormat, err)
}
Expand All @@ -100,6 +124,7 @@ func NewUpstream(ctx context.Context, upstream *url.URL, resolverNetwork string)
Scheme: scheme,
Hostname: hostname,
Port: port,
Path: path,
Ip46: ip46,
}, nil
}
Expand All @@ -115,9 +140,9 @@ func (u *Upstream) SupportedNetworks() (ipversions []consts.IpVersionStr, l4prot
}
}
switch u.Scheme {
case UpstreamScheme_TCP:
case UpstreamScheme_TCP, UpstreamScheme_HTTPS, UpstreamScheme_TLS:
l4protos = []consts.L4ProtoStr{consts.L4ProtoStr_TCP}
case UpstreamScheme_UDP:
case UpstreamScheme_UDP, UpstreamScheme_QUIC, UpstreamScheme_H3:
l4protos = []consts.L4ProtoStr{consts.L4ProtoStr_UDP}
case UpstreamScheme_TCP_UDP:
// UDP first.
Expand All @@ -127,7 +152,7 @@ func (u *Upstream) SupportedNetworks() (ipversions []consts.IpVersionStr, l4prot
}

func (u *Upstream) String() string {
return string(u.Scheme) + "://" + net.JoinHostPort(u.Hostname, strconv.Itoa(int(u.Port)))
return string(u.Scheme) + "://" + net.JoinHostPort(u.Hostname, strconv.Itoa(int(u.Port))) + u.Path
}

type UpstreamResolver struct {
Expand Down
Loading
Loading