1
//! Help the guard manager (and other crates) deal with "pending
2
//! information".
3
//!
4
//! There are two kinds of pending information to deal with.  First,
5
//! every guard that we hand out needs to be marked as succeeded or
6
//! failed. Second, if a guard is given out on an exploratory basis,
7
//! then the circuit manager can't know whether to use a circuit built
8
//! through that guard until the guard manager tells it.  This is
9
//! handled via [`GuardUsable`].
10
use crate::{daemon, GuardId};
11

            
12
use educe::Educe;
13
use futures::{
14
    channel::{mpsc::UnboundedSender, oneshot},
15
    Future,
16
};
17
use pin_project::pin_project;
18
use std::fmt::Debug;
19
use std::pin::Pin;
20
use std::sync::atomic::{AtomicU64, Ordering};
21
use std::task::{Context, Poll};
22
use std::time::Instant;
23

            
24
use tor_basic_utils::skip_fmt;
25

            
26
/// A future used to see if we have "permission" to use a guard.
27
///
28
/// For efficiency, the [`GuardMgr`](crate::GuardMgr) implementation sometimes gives
29
/// out lower-priority guards when it is not certain whether
30
/// higher-priority guards are running.  After having built a circuit
31
/// with such a guard, the caller must wait on this future to see whether
32
/// the circuit is usable or not.
33
///
34
/// The circuit may be usable immediately (as happens if the guard was
35
/// of sufficient priority, or if all higher-priority guards are
36
/// _known_ to be down).  It may eventually _become_ usable (if all of
37
/// the higher-priority guards are _discovered_ to be down).  Or it may
38
/// eventually become unusable (if we find a higher-priority guard
39
/// that works).
40
///
41
/// Any [`GuardRestriction`](crate::GuardRestriction)s that were used to select this guard
42
/// may influence whether it is usable: if higher priority guards were
43
/// ignored because of a restriction, then we might use a guard that we
44
/// otherwise wouldn't.
45
3740
#[pin_project]
46
pub struct GuardUsable {
47
    /// If present, then this is a future to wait on to see whether the
48
    /// guard is usable.
49
    ///
50
    /// If absent, then the guard is ready immediately and no waiting
51
    /// is needed.
52
    #[pin]
53
    u: Option<oneshot::Receiver<bool>>,
54
}
55

            
56
impl Future for GuardUsable {
57
    type Output = Result<bool, oneshot::Canceled>;
58

            
59
3740
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
60
3740
        match self.project().u.as_pin_mut() {
61
3724
            None => Poll::Ready(Ok(true)),
62
16
            Some(u) => u.poll(cx),
63
        }
64
3740
    }
