1use async_broadcast::{InactiveReceiver, Receiver, Sender as Broadcaster, broadcast};
3use enumflags2::BitFlags;
4use event_listener::{Event, EventListener};
5use std::{
6 collections::HashMap,
7 future::Future,
8 io,
9 sync::{
10 Arc, OnceLock, Weak,
11 atomic::{AtomicBool, Ordering},
12 },
13 time::Duration,
14};
15use tracing::{Instrument, debug, info_span, instrument, trace, trace_span, warn};
16use zbus_names::{BusName, ErrorName, InterfaceName, MemberName, OwnedUniqueName, WellKnownName};
17use zvariant::ObjectPath;
18
19use futures_lite::StreamExt;
20use ordered_stream::OrderedFuture;
21
22use crate::{
23 DBusError, Error, Executor, MatchRule, ObjectServer, OwnedGuid, OwnedMatchRule, Result, Task,
24 async_lock::{Mutex, Semaphore, SemaphorePermit},
25 fdo::{ConnectionCredentials, ReleaseNameReply, RequestNameFlags, RequestNameReply},
26 is_flatpak,
27 message::{Flags, Message, Type},
28 timeout::timeout,
29};
30
31mod builder;
32pub use builder::Builder;
33
34pub mod socket;
35pub use socket::Socket;
36
37mod socket_reader;
38use socket_reader::{SocketReader, SocketStatus};
39
40mod pending_method_calls;
41use pending_method_calls::PendingMethodCalls;
42
43pub(crate) mod handshake;
44pub use handshake::AuthMechanism;
45use handshake::Authenticated;
46
47const DEFAULT_MAX_QUEUED: usize = 64;
48
49#[derive(Debug)]
51pub(crate) struct ConnectionInner {
52 server_guid: OwnedGuid,
53 #[cfg(unix)]
54 cap_unix_fd: bool,
55 #[cfg(feature = "p2p")]
56 bus_conn: bool,
57 unique_name: OnceLock<OwnedUniqueName>,
58 registered_names: Mutex<HashMap<WellKnownName<'static>, NameStatus>>,
59
60 socket_status: Arc<SocketStatus>,
61 socket_write: Mutex<Box<dyn socket::WriteHalf>>,
62
63 executor: Executor<'static>,
65
66 #[allow(unused)]
68 socket_reader_task: OnceLock<Task<()>>,
69
70 pub(crate) msg_receiver: InactiveReceiver<Result<Message>>,
71 msg_senders: Arc<Mutex<HashMap<Option<OwnedMatchRule>, MsgBroadcaster>>>,
72 pending_method_calls: PendingMethodCalls,
73
74 subscriptions: Mutex<Subscriptions>,
75
76 object_server: OnceLock<ObjectServer>,
77 object_server_dispatch_task: OnceLock<Task<()>>,
78
79 drop_event: Event,
80
81 method_timeout: Option<Duration>,
82 credentials: OnceLock<Arc<ConnectionCredentials>>,
84}
85
86impl Drop for ConnectionInner {
87 fn drop(&mut self) {
88 self.drop_event.notify(usize::MAX);
92 }
93}
94
95type Subscriptions = HashMap<OwnedMatchRule, (u64, InactiveReceiver<Result<Message>>)>;
96
97pub(crate) type MsgBroadcaster = Broadcaster<Result<Message>>;
98
99#[derive(Clone, Debug)]
213#[must_use = "Dropping a `Connection` will close the underlying socket."]
214pub struct Connection {
215 pub(crate) inner: Arc<ConnectionInner>,
216}
217
218impl Connection {
219 pub async fn send(&self, msg: &Message) -> Result<()> {
221 #[cfg(unix)]
222 if !msg.data().fds().is_empty() && !self.inner.cap_unix_fd {
223 return Err(Error::Unsupported);
224 }
225
226 self.inner.socket_status.activity_event.notify(usize::MAX);
227 let mut write = self.inner.socket_write.lock().await;
228
229 write.send_message(msg).await
230 }
231
232 pub async fn call_method<'d, 'p, 'i, 'm, D, P, I, M, B>(
239 &self,
240 destination: Option<D>,
241 path: P,
242 interface: Option<I>,
243 method_name: M,
244 body: &B,
245 ) -> Result<Message>
246 where
247 D: TryInto<BusName<'d>>,
248 P: TryInto<ObjectPath<'p>>,
249 I: TryInto<InterfaceName<'i>>,
250 M: TryInto<MemberName<'m>>,
251 D::Error: Into<Error>,
252 P::Error: Into<Error>,
253 I::Error: Into<Error>,
254 M::Error: Into<Error>,
255 B: serde::ser::Serialize + zvariant::DynamicType,
256 {
257 let method = self
258 .call_method_raw(
259 destination,
260 path,
261 interface,
262 method_name,
263 BitFlags::empty(),
264 body,
265 )
266 .await?
267 .expect("no reply");
268
269 if let Some(tout) = self.method_timeout() {
270 timeout(method, tout).await
271 } else {
272 method.await
273 }
274 }
275
276 pub(crate) async fn call_method_raw<'d, 'p, 'i, 'm, D, P, I, M, B>(
287 &self,
288 destination: Option<D>,
289 path: P,
290 interface: Option<I>,
291 method_name: M,
292 flags: BitFlags<Flags>,
293 body: &B,
294 ) -> Result<
295 Option<
296 impl Future<Output = Result<Message>>
297 + OrderedFuture<Output = Result<Message>, Ordering = crate::message::Sequence>,
298 >,
299 >
300 where
301 D: TryInto<BusName<'d>>,
302 P: TryInto<ObjectPath<'p>>,
303 I: TryInto<InterfaceName<'i>>,
304 M: TryInto<MemberName<'m>>,
305 D::Error: Into<Error>,
306 P::Error: Into<Error>,
307 I::Error: Into<Error>,
308 M::Error: Into<Error>,
309 B: serde::ser::Serialize + zvariant::DynamicType,
310 {
311 let _permit = acquire_serial_num_semaphore().await;
312
313 let mut builder = Message::method_call(path, method_name)?;
314 if let Some(sender) = self.unique_name() {
315 builder = builder.sender(sender)?
316 }
317 if let Some(destination) = destination {
318 builder = builder.destination(destination)?
319 }
320 if let Some(interface) = interface {
321 builder = builder.interface(interface)?
322 }
323 for flag in flags {
324 builder = builder.with_flags(flag)?;
325 }
326 let msg = builder.build(body)?;
327
328 let serial = msg.primary_header().serial_num();
329 if flags.contains(Flags::NoReplyExpected) {
330 self.send(&msg).await?;
331
332 Ok(None)
333 } else {
334 let pending_call = self.inner.pending_method_calls.register_call(serial);
335 self.send(&msg).await?;
336
337 Ok(Some(pending_call))
338 }
339 }
340
341 pub async fn emit_signal<'d, 'p, 'i, 'm, D, P, I, M, B>(
345 &self,
346 destination: Option<D>,
347 path: P,
348 interface: I,
349 signal_name: M,
350 body: &B,
351 ) -> Result<()>
352 where
353 D: TryInto<BusName<'d>>,
354 P: TryInto<ObjectPath<'p>>,
355 I: TryInto<InterfaceName<'i>>,
356 M: TryInto<MemberName<'m>>,
357 D::Error: Into<Error>,
358 P::Error: Into<Error>,
359 I::Error: Into<Error>,
360 M::Error: Into<Error>,
361 B: serde::ser::Serialize + zvariant::DynamicType,
362 {
363 let _permit = acquire_serial_num_semaphore().await;
364
365 let mut b = Message::signal(path, interface, signal_name)?;
366 if let Some(sender) = self.unique_name() {
367 b = b.sender(sender)?;
368 }
369 if let Some(destination) = destination {
370 b = b.destination(destination)?;
371 }
372 let m = b.build(body)?;
373
374 self.send(&m).await
375 }
376
377 pub async fn reply<B>(&self, call: &zbus::message::Header<'_>, body: &B) -> Result<()>
382 where
383 B: serde::ser::Serialize + zvariant::DynamicType,
384 {
385 let _permit = acquire_serial_num_semaphore().await;
386
387 let mut b = Message::method_return(call)?;
388 if let Some(sender) = self.unique_name() {
389 b = b.sender(sender)?;
390 }
391 let m = b.build(body)?;
392 self.send(&m).await
393 }
394
395 pub async fn reply_error<'e, E, B>(
400 &self,
401 call: &zbus::message::Header<'_>,
402 error_name: E,
403 body: &B,
404 ) -> Result<()>
405 where
406 B: serde::ser::Serialize + zvariant::DynamicType,
407 E: TryInto<ErrorName<'e>>,
408 E::Error: Into<Error>,
409 {
410 let _permit = acquire_serial_num_semaphore().await;
411
412 let mut b = Message::error(call, error_name)?;
413 if let Some(sender) = self.unique_name() {
414 b = b.sender(sender)?;
415 }
416 let m = b.build(body)?;
417 self.send(&m).await
418 }
419
420 pub async fn reply_dbus_error(
425 &self,
426 call: &zbus::message::Header<'_>,
427 err: impl DBusError,
428 ) -> Result<()> {
429 let _permit = acquire_serial_num_semaphore().await;
430
431 let m = err.create_reply(call)?;
432 self.send(&m).await
433 }
434
435 pub async fn request_name<'w, W>(&self, well_known_name: W) -> Result<()>
465 where
466 W: TryInto<WellKnownName<'w>>,
467 W::Error: Into<Error>,
468 {
469 self.request_name_with_flags(well_known_name, BitFlags::default())
470 .await
471 .map(|_| ())
472 }
473
474 pub async fn request_name_with_flags<'w, W>(
548 &self,
549 well_known_name: W,
550 flags: BitFlags<RequestNameFlags>,
551 ) -> Result<RequestNameReply>
552 where
553 W: TryInto<WellKnownName<'w>>,
554 W::Error: Into<Error>,
555 {
556 let well_known_name = well_known_name.try_into().map_err(Into::into)?;
557
558 if self.is_bus() && self.inner.object_server.get().is_none() {
561 warn!(
562 "Requesting name `{well_known_name}` before setting up the object server. \
563 Method calls arriving before interfaces are registered may be lost. \
564 Consider using `connection::Builder::serve_at()` and `::name()` instead.",
565 );
566 }
567 let mut names = self.inner.registered_names.lock().await;
570
571 match names.get(&well_known_name) {
572 Some(NameStatus::Owner(_)) => return Ok(RequestNameReply::AlreadyOwner),
573 Some(NameStatus::Queued(_)) => return Ok(RequestNameReply::InQueue),
574 None => (),
575 }
576
577 if !self.is_bus() {
578 names.insert(well_known_name.to_owned(), NameStatus::Owner(None));
579
580 return Ok(RequestNameReply::PrimaryOwner);
581 }
582
583 let acquired_match_rule = MatchRule::fdo_signal_builder("NameAcquired")
584 .arg(0, well_known_name.as_ref())
585 .unwrap()
586 .build();
587 let mut acquired_stream = self.add_match(acquired_match_rule.into(), None).await?;
588 let lost_match_rule = MatchRule::fdo_signal_builder("NameLost")
589 .arg(0, well_known_name.as_ref())
590 .unwrap()
591 .build();
592 let mut lost_stream = self.add_match(lost_match_rule.into(), None).await?;
593 let reply = self
594 .call_method(
595 Some("org.freedesktop.DBus"),
596 "/org/freedesktop/DBus",
597 Some("org.freedesktop.DBus"),
598 "RequestName",
599 &(well_known_name.clone(), flags),
600 )
601 .await?
602 .body()
603 .deserialize::<RequestNameReply>()?;
604 let lost_task_name = format!("monitor_name_lost{{name={well_known_name}}}");
605 let lost_task_name_span = info_span!("monitor_name_lost", name = %well_known_name);
606 let name_lost_fut = if flags.contains(RequestNameFlags::AllowReplacement) {
607 let weak_conn = WeakConnection::from(self);
608 let well_known_name = well_known_name.to_owned();
609 Some(
610 async move {
611 loop {
612 let signal = lost_stream.next().await;
613 let inner = match weak_conn.upgrade() {
614 Some(conn) => conn.inner.clone(),
615 None => break,
616 };
617
618 match signal {
619 Some(signal) => match signal {
620 Ok(_) => {
621 tracing::info!(
622 "Connection `{}` lost name `{}`",
623 inner.unique_name.get().unwrap(),
626 well_known_name
627 );
628 inner.registered_names.lock().await.remove(&well_known_name);
629
630 break;
631 }
632 Err(e) => warn!("Failed to parse `NameLost` signal: {}", e),
633 },
634 None => {
635 trace!("`NameLost` signal stream closed");
636 break;
645 }
646 }
647 }
648 }
649 .instrument(lost_task_name_span),
650 )
651 } else {
652 None
653 };
654 let status = match reply {
655 RequestNameReply::InQueue => {
656 let weak_conn = WeakConnection::from(self);
657 let well_known_name = well_known_name.to_owned();
658 let task_name = format!("monitor_name_acquired{{name={well_known_name}}}");
659 let task_name_span = info_span!("monitor_name_acquired", name = %well_known_name);
660 let task = self.executor().spawn(
661 async move {
662 loop {
663 let signal = acquired_stream.next().await;
664 let inner = match weak_conn.upgrade() {
665 Some(conn) => conn.inner.clone(),
666 None => break,
667 };
668 match signal {
669 Some(signal) => match signal {
670 Ok(_) => {
671 let mut names = inner.registered_names.lock().await;
672 if let Some(status) = names.get_mut(&well_known_name) {
673 let task = name_lost_fut.map(|fut| {
674 inner.executor.spawn(fut, &lost_task_name)
675 });
676 *status = NameStatus::Owner(task);
677
678 break;
679 }
680 }
682 Err(e) => warn!("Failed to parse `NameAcquired` signal: {}", e),
683 },
684 None => {
685 trace!("`NameAcquired` signal stream closed");
686 break;
689 }
690 }
691 }
692 }
693 .instrument(task_name_span),
694 &task_name,
695 );
696
697 NameStatus::Queued(task)
698 }
699 RequestNameReply::PrimaryOwner | RequestNameReply::AlreadyOwner => {
700 let task = name_lost_fut.map(|fut| self.executor().spawn(fut, &lost_task_name));
701
702 NameStatus::Owner(task)
703 }
704 RequestNameReply::Exists => return Err(Error::NameTaken),
705 };
706
707 names.insert(well_known_name.to_owned(), status);
708
709 Ok(reply)
710 }
711
712 pub async fn release_name<'w, W>(&self, well_known_name: W) -> Result<bool>
721 where
722 W: TryInto<WellKnownName<'w>>,
723 W::Error: Into<Error>,
724 {
725 let well_known_name: WellKnownName<'w> = well_known_name.try_into().map_err(Into::into)?;
726 let mut names = self.inner.registered_names.lock().await;
727 if names.remove(&well_known_name.to_owned()).is_none() {
729 return Ok(false);
730 };
731
732 if !self.is_bus() {
733 return Ok(true);
734 }
735
736 self.call_method(
737 Some("org.freedesktop.DBus"),
738 "/org/freedesktop/DBus",
739 Some("org.freedesktop.DBus"),
740 "ReleaseName",
741 &well_known_name,
742 )
743 .await?
744 .body()
745 .deserialize::<ReleaseNameReply>()
746 .map(|r| r == ReleaseNameReply::Released)
747 }
748
749 pub fn is_bus(&self) -> bool {
754 #[cfg(feature = "p2p")]
755 {
756 self.inner.bus_conn
757 }
758 #[cfg(not(feature = "p2p"))]
759 {
760 true
761 }
762 }
763
764 pub fn unique_name(&self) -> Option<&OwnedUniqueName> {
769 self.inner.unique_name.get()
770 }
771
772 #[cfg(feature = "bus-impl")]
782 pub fn set_unique_name<U>(&self, unique_name: U) -> Result<()>
783 where
784 U: TryInto<OwnedUniqueName>,
785 U::Error: Into<Error>,
786 {
787 let name = unique_name.try_into().map_err(Into::into)?;
788 self.set_unique_name_(name);
789
790 Ok(())
791 }
792
793 pub fn max_queued(&self) -> usize {
795 self.inner.msg_receiver.capacity()
796 }
797
798 pub fn set_max_queued(&mut self, max: usize) {
800 self.inner.msg_receiver.clone().set_capacity(max);
801 }
802
803 pub fn server_guid(&self) -> &OwnedGuid {
805 &self.inner.server_guid
806 }
807
808 pub fn executor(&self) -> &Executor<'static> {
860 &self.inner.executor
861 }
862
863 pub fn object_server(&self) -> &ObjectServer {
871 self.ensure_object_server(true)
872 }
873
874 pub(crate) fn ensure_object_server(&self, start: bool) -> &ObjectServer {
875 self.inner
876 .object_server
877 .get_or_init(move || self.setup_object_server(start, None))
878 }
879
880 fn setup_object_server(&self, start: bool, started_event: Option<Event>) -> ObjectServer {
881 if start {
882 self.start_object_server(started_event);
883 }
884
885 ObjectServer::new(self)
886 }
887
888 #[instrument(skip(self))]
889 pub(crate) fn start_object_server(&self, started_event: Option<Event>) {
890 self.inner.object_server_dispatch_task.get_or_init(|| {
891 trace!("starting ObjectServer task");
892 let weak_conn = WeakConnection::from(self);
893
894 self.inner.executor.spawn(
895 async move {
896 let mut stream = match weak_conn.upgrade() {
897 Some(conn) => {
898 let mut builder = MatchRule::builder().msg_type(Type::MethodCall);
899 if let Some(unique_name) = conn.unique_name() {
900 builder = builder.destination(&**unique_name).expect("unique name");
901 }
902 let rule = builder.build();
903 match conn.add_match(rule.into(), None).await {
904 Ok(stream) => stream,
905 Err(e) => {
906 debug!("Failed to create message stream: {}", e);
908
909 return;
910 }
911 }
912 }
913 None => {
914 trace!("Connection is gone, stopping associated object server task");
915
916 return;
917 }
918 };
919 if let Some(started_event) = started_event {
920 started_event.notify(1);
921 }
922
923 trace!("waiting for incoming method call messages..");
924 while let Some(msg) = stream.next().await.and_then(|m| {
925 if let Err(e) = &m {
926 debug!("Error while reading from object server stream: {:?}", e);
927 }
928 m.ok()
929 }) {
930 if let Some(conn) = weak_conn.upgrade() {
931 let hdr = msg.header();
932 if !conn.is_bus() {
935 match hdr.destination() {
936 Some(BusName::Unique(_)) | None => (),
938 Some(BusName::WellKnown(dest)) => {
939 let names = conn.inner.registered_names.lock().await;
940 if !names.is_empty() && !names.contains_key(dest) {
944 trace!(
945 "Got a method call for a different destination: {}",
946 dest
947 );
948
949 continue;
950 }
951 }
952 }
953 }
954 let server = conn.object_server();
955 if let Err(e) = server.dispatch_call(&msg, &hdr).await {
956 debug!(
957 "Error dispatching message. Message: {:?}, error: {:?}",
958 msg, e
959 );
960 }
961 } else {
962 trace!("Connection is gone, stopping associated object server task");
965 break;
966 }
967 }
968 }
969 .instrument(info_span!("obj_server_task")),
970 "obj_server_task",
971 )
972 });
973 }
974
975 pub(crate) async fn add_match(
976 &self,
977 rule: OwnedMatchRule,
978 max_queued: Option<usize>,
979 ) -> Result<Receiver<Result<Message>>> {
980 use std::collections::hash_map::Entry;
981
982 if self.inner.msg_senders.lock().await.is_empty() {
983 return Err(Error::InputOutput(Arc::new(io::Error::new(
985 io::ErrorKind::BrokenPipe,
986 "Socket reader task has errored out",
987 ))));
988 }
989
990 let mut subscriptions = self.inner.subscriptions.lock().await;
991 let msg_type = rule.msg_type().unwrap_or(Type::Signal);
992 match subscriptions.entry(rule.clone()) {
993 Entry::Vacant(e) => {
994 let max_queued = max_queued.unwrap_or(DEFAULT_MAX_QUEUED);
995 let (sender, mut receiver) = broadcast(max_queued);
996 receiver.set_await_active(false);
997 if self.is_bus() && msg_type == Type::Signal {
998 self.call_method(
999 Some("org.freedesktop.DBus"),
1000 "/org/freedesktop/DBus",
1001 Some("org.freedesktop.DBus"),
1002 "AddMatch",
1003 &e.key(),
1004 )
1005 .await?;
1006 }
1007 e.insert((1, receiver.clone().deactivate()));
1008 self.inner
1009 .msg_senders
1010 .lock()
1011 .await
1012 .insert(Some(rule), sender);
1013
1014 Ok(receiver)
1015 }
1016 Entry::Occupied(mut e) => {
1017 let (num_subscriptions, receiver) = e.get_mut();
1018 *num_subscriptions += 1;
1019 if let Some(max_queued) = max_queued {
1020 if max_queued > receiver.capacity() {
1021 receiver.set_capacity(max_queued);
1022 }
1023 }
1024
1025 Ok(receiver.activate_cloned())
1026 }
1027 }
1028 }
1029
1030 pub(crate) async fn remove_match(&self, rule: OwnedMatchRule) -> Result<bool> {
1031 use std::collections::hash_map::Entry;
1032 let mut subscriptions = self.inner.subscriptions.lock().await;
1033 let msg_type = rule.msg_type().unwrap_or(Type::Signal);
1036 match subscriptions.entry(rule) {
1037 Entry::Vacant(_) => Ok(false),
1038 Entry::Occupied(mut e) => {
1039 let rule = e.key().inner().clone();
1040 e.get_mut().0 -= 1;
1041 if e.get().0 == 0 {
1042 if self.is_bus() && msg_type == Type::Signal {
1043 self.call_method(
1044 Some("org.freedesktop.DBus"),
1045 "/org/freedesktop/DBus",
1046 Some("org.freedesktop.DBus"),
1047 "RemoveMatch",
1048 &rule,
1049 )
1050 .await?;
1051 }
1052 e.remove();
1053 self.inner
1054 .msg_senders
1055 .lock()
1056 .await
1057 .remove(&Some(rule.into()));
1058 }
1059 Ok(true)
1060 }
1061 }
1062 }
1063
1064 pub(crate) fn queue_remove_match(&self, rule: OwnedMatchRule) {
1065 let conn = self.clone();
1066 let task_name = format!("Remove match `{}`", *rule);
1067 let remove_match =
1068 async move { conn.remove_match(rule).await }.instrument(trace_span!("{}", task_name));
1069 self.inner.executor.spawn(remove_match, &task_name).detach()
1070 }
1071
1072 pub fn method_timeout(&self) -> Option<Duration> {
1074 self.inner.method_timeout
1075 }
1076
1077 pub(crate) async fn new(
1078 auth: Authenticated,
1079 #[allow(unused)] bus_connection: bool,
1080 executor: Executor<'static>,
1081 method_timeout: Option<Duration>,
1082 ) -> Result<Self> {
1083 #[cfg(unix)]
1084 let cap_unix_fd = auth.cap_unix_fd;
1085
1086 macro_rules! create_msg_broadcast_channel {
1087 ($size:expr) => {{
1088 let (msg_sender, msg_receiver) = broadcast($size);
1089 let mut msg_receiver = msg_receiver.deactivate();
1090 msg_receiver.set_await_active(false);
1091
1092 (msg_sender, msg_receiver)
1093 }};
1094 }
1095 let (msg_sender, msg_receiver) = create_msg_broadcast_channel!(DEFAULT_MAX_QUEUED);
1097 let mut msg_senders = HashMap::new();
1098 msg_senders.insert(None, msg_sender);
1099
1100 let msg_senders = Arc::new(Mutex::new(msg_senders));
1101 let pending_method_calls = PendingMethodCalls::default();
1102 let subscriptions = Mutex::new(HashMap::new());
1103
1104 let connection = Self {
1105 inner: Arc::new(ConnectionInner {
1106 socket_status: Arc::new(SocketStatus {
1107 activity_event: Event::new(),
1108 closed: AtomicBool::new(false),
1109 closed_event: Event::new(),
1110 }),
1111 socket_write: Mutex::new(auth.socket_write),
1112 server_guid: auth.server_guid,
1113 #[cfg(unix)]
1114 cap_unix_fd,
1115 #[cfg(feature = "p2p")]
1116 bus_conn: bus_connection,
1117 unique_name: OnceLock::new(),
1118 subscriptions,
1119 object_server: OnceLock::new(),
1120 object_server_dispatch_task: OnceLock::new(),
1121 executor,
1122 socket_reader_task: OnceLock::new(),
1123 msg_senders,
1124 pending_method_calls,
1125 msg_receiver,
1126 registered_names: Mutex::new(HashMap::new()),
1127 drop_event: Event::new(),
1128 method_timeout,
1129 credentials: OnceLock::new(),
1130 }),
1131 };
1132
1133 if let Some(unique_name) = auth.unique_name {
1134 connection.set_unique_name_(unique_name);
1135 }
1136
1137 Ok(connection)
1138 }
1139
1140 pub async fn session() -> Result<Self> {
1142 Builder::session()?.build().await
1143 }
1144
1145 pub async fn system() -> Result<Self> {
1147 Builder::system()?.build().await
1148 }
1149
1150 pub fn monitor_activity(&self) -> EventListener {
1154 self.inner.socket_status.activity_event.listen()
1155 }
1156
1157 pub fn is_closed(&self) -> bool {
1162 self.inner.socket_status.closed.load(Ordering::Relaxed)
1163 }
1164
1165 pub async fn closed(&self) {
1172 loop {
1173 let listener = self.inner.socket_status.closed_event.listen();
1174 if self.inner.socket_status.closed.load(Ordering::Acquire) {
1175 return;
1176 }
1177 listener.await;
1178 }
1179 }
1180
1181 pub async fn peer_creds(&self) -> io::Result<&Arc<ConnectionCredentials>> {
1192 let mut socket_write = self.inner.socket_write.lock().await;
1193
1194 if let Some(creds) = self.inner.credentials.get() {
1196 return Ok(creds);
1197 }
1198
1199 self.inner
1200 .credentials
1201 .set(socket_write.peer_credentials().await.map(Arc::new)?)
1202 .expect("credentials cache set more than once");
1203
1204 Ok(self
1205 .inner
1206 .credentials
1207 .get()
1208 .expect("credentials should have been set"))
1209 }
1210
1211 #[deprecated(since = "5.13.0", note = "Use `peer_creds` instead")]
1220 pub async fn peer_credentials(&self) -> io::Result<ConnectionCredentials> {
1221 self.inner
1222 .socket_write
1223 .lock()
1224 .await
1225 .peer_credentials()
1226 .await
1227 }
1228
1229 pub async fn close(self) -> Result<()> {
1233 self.inner.socket_status.activity_event.notify(usize::MAX);
1234 let result = self
1235 .inner
1236 .socket_write
1237 .lock()
1238 .await
1239 .close()
1240 .await
1241 .map_err(Into::into);
1242 self.inner
1243 .socket_status
1244 .closed
1245 .store(true, Ordering::Release);
1246 self.inner.socket_status.closed_event.notify(usize::MAX);
1247 result
1248 }
1249
1250 pub async fn graceful_shutdown(self) {
1294 let listener = self.inner.drop_event.listen();
1295 drop(self);
1296 listener.await;
1297 }
1298
1299 pub(crate) fn init_socket_reader(
1300 &self,
1301 socket_read: Box<dyn socket::ReadHalf>,
1302 already_read: Vec<u8>,
1303 #[cfg(unix)] already_received_fds: Vec<std::os::fd::OwnedFd>,
1304 ) {
1305 let inner = &self.inner;
1306 inner
1307 .socket_reader_task
1308 .set(
1309 SocketReader::new(
1310 socket_read,
1311 inner.msg_senders.clone(),
1312 inner.pending_method_calls.clone(),
1313 already_read,
1314 #[cfg(unix)]
1315 already_received_fds,
1316 inner.socket_status.clone(),
1317 )
1318 .spawn(&inner.executor),
1319 )
1320 .expect("Attempted to set `socket_reader_task` twice");
1321 }
1322
1323 fn set_unique_name_(&self, name: OwnedUniqueName) {
1324 self.inner
1325 .unique_name
1326 .set(name)
1327 .expect("unique name already set");
1329 }
1330}
1331
1332#[cfg(feature = "blocking-api")]
1333impl From<crate::blocking::Connection> for Connection {
1334 fn from(conn: crate::blocking::Connection) -> Self {
1335 conn.into_inner()
1336 }
1337}
1338
1339#[derive(Debug, Clone)]
1341pub(crate) struct WeakConnection {
1342 inner: Weak<ConnectionInner>,
1343}
1344
1345impl WeakConnection {
1346 pub fn upgrade(&self) -> Option<Connection> {
1348 self.inner.upgrade().map(|inner| Connection { inner })
1349 }
1350}
1351
1352impl From<&Connection> for WeakConnection {
1353 fn from(conn: &Connection) -> Self {
1354 Self {
1355 inner: Arc::downgrade(&conn.inner),
1356 }
1357 }
1358}
1359
1360#[derive(Debug)]
1361enum NameStatus {
1362 Owner(#[allow(unused)] Option<Task<()>>),
1364 Queued(#[allow(unused)] Task<()>),
1366}
1367
1368static SERIAL_NUM_SEMAPHORE: Semaphore = Semaphore::new(1);
1369
1370async fn acquire_serial_num_semaphore() -> Option<SemaphorePermit<'static>> {
1375 if is_flatpak() {
1376 Some(SERIAL_NUM_SEMAPHORE.acquire().await)
1377 } else {
1378 None
1379 }
1380}
1381
1382#[cfg(test)]
1383mod tests {
1384 use super::*;
1385 use crate::fdo::DBusProxy;
1386 use ntest::timeout;
1387 use std::{pin::pin, time::Duration};
1388 use test_log::test;
1389
1390 #[cfg(windows)]
1391 #[test]
1392 fn connect_autolaunch_session_bus() {
1393 let addr =
1394 crate::win32::autolaunch_bus_address().expect("Unable to get session bus address");
1395
1396 crate::block_on(async { addr.connect().await }).expect("Unable to connect to session bus");
1397 }
1398
1399 #[cfg(target_os = "macos")]
1400 #[test]
1401 fn connect_launchd_session_bus() {
1402 use crate::address::{Address, Transport, transport::Launchd};
1403 crate::block_on(async {
1404 let addr = Address::from(Transport::Launchd(Launchd::new(
1405 "DBUS_LAUNCHD_SESSION_BUS_SOCKET",
1406 )));
1407 addr.connect().await
1408 })
1409 .expect("Unable to connect to session bus");
1410 }
1411
1412 #[test]
1413 #[timeout(15000)]
1414 fn disconnect_on_drop() {
1415 crate::utils::block_on(test_disconnect_on_drop());
1418 }
1419
1420 async fn test_disconnect_on_drop() {
1421 #[derive(Default)]
1422 struct MyInterface {}
1423
1424 #[crate::interface(name = "dev.peelz.FooBar.Baz")]
1425 impl MyInterface {
1426 fn do_thing(&self) {}
1427 }
1428 let name = "dev.peelz.foobar";
1429 let connection = Builder::session()
1430 .unwrap()
1431 .name(name)
1432 .unwrap()
1433 .serve_at("/dev/peelz/FooBar", MyInterface::default())
1434 .unwrap()
1435 .build()
1436 .await
1437 .unwrap();
1438
1439 let connection2 = Connection::session().await.unwrap();
1440 let dbus = DBusProxy::new(&connection2).await.unwrap();
1441 let mut stream = dbus
1442 .receive_name_owner_changed_with_args(&[(0, name), (2, "")])
1443 .await
1444 .unwrap();
1445
1446 drop(connection);
1447
1448 stream.next().await.unwrap();
1450
1451 let name_has_owner = dbus.name_has_owner(name.try_into().unwrap()).await.unwrap();
1453 assert!(!name_has_owner);
1454 }
1455
1456 #[tokio::test(start_paused = true)]
1457 #[timeout(15000)]
1458 async fn test_graceful_shutdown() {
1459 let connection = Connection::session().await.unwrap();
1461 let clone = connection.clone();
1462 let mut shutdown = pin!(connection.graceful_shutdown());
1463 tokio::select! {
1466 _ = tokio::time::sleep(Duration::from_secs(u64::MAX)) => {},
1467 _ = &mut shutdown => {
1468 panic!("Graceful shutdown unexpectedly completed");
1469 }
1470 }
1471
1472 drop(clone);
1473 shutdown.await;
1474
1475 struct GracefulInterface {
1477 method_called: Event,
1478 wait_before_return: Option<EventListener>,
1479 announce_done: Event,
1480 }
1481
1482 #[crate::interface(name = "dev.peelz.TestGracefulShutdown")]
1483 impl GracefulInterface {
1484 async fn do_thing(&mut self) {
1485 self.method_called.notify(1);
1486 if let Some(listener) = self.wait_before_return.take() {
1487 listener.await;
1488 }
1489 self.announce_done.notify(1);
1490 }
1491 }
1492
1493 let method_called = Event::new();
1494 let method_called_listener = method_called.listen();
1495
1496 let trigger_return = Event::new();
1497 let wait_before_return = Some(trigger_return.listen());
1498
1499 let announce_done = Event::new();
1500 let done_listener = announce_done.listen();
1501
1502 let interface = GracefulInterface {
1503 method_called,
1504 wait_before_return,
1505 announce_done,
1506 };
1507
1508 let name = "dev.peelz.TestGracefulShutdown";
1509 let obj = "/dev/peelz/TestGracefulShutdown";
1510 let connection = Builder::session()
1511 .unwrap()
1512 .name(name)
1513 .unwrap()
1514 .serve_at(obj, interface)
1515 .unwrap()
1516 .build()
1517 .await
1518 .unwrap();
1519
1520 let client_conn = Connection::session().await.unwrap();
1522 tokio::spawn(async move {
1523 client_conn
1524 .call_method(Some(name), obj, Some(name), "DoThing", &())
1525 .await
1526 .unwrap();
1527 });
1528
1529 method_called_listener.await;
1532
1533 let mut shutdown = pin!(connection.graceful_shutdown());
1534 tokio::select! {
1535 _ = tokio::time::sleep(Duration::from_secs(u64::MAX)) => {},
1536 _ = &mut shutdown => {
1537 panic!("Graceful shutdown unexpectedly completed");
1539 }
1540 }
1541
1542 trigger_return.notify(1);
1544 shutdown.await;
1545
1546 done_listener.await;
1548 }
1549}
1550
1551#[cfg(feature = "p2p")]
1552#[cfg(test)]
1553mod p2p_tests {
1554 use event_listener::Event;
1555 use futures_util::TryStreamExt;
1556 use ntest::timeout;
1557 use test_log::test;
1558 use zvariant::{Endian, NATIVE_ENDIAN};
1559
1560 use super::{Builder, Connection, socket};
1561 use crate::{Guid, Message, MessageStream, Result, conn::AuthMechanism};
1562
1563 async fn test_p2p(
1565 server1: Connection,
1566 client1: Connection,
1567 server2: Connection,
1568 client2: Connection,
1569 ) -> Result<()> {
1570 let forward1 = {
1571 let stream = MessageStream::from(server1.clone());
1572 let sink = client2.clone();
1573
1574 stream.try_for_each(move |msg| {
1575 let sink = sink.clone();
1576 async move { sink.send(&msg).await }
1577 })
1578 };
1579 let forward2 = {
1580 let stream = MessageStream::from(client2.clone());
1581 let sink = server1.clone();
1582
1583 stream.try_for_each(move |msg| {
1584 let sink = sink.clone();
1585 async move { sink.send(&msg).await }
1586 })
1587 };
1588 let _forward_task = client1.executor().spawn(
1589 async move { futures_util::try_join!(forward1, forward2) },
1590 "forward_task",
1591 );
1592
1593 let server_ready = Event::new();
1594 let server_ready_listener = server_ready.listen();
1595 let client_done = Event::new();
1596 let client_done_listener = client_done.listen();
1597
1598 let server_future = async move {
1599 let mut stream = MessageStream::from(&server2);
1600 server_ready.notify(1);
1601 let method = loop {
1602 let m = stream.try_next().await?.unwrap();
1603 if m.to_string() == "Method call Test" {
1604 assert_eq!(m.body().deserialize::<u64>().unwrap(), 64);
1605 break m;
1606 }
1607 };
1608
1609 server2
1611 .emit_signal(None::<()>, "/", "org.zbus.p2p", "ASignalForYou", &())
1612 .await?;
1613 server2.reply(&method.header(), &("yay")).await?;
1614 client_done_listener.await;
1615
1616 Ok(())
1617 };
1618
1619 let client_future = async move {
1620 let mut stream = MessageStream::from(&client1);
1621 server_ready_listener.await;
1622 let endian = match NATIVE_ENDIAN {
1626 Endian::Little => Endian::Big,
1627 Endian::Big => Endian::Little,
1628 };
1629 let method = Message::method_call("/", "Test")?
1630 .interface("org.zbus.p2p")?
1631 .endian(endian)
1632 .build(&64u64)?;
1633 client1.send(&method).await?;
1634 let m = stream.try_next().await?.unwrap();
1636 client_done.notify(1);
1637 assert_eq!(m.to_string(), "Signal ASignalForYou");
1638 let reply = stream.try_next().await?.unwrap();
1639 assert_eq!(reply.to_string(), "Method return");
1640 assert_eq!(Endian::from(reply.primary_header().endian_sig()), endian);
1642 reply.body().deserialize::<String>()
1643 };
1644
1645 let (val, _) = futures_util::try_join!(client_future, server_future,)?;
1646 assert_eq!(val, "yay");
1647
1648 Ok(())
1649 }
1650
1651 #[test]
1652 #[timeout(15000)]
1653 fn tcp_p2p() {
1654 crate::utils::block_on(test_tcp_p2p()).unwrap();
1655 }
1656
1657 async fn test_tcp_p2p() -> Result<()> {
1658 let (server1, client1) = tcp_p2p_pipe().await?;
1659 let (server2, client2) = tcp_p2p_pipe().await?;
1660
1661 test_p2p(server1, client1, server2, client2).await
1662 }
1663
1664 async fn tcp_p2p_pipe() -> Result<(Connection, Connection)> {
1665 let guid = Guid::generate();
1666
1667 #[cfg(not(feature = "tokio"))]
1668 let (server_conn_builder, client_conn_builder) = {
1669 let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
1670 let addr = listener.local_addr().unwrap();
1671 let p1 = std::net::TcpStream::connect(addr).unwrap();
1672 let p0 = listener.incoming().next().unwrap().unwrap();
1673
1674 (
1675 Builder::tcp_stream(p0)
1676 .server(guid)
1677 .unwrap()
1678 .p2p()
1679 .auth_mechanism(AuthMechanism::Anonymous),
1680 Builder::tcp_stream(p1).p2p(),
1681 )
1682 };
1683
1684 #[cfg(feature = "tokio")]
1685 let (server_conn_builder, client_conn_builder) = {
1686 let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
1687 let addr = listener.local_addr().unwrap();
1688 let p1 = tokio::net::TcpStream::connect(addr).await.unwrap();
1689 let p0 = listener.accept().await.unwrap().0;
1690
1691 (
1692 Builder::tcp_stream(p0)
1693 .server(guid)
1694 .unwrap()
1695 .p2p()
1696 .auth_mechanism(AuthMechanism::Anonymous),
1697 Builder::tcp_stream(p1).p2p(),
1698 )
1699 };
1700
1701 futures_util::try_join!(server_conn_builder.build(), client_conn_builder.build())
1702 }
1703
1704 #[cfg(unix)]
1705 #[test]
1706 #[timeout(15000)]
1707 fn unix_p2p() {
1708 crate::utils::block_on(test_unix_p2p()).unwrap();
1709 }
1710
1711 #[cfg(unix)]
1712 async fn test_unix_p2p() -> Result<()> {
1713 let (server1, client1) = unix_p2p_pipe().await?;
1714 let (server2, client2) = unix_p2p_pipe().await?;
1715
1716 test_p2p(server1, client1, server2, client2).await
1717 }
1718
1719 #[cfg(unix)]
1720 async fn unix_p2p_pipe() -> Result<(Connection, Connection)> {
1721 #[cfg(not(feature = "tokio"))]
1722 use std::os::unix::net::UnixStream;
1723 #[cfg(feature = "tokio")]
1724 use tokio::net::UnixStream;
1725 #[cfg(all(windows, not(feature = "tokio")))]
1726 use uds_windows::UnixStream;
1727
1728 let guid = Guid::generate();
1729
1730 let (p0, p1) = UnixStream::pair().unwrap();
1731
1732 futures_util::try_join!(
1733 Builder::unix_stream(p1).p2p().build(),
1734 Builder::unix_stream(p0).server(guid).unwrap().p2p().build(),
1735 )
1736 }
1737
1738 #[cfg(any(
1739 all(feature = "vsock", not(feature = "tokio")),
1740 feature = "tokio-vsock"
1741 ))]
1742 #[test]
1743 #[timeout(15000)]
1744 fn vsock_connect() {
1745 let _ = crate::utils::block_on(test_vsock_connect()).unwrap();
1746 }
1747
1748 #[cfg(any(
1749 all(feature = "vsock", not(feature = "tokio")),
1750 feature = "tokio-vsock"
1751 ))]
1752 async fn test_vsock_connect() -> Result<(Connection, Connection)> {
1753 #[cfg(feature = "tokio-vsock")]
1754 use futures_util::StreamExt;
1755
1756 let guid = Guid::generate();
1757
1758 #[cfg(all(feature = "vsock", not(feature = "tokio")))]
1759 let listener = vsock::VsockListener::bind_with_cid_port(vsock::VMADDR_CID_LOCAL, u32::MAX)?;
1760 #[cfg(feature = "tokio-vsock")]
1761 let listener = tokio_vsock::VsockListener::bind(tokio_vsock::VsockAddr::new(1, u32::MAX))?;
1762
1763 let addr = listener.local_addr()?;
1764 let addr = format!("vsock:cid={},port={},guid={guid}", addr.cid(), addr.port());
1765
1766 let server = async {
1767 #[cfg(all(feature = "vsock", not(feature = "tokio")))]
1768 let server =
1769 crate::Task::spawn_blocking(move || listener.incoming().next(), "").await?;
1770 #[cfg(feature = "tokio-vsock")]
1771 let server = listener.incoming().next().await;
1772 Builder::vsock_stream(server.unwrap()?)
1773 .server(guid)?
1774 .p2p()
1775 .auth_mechanism(AuthMechanism::Anonymous)
1776 .build()
1777 .await
1778 };
1779
1780 let client = crate::connection::Builder::address(addr.as_str())?
1781 .p2p()
1782 .build();
1783
1784 futures_util::try_join!(server, client)
1785 }
1786
1787 #[cfg(any(
1788 all(feature = "vsock", not(feature = "tokio")),
1789 feature = "tokio-vsock"
1790 ))]
1791 #[test]
1792 #[timeout(15000)]
1793 fn vsock_p2p() {
1794 crate::utils::block_on(test_vsock_p2p()).unwrap();
1795 }
1796
1797 #[cfg(any(
1798 all(feature = "vsock", not(feature = "tokio")),
1799 feature = "tokio-vsock"
1800 ))]
1801 async fn test_vsock_p2p() -> Result<()> {
1802 let (server1, client1) = vsock_p2p_pipe().await?;
1803 let (server2, client2) = vsock_p2p_pipe().await?;
1804
1805 test_p2p(server1, client1, server2, client2).await
1806 }
1807
1808 #[cfg(all(feature = "vsock", not(feature = "tokio")))]
1809 async fn vsock_p2p_pipe() -> Result<(Connection, Connection)> {
1810 let guid = Guid::generate();
1811
1812 let listener =
1813 vsock::VsockListener::bind_with_cid_port(vsock::VMADDR_CID_LOCAL, u32::MAX).unwrap();
1814 let addr = listener.local_addr().unwrap();
1815 let client = vsock::VsockStream::connect(&addr).unwrap();
1816 let server = listener.incoming().next().unwrap().unwrap();
1817
1818 futures_util::try_join!(
1819 Builder::vsock_stream(server)
1820 .server(guid)
1821 .unwrap()
1822 .p2p()
1823 .auth_mechanism(AuthMechanism::Anonymous)
1824 .build(),
1825 Builder::vsock_stream(client).p2p().build(),
1826 )
1827 }
1828
1829 #[cfg(feature = "tokio-vsock")]
1830 async fn vsock_p2p_pipe() -> Result<(Connection, Connection)> {
1831 use futures_util::StreamExt;
1832 use tokio_vsock::VsockAddr;
1833
1834 let guid = Guid::generate();
1835
1836 let listener = tokio_vsock::VsockListener::bind(VsockAddr::new(1, u32::MAX)).unwrap();
1837 let addr = listener.local_addr().unwrap();
1838 let client = tokio_vsock::VsockStream::connect(addr).await.unwrap();
1839 let server = listener.incoming().next().await.unwrap().unwrap();
1840
1841 futures_util::try_join!(
1842 Builder::vsock_stream(server)
1843 .server(guid)
1844 .unwrap()
1845 .p2p()
1846 .auth_mechanism(AuthMechanism::Anonymous)
1847 .build(),
1848 Builder::vsock_stream(client).p2p().build(),
1849 )
1850 }
1851
1852 #[test]
1853 #[timeout(15000)]
1854 fn channel_pair() {
1855 crate::utils::block_on(test_channel_pair()).unwrap();
1856 }
1857
1858 async fn test_channel_pair() -> Result<()> {
1859 let (server1, client1) = create_channel_pair().await;
1860 let (server2, client2) = create_channel_pair().await;
1861
1862 test_p2p(server1, client1, server2, client2).await
1863 }
1864
1865 async fn create_channel_pair() -> (Connection, Connection) {
1866 let (a, b) = socket::Channel::pair();
1867
1868 let guid = crate::Guid::generate();
1869 let conn1 = Builder::authenticated_socket(a, guid.clone())
1870 .unwrap()
1871 .p2p()
1872 .build()
1873 .await
1874 .unwrap();
1875 let conn2 = Builder::authenticated_socket(b, guid)
1876 .unwrap()
1877 .p2p()
1878 .build()
1879 .await
1880 .unwrap();
1881
1882 (conn1, conn2)
1883 }
1884}