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
use kitsune_p2p_timestamp::InclusiveTimestampInterval;
use kitsune_p2p_timestamp::Timestamp;
use std::sync::Arc;

#[derive(Clone)]
pub enum AgentSpaceBlockReason {
    BadCrypto,
}

#[derive(Clone, serde::Serialize, Debug, Eq, PartialEq, Hash)]
pub enum NodeBlockReason {
    /// The node did some bad cryptography.
    BadCrypto,
    /// DOS attack.
    DOS,
}

#[derive(Clone, serde::Serialize, Debug, Eq, PartialEq, Hash)]
pub enum NodeSpaceBlockReason {
    BadWire,
}

#[derive(Clone, serde::Serialize, Debug, Eq, PartialEq, Hash)]
pub enum IpBlockReason {
    /// Classic DOS.
    DOS,
}

pub type NodeId = Arc<[u8; 32]>;

#[derive(Clone, Eq, PartialEq, Hash)]
pub enum BlockTarget {
    Node(NodeId, NodeBlockReason),
    NodeSpace(
        NodeId,
        Arc<kitsune_p2p_bin_data::KitsuneSpace>,
        NodeSpaceBlockReason,
    ),
    Ip(std::net::Ipv4Addr, IpBlockReason),
}

pub enum BlockTargetId {
    Node(NodeId),
    NodeSpace(NodeId, Arc<kitsune_p2p_bin_data::KitsuneSpace>),
    Ip(std::net::Ipv4Addr),
}

impl From<BlockTarget> for BlockTargetId {
    fn from(block_target: BlockTarget) -> Self {
        match block_target {
            BlockTarget::NodeSpace(node_id, space, _) => Self::NodeSpace(node_id, space),
            BlockTarget::Node(node_id, _) => Self::Node(node_id),
            BlockTarget::Ip(ip_addr, _) => Self::Ip(ip_addr),
        }
    }
}

#[derive(Clone, Eq, PartialEq, Hash)]
pub struct Block {
    target: BlockTarget,
    interval: InclusiveTimestampInterval,
}

impl Block {
    pub fn new(target: BlockTarget, interval: InclusiveTimestampInterval) -> Self {
        Self { target, interval }
    }

    pub fn target(&self) -> &BlockTarget {
        &self.target
    }

    pub fn into_target(self) -> BlockTarget {
        self.target
    }

    pub fn into_interval(self) -> InclusiveTimestampInterval {
        self.interval
    }

    pub fn start(&self) -> Timestamp {
        self.interval.start()
    }

    pub fn end(&self) -> Timestamp {
        self.interval.end()
    }
}