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