|
|
@@ -7,6 +7,8 @@ package dns
|
|
|
import (
|
|
|
"context"
|
|
|
"log"
|
|
|
+ "net/url"
|
|
|
+ "strconv"
|
|
|
"strings"
|
|
|
"sync"
|
|
|
"time"
|
|
|
@@ -85,22 +87,49 @@ func New(ctx context.Context, config *Config) (*Server, error) {
|
|
|
}
|
|
|
server.hosts = hosts
|
|
|
|
|
|
+ parseDOHURI := func(d string, endpoint *net.Endpoint) (host string, port uint32, err error) {
|
|
|
+ u, err := url.Parse(d)
|
|
|
+ if err != nil {
|
|
|
+ return "", 0, err
|
|
|
+ }
|
|
|
+ host = u.Hostname()
|
|
|
+ port = 443
|
|
|
+ if u.Port() != "" {
|
|
|
+ p, err := strconv.ParseUint(u.Port(), 10, 16)
|
|
|
+ if err != nil {
|
|
|
+ return "", 0, err
|
|
|
+ }
|
|
|
+ port = uint32(p)
|
|
|
+ }
|
|
|
+ if endpoint.Port != 0 {
|
|
|
+ port = endpoint.Port
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
addNameServer := func(endpoint *net.Endpoint) int {
|
|
|
address := endpoint.Address.AsAddress()
|
|
|
if address.Family().IsDomain() && address.Domain() == "localhost" {
|
|
|
server.clients = append(server.clients, NewLocalNameServer())
|
|
|
- } else if address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "DOHL_") {
|
|
|
- dohHost := address.Domain()[5:]
|
|
|
- server.clients = append(server.clients, NewDoHLocalNameServer(dohHost, endpoint.Port, server.clientIP))
|
|
|
- } else if address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "DOH_") {
|
|
|
- // DOH_ prefix makes net.Address think it's a domain
|
|
|
- dohHost := address.Domain()[4:]
|
|
|
+ } else if address.Family().IsDomain() && strings.HasPrefix(address.Domain(), "https+local://") {
|
|
|
+ // URI schemed string treated as domain
|
|
|
+ dohlHost, dohlPort, err := parseDOHURI(address.Domain(), endpoint)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatalln(newError("DNS config error").Base(err))
|
|
|
+ }
|
|
|
+ server.clients = append(server.clients, NewDoHLocalNameServer(dohlHost, dohlPort, server.clientIP))
|
|
|
+ } else if address.Family().IsDomain() &&
|
|
|
+ strings.HasPrefix(address.Domain(), "https://") {
|
|
|
+ dohHost, dohPort, err := parseDOHURI(address.Domain(), endpoint)
|
|
|
+ if err != nil {
|
|
|
+ log.Fatalln(newError("DNS config error").Base(err))
|
|
|
+ }
|
|
|
idx := len(server.clients)
|
|
|
server.clients = append(server.clients, nil)
|
|
|
|
|
|
// need the core dispatcher, register DOHClient at callback
|
|
|
common.Must(core.RequireFeatures(ctx, func(d routing.Dispatcher) {
|
|
|
- c, err := NewDoHNameServer(dohHost, endpoint.Port, d, server.clientIP)
|
|
|
+ c, err := NewDoHNameServer(dohHost, dohPort, d, server.clientIP)
|
|
|
if err != nil {
|
|
|
log.Fatalln(newError("DNS config error").Base(err))
|
|
|
}
|