async_dnssd/lib.rs
1#![doc(html_root_url = "https://docs.rs/async-dnssd/0.5.1")]
2#![warn(missing_docs)]
3#![warn(unused_extern_crates, unused_qualifications)]
4//! # Asynchronous wrapper for DNS-SD C libraries
5//!
6//! Interesting entry points:
7//!
8//! * [Browse for available services][`browse`]
9//! * [Create Connection to register records with][`connect`]
10//! * [Enumerate domains that are recommended for registration or browsing][`enumerate_domains`]
11//! * [Query for an arbitrary DNS record][`query_record`]
12//! * [Register a service][`register`]
13//! * [Add a record to a registered service][`RegistrationHandle::add_record`]
14//! * [Register record][`Connection::register_record`]
15//! * [Find hostname and port (and more) for a service][`resolve`]
16//!
17//! Also the following things might be interesting:
18//!
19//! * [Purge record from cache][`reconfirm_record`]
20//! * [Construct full name][`FullName::construct`]
21//! * [Stream timeouts][`TimeoutStream`]
22//!
23//! ## Porting from dnssd C API
24//!
25//! | C API | functionality in this crate |
26//! |---------------------------------|--------------------------------------------------------------|
27//! | [`DNSServiceAddRecord`] | [`RegistrationHandle::add_record`] |
28//! | [`DNSServiceBrowse`] | [`browse`] |
29//! | [`DNSServiceConstructFullName`] | [`FullName::construct`] |
30//! | [`DNSServiceCreateConnection`] | [`connect`] |
31//! | [`DNSServiceEnumerateDomains`] | [`enumerate_domains`] |
32//! | [`DNSServiceQueryRecord`] | [`query_record`] |
33//! | [`DNSServiceReconfirmRecord`] | [`reconfirm_record`] |
34//! | [`DNSServiceRegister`] | [`register`] |
35//! | [`DNSServiceRegisterRecord`] | [`Connection::register_record`] |
36//! | [`DNSServiceResolve`] | [`resolve`] |
37//! | [`DNSServiceUpdateRecord`] | [`Record::update_record`], [`RegisterRecord::update_record`] |
38//!
39//! The following functions are called automatically when needed:
40//! * [`DNSServiceProcessResult`] driving callbacks (event loop)
41//! * [`DNSServiceRefDeallocate`] called when dropping various resource handles
42//! * [`DNSServiceRefSockFD`] used for integration with tokio (event loop)
43//! * [`DNSServiceRemoveRecord`] called when dropping [`Record`]
44//!
45//! The `TXTRecord*` "TXT Record Construction Functions" are not
46//! wrapped; [`TxtRecord`] provides a native rust implementation with
47//! similar functionality.
48//!
49//! [`DNSServiceAddRecord`]: https://developer.apple.com/documentation/dnssd/1804730-dnsserviceaddrecord
50//! [`DNSServiceBrowse`]: https://developer.apple.com/documentation/dnssd/1804742-dnsservicebrowse
51//! [`DNSServiceConstructFullName`]: https://developer.apple.com/documentation/dnssd/1804753-dnsserviceconstructfullname
52//! [`DNSServiceCreateConnection`]: https://developer.apple.com/documentation/dnssd/1804724-dnsservicecreateconnection
53//! [`DNSServiceEnumerateDomains`]: https://developer.apple.com/documentation/dnssd/1804754-dnsserviceenumeratedomains
54//! [`DNSServiceQueryRecord`]: https://developer.apple.com/documentation/dnssd/1804747-dnsservicequeryrecord
55//! [`DNSServiceReconfirmRecord`]: https://developer.apple.com/documentation/dnssd/1804726-dnsservicereconfirmrecord
56//! [`DNSServiceRegister`]: https://developer.apple.com/documentation/dnssd/1804733-dnsserviceregister
57//! [`DNSServiceRegisterRecord`]: https://developer.apple.com/documentation/dnssd/1804727-dnsserviceregisterrecord
58//! [`DNSServiceResolve`]: https://developer.apple.com/documentation/dnssd/1804744-dnsserviceresolve
59//! [`DNSServiceUpdateRecord`]: https://developer.apple.com/documentation/dnssd/1804739-dnsserviceupdaterecord
60//! [`DNSServiceProcessResult`]: https://developer.apple.com/documentation/dnssd/1804696-dnsserviceprocessresult
61//! [`DNSServiceRefDeallocate`]: https://developer.apple.com/documentation/dnssd/1804697-dnsservicerefdeallocate
62//! [`DNSServiceRefSockFD`]: https://developer.apple.com/documentation/dnssd/1804698-dnsservicerefsockfd
63//! [`DNSServiceRemoveRecord`]: https://developer.apple.com/documentation/dnssd/1804736-dnsserviceremoverecord
64
65pub use self::{
66 dns_consts::{
67 Class,
68 Type,
69 },
70 error::Error,
71 ffi::MAX_DOMAIN_NAME,
72 interface::{
73 Interface,
74 InterfaceIndex,
75 },
76 service::*,
77 timeout_stream::{
78 StreamTimeoutExt,
79 TimeoutStream,
80 },
81 txt_record::{
82 TxtRecord,
83 TxtRecordError,
84 TxtRecordIter,
85 },
86};
87
88mod cstr;
89mod dns_consts;
90mod error;
91mod evented;
92mod ffi;
93mod fused_err_stream;
94mod future;
95mod inner;
96mod interface;
97mod non_exhaustive_struct;
98mod notify;
99mod service;
100mod stream;
101mod timeout_stream;
102mod txt_record;
103
104#[allow(dead_code)]
105#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))]
106// SAFETY: Only call in single-threaded process.
107unsafe fn set_avahi_compat_nowarn() {
108 use std::sync::Once;
109
110 static INIT: Once = Once::new();
111 INIT.call_once(|| {
112 const AVAHI_COMPAT_NOWARN: &str = "AVAHI_COMPAT_NOWARN";
113 if std::env::var_os(AVAHI_COMPAT_NOWARN).is_none() {
114 unsafe { std::env::set_var(AVAHI_COMPAT_NOWARN, "1") };
115 }
116 });
117}
118
119#[cfg(all(
120 unix,
121 not(any(target_os = "macos", target_os = "ios")),
122 target_env = "gnu"
123))]
124fn init_avahi_gnu() {
125 // https://sourceware.org/glibc/manual/2.42/html_node/Single_002dThreaded.html
126 unsafe extern "C" {
127 static __libc_single_threaded: libc::c_char;
128 }
129
130 if unsafe { __libc_single_threaded } != 0 {
131 unsafe {
132 set_avahi_compat_nowarn();
133 }
134 }
135}
136
137fn init() {
138 #[cfg(all(
139 unix,
140 not(any(target_os = "macos", target_os = "ios")),
141 target_env = "gnu"
142 ))]
143 {
144 init_avahi_gnu();
145 }
146}