2020-08-17 22:44:45 +01:00
|
|
|
// Package mdns is an mdns router
|
|
|
|
package mdns
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
|
2020-08-19 17:47:17 +03:00
|
|
|
"github.com/unistack-org/micro/v3/router"
|
|
|
|
"github.com/unistack-org/micro/v3/util/mdns"
|
2020-08-17 22:44:45 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// NewRouter returns an initialized dns router
|
|
|
|
func NewRouter(opts ...router.Option) router.Router {
|
|
|
|
options := router.DefaultOptions()
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&options)
|
|
|
|
}
|
|
|
|
if len(options.Network) == 0 {
|
|
|
|
options.Network = "micro"
|
|
|
|
}
|
|
|
|
return &mdnsRouter{options}
|
|
|
|
}
|
|
|
|
|
|
|
|
type mdnsRouter struct {
|
|
|
|
options router.Options
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mdnsRouter) Init(opts ...router.Option) error {
|
|
|
|
for _, o := range opts {
|
|
|
|
o(&m.options)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mdnsRouter) Options() router.Options {
|
|
|
|
return m.options
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mdnsRouter) Table() router.Table {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mdnsRouter) Lookup(opts ...router.QueryOption) ([]router.Route, error) {
|
|
|
|
options := router.NewQuery(opts...)
|
|
|
|
|
|
|
|
// check to see if we have the port provided in the service, e.g. go-micro-srv-foo:8000
|
|
|
|
service, port, err := net.SplitHostPort(options.Service)
|
|
|
|
if err != nil {
|
|
|
|
service = options.Service
|
|
|
|
}
|
|
|
|
|
|
|
|
// query for the host
|
|
|
|
entries := make(chan *mdns.ServiceEntry)
|
|
|
|
|
|
|
|
p := mdns.DefaultParams(service)
|
|
|
|
p.Timeout = time.Millisecond * 100
|
|
|
|
p.Entries = entries
|
|
|
|
|
|
|
|
// check if we're using our own network
|
|
|
|
if len(options.Network) > 0 {
|
|
|
|
p.Domain = options.Network
|
|
|
|
}
|
|
|
|
|
|
|
|
// do the query
|
|
|
|
if err := mdns.Query(p); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var routes []router.Route
|
|
|
|
|
|
|
|
// compose the routes based on the entries
|
|
|
|
for e := range entries {
|
|
|
|
addr := e.Host
|
|
|
|
// prefer ipv4 addrs
|
|
|
|
if len(e.AddrV4) > 0 {
|
|
|
|
addr = e.AddrV4.String()
|
|
|
|
// else use ipv6
|
|
|
|
} else if len(e.AddrV6) > 0 {
|
|
|
|
addr = "[" + e.AddrV6.String() + "]"
|
|
|
|
} else if len(addr) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
pt := 443
|
|
|
|
|
|
|
|
if e.Port > 0 {
|
|
|
|
pt = e.Port
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the port
|
|
|
|
if len(port) > 0 {
|
|
|
|
pt, _ = strconv.Atoi(port)
|
|
|
|
}
|
|
|
|
|
|
|
|
routes = append(routes, router.Route{
|
|
|
|
Service: service,
|
|
|
|
Address: fmt.Sprintf("%s:%d", addr, pt),
|
|
|
|
Network: p.Domain,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return routes, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mdnsRouter) Watch(opts ...router.WatchOption) (router.Watcher, error) {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mdnsRouter) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *mdnsRouter) String() string {
|
|
|
|
return "mdns"
|
|
|
|
}
|