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

Discovery: Refactor and add Avahi DBus backend #1347

Merged
merged 17 commits into from
Oct 26, 2024

Conversation

wisp3rwind
Copy link
Contributor

So... I was mildly annoyed by the

*** WARNING *** The program 'librespot' uses the Apple Bonjour compatibility layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see <http://0pointer.de/blog/projects/avahi-compat.html>

warnings from the dns_sd compat library and thought it would be a fun little project to write an additional MDNS/DNS-SD backend that directly talks to Avahi via DBus.

This PR is a minimal working example of that. I made quite some refactorings to the discovery module in order to keep the code readable and not litter it too much with #[cfg(feature = "with-xyz")] guards. This should be fairly easy to review by looking at the individual commits and their messages.

I have a local branch with some more error handling in the avahi_task, but I'd be happy about your opinion on this before making things more complicated (I'd also need to clean that up a bit).

Does this have a place in librespot upstream? If so, I'd add some more documentation around the new feature flags and commandline flag.

@wisp3rwind
Copy link
Contributor Author

wisp3rwind commented Sep 24, 2024

Tests seem to pass now (I've had to bump MSRV and improve handling of the feature flags). The one remaining test failure seems to be spurious: It's a timeout when testing Session.connect, which shouldn't be affected by anything in this PR as far as I can tell.

EDIT: Re-based and cleaned up commit history.

@meiser79
Copy link

meiser79 commented Oct 5, 2024

Hi,
just tried to compile it with cargo build --release --no-default-features --features "pulseaudio-backend", but I get the following compile errors:

   Compiling librespot-discovery v0.5.0-dev (/tmp/librespot/discovery)
error[E0432]: unresolved import `self::avahi`
  --> discovery/src/lib.rs:26:5
   |
26 |     avahi::EntryGroupState,
   |     ^^^^^ could not find `avahi` in the crate root

error[E0433]: failed to resolve: use of undeclared crate or module `zbus`
   --> discovery/src/lib.rs:152:11
    |
152 | impl From<zbus::Error> for DiscoveryError {
    |           ^^^^ use of undeclared crate or module `zbus`

error[E0433]: failed to resolve: use of undeclared crate or module `zbus`
   --> discovery/src/lib.rs:153:20
    |
153 |     fn from(error: zbus::Error) -> Self {
    |                    ^^^^ use of undeclared crate or module `zbus`

Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.
error: could not compile `librespot-discovery` (lib) due to 3 previous errors

@yubiuser
Copy link
Contributor

yubiuser commented Oct 5, 2024

I've build this branch successfully using cargo build --release --no-default-features --features with-avahi. It was even possible to build a static binary (with RUSTFLAGS="-C target-feature=+crt-static").

When I don't specify any 'zeroconf' backend (e.g. cargo build --release --no-default-features) I get the same errors as @meiser79

@wisp3rwind
Copy link
Contributor Author

Sorry, I have fixed that locally already and forgot to push it. Will do so later today!

@wisp3rwind wisp3rwind force-pushed the avahi-dbus-v2 branch 3 times, most recently from 99e5ed4 to 33964da Compare October 6, 2024 09:47
@wisp3rwind
Copy link
Contributor Author

Build should be fixed now for any feature combination :)

@yubiuser
Copy link
Contributor

yubiuser commented Oct 6, 2024

Building with only --no-default-features works now, but it won't start successful.

[2024-10-06T11:17:43Z ERROR librespot] Invalid `--zeroconf-backend` / `-`: ""
Default: <none>

@wisp3rwind
Copy link
Contributor Author

Building with only --no-default-features works now, but it won't start successful.

[2024-10-06T11:17:43Z ERROR librespot] Invalid `--zeroconf-backend` / `-`: ""
Default: <none>

Oh, right: I didn't think about that case. Previously, there was no way to compile librespot without discovery/zeroconf support, but this is a possibility now. (And I guess it's sensible: If people want to build a minimal-size executable, and require only OAuth support, they could compile without zeroconf backend.)

Should be fixed now, with librespot exiting with an error message if the combination of compile-time features and CLI options leaves no way to authenticate.

@yubiuser
Copy link
Contributor

yubiuser commented Oct 6, 2024

Works now.

[2024-10-06T15:58:03Z INFO  librespot] librespot 0.5.0-dev d07063f (Built on 2024-10-06, Build ID: YkDAkydC, Profile: debug)
[2024-10-06T15:58:03Z ERROR librespot] Credentials are required if discovery and oauth login are disabled.

@wisp3rwind wisp3rwind marked this pull request as ready for review October 15, 2024 14:22
Copy link
Member

@roderickvd roderickvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is awesome! Please note that I'm the process of releasing 0.5.0 as we speak, so please move your changelog entries into a post-0.5.0 "Unreleased" section that should be there momentarily.

src/main.rs Outdated Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
discovery/src/server.rs Outdated Show resolved Hide resolved
discovery/src/avahi.rs Show resolved Hide resolved
discovery/src/avahi.rs Show resolved Hide resolved
Copy link
Contributor Author

@wisp3rwind wisp3rwind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review 👍 I left some comments inline, and will push an update in a minute.

discovery/src/avahi.rs Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
discovery/src/avahi.rs Show resolved Hide resolved
discovery/src/server.rs Outdated Show resolved Hide resolved
@roderickvd
Copy link
Member

If you could resolve that last comment, and resolve the conflicts, I'm all for merging this. 👍

@roderickvd
Copy link
Member

You think you could do something about #1379 here?

@wisp3rwind
Copy link
Contributor Author

If you could resolve that last comment, and resolve the conflicts, I'm all for merging this. 👍

Will do!

You think you could do something about #1379 here?

The new backend should not be affected by that issue, cf. my comment at #1379.

I think there's room to improve documentation around that issue, and maybe also to improve librespot defaults. However, I think that's out of scope here.

@roderickvd
Copy link
Member

Thanks for the update. I think there's something up with the changelog merge. Could you move your changes up to the "Unreleased" section? Also probably should mark the discovery changes as breaking if there were any API changes there that upstream devs should be aware of.

You think you could do something about #1379 here?

The new backend should not be affected by that issue, cf. my comment at #1379.

I think there's room to improve documentation around that issue, and maybe also to improve librespot defaults. However, I think that's out of scope here.

Props for the extensive reply there. All good to me. I thought maybe it was easy to slip that proposal in here, but totally fine to keep that for some other PR.

This helps to decouple discovery and core by not leaking implementation
details of the zeroconf backend into Error conversion impls in core.
previously, libmdns errors would use a generic conversion
from std::io::Error to core::Error
in preparation for adding another backend: The only purpose of this is
to unregister the service on drop. Thus, it is much easier to work with
an opaque type, which avoids proliferation #[cfg(...)] gates.
in preparation for re-working feature flags and adding another backend
i.e. add with-libmdns instead of using not(with-dns-sd). This is in
preparation for adding another backend, and in general recommended, cf.
https://doc.rust-lang.org/cargo/reference/features.html#mutually-exclusive-features

The logic is such that enabling with-dns-sd in addition to the default
with-libmdns will still end up using dns-sd, as before.
If only with-libmdns is enabled, that will be the default.
If none of the features is enabled, attempting to build a `Discovery`
will yield an error.
required by zbus >= 4
Previously, on drop the the shutdown_tx/close_tx, it wasn't guaranteed
the corresponding tasks would continue to be polled until they actually
completed their shutdown.

Since dns_sd::Service is not Send and non-async, and because libmdns is
non-async, put them on their own threads.
This deals gracefully with the case where the Avahi daemon is restarted
or not running initially.
...but exit with an error if there's no way to authenticate
@wisp3rwind
Copy link
Contributor Author

Thanks for the update. I think there's something up with the changelog merge. Could you move your changes up to the "Unreleased" section? Also probably should mark the discovery changes as breaking if there were any API changes there that upstream devs should be aware of.

Completely missed this when rebasing, thanks for the heads-up! Hopefully, this should be fixed now.

You think you could do something about #1379 here?

The new backend should not be affected by that issue, cf. my comment at #1379.
I think there's room to improve documentation around that issue, and maybe also to improve librespot defaults. However, I think that's out of scope here.

Props for the extensive reply there. All good to me. I thought maybe it was easy to slip that proposal in here, but totally fine to keep that for some other PR.

👍

@roderickvd roderickvd merged commit 94d174c into librespot-org:dev Oct 26, 2024
13 checks passed
@roderickvd
Copy link
Member

Merged, thanks a lot! May I ask you to also update the wiki with the new command line options?

With these breaking changes, we're going to up the version to 0.6.0. And hey, since faster releases are requested, would what we have now not be a nice scope?

@wisp3rwind
Copy link
Contributor Author

Merged, thanks a lot! May I ask you to also update the wiki with the new command line options?

Done!

@michaelherger
Copy link
Contributor

Is there a summary somewhere as to which library to use under which circumstances? What are the pros and cons of them? (I'm not familiar with mDNS here, but providing a librespot based binary to many platforms... Windows, Mac, Linux)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

librespot mdns reponder competes with avahi -> forces avahi to add '-2' to the hostname
5 participants