Skip to content

Commit 8019f6e

Browse files
committed
add DNS fault support
Signed-off-by: Sylvain Hellegouarch <[email protected]>
1 parent 821e277 commit 8019f6e

File tree

22 files changed

+606
-234
lines changed

22 files changed

+606
-234
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
## Changed
44

5-
- Fix ghcr repository URL
5+
- Add proper DNS fault support

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ members = ["fault-cli", "fault-ebpf-programs"]
44
default-members = ["fault-cli"]
55

66
[workspace.package]
7-
version = "0.15.1"
7+
version = "0.16.0"
88
edition = "2024"
99
rust-version = "1.85"
1010
license-file = "LICENSE"

fault-cli/src/cli.rs

Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::types::BandwidthUnit;
2222
use crate::types::DbCase;
2323
use crate::types::DbTarget;
2424
use crate::types::Direction;
25+
use crate::types::DnsCase;
2526
use crate::types::LatencyDistribution;
2627
use crate::types::LlmCase;
2728
use crate::types::LlmTarget;
@@ -377,6 +378,22 @@ pub struct DbOptions {
377378
pub corruption_rate: f64,
378379
}
379380

381+
#[derive(Parser, Clone, Debug)]
382+
#[clap(next_help_heading = "DNS Options")]
383+
pub struct DnsOptions {
384+
/// Remote resolver for passing queries (IP, IP:PORT)
385+
#[clap(long, default_value = "127.0.0.1:53", env = "FAULT_DNS_RESOLVER")]
386+
pub resolver: String,
387+
388+
/// Probability for injection [0, 1] (never to always)
389+
#[clap(long, default_value = "1.0", value_parser = validate_probability, env = "FAULT_LLM_PROBABILITY",)]
390+
pub probability: f64,
391+
392+
/// Delay per query (e.g. "200ms")
393+
#[clap(long, value_parser = validate_parse_human_duration, env = "FAULT_DNS_DELAY")]
394+
pub delay: Option<Duration>,
395+
}
396+
380397
#[derive(Subcommand, Clone, Debug)]
381398
#[clap(subcommand_required = false, subcommand = "proxy")]
382399
pub enum RunCommands {
@@ -397,7 +414,7 @@ pub enum RunCommands {
397414
settings: LlmOptions,
398415
},
399416

400-
#[clap(next_help_heading = "Databaase-specific faults")]
417+
#[clap(next_help_heading = "Database-specific faults")]
401418
Db {
402419
/// Which database to target
403420
#[clap(value_enum)]
@@ -410,6 +427,16 @@ pub enum RunCommands {
410427
#[clap(flatten)]
411428
settings: DbOptions,
412429
},
430+
431+
#[clap(next_help_heading = "DNS-specific faults")]
432+
Dns {
433+
/// Which scenarios to run
434+
#[clap(value_enum, long = "case")]
435+
cases: Vec<DnsCase>,
436+
437+
#[clap(flatten)]
438+
settings: DnsOptions,
439+
},
413440
}
414441

415442
#[derive(Parser, Debug, Serialize, Deserialize, Clone)]
@@ -678,41 +705,6 @@ pub struct JitterOptions {
678705
pub jitter_sched: Option<String>,
679706
}
680707

681-
#[derive(Parser, Debug, Serialize, Deserialize, Clone)]
682-
pub struct DnsOptions {
683-
/// Dns fault enabled
684-
#[arg(
685-
help_heading = "DNS Options",
686-
action,
687-
name = "dns_enabled",
688-
long = "with-dns",
689-
default_value_t = false,
690-
help = "Enable dns network fault.",
691-
env = "FAULT_WITH_DNS"
692-
)]
693-
pub enabled: bool,
694-
695-
/// Probability to inject the error between 0 and 100
696-
#[arg(
697-
help_heading = "DNS Options",
698-
long,
699-
default_value_t = 0.5,
700-
help = "Probability to trigger the DNS failure between 0.0 and 1.0.",
701-
value_parser = validate_probability,
702-
env = "FAULT_DNS_PROBABILITY",
703-
)]
704-
pub dns_rate: f64,
705-
706-
/// Dns period
707-
#[arg(
708-
help_heading = "DNS Options",
709-
long,
710-
help = "Dns schedule",
711-
env = "FAULT_DNS_SCHED"
712-
)]
713-
pub dns_sched: Option<String>,
714-
}
715-
716708
#[derive(Parser, Debug, Serialize, Deserialize, Clone)]
717709
pub struct PacketLossOptions {
718710
/// Packet Loss fault enabled
@@ -938,10 +930,6 @@ pub struct RunCommonOptions {
938930
#[command(flatten)]
939931
pub jitter: JitterOptions,
940932

941-
// Dns Options
942-
#[command(flatten)]
943-
pub dns: DnsOptions,
944-
945933
// Packet Loss Options
946934
#[command(flatten)]
947935
pub packet_loss: PacketLossOptions,

fault-cli/src/config.rs

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ use crate::cli::LlmOptions;
1717
//use crate::cli::PacketDuplicationOptions;
1818
use crate::cli::PacketLossOptions;
1919
use crate::cli::RunCommonOptions;
20-
use crate::fault::content::ContentInjectSettings;
21-
use crate::fault::llm::openai::OpenAiInjector;
2220
use crate::fault::llm::openai::OpenAiSettings;
2321
use crate::fault::llm::openai::SlowStreamSettings;
2422
use crate::types::BandwidthUnit;
2523
use crate::types::DbCase;
2624
use crate::types::Direction;
25+
use crate::types::DnsCase;
2726
use crate::types::LatencyDistribution;
2827
use crate::types::LlmCase;
2928
use crate::types::ProtocolType;
@@ -78,11 +77,12 @@ pub struct JitterSettings {
7877
}
7978

8079
/// Internal Configuration for DNS Fault
81-
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq)]
80+
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
8281
pub struct DnsSettings {
83-
pub kind: FaultKind,
8482
pub enabled: bool,
85-
pub rate: f64, // between 0 and 1.0
83+
pub probability: f64,
84+
pub case: DnsCase,
85+
pub delay_ms: Option<Duration>,
8686
}
8787

