Copyright 2011 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.
+build aix darwin dragonfly freebsd linux netbsd openbsd solaris

package net

import (
	
	
	
	

	
)

var onceReadProtocols sync.Once
readProtocols loads contents of /etc/protocols into protocols map for quick access.
func () {
	,  := open("/etc/protocols")
	if  != nil {
		return
	}
	defer .close()

tcp 6 TCP # transmission control protocol
		if  := bytealg.IndexByteString(, '#');  >= 0 {
			 = [0:]
		}
		 := getFields()
		if len() < 2 {
			continue
		}
		if , ,  := dtoi([1]);  {
			if ,  := protocols[[0]]; ! {
				protocols[[0]] = 
			}
			for ,  := range [2:] {
				if ,  := protocols[]; ! {
					protocols[] = 
				}
			}
		}
	}
}
lookupProtocol looks up IP protocol name in /etc/protocols and returns correspondent protocol number.
Calling Dial here is scary -- we have to be sure not to dial a name that will require a DNS lookup, or Dial will call back here to translate it. The DNS config parser has already checked that all the cfg.servers are IP addresses, which Dial will use without a DNS lookup.
	var  Conn
	var  error
	if  != nil && .Dial != nil {
		,  = .Dial(, , )
	} else {
		var  Dialer
		,  = .DialContext(, , )
	}
	if  != nil {
		return nil, mapErr()
	}
	return , nil
}

