diff --git a/server.go b/server.go index 70fd11ac..ccb7dd74 100644 --- a/server.go +++ b/server.go @@ -21,13 +21,11 @@ const ( multicastRepetitions = 2 ) -// Register a service by given arguments. This call will take the system's hostname -// and lookup IP by that hostname. -func Register(instance, service, domain string, port int, text []string, ifaces []net.Interface) (*Server, error) { - entry := NewServiceEntry(instance, service, domain) - entry.Port = port - entry.Text = text - +// RegisterServiceEntry registers a service entry. +// If no HostName is set, the system's hostname will be set and used. +// If ifaces is empty, it will use all the available interfaces. +// If neither AddrIPv4 nor AddrIPv6 is set, it will set and use all available IPs. +func RegisterServiceEntry(entry *ServiceEntry, ifaces []net.Interface) (*Server, error) { if entry.Instance == "" { return nil, fmt.Errorf("missing service instance name") } @@ -49,18 +47,20 @@ func Register(instance, service, domain string, port int, text []string, ifaces } } - if !strings.HasSuffix(trimDot(entry.HostName), entry.Domain) { - entry.HostName = fmt.Sprintf("%s.%s.", trimDot(entry.HostName), trimDot(entry.Domain)) + if !strings.HasSuffix(trimDot(entry.HostName), trimDot(entry.Domain)) { + entry.HostName = trimDot(entry.HostName) + "." + trimDot(entry.Domain) + "." } if len(ifaces) == 0 { ifaces = listMulticastInterfaces() } - for _, iface := range ifaces { - v4, v6 := addrsForInterface(&iface) - entry.AddrIPv4 = append(entry.AddrIPv4, v4...) - entry.AddrIPv6 = append(entry.AddrIPv6, v6...) + if entry.AddrIPv4 == nil && entry.AddrIPv6 == nil { + for _, iface := range ifaces { + v4, v6 := addrsForInterface(&iface) + entry.AddrIPv4 = append(entry.AddrIPv4, v4...) + entry.AddrIPv6 = append(entry.AddrIPv6, v6...) + } } if entry.AddrIPv4 == nil && entry.AddrIPv6 == nil { @@ -79,6 +79,16 @@ func Register(instance, service, domain string, port int, text []string, ifaces return s, nil } +// Register a service by given arguments. This call will take the system's hostname +// and lookup IP by that hostname. +func Register(instance, service, domain string, port int, text []string, ifaces []net.Interface) (*Server, error) { + entry := NewServiceEntry(instance, service, domain) + entry.Port = port + entry.Text = text + + return RegisterServiceEntry(entry, ifaces) +} + // RegisterProxy registers a service proxy. This call will skip the hostname/IP lookup and // will use the provided values. func RegisterProxy(instance, service, domain string, port int, host string, ips []string, text []string, ifaces []net.Interface) (*Server, error) { @@ -87,25 +97,9 @@ func RegisterProxy(instance, service, domain string, port int, host string, ips entry.Text = text entry.HostName = host - if entry.Instance == "" { - return nil, fmt.Errorf("missing service instance name") - } - if entry.Service == "" { - return nil, fmt.Errorf("missing service name") - } if entry.HostName == "" { return nil, fmt.Errorf("missing host name") } - if entry.Domain == "" { - entry.Domain = "local" - } - if entry.Port == 0 { - return nil, fmt.Errorf("missing port") - } - - if !strings.HasSuffix(trimDot(entry.HostName), entry.Domain) { - entry.HostName = fmt.Sprintf("%s.%s.", trimDot(entry.HostName), trimDot(entry.Domain)) - } for _, ip := range ips { ipAddr := net.ParseIP(ip) @@ -120,20 +114,7 @@ func RegisterProxy(instance, service, domain string, port int, host string, ips } } - if len(ifaces) == 0 { - ifaces = listMulticastInterfaces() - } - - s, err := newServer(ifaces) - if err != nil { - return nil, err - } - - s.service = entry - go s.mainloop() - go s.probe() - - return s, nil + return RegisterServiceEntry(entry, ifaces) } const ( diff --git a/server_test.go b/server_test.go new file mode 100644 index 00000000..6020030b --- /dev/null +++ b/server_test.go @@ -0,0 +1,77 @@ +package zeroconf + +import ( + "os" + "strings" + "testing" +) + +func TestRegister(t *testing.T) { + expected := ServiceEntry{ + ServiceRecord: ServiceRecord{ + Instance: "instance", + Service: "service", + Domain: "domain", + }, + Port: 1337, + Text: []string{"txtv=0", "lo=1", "la=2"}, + } + server, err := Register(expected.Instance, expected.Service, expected.Domain, expected.Port, expected.Text, nil) + if err != nil { + t.Fatal(err) + } + server.Shutdown() + + hostname, err := os.Hostname() + if err != nil { + t.Fatal(err) + } + expected.HostName = hostname + ".domain." + + checkServiceEntry(t, *server.service, expected) +} + +func TestRegisterProxy(t *testing.T) { + expected := ServiceEntry{ + ServiceRecord: ServiceRecord{ + Instance: "instance", + Service: "service", + Domain: "domain", + }, + Port: 1337, + HostName: "proxy.domain.", + Text: []string{"txtv=0", "lo=1", "la=2"}, + } + server, err := RegisterProxy(expected.Instance, expected.Service, expected.Domain, expected.Port, expected.HostName, nil, expected.Text, nil) + if err != nil { + t.Fatal(err) + } + server.Shutdown() + + checkServiceEntry(t, *server.service, expected) +} + +func checkServiceEntry(t *testing.T, got, expected ServiceEntry) { + t.Helper() + if got.Instance != expected.Instance { + t.Fatalf("Expected Instance is %s, but got %s", expected.Instance, got.Instance) + } + if got.Service != expected.Service { + t.Fatalf("Expected Service is %s, but got %s", expected.Service, got.Service) + } + if got.Domain != expected.Domain { + t.Fatalf("Expected Domain is %s, but got %s", expected.Domain, got.Domain) + } + if got.Port != expected.Port { + t.Fatalf("Expected Port is %d, but got %d", expected.Port, got.Port) + } + if strings.Join(got.Text, " ") != strings.Join(expected.Text, " ") { + t.Fatalf("Expected Text is %s, but got %s", expected.Text, got.Text) + } + if got.HostName != expected.HostName { + t.Fatalf("Expected HostName is %s, but got %s", expected.HostName, got.HostName) + } + if len(got.AddrIPv4) == 0 && len(got.AddrIPv6) == 0 { + t.Fatal("Unexpected empty IPV4 and IPV6") + } +} diff --git a/service_test.go b/service_test.go index 2c5a23ed..0107d092 100644 --- a/service_test.go +++ b/service_test.go @@ -74,7 +74,7 @@ func TestNoRegister(t *testing.T) { t.Fatalf("Expected create resolver success, but got %v", err) } - // before register, mdns resolve shuold not have any entry + // before register, mdns resolve should not have any entry entries := make(chan *ServiceEntry) go func(results <-chan *ServiceEntry) { s := <-results