File: mdns_provider.go

package info (click to toggle)
golang-github-hashicorp-go-discover 0.0%2Bgit20190905.34a6505-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 480 kB
  • sloc: makefile: 9
file content (119 lines) | stat: -rw-r--r-- 2,944 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Package mdns provides node discovery via mDNS.
package mdns

import (
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"strconv"
	"time"

	m "github.com/hashicorp/mdns"
)

// Provider implements the Provider interface.
type Provider struct{}

// Help returns help information for the mDNS package.
func (p *Provider) Help() string {
	return `mDNS:

    provider:          "mdns"
    service:           The mDNS service name.
    domain:            The mDNS discovery domain.  Default "local".
    timeout:           The mDNS lookup timeout.  Default "5s" (five seconds).
    v6:                IPv6 will be allowed and preferred when set to "true"
                       and disabled when set to "false".  Default "true".
    v4:                IPv4 will be allowed when set to "true" and disabled
                       when set to "false".  Default "true".
`
}

// Addrs returns discovered addresses for the mDNS package.
func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error) {
	var params *m.QueryParam
	var ch chan *m.ServiceEntry
	var v6, v4 bool
	var addrs []string
	var err error

	// default to null logger
	if l == nil {
		l = log.New(ioutil.Discard, "", 0)
	}

	// init params
	params = new(m.QueryParam)

	// validate and set service record
	if args["service"] == "" {
		return nil, fmt.Errorf("discover-mdns: Service record not provided." +
			"  Please specify a service record for the mDNS lookup.")
	}
	params.Service = args["service"]

	// validate and set domain
	if args["domain"] != "" {
		params.Domain = args["domain"]
	} else {
		params.Domain = "local"
	}

	// validate and set timeout
	if args["timeout"] != "" {
		if params.Timeout, err = time.ParseDuration(args["timeout"]); err != nil {
			return nil, fmt.Errorf("discover-mdns: Failed to parse timeout: %s", err)
		}
	} else {
		params.Timeout = 5 * time.Second
	}

	// validate and set v6 toggle
	if args["v6"] != "" {
		if v6, err = strconv.ParseBool(args["v6"]); err != nil {
			return nil, fmt.Errorf("discover-mdns: Failed to parse v6: %s", err)
		}
	} else {
		v6 = true
	}

	// validate and set v4 toggle
	if args["v4"] != "" {
		if v4, err = strconv.ParseBool(args["v4"]); err != nil {
			return nil, fmt.Errorf("discover-mdns: Failed to parse v4: %s", err)
		}
	} else {
		v4 = true
	}

	// init entries channel
	ch = make(chan *m.ServiceEntry)
	defer close(ch)
	params.Entries = ch

	// build addresses
	go func() {
		var addr string
		for e := range ch {
			addr = "" // reset addr each loop
			if v6 && e.AddrV6 != nil {
				addr = net.JoinHostPort(e.AddrV6.String(),
					strconv.Itoa(e.Port))
			}
			if addr == "" && v4 && e.AddrV4 != nil {
				addr = net.JoinHostPort(e.AddrV4.String(),
					strconv.Itoa(e.Port))
			}
			if addr != "" {
				l.Printf("[DEBUG] discover-mdns: %s -> %s",
					e.Host, addr)
				// build address list
				addrs = append(addrs, addr)
			}
		}
	}()

	// lookup and return
	return addrs, m.Query(params)
}