From 1107da7247db32199fde92f42c916bcb4c60dc3f Mon Sep 17 00:00:00 2001 From: Simon Bos Date: Mon, 8 Aug 2022 18:48:36 +0200 Subject: [PATCH] dlna: specify SSDP interface names from command line --- cmd/serve/dlna/dlna.go | 26 ++++++++++++++++++++++---- cmd/serve/dlna/dlna_test.go | 4 +++- cmd/serve/dlna/dlna_util.go | 6 +++++- cmd/serve/dlna/dlnaflags/dlnaflags.go | 15 +++++++++------ 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/cmd/serve/dlna/dlna.go b/cmd/serve/dlna/dlna.go index fc802226c..da6a08a19 100644 --- a/cmd/serve/dlna/dlna.go +++ b/cmd/serve/dlna/dlna.go @@ -51,7 +51,10 @@ files that they are not able to play back correctly. f := cmd.NewFsSrc(args) cmd.Run(false, false, command, func() error { - s := newServer(f, &dlnaflags.Opt) + s, err := newServer(f, &dlnaflags.Opt) + if err != nil { + return err + } if err := s.Serve(); err != nil { return err } @@ -92,17 +95,32 @@ type server struct { vfs *vfs.VFS } -func newServer(f fs.Fs, opt *dlnaflags.Options) *server { +func newServer(f fs.Fs, opt *dlnaflags.Options) (*server, error) { friendlyName := opt.FriendlyName if friendlyName == "" { friendlyName = makeDefaultFriendlyName() } + interfaces := make([]net.Interface, 0, len(opt.InterfaceNames)) + for _, interfaceName := range opt.InterfaceNames { + var err error + intf, err := net.InterfaceByName(interfaceName) + if err != nil { + return nil, fmt.Errorf("failed to resolve interface name '%s': %w", interfaceName, err) + } + if !isAppropriatelyConfigured(*intf) { + return nil, fmt.Errorf("interface '%s' is not appropriately configured (it should be UP, MULTICAST and MTU > 0)", interfaceName) + } + interfaces = append(interfaces, *intf) + } + if len(interfaces) == 0 { + interfaces = listInterfaces() + } s := &server{ AnnounceInterval: 10 * time.Second, FriendlyName: friendlyName, RootDeviceUUID: makeDeviceUUID(friendlyName), - Interfaces: listInterfaces(), + Interfaces: interfaces, httpListenAddr: opt.ListenAddr, @@ -138,7 +156,7 @@ func newServer(f fs.Fs, opt *dlnaflags.Options) *server { http.FileServer(data.Assets)))) s.handler = logging(withHeader("Server", serverField, r)) - return s + return s, nil } // UPnPService is the interface for the SOAP service. diff --git a/cmd/serve/dlna/dlna_test.go b/cmd/serve/dlna/dlna_test.go index 8327ee054..3a3d2fa4b 100644 --- a/cmd/serve/dlna/dlna_test.go +++ b/cmd/serve/dlna/dlna_test.go @@ -35,7 +35,9 @@ const ( func startServer(t *testing.T, f fs.Fs) { opt := dlnaflags.DefaultOpt opt.ListenAddr = testBindAddress - dlnaServer = newServer(f, &opt) + var err error + dlnaServer, err = newServer(f, &opt) + assert.NoError(t, err) assert.NoError(t, dlnaServer.Serve()) baseURL = "http://" + dlnaServer.HTTPConn.Addr().String() } diff --git a/cmd/serve/dlna/dlna_util.go b/cmd/serve/dlna/dlna_util.go index ad961e067..d54dfea5b 100644 --- a/cmd/serve/dlna/dlna_util.go +++ b/cmd/serve/dlna/dlna_util.go @@ -47,13 +47,17 @@ func listInterfaces() []net.Interface { var active []net.Interface for _, intf := range ifs { - if intf.Flags&net.FlagUp != 0 && intf.Flags&net.FlagMulticast != 0 && intf.MTU > 0 { + if isAppropriatelyConfigured(intf) { active = append(active, intf) } } return active } +func isAppropriatelyConfigured(intf net.Interface) bool { + return intf.Flags&net.FlagUp != 0 && intf.Flags&net.FlagMulticast != 0 && intf.MTU > 0 +} + func didlLite(chardata string) string { return `