#[cfg(feature = "circ-padding")]
use {crate::circuit::cell_sender::CircuitCellSender, crate::client::circuit::padding};
#[derive(Copy, Clone, Debug)]
pub(crate) enum CircPaddingDisposition {
QueuePaddingNormally,
QueuePaddingAndBypass,
TreatQueuedCellAsPadding,
}
#[cfg(feature = "circ-padding")]
pub(crate) fn padding_disposition(
send_padding: &padding::SendPadding,
chan_sender: &CircuitCellSender,
padding_block: Option<&padding::StartBlocking>,
) -> CircPaddingDisposition {
use CircPaddingDisposition::*;
use padding::Bypass::*;
use padding::Replace::*;
let have_queued_cell_for_hop = chan_sender.have_queued_cell_for_hop_or_later(send_padding.hop);
match padding_block {
Some(blocking) if blocking.is_bypassable => {
match (
send_padding.may_replace_with_data(),
send_padding.may_bypass_block(),
) {
(NotReplaceable, DoNotBypass) => QueuePaddingNormally,
(NotReplaceable, BypassBlocking) => QueuePaddingAndBypass,
(Replaceable, DoNotBypass) => {
if have_queued_cell_for_hop {
TreatQueuedCellAsPadding
} else {
QueuePaddingNormally
}
}
(Replaceable, BypassBlocking) => {
if have_queued_cell_for_hop {
TreatQueuedCellAsPadding
} else {
QueuePaddingAndBypass
}
}
}
}
Some(_) | None => match send_padding.may_replace_with_data() {
Replaceable => {
if have_queued_cell_for_hop {
TreatQueuedCellAsPadding
} else {
QueuePaddingNormally
}
}
NotReplaceable => QueuePaddingNormally,
},
}
}