internal/controld: check if ipv4 is available before connect to API

Updates #53
This commit is contained in:
Cuong Manh Le
2023-02-10 01:19:53 +07:00
committed by Cuong Manh Le
parent 45f827a2c5
commit 83b551fb2d
8 changed files with 108 additions and 87 deletions

View File

@@ -8,6 +8,8 @@ import (
"net"
"net/http"
"time"
ctrldnet "github.com/Control-D-Inc/ctrld/internal/net"
)
const (
@@ -15,20 +17,6 @@ const (
InvalidConfigCode = 40401
)
const bootstrapDNS = "76.76.2.0:53"
var Dialer = &net.Dialer{
Resolver: &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: 10 * time.Second,
}
return d.DialContext(ctx, "udp", bootstrapDNS)
},
},
}
// ResolverConfig represents Control D resolver data.
type ResolverConfig struct {
DOH string `json:"doh"`
@@ -70,7 +58,13 @@ func FetchResolverConfig(uid string) (*ResolverConfig, error) {
req.Header.Add("Content-Type", "application/json")
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
return Dialer.DialContext(ctx, "tcp4", addr)
// We experiment hanging in TLS handshake when connecting to ControlD API
// with ipv6. So prefer ipv4 if available.
network = "tcp6"
if ctrldnet.SupportsIPv4() {
network = "tcp4"
}
return ctrldnet.Dialer.DialContext(ctx, network, addr)
}
client := http.Client{
Timeout: 10 * time.Second,