func ( *Resolver) ( context.Context,  string) ( []string,  error) {
	 := systemConf().hostLookupOrder(, )
	if !.preferGo() &&  == hostLookupCgo {
		if , ,  := cgoLookupHost(, );  {
			return , 
cgo not available (or netgo); fall back to Go's DNS resolver
		 = hostLookupFilesDNS
	}
	return .goLookupHostOrder(, , )
}

func ( *Resolver) ( context.Context, ,  string) ( []IPAddr,  error) {
	if .preferGo() {
		return .goLookupIP(, )
	}
	 := systemConf().hostLookupOrder(, )
	if  == hostLookupCgo {
		if , ,  := cgoLookupIP(, , );  {
			return , 
cgo not available (or netgo); fall back to Go's DNS resolver
		 = hostLookupFilesDNS
	}
	, ,  := .goLookupIPCNAMEOrder(, , )
	return , 
}

func ( *Resolver) ( context.Context, ,  string) (int, error) {
	if !.preferGo() && systemConf().canUseCgo() {
		if , ,  := cgoLookupPort(, , );  {
Issue 18213: if cgo fails, first check to see whether we have the answer baked-in to the net package.
				if ,  := goLookupPort(, );  == nil {
					return , nil
				}
			}
			return , 
		}
	}
	return goLookupPort(, )
}

func ( *Resolver) ( context.Context,  string) (string, error) {
	if !.preferGo() && systemConf().canUseCgo() {
		if , ,  := cgoLookupCNAME(, );  {
			return , 
		}
	}
	return .goLookupCNAME(, )
}

func ( *Resolver) ( context.Context, , ,  string) (string, []*SRV, error) {
	var  string
	if  == "" &&  == "" {
		 = 
	} else {
		 = "_" +  + "._" +  + "." + 
	}
	, ,  := .lookup(, , dnsmessage.TypeSRV)
	if  != nil {
		return "", nil, 
	}
	var  []*SRV
	var  dnsmessage.Name
	for {
		,  := .AnswerHeader()
		if  == dnsmessage.ErrSectionDone {
			break
		}
		if  != nil {
			return "", nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
		}
		if .Type != dnsmessage.TypeSRV {
			if  := .SkipAnswer();  != nil {
				return "", nil, &DNSError{
					Err:    "cannot unmarshal DNS message",
					Name:   ,
					Server: ,
				}
			}
			continue
		}
		if .Length == 0 && .Name.Length != 0 {
			 = .Name
		}
		,  := .SRVResource()
		if  != nil {
			return "", nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
		}
		 = append(, &SRV{Target: .Target.String(), Port: .Port, Priority: .Priority, Weight: .Weight})
	}
	byPriorityWeight().sort()
	return .String(), , nil
}

func ( *Resolver) ( context.Context,  string) ([]*MX, error) {
	, ,  := .lookup(, , dnsmessage.TypeMX)
	if  != nil {
		return nil, 
	}
	var  []*MX
	for {
		,  := .AnswerHeader()
		if  == dnsmessage.ErrSectionDone {
			break
		}
		if  != nil {
			return nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
		}
		if .Type != dnsmessage.TypeMX {
			if  := .SkipAnswer();  != nil {
				return nil, &DNSError{
					Err:    "cannot unmarshal DNS message",
					Name:   ,
					Server: ,
				}
			}
			continue
		}
		,  := .MXResource()
		if  != nil {
			return nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
		}
		 = append(, &MX{Host: .MX.String(), Pref: .Pref})

	}
	byPref().sort()
	return , nil
}

func ( *Resolver) ( context.Context,  string) ([]*NS, error) {
	, ,  := .lookup(, , dnsmessage.TypeNS)
	if  != nil {
		return nil, 
	}
	var  []*NS
	for {
		,  := .AnswerHeader()
		if  == dnsmessage.ErrSectionDone {
			break
		}
		if  != nil {
			return nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
		}
		if .Type != dnsmessage.TypeNS {
			if  := .SkipAnswer();  != nil {
				return nil, &DNSError{
					Err:    "cannot unmarshal DNS message",
					Name:   ,
					Server: ,
				}
			}
			continue
		}
		,  := .NSResource()
		if  != nil {
			return nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
		}
		 = append(, &NS{Host: .NS.String()})
	}
	return , nil
}

func ( *Resolver) ( context.Context,  string) ([]string, error) {
	, ,  := .lookup(, , dnsmessage.TypeTXT)
	if  != nil {
		return nil, 
	}
	var  []string
	for {
		,  := .AnswerHeader()
		if  == dnsmessage.ErrSectionDone {
			break
		}
		if  != nil {
			return nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
		}
		if .Type != dnsmessage.TypeTXT {
			if  := .SkipAnswer();  != nil {
				return nil, &DNSError{
					Err:    "cannot unmarshal DNS message",
					Name:   ,
					Server: ,
				}
			}
			continue
		}
		,  := .TXTResource()
		if  != nil {
			return nil, &DNSError{
				Err:    "cannot unmarshal DNS message",
				Name:   ,
				Server: ,
			}
Multiple strings in one TXT record need to be concatenated without separator to be consistent with previous Go resolver.
		 := 0
		for ,  := range .TXT {
			 += len()
		}
		 := make([]byte, 0, )
		for ,  := range .TXT {
			 = append(, ...)
		}
		if len() == 0 {
			 = make([]string, 0, 1)
		}
		 = append(, string())
	}
	return , nil
}

func ( *Resolver) ( context.Context,  string) ([]string, error) {
	if !.preferGo() && systemConf().canUseCgo() {
		if , ,  := cgoLookupPTR(, );  {
			return , 
		}
	}
	return .goLookupPTR(, )
}
concurrentThreadsLimit returns the number of threads we permit to run concurrently doing DNS lookups via cgo. A DNS lookup may use a file descriptor so we limit this to less than the number of permitted open files. On some systems, notably Darwin, if getaddrinfo is unable to open a file descriptor it simply returns EAI_NONAME rather than a useful error. Limiting the number of concurrent getaddrinfo calls to less than the permitted number of file descriptors makes that error less likely. We don't bother to apply the same limit to DNS lookups run directly from Go, because there we will return a meaningful "too many open files" error.
func () int {
	var  syscall.Rlimit
	if  := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &);  != nil {
		return 500
	}
	 := int(.Cur)
	if  > 500 {
		 = 500
	} else if  > 30 {
		 -= 30
	}
	return