You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: recursive.go
    path of file: ./repos/sliver/vendor/tailscale.com/net/dns/recursive
    
    the code of the file until where you have to start completion: // Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause

// Package recursive implements a simple recursive DNS resolver.
package recursive

import (
	"context"
	"errors"
	"fmt"
	"net"
	"net/netip"
	"slices"
	"strings"
	"time"

	"github.com/miekg/dns"
	"tailscale.com/envknob"
	"tailscale.com/net/netns"
	"tailscale.com/types/logger"
	"tailscale.com/util/dnsname"
	"tailscale.com/util/mak"
	"tailscale.com/util/multierr"
	"tailscale.com/util/slicesx"
)

const (
	// maxDepth is how deep from the root nameservers we'll recurse when
	// resolving; passing this limit will instead return an error.
	//
	// maxDepth must be at least 20 to resolve "console.aws.amazon.com",
	// which is a domain with a moderat
    
func (r *Resolver) newState() *queryState {
	var rootServers []netip.Addr
	if len(r.rootServers) > 0 {
		rootServers = r.rootServers
	} else {
		// Select a random subset of root nameservers to start from, since if
		// we don't get responses from those, something else has probably gone
		// horribly wrong.
		roots4 := slices.Clone(rootServersV4)
		slicesx.Shuffle(roots4)
		roots4 = roots4[:numStartingServers]

		var roots6 []netip.Addr
		if !r.NoIPv6 {
			roots6 = slices.Clone(rootServersV6)
			slicesx.Shuffle(roots6)
			roots6 = roots6[:numStartingServers]
		}

		// Interleave the root servers so that we try to contact them over
		// IPv4, then IPv6, IPv4, IPv6, etc.
		rootServers = slicesx.Interleave(roots4, roots6)
	}

	return &queryState{
		rootServers: rootServers,
	}
}