...
Run Format

Source file src/net/lookup_unix.go

     1	// Copyright 2011 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build darwin dragonfly freebsd linux netbsd openbsd solaris
     6	
     7	package net
     8	
     9	import (
    10		"context"
    11		"sync"
    12	)
    13	
    14	var onceReadProtocols sync.Once
    15	
    16	// readProtocols loads contents of /etc/protocols into protocols map
    17	// for quick access.
    18	func readProtocols() {
    19		if file, err := open("/etc/protocols"); err == nil {
    20			for line, ok := file.readLine(); ok; line, ok = file.readLine() {
    21				// tcp    6   TCP    # transmission control protocol
    22				if i := byteIndex(line, '#'); i >= 0 {
    23					line = line[0:i]
    24				}
    25				f := getFields(line)
    26				if len(f) < 2 {
    27					continue
    28				}
    29				if proto, _, ok := dtoi(f[1]); ok {
    30					if _, ok := protocols[f[0]]; !ok {
    31						protocols[f[0]] = proto
    32					}
    33					for _, alias := range f[2:] {
    34						if _, ok := protocols[alias]; !ok {
    35							protocols[alias] = proto
    36						}
    37					}
    38				}
    39			}
    40			file.close()
    41		}
    42	}
    43	
    44	// lookupProtocol looks up IP protocol name in /etc/protocols and
    45	// returns correspondent protocol number.
    46	func lookupProtocol(_ context.Context, name string) (int, error) {
    47		onceReadProtocols.Do(readProtocols)
    48		return lookupProtocolMap(name)
    49	}
    50	
    51	func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string, err error) {
    52		order := systemConf().hostLookupOrder(host)
    53		if !r.PreferGo && order == hostLookupCgo {
    54			if addrs, err, ok := cgoLookupHost(ctx, host); ok {
    55				return addrs, err
    56			}
    57			// cgo not available (or netgo); fall back to Go's DNS resolver
    58			order = hostLookupFilesDNS
    59		}
    60		return goLookupHostOrder(ctx, host, order)
    61	}
    62	
    63	func (r *Resolver) lookupIP(ctx context.Context, host string) (addrs []IPAddr, err error) {
    64		if r.PreferGo {
    65			return goLookupIP(ctx, host)
    66		}
    67		order := systemConf().hostLookupOrder(host)
    68		if order == hostLookupCgo {
    69			if addrs, err, ok := cgoLookupIP(ctx, host); ok {
    70				return addrs, err
    71			}
    72			// cgo not available (or netgo); fall back to Go's DNS resolver
    73			order = hostLookupFilesDNS
    74		}
    75		addrs, _, err = goLookupIPCNAMEOrder(ctx, host, order)
    76		return
    77	}
    78	
    79	func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int, error) {
    80		if !r.PreferGo && systemConf().canUseCgo() {
    81			if port, err, ok := cgoLookupPort(ctx, network, service); ok {
    82				if err != nil {
    83					// Issue 18213: if cgo fails, first check to see whether we
    84					// have the answer baked-in to the net package.
    85					if port, err := goLookupPort(network, service); err == nil {
    86						return port, nil
    87					}
    88				}
    89				return port, err
    90			}
    91		}
    92		return goLookupPort(network, service)
    93	}
    94	
    95	func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
    96		if !r.PreferGo && systemConf().canUseCgo() {
    97			if cname, err, ok := cgoLookupCNAME(ctx, name); ok {
    98				return cname, err
    99			}
   100		}
   101		return goLookupCNAME(ctx, name)
   102	}
   103	
   104	func (*Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
   105		var target string
   106		if service == "" && proto == "" {
   107			target = name
   108		} else {
   109			target = "_" + service + "._" + proto + "." + name
   110		}
   111		cname, rrs, err := lookup(ctx, target, dnsTypeSRV)
   112		if err != nil {
   113			return "", nil, err
   114		}
   115		srvs := make([]*SRV, len(rrs))
   116		for i, rr := range rrs {
   117			rr := rr.(*dnsRR_SRV)
   118			srvs[i] = &SRV{Target: rr.Target, Port: rr.Port, Priority: rr.Priority, Weight: rr.Weight}
   119		}
   120		byPriorityWeight(srvs).sort()
   121		return cname, srvs, nil
   122	}
   123	
   124	func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
   125		_, rrs, err := lookup(ctx, name, dnsTypeMX)
   126		if err != nil {
   127			return nil, err
   128		}
   129		mxs := make([]*MX, len(rrs))
   130		for i, rr := range rrs {
   131			rr := rr.(*dnsRR_MX)
   132			mxs[i] = &MX{Host: rr.Mx, Pref: rr.Pref}
   133		}
   134		byPref(mxs).sort()
   135		return mxs, nil
   136	}
   137	
   138	func (*Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
   139		_, rrs, err := lookup(ctx, name, dnsTypeNS)
   140		if err != nil {
   141			return nil, err
   142		}
   143		nss := make([]*NS, len(rrs))
   144		for i, rr := range rrs {
   145			nss[i] = &NS{Host: rr.(*dnsRR_NS).Ns}
   146		}
   147		return nss, nil
   148	}
   149	
   150	func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) {
   151		_, rrs, err := lookup(ctx, name, dnsTypeTXT)
   152		if err != nil {
   153			return nil, err
   154		}
   155		txts := make([]string, len(rrs))
   156		for i, rr := range rrs {
   157			txts[i] = rr.(*dnsRR_TXT).Txt
   158		}
   159		return txts, nil
   160	}
   161	
   162	func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
   163		if !r.PreferGo && systemConf().canUseCgo() {
   164			if ptrs, err, ok := cgoLookupPTR(ctx, addr); ok {
   165				return ptrs, err
   166			}
   167		}
   168		return goLookupPTR(ctx, addr)
   169	}
   170	

View as plain text