brutella / dnssd

This library implements Multicast DNS (mDNS) and DNS-Based Service Discovery (DNS-SD) for Zero Configuration Networking in Go.
MIT License
207 stars 33 forks source link

Publish service on provided interfaces only #33

Closed mmadraimov92 closed 1 year ago

mmadraimov92 commented 2 years ago

Hello,

First of all thank you for the library.

I had couple of issues: How can I publish service on selected interface only? Providing config.Ifaces seems not working.

Here is the testing code:

package main

import (
    "context"
    "fmt"
    "os"
    "os/signal"
    "time"

    slog "log"

    "github.com/brutella/dnssd"
)

func main() {
    // log.Debug.Enable()
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    go startDNSSDServer(ctx)

    time.Sleep(time.Second)
    go queryDNSSD(ctx)

    go func() {
        stop := make(chan os.Signal, 1)
        signal.Notify(stop, os.Interrupt)

        select {
        case <-stop:
            cancel()
        }
    }()

    <-ctx.Done()
}

func queryDNSSD(ctx context.Context) {
    service := "_service_type._tcp.local."

    slog.Printf("Lookup %s\n", service)

    addFn := func(e dnssd.BrowseEntry) {
        slog.Printf(
            "%s can be reached at %s %v\n",
            e.ServiceInstanceName(),
            e.IPs,
            e.Text)
    }

    if err := dnssd.LookupType(ctx, service, addFn, func(dnssd.BrowseEntry) {}); err != nil {
        fmt.Println(err)
        return
    }
}

func startDNSSDServer(ctx context.Context) {
    txtRecord := map[string]string{
        "txtvers": "1",
        "data":    "some-data",
    }
    config := dnssd.Config{
        Name:   "my_service",
        Type:   "_service_type._tcp",
        Domain: "local",
        Port:   1337,
        Text:   txtRecord,
        Ifaces: []string{"en0"},
        // IPs: []net.IP{net.ParseIP("192.168.228.92")},
    }

    service, err := dnssd.NewService(config)
    if err != nil {
        slog.Fatal(err)
    }

    responder, err := dnssd.NewResponder()
    if err != nil {
        slog.Fatal(err)
    }

    _, err = responder.Add(service)
    if err != nil {
        slog.Fatal(err)
    }

    slog.Println("Starting dnssd server")
    err = responder.Respond(ctx)
    if err != nil {
        slog.Fatal(err)
    }
}

This outputs:

$ go run main.go
2022/04/01 12:21:33 Starting dnssd server
2022/04/01 12:21:34 Lookup _service_type._tcp.local.
2022/04/01 12:21:34 my_service._service_type._tcp.local. can be reached at [127.0.0.1 ::1 fe80::1] map[data:some-data txtvers:1]
2022/04/01 12:21:34 my_service._service_type._tcp.local. can be reached at [192.168.228.92 fe80::107e:be39:9b23:64e5] map[data:some-data txtvers:1]
2022/04/01 12:21:34 my_service._service_type._tcp.local. can be reached at [fe80::f483:f4ff:fe0f:6312] map[data:some-data txtvers:1]
2022/04/01 12:21:34 my_service._service_type._tcp.local. can be reached at [fe80::278d:3c6:4662:f2b2] map[data:some-data txtvers:1]
2022/04/01 12:21:34 my_service._service_type._tcp.local. can be reached at [fe80::503:1e69:3b2e:b7a4] map[data:some-data txtvers:1]

As you can see from output, it includes multiple interfaces.

Second issue I had is related to TXT records. In the same file if you remove time.Sleep() before querying data, the results do not include TXT record. Might be related to #16.

Output:

$ go run main.go
2022/04/01 12:29:14 Lookup _service_type._tcp.local.
2022/04/01 12:29:14 Starting dnssd server
2022/04/01 12:29:14 my_service._service_type._tcp.local. can be reached at [192.168.228.92 fe80::107e:be39:9b23:64e5] map[]
2022/04/01 12:29:14 my_service._service_type._tcp.local. can be reached at [127.0.0.1 ::1 fe80::1] map[data:some-data txtvers:1]
2022/04/01 12:29:15 my_service._service_type._tcp.local. can be reached at [fe80::f483:f4ff:fe0f:6312] map[data:some-data txtvers:1]
2022/04/01 12:29:15 my_service._service_type._tcp.local. can be reached at [fe80::278d:3c6:4662:f2b2] map[data:some-data txtvers:1]
2022/04/01 12:29:15 my_service._service_type._tcp.local. can be reached at [fe80::503:1e69:3b2e:b7a4] map[data:some-data txtvers:1]
stefanopulze commented 1 year ago

I have found the problem and try correct it in my fork: https://github.com/stefanopulze/dnssd. Can you test if it's works and then I will create a merge request

brutella commented 1 year ago

Thanks for your additions. I've further worked on your changes and made them available at branch ifaces.

This should now completely solve the issues when defining a service for specific interfaces.

brutella commented 1 year ago

This should be fixed by now.