2
0

manager_openbsd.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package dns
  4. import (
  5. "bytes"
  6. "fmt"
  7. "os"
  8. "tailscale.com/control/controlknobs"
  9. "tailscale.com/health"
  10. "tailscale.com/types/logger"
  11. "tailscale.com/util/eventbus"
  12. "tailscale.com/util/syspolicy/policyclient"
  13. )
  14. type kv struct {
  15. k, v string
  16. }
  17. func (kv kv) String() string {
  18. return fmt.Sprintf("%s=%s", kv.k, kv.v)
  19. }
  20. // NewOSConfigurator created a new OS configurator.
  21. //
  22. // The health tracker may be nil; the knobs may be nil and are ignored on this platform.
  23. func NewOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, _ policyclient.Client, _ *controlknobs.Knobs, interfaceName string) (OSConfigurator, error) {
  24. return newOSConfigurator(logf, health, bus, interfaceName,
  25. newOSConfigEnv{
  26. rcIsResolvd: rcIsResolvd,
  27. fs: directFS{},
  28. })
  29. }
  30. // newOSConfigEnv are the funcs newOSConfigurator needs, pulled out for testing.
  31. type newOSConfigEnv struct {
  32. fs directFS
  33. rcIsResolvd func(resolvConfContents []byte) bool
  34. }
  35. func newOSConfigurator(logf logger.Logf, health *health.Tracker, bus *eventbus.Bus, interfaceName string, env newOSConfigEnv) (ret OSConfigurator, err error) {
  36. var debug []kv
  37. dbg := func(k, v string) {
  38. debug = append(debug, kv{k, v})
  39. }
  40. defer func() {
  41. if ret != nil {
  42. dbg("ret", fmt.Sprintf("%T", ret))
  43. }
  44. logf("dns: %v", debug)
  45. }()
  46. bs, err := env.fs.ReadFile(resolvConf)
  47. if os.IsNotExist(err) {
  48. dbg("rc", "missing")
  49. return newDirectManager(logf, health, bus), nil
  50. }
  51. if err != nil {
  52. return nil, fmt.Errorf("reading /etc/resolv.conf: %w", err)
  53. }
  54. if env.rcIsResolvd(bs) {
  55. dbg("resolvd", "yes")
  56. return newResolvdManager(logf, interfaceName)
  57. }
  58. dbg("resolvd", "missing")
  59. return newDirectManager(logf, health, bus), nil
  60. }
  61. func rcIsResolvd(resolvConfContents []byte) bool {
  62. // If we have the string "# resolvd:" in resolv.conf resolvd(8) is
  63. // managing things.
  64. if bytes.Contains(resolvConfContents, []byte("# resolvd:")) {
  65. return true
  66. }
  67. return false
  68. }