1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Packet rules — the extension point for latency, drops, partitions,
//! and other fault injection.
//!
//! The fabric consults every installed rule, in install order, for
//! each non-loopback packet leaving a host. The first rule to return
//! a non-[`Verdict::Pass`] verdict wins; if every rule passes, the
//! packet is delivered immediately.
//!
//! Loopback is inline and skips rules — a single-host test doesn't
//! need fault injection on 127.0.0.1 traffic, and bypassing keeps the
//! fast path fast.
//!
//! # Installing
//!
//! ```ignore
//! // Free fn (from any task inside the Net): uninstalls on drop.
//! let guard = turmoil_net::rule(Latency::fixed(Duration::from_millis(10)));
//! // Or permanently at Net construction:
//! let net = Net::new();
//! net.install_permanent(Latency::fixed(/* .. */));
//! ```
use ;
use crate::;
/// What should happen to a packet.
/// Decides the fate of each packet the fabric sees.
///
/// Rules have exclusive `&mut` during evaluation, so they can hold
/// counters, RNG state, or other per-rule bookkeeping without
/// synchronization. Evaluation is deterministic: rules run in install
/// order, and for each packet the first non-[`Verdict::Pass`] wins.
/// Handle returned by every installer. The `RuleId` is stable for the
/// life of the rule — uninstalling twice is a no-op.
u64);
/// A rule that delays every packet by a fixed duration.
///
/// Apply selectively by src/dst if you want one-way latency — the
/// matcher closure is called for each packet and receives the
/// endpoints.
/// Adapter that lifts a `FnMut(&Packet) -> Verdict` into a [`Rule`].
/// Lets tests write ad-hoc rules without a full type declaration.
/// RAII handle for a rule installed via [`rule`](crate::rule) or
/// [`EnterGuard::rule`](crate::EnterGuard::rule).
/// Drop uninstalls the rule; [`RuleGuard::forget`] leaks it instead,
/// leaving the rule installed for the rest of the simulation.
///
/// The guard is `!Send`: it's tied to the thread that owns the `Net`,
/// and the thread-local uninstall on drop would be unsound across
/// threads.