Ensure http.Transport defaults are set correctly and resolve IPv6 issue with imctl check run

This commit is contained in:
Peter 2021-10-22 11:12:46 +02:00
parent 31e0165100
commit 01ecd7a442
Signed by: prskr
GPG key ID: C1DB5D2E8DB512F9
3 changed files with 41 additions and 22 deletions

View file

@ -94,6 +94,8 @@ tasks:
deps:
- go-generate
- protoc
cmds:
- task: format
test:
desc: run short running unit tests that do not need sudo
@ -191,7 +193,6 @@ tasks:
- deps
- generate
cmds:
- task: format
- goreleaser release --snapshot --skip-publish --rm-dist
release:
@ -200,7 +201,6 @@ tasks:
- deps
- generate
cmds:
- task: format
- goreleaser release --rm-dist
docs:

View file

@ -105,7 +105,7 @@ func init() {
runCheckCmd.Flags().Uint16Var(&args.HTTPPort, "http-port", uint16(defaultHTTPPort), "Port to connect to for 'http://' requests")
runCheckCmd.Flags().Uint16Var(&args.HTTPSPort, "https-port", defaultHTTPSPort, "Port to connect to for 'https://' requests")
runCheckCmd.Flags().Uint16Var(&args.DNSPort, "dns-port", defaultDNSPort, "Port to connect to for DNS requests")
runCheckCmd.Flags().StringVar(&args.DNSProto, "dns-proto", "tcp4", "Protocol to use for DNS requests one of [tcp, tcp4, tcp6, udp, udp4, udp6]")
runCheckCmd.Flags().StringVar(&args.DNSProto, "dns-proto", "tcp", "Protocol to use for DNS requests one of [tcp, tcp4, tcp6, udp, udp4, udp6]")
runCheckCmd.Flags().Uint16Var(&args.DoTPort, "dot-port", defaultDoTPort, "Port to use for DoT requests")
runCheckCmd.Flags().DurationVar(&args.Timeout, "check-timeout", defaultTimeout, "timeout to execute the check")
runCheckCmd.Flags().StringVar(&args.CACertPath, "ca-cert", "", "Path to CA cert file to trust additionally to system cert pool")
@ -178,38 +178,26 @@ func setupClients(
logger logging.Logger,
args *runCheckArgs,
) (health.HTTPClientForModule, health.ResolverForModule, error) {
logger = logger.With(zap.String("target", args.Target))
if targetIP := net.ParseIP(args.Target); len(targetIP) == 0 {
logger.Debug("target is apparently not an IP - resolving IP address")
if addrs, err := net.DefaultResolver.LookupHost(ctx, args.Target); err != nil {
target, err := resolveTargetIP(ctx, logger, args.Target)
if err != nil {
return nil, nil, err
} else {
logger.Debug("Resolved target addresses", zap.Strings("resolvedAddresses", addrs))
//nolint:gosec // no need for cryptographic security when picking a random IP address to contact
idx := rand.Intn(len(addrs))
logger.Debug("Picked random address", zap.String("newTargetAddress", addrs[idx]))
args.Target = addrs[idx]
}
} else {
logger.Debug("target is an IP address - will be set for clients")
}
healthCfg := health.Config{
Client: health.ClientsConfig{
HTTP: health.Server{
IP: args.Target,
IP: target,
Port: args.HTTPPort,
},
HTTPS: health.Server{
IP: args.Target,
IP: target,
Port: args.HTTPSPort,
},
DNS: health.Server{
IP: args.Target,
IP: target,
Port: args.DNSPort,
},
DoT: health.Server{
IP: args.Target,
IP: target,
Port: args.DoTPort,
},
},
@ -266,3 +254,29 @@ func addCACertToPool(pool *x509.CertPool) (err error) {
pool.AppendCertsFromPEM(buffer.Bytes())
return nil
}
func resolveTargetIP(ctx context.Context, logger logging.Logger, target string) (string, error) {
logger = logger.With(zap.String("target", target))
if targetIP := net.ParseIP(target); targetIP != nil && len(targetIP) > 0 {
logger.Debug("target is an IP address - will be set for clients")
return target, nil
}
logger.Debug("target is apparently not an IP - resolving IP address")
if addrs, err := net.DefaultResolver.LookupHost(ctx, args.Target); err != nil {
return "", err
} else {
logger.Debug("Resolved target addresses", zap.Strings("resolvedAddresses", addrs))
//nolint:gosec // no need for cryptographic security when picking a random IP address to contact
pickedAddr := addrs[rand.Intn(len(addrs))]
logger.Debug("Picked random address", zap.String("newTargetAddress", pickedAddr))
if parsed := net.ParseIP(pickedAddr); parsed == nil {
logger.Error("Could not parse resolved IP", zap.String("addr", pickedAddr))
return "", errors.New("could not parse resolved IP")
} else if parsed.To4() == nil {
pickedAddr = fmt.Sprintf("[%s]", pickedAddr)
}
args.Target = pickedAddr
}
return target, nil
}

View file

@ -6,6 +6,7 @@ import (
"fmt"
"net"
gohttp "net/http"
"time"
"golang.org/x/net/http2"
)
@ -44,6 +45,10 @@ func HTTPClient(cfg Config, tlsConfig *tls.Config) *gohttp.Client {
)
roundTripper := &gohttp.Transport{
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
return netDialer.DialContext(ctx, "tcp", fmt.Sprintf("%s:%d", httpEndpoint.IP, httpEndpoint.Port))
},