65
}
66

            
67
impl GuardUsable {
68
    /// Create a new GuardUsable for a primary guard.
69
    ///
70
    /// (Circuits built through primary guards are usable immediately,
71
    /// so we don't need a way to report that this guard is usable.)
72
3740
    pub(crate) fn new_primary() -> Self {
73
3740
        GuardUsable { u: None }
74
3740
    }
75

            
76
    /// Create a new GuardUsable for a guard with undecided usability
77
    /// status.
78
8
    pub(crate) fn new_uncertain() -> (Self, oneshot::Sender<bool>) {
79
8
        let (snd, rcv) = oneshot::channel();
80
8
        (GuardUsable { u: Some(rcv) }, snd)
81
8
    }
82
}
83

            
84
/// A message that we can get back from the circuit manager who asked
85
/// for a guard.
86
#[derive(Copy, Clone, Debug)]
87
#[non_exhaustive]
88
pub enum GuardStatus {
89
    /// The guard was used successfully.
90
    Success,
91
    /// The guard was used unsuccessfully.
92
    Failure,
93
    /// The circuit failed in a way that we cannot prove is the guard's
94
    /// fault, but which _might_ be the guard's fault.
95
    Indeterminate,
96
    /// Our attempt to use the guard didn't get far enough to be sure
97
    /// whether the guard is usable or not.
98
    AttemptAbandoned,
99
}
100

            
101
/// An object used to tell the [`GuardMgr`](crate::GuardMgr) about the result of
102
/// trying to build a circuit through a guard.
103
///
104
/// The `GuardMgr` needs to know about these statuses, so that it can tell
105
/// whether the guard is running or not.
106
#[must_use = "You need to report the status of any guard that you asked for"]
107
#[derive(Educe)]
108
#[educe(Debug)]
109
pub struct GuardMonitor {
110
    /// The Id that we're going to report about.
111
    id: RequestId,
112
    /// The status that we will report if this monitor is dropped now.
113
    pending_status: GuardStatus,
114
    /// If set, we change `Indeterminate` to `AttemptAbandoned` before
115
    /// reporting it to the guard manager.
116
    ///
117
    /// We do this when a failure to finish the circuit doesn't reflect
118
    /// badly against the guard at all: typically, because the circuit's
119
    /// path is not random.
120
    ignore_indeterminate: bool,
121
    /// A sender that needs to get told when the attempt to use the guard is
122
    /// finished or abandoned.
123
    ///
124
    /// TODO: This doesn't really need to be an Option, but we use None
125
    /// here to indicate that we've already used the sender, and it can't
126
    /// be used again.
127
    #[educe(Debug(method = "skip_fmt"))]
128
    snd: Option<UnboundedSender<daemon::Msg>>,
129
}
130

            
131
impl GuardMonitor {
132
    /// Create a new GuardMonitor object.
133
3748
    pub(crate) fn new(id: RequestId, snd: UnboundedSender<daemon::Msg>) -> Self {
134
3748
        GuardMonitor {
135
3748
            id,
136
3748
            pending_status: GuardStatus::AttemptAbandoned,
137
3748
            ignore_indeterminate: false,
138
3748
            snd: Some(snd),
139
3748
        }
140
3748
    }
141

            
142
    /// Report that a circuit was successfully built in a way that
143
    /// indicates that the guard is working.
144
    ///
145
    /// Note that this doesn't necessarily mean that the circuit
146
    /// succeeded. For example, we might decide that extending to a
147
    /// second hop means that a guard is usable, even if the circuit
148
    /// stalled at the third hop.
149
3728
    pub fn succeeded(self) {
150
3728
        self.report(GuardStatus::Success);
151
3728
    }
152

            
153
    /// Report that the circuit could not be built successfully, in
154
    /// a way that indicates that the guard isn't working.
155
    ///
156
    /// (This either be because of a network failure, a timeout, or
157
    /// something else.)
158
12
    pub fn failed(self) {
159
12
        self.report(GuardStatus::Failure);
160
12
    }
161

            
162
    /// Report that we did not try to build a circuit using the guard,
163
    /// or that we can't tell whether the guard is working.
164
    ///
165
    /// Dropping a `GuardMonitor` is without calling `succeeded` or
166
    /// `failed` or `pending_status` is equivalent to calling this
167
    /// function.
168
    pub fn attempt_abandoned(self) {
169
        self.report(GuardStatus::AttemptAbandoned);
170
    }
171

            
172
    /// Configure this monitor so that, if it is dropped before use,
173
    /// it sends the status `status`.
174
    pub fn pending_status(&mut self, status: GuardStatus) {
175
        self.pending_status = status;
176
    }
177

            
178
    /// Return the current pending status and "ignore indeterminate"
179
    /// status for this guard monitor.
180
    #[cfg(feature = "testing")]
181
1320
    pub fn inspect_pending_status(&self) -> (GuardStatus, bool) {
182
1320
        (self.pending_status, self.ignore_indeterminate)
183
1320
    }
184

            
185
    /// Configure this monitor to ignore any indeterminate status
186
    /// values, and treat them as abandoned attempts.
187
    ///
188
    /// We should use this whenever the path being built with this guard
189
    /// is not randomly generated.
190
120
    pub fn ignore_indeterminate_status(&mut self) {
191
120
        self.ignore_indeterminate = true;
192
120
    }
193

            
194
    /// Report a message for this guard.
195
3740
    pub fn report(mut self, msg: GuardStatus) {
196
3740
        self.report_impl(msg);
197
3740
    }
198

            
199
    /// As [`GuardMonitor::report`], but take a &mut reference.
200
3748
    fn report_impl(&mut self, msg: GuardStatus) {
201
3748
        let msg = match (msg, self.ignore_indeterminate) {
202
            (GuardStatus::Indeterminate, true) => GuardStatus::AttemptAbandoned,
203
3748
            (m, _) => m,
204
        };
205
3748
        let _ignore = self
206
3748
            .snd
207
3748
            .take()
208
3748
            .expect("GuardMonitor initialized with no sender")
209
3748
            .unbounded_send(daemon::Msg::Status(self.id, msg));
210
3748
    }
211

            
212
    /// Report the pending message for his guard, whatever it is.
213
    pub fn commit(self) {
214
        let status = self.pending_status;
215
        self.report(status);
216
    }
217
}
218

            
219
impl Drop for GuardMonitor {
220
3748
    fn drop(&mut self) {
221
3748
        if self.snd.is_some() {
222
8
            self.report_impl(self.pending_status);
223
3740
        }
224
3748
    }
225
}
226

            
227
/// Internal unique identifier used to tell PendingRequest objects apart.
228
545
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
229
pub(crate) struct RequestId {
230
    /// The value of the identifier.
231
    id: u64,
232
}
233

            
234
impl RequestId {
235
    /// Create a new, never-before-used RequestId.
236
    ///
237
    /// # Panics
238
    ///
239
    /// Panics if we have somehow exhausted a 64-bit space of request IDs.
240
3748
    pub(crate) fn next() -> RequestId {
241
3748
        /// The next identifier in sequence we'll give out.
242
3748
        static NEXT_VAL: AtomicU64 = AtomicU64::new(1);
243
3748
        let id = NEXT_VAL.fetch_add(1, Ordering::Relaxed);
244
3748
        assert!(id != 0, "Exhausted guard request Id space.");
245
3748
        RequestId { id }
246
3748
    }
247
}
248

            
249
/// Pending information about a guard that we handed out in response to
250
/// some request, but where we have not yet reported whether the guard
251
/// is usable.
252
///
253
/// We create one of these whenever we give out a guard with an
254
/// uncertain usability status via [`GuardUsable::new_uncertain`].
255
#[derive(Debug)]
256
pub(crate) struct PendingRequest {
257
    /// Identity of the guard that we gave out.
258
    guard_id: GuardId,
259
    /// The usage for which this guard was requested.
260
    ///
261
    /// We need this information because, if we find that a better guard
262
    /// than this one might be usable, we should only give it precedence
263
    /// if that guard is also allowable _for this usage_.
264
    usage: crate::GuardUsage,
265
    /// A oneshot channel used to tell the circuit manager that a circuit
266
    /// built through this guard can be used.
267
    ///
268
    /// (This is an option so that we can safely make reply() once-only.
269
    /// Otherwise we run into lifetime issues elsewhere.)
270
    usable: Option<oneshot::Sender<bool>>,
271
    /// The time at which the circuit manager told us that this guard was
272
    /// successful.
273
    waiting_since: Option<Instant>,
274
    /// If true, then the network has been down for a long time when we
275
    /// launched this request.
276
    ///
277
    /// If this request succeeds, it probably means that the net has
278
    /// come back up.
279
    net_has_been_down: bool,
280
}
281

            
282
impl PendingRequest {
283
    /// Create a new PendingRequest.
284
3748
    pub(crate) fn new(
285
3748
        guard_id: GuardId,
286
3748
        usage: crate::GuardUsage,
287
3748
        usable: Option<oneshot::Sender<bool>>,
288
3748
        net_has_been_down: bool,
289
3748
    ) -> Self {
290
3748
        PendingRequest {
291
3748
            guard_id,
292
3748
            usage,
293
3748
            usable,
294
3748
            waiting_since: None,
295
3748
            net_has_been_down,
296
3748
        }
297
3748
    }
298

            
299
    /// Return the Id of the guard we gave out.
300
7220
    pub(crate) fn guard_id(&self) -> &GuardId {
301
7220
        &self.guard_id
302
7220
    }
303

            
304
    /// Return the usage for which we gave out the guard.
305
3608
    pub(crate) fn usage(&self) -> &crate::GuardUsage {
306
3608
        &self.usage
307
3608
    }
308

            
309
    /// Return the time (if any) when we were told that the guard
310
    /// was successful.
311
    pub(crate) fn waiting_since(&self) -> Option<Instant> {
312
        self.waiting_since
313
    }
314

            
315
    /// Return true if the network had been down for a long time when
316
    /// this guard was handed out.
317
3608
    pub(crate) fn net_has_been_down(&self) -> bool {
318
3608
        self.net_has_been_down
319
3608
    }
320

            
321
    /// Tell the circuit manager that the guard is usable (or unusable),
322
    /// depending on the argument.
323
    ///
324
    /// Does nothing if reply() has already been called.
325
    pub(crate) fn reply(&mut self, usable: bool) {
326
3627
        if let Some(sender) = self.usable.take() {
327
8
            // If this gives us an error, then the circuit manager doesn't
328
8
            // care about this circuit any more.
329
8
            let _ignore = sender.send(usable);
330
3619
        }
331
3627
    }
332

            
333
    /// Mark this request as "waiting" since the time `now`.
334
    ///
335
    /// This function should only be called once per request.
336
    pub(crate) fn mark_waiting(&mut self, now: Instant) {
337
        debug_assert!(self.waiting_since.is_none());
338
        self.waiting_since = Some(now);
339
    }
340
}