micro-router-mdns/mdns.go
Vasiliy Tolstov d0e3d2fde0 initial import from go-micro
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2020-08-28 12:22:01 +03:00

118 lines
2.2 KiB
Go

// Package mdns is an mdns router
package mdns
import (
"fmt"
"net"
"strconv"
"time"
"github.com/unistack-org/micro/v3/router"
"github.com/unistack-org/micro/v3/util/mdns"
)
// 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"
}