8888
/// Internal Configuration for Packet Duplication Fault
@@ -139,7 +139,6 @@ pub struct LlmSettings {}
139139
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
140140
pub enum FaultConfig {
141141
// network
142-
Dns(DnsSettings),
143142
Latency(LatencySettings),
144143
PacketLoss(PacketLossSettings),
145144
Bandwidth(BandwidthSettings),
@@ -153,6 +152,9 @@ pub enum FaultConfig {
153152
PromptScramble(OpenAiSettings),
154153
InjectBias(OpenAiSettings),
155154
TruncateResponse(OpenAiSettings),
155+
156+
// dns
157+
Dns(DnsSettings),
156158
}
157159

158160
/// Implement Default manually for FaultConfig
@@ -165,7 +167,6 @@ impl Default for FaultConfig {
165167
impl fmt::Display for FaultConfig {
166168
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167169
match self {
168-
FaultConfig::Dns(_) => write!(f, "dns"),
169170
FaultConfig::Latency(_) => write!(f, "latency"),
170171
FaultConfig::PacketLoss(_) => write!(f, "packet-loss"),
171172
FaultConfig::Bandwidth(_) => write!(f, "bandwidth"),
@@ -181,14 +182,14 @@ impl fmt::Display for FaultConfig {
181182
write!(f, "llm-truncate-response")
182183
}
183184
FaultConfig::SlowStream(_) => write!(f, "llm-slow-stream"),
185+
FaultConfig::Dns(_) => write!(f, "dns"),
184186
}
185187
}
186188
}
187189

188190
impl FaultConfig {
189191
pub fn kind(&self) -> FaultKind {
190192
match self {
191-
FaultConfig::Dns(_) => FaultKind::Dns,
192193
FaultConfig::Latency(_) => FaultKind::Latency,
193194
FaultConfig::PacketLoss(_) => FaultKind::PacketLoss,
194195
FaultConfig::Bandwidth(_) => FaultKind::Bandwidth,
@@ -200,6 +201,7 @@ impl FaultConfig {
200201
FaultConfig::InjectBias(_) => FaultKind::InjectBias,
201202
FaultConfig::TruncateResponse(_) => FaultKind::TruncateResponse,
202203
FaultConfig::SlowStream(_) => FaultKind::SlowStream,
204+
FaultConfig::Dns(_) => FaultKind::Dns,
203205
}
204206
}
205207
}
@@ -212,7 +214,6 @@ pub enum FaultKind {
212214
Unknown,
213215

214216
// network
215-
Dns,
216217
Latency,
217218
PacketLoss,
218219
Bandwidth,
@@ -228,13 +229,15 @@ pub enum FaultKind {
228229
PromptScramble,
229230
InjectBias,
230231
TruncateResponse,
232+
233+
// dns
234+
Dns,
231235
}
232236

233237
impl fmt::Display for FaultKind {
234238
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235239
match self {
236240
FaultKind::Unknown => write!(f, "unknown"),
237-
FaultKind::Dns => write!(f, "dns"),
238241
FaultKind::Latency => write!(f, "latency"),
239242
FaultKind::PacketLoss => write!(f, "packet-loss"),
240243
FaultKind::Bandwidth => write!(f, "bandwidth"),
@@ -248,6 +251,7 @@ impl fmt::Display for FaultKind {
248251
FaultKind::InjectBias => write!(f, "inject-bias"),
249252
FaultKind::TruncateResponse => write!(f, "truncate-response"),
250253
FaultKind::SlowStream => write!(f, "slow-stream"),
254+
FaultKind::Dns => write!(f, "dns"),
251255
}
252256
}
253257
}
@@ -279,10 +283,6 @@ impl From<RunCommonOptions> for ProxyConfig {
279283
faults.push(FaultConfig::Bandwidth((&cli.bandwidth).into()));
280284
}
281285

282-
if cli.dns.enabled && cli.dns.dns_sched.is_none() {
283-
faults.push(FaultConfig::Dns((&cli.dns).into()));
284-
}
285-
286286
if cli.jitter.enabled && cli.jitter.jitter_sched.is_none() {
287287
faults.push(FaultConfig::Jitter((&cli.jitter).into()));
288288
}
@@ -360,16 +360,6 @@ impl From<&JitterOptions> for JitterSettings {
360360
}
361361
}
362362

363-
impl From<&DnsOptions> for DnsSettings {
364-
fn from(cli: &DnsOptions) -> Self {
365-
DnsSettings {
366-
enabled: cli.enabled,
367-
kind: FaultKind::Dns,
368-
rate: cli.dns_rate,
369-
}
370-
}
371-
}
372-
373363
impl From<&PacketLossOptions> for PacketLossSettings {
374364
fn from(cli: &PacketLossOptions) -> Self {
375365
PacketLossSettings {
@@ -526,3 +516,58 @@ impl From<(DbCase, &DbOptions)> for FaultConfig {
526516
}
527517
}
528518
}
519+
520+
impl From<(DnsCase, &DnsOptions)> for FaultConfig {
521+
fn from((case, options): (DnsCase, &DnsOptions)) -> Self {
522+
match case {
523+
DnsCase::NxDomain => FaultConfig::Dns(DnsSettings {
524+
enabled: true,
525+
probability: options.probability,
526+
case: DnsCase::NxDomain,
527+
delay_ms: options.delay,
528+
}),
529+
DnsCase::ServFail => FaultConfig::Dns(DnsSettings {
530+
enabled: true,
531+
probability: options.probability,
532+
case: DnsCase::ServFail,
533+
delay_ms: options.delay,
534+
}),
535+
DnsCase::Refused => FaultConfig::Dns(DnsSettings {
536+
enabled: true,
537+
probability: options.probability,
538+
case: DnsCase::Refused,
539+
delay_ms: options.delay,
540+
}),
541+
DnsCase::Timeout => FaultConfig::Dns(DnsSettings {
542+
enabled: true,
543+
probability: options.probability,
544+
case: DnsCase::Timeout,
545+
delay_ms: options.delay,
546+
}),
547+
DnsCase::Truncated => FaultConfig::Dns(DnsSettings {
548+
enabled: true,
549+
probability: options.probability,
550+
case: DnsCase::Truncated,
551+
delay_ms: options.delay,
552+
}),
553+
DnsCase::Delay => FaultConfig::Dns(DnsSettings {
554+
enabled: true,
555+
probability: options.probability,
556+
case: DnsCase::Delay,
557+
delay_ms: options.delay,
558+
}),
559+
DnsCase::RandomA => FaultConfig::Dns(DnsSettings {
560+
enabled: true,
561+
probability: options.probability,
562+
case: DnsCase::RandomA,
563+
delay_ms: options.delay,
564+
}),
565+
DnsCase::EmptyAnswer => FaultConfig::Dns(DnsSettings {
566+
enabled: true,
567+
probability: options.probability,
568+
case: DnsCase::EmptyAnswer,
569+
delay_ms: options.delay,
570+
}),
571+
}
572+
}
573+
}

fault-cli/src/event.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ pub enum FaultEvent {
407407
Dns {
408408
direction: Direction,
409409
side: StreamSide,
410+
case: String,
410411
triggered: Option<bool>,
411412
},
412413
Bandwidth {

0 commit comments

Comments
 (0)