Skip to content

net: add configuration knob to force TCP-only DNS requests in the pure Go resolver on unix #29358

@jfbus

Description

@jfbus

Context

There is a DNS resolution bug in Kubernetes (UDP response packets get dropped by conntrack, causing timeouts in DNS queries) : kubernetes/kubernetes#56903

A work-around is to configure the linux resolver to use TCP (e.g. using the use-vc option in resolv.conf).

This workaround works with the cgo resolver on glibc-based platforms, but not on musl-based plaforms (e.g. Alpine).

This workaround cannot be used with the pure Go resolver, as it always tries UDP before switching to TCP.

Proposal 1

A solution would be to look for the use-vc option in resolv.conf, and switch to TCP when found.

=> https://go-review.googlesource.com/c/go/+/156366

Proposal 2

Another solution would be to be able to configure the Go resolver to use TCP, either using the GODEBUG env var (e.g. GODEBUG=netdns=go+tcp) or using a net.Resolver flag (e.g. PreferTCP).

in net/dnsclient_unix.go

func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration) (dnsmessage.Parser, dnsmessage.Header, error) {
[...]
    var networks []string
    if r.PreferTCP || systemConf().preferTCP {
        networks = []string{"tcp"}
    } else {
        networks = []string{"udp", "tcp"}
    }
    for _, network := range networks {

=> https://go-review.googlesource.com/c/go/+/155378

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions