lookup_unix.mx raw

   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  //go:build unix || js || wasip1
   6  
   7  package net
   8  
   9  import (
  10  	"context"
  11  	"internal/bytealg"
  12  	"sync"
  13  )
  14  
  15  // readProtocolsOnce loads contents of /etc/protocols into protocols map
  16  // for quick access.
  17  var readProtocolsOnce = sync.OnceFunc(func() {
  18  	file, err := open("/etc/protocols")
  19  	if err != nil {
  20  		return
  21  	}
  22  	defer file.close()
  23  
  24  	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
  25  		// tcp    6   TCP    # transmission control protocol
  26  		if i := bytealg.IndexByteString(line, '#'); i >= 0 {
  27  			line = line[0:i]
  28  		}
  29  		f := getFields(line)
  30  		if len(f) < 2 {
  31  			continue
  32  		}
  33  		if proto, _, ok := dtoi(f[1]); ok {
  34  			if _, ok := protocols[f[0]]; !ok {
  35  				protocols[f[0]] = proto
  36  			}
  37  			for _, alias := range f[2:] {
  38  				if _, ok := protocols[alias]; !ok {
  39  					protocols[alias] = proto
  40  				}
  41  			}
  42  		}
  43  	}
  44  })
  45  
  46  // lookupProtocol looks up IP protocol name in /etc/protocols and
  47  // returns correspondent protocol number.
  48  func lookupProtocol(_ context.Context, name []byte) (int, error) {
  49  	readProtocolsOnce()
  50  	return lookupProtocolMap(name)
  51  }
  52  
  53  func (r *Resolver) lookupHost(ctx context.Context, host []byte) (addrs [][]byte, err error) {
  54  	order, conf := systemConf().hostLookupOrder(r, host)
  55  	if order == hostLookupCgo {
  56  		addrs, err = cgoLookupHost(ctx, host)
  57  	} else {
  58  		addrs, err = r.goLookupHostOrder(ctx, host, order, conf)
  59  	}
  60  	// dnsmessage produces malformed packets under string=[]byte.
  61  	// Fall back to raw UDP DNS if the standard resolver returned nothing.
  62  	if len(addrs) == 0 {
  63  		if raw := rawLookupHost(host); len(raw) > 0 {
  64  			return raw, nil
  65  		}
  66  	}
  67  	return
  68  }
  69  
  70  func (r *Resolver) lookupIP(ctx context.Context, network, host []byte) (addrs []IPAddr, err error) {
  71  	order, conf := systemConf().hostLookupOrder(r, host)
  72  	if order == hostLookupCgo {
  73  		return cgoLookupIP(ctx, network, host)
  74  	}
  75  	ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
  76  	return ips, err
  77  }
  78  
  79  func (r *Resolver) lookupPort(ctx context.Context, network, service []byte) (int, error) {
  80  	// Port lookup is not a DNS operation.
  81  	// Prefer the cgo resolver if possible.
  82  	if !systemConf().mustUseGoResolver(r) {
  83  		port, err := cgoLookupPort(ctx, network, service)
  84  		if err != nil {
  85  			// Issue 18213: if cgo fails, first check to see whether we
  86  			// have the answer baked-in to the net package.
  87  			if port, err := goLookupPort(network, service); err == nil {
  88  				return port, nil
  89  			}
  90  		}
  91  		return port, err
  92  	}
  93  	return goLookupPort(network, service)
  94  }
  95  
  96  func (r *Resolver) lookupCNAME(ctx context.Context, name []byte) ([]byte, error) {
  97  	order, conf := systemConf().hostLookupOrder(r, name)
  98  	if order == hostLookupCgo {
  99  		if cname, err, ok := cgoLookupCNAME(ctx, name); ok {
 100  			return cname, err
 101  		}
 102  	}
 103  	return r.goLookupCNAME(ctx, name, order, conf)
 104  }
 105  
 106  func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name []byte) ([]byte, []*SRV, error) {
 107  	return r.goLookupSRV(ctx, service, proto, name)
 108  }
 109  
 110  func (r *Resolver) lookupMX(ctx context.Context, name []byte) ([]*MX, error) {
 111  	return r.goLookupMX(ctx, name)
 112  }
 113  
 114  func (r *Resolver) lookupNS(ctx context.Context, name []byte) ([]*NS, error) {
 115  	return r.goLookupNS(ctx, name)
 116  }
 117  
 118  func (r *Resolver) lookupTXT(ctx context.Context, name []byte) ([][]byte, error) {
 119  	return r.goLookupTXT(ctx, name)
 120  }
 121  
 122  func (r *Resolver) lookupAddr(ctx context.Context, addr []byte) ([][]byte, error) {
 123  	order, conf := systemConf().addrLookupOrder(r, addr)
 124  	if order == hostLookupCgo {
 125  		return cgoLookupPTR(ctx, addr)
 126  	}
 127  	return r.goLookupPTR(ctx, addr, order, conf)
 128  }
 129