// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package netimport (_// for go:linkname)// provided by runtime////go:linkname runtime_rand runtime.randfunc runtime_rand() uint64func randInt() int {returnint(uint(runtime_rand()) >> 1) // clear sign bit}func randIntn( int) int {returnrandInt() % }// reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP// address addr suitable for rDNS (PTR) record lookup or an error if it fails// to parse the IP address.func reverseaddr( string) ( string, error) { := ParseIP()if == nil {return"", &DNSError{Err: "unrecognized address", Name: } }if .To4() != nil {returnitoa.Uitoa(uint([15])) + "." + itoa.Uitoa(uint([14])) + "." + itoa.Uitoa(uint([13])) + "." + itoa.Uitoa(uint([12])) + ".in-addr.arpa.", nil }// Must be IPv6 := make([]byte, 0, len()*4+len("ip6.arpa."))// Add it, in reverse, to the bufferfor := len() - 1; >= 0; -- { := [] = append(, hexDigit[&0xF],'.',hexDigit[>>4],'.') }// Append "ip6.arpa." and return (buf already has the final .) = append(, "ip6.arpa."...)returnstring(), nil}func equalASCIIName(, dnsmessage.Name) bool {if .Length != .Length {returnfalse }for := 0; < int(.Length); ++ { := .Data[] := .Data[]if'A' <= && <= 'Z' { += 0x20 }if'A' <= && <= 'Z' { += 0x20 }if != {returnfalse } }returntrue}// isDomainName checks if a string is a presentation-format domain name// (currently restricted to hostname-compatible "preferred name" LDH labels and// SRV-like "underscore labels"; see golang.org/issue/12421).//// isDomainName should be an internal detail,// but widely used packages access it using linkname.// Notable members of the hall of shame include:// - github.com/sagernet/sing//// Do not remove or change the type signature.// See go.dev/issue/67401.////go:linkname isDomainNamefunc isDomainName( string) bool {// The root domain name is valid. See golang.org/issue/45715.if == "." {returntrue }// See RFC 1035, RFC 3696. // Presentation format has dots before every label except the first, and the // terminal empty label is optional here because we assume fully-qualified // (absolute) input. We must therefore reserve space for the first and last // labels' length octets in wire format, where they are necessary and the // maximum total length is 255. // So our _effective_ maximum is 253, but 254 is not rejected if the last // character is a dot. := len()if == 0 || > 254 || == 254 && [-1] != '.' {returnfalse } := byte('.') := false// true once we've seen a letter or hyphen := 0for := 0; < len(); ++ { := []switch {default:returnfalsecase'a' <= && <= 'z' || 'A' <= && <= 'Z' || == '_': = true ++case'0' <= && <= '9':// fine ++case == '-':// Byte before dash cannot be dot.if == '.' {returnfalse } ++ = truecase == '.':// Byte before dot cannot be dot, dash.if == '.' || == '-' {returnfalse }if > 63 || == 0 {returnfalse } = 0 } = }if == '-' || > 63 {returnfalse }return}// absDomainName returns an absolute domain name which ends with a// trailing dot to match pure Go reverse resolver and all other lookup// routines.// See golang.org/issue/12189.// But we don't want to add dots for local names from /etc/hosts.// It's hard to tell so we settle on the heuristic that names without dots// (like "localhost" or "myhost") do not get trailing dots, but any other// names do.func absDomainName( string) string {ifbytealg.IndexByteString(, '.') != -1 && [len()-1] != '.' { += "." }return}// An SRV represents a single DNS SRV record.typeSRVstruct { Target string Port uint16 Priority uint16 Weight uint16}// byPriorityWeight sorts SRV records by ascending priority and weight.type byPriorityWeight []*SRV// shuffleByWeight shuffles SRV records by weight using the algorithm// described in RFC 2782.func ( byPriorityWeight) () { := 0for , := range { += int(.Weight) }for > 0 && len() > 1 { := 0 := randIntn()for := range { += int([].Weight)if > {if > 0 { [0], [] = [], [0] }break } } -= int([0].Weight) = [1:] }}// sort reorders SRV records as specified in RFC 2782.func ( byPriorityWeight) () {slices.SortFunc(, func(, *SRV) int {if := cmp.Compare(.Priority, .Priority); != 0 {return }returncmp.Compare(.Weight, .Weight) }) := 0for := 1; < len(); ++ {if [].Priority != [].Priority { [:].shuffleByWeight() = } } [:].shuffleByWeight()}// An MX represents a single DNS MX record.typeMXstruct { Host string Pref uint16}// byPref sorts MX records by preferencetype byPref []*MX// sort reorders MX records as specified in RFC 5321.func ( byPref) () {for := range { := randIntn( + 1) [], [] = [], [] }slices.SortFunc(, func(, *MX) int {returncmp.Compare(.Pref, .Pref) })}// An NS represents a single DNS NS record.typeNSstruct { Host string}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.