Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add RegisterServiceEntry function #107

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 24 additions & 43 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand All @@ -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 {
Expand All @@ -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) {
Expand All @@ -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)
Expand All @@ -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 (
Expand Down
77 changes: 77 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
@@ -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")
}
}
2 changes: 1 addition & 1 deletion service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down