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}