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
132
133
134
135
136
137
138
use crate::peer_store::{Score, SessionType, ADDR_MAX_FAILURES, ADDR_MAX_RETRIES, ADDR_TIMEOUT_MS};
use ipnetwork::IpNetwork;
use p2p::multiaddr::{Multiaddr, Protocol};
use serde::{Deserialize, Serialize};
use std::net::IpAddr;
#[derive(Debug, Clone)]
pub struct PeerInfo {
pub connected_addr: Multiaddr,
pub session_type: SessionType,
pub last_connected_at_ms: u64,
}
impl PeerInfo {
pub fn new(
connected_addr: Multiaddr,
session_type: SessionType,
last_connected_at_ms: u64,
) -> Self {
PeerInfo {
connected_addr,
session_type,
last_connected_at_ms,
}
}
}
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct AddrInfo {
pub addr: Multiaddr,
pub score: Score,
pub last_connected_at_ms: u64,
pub last_tried_at_ms: u64,
pub attempts_count: u32,
pub random_id_pos: usize,
}
impl AddrInfo {
pub fn new(addr: Multiaddr, last_connected_at_ms: u64, score: Score) -> Self {
AddrInfo {
addr,
score,
last_connected_at_ms,
last_tried_at_ms: 0,
attempts_count: 0,
random_id_pos: 0,
}
}
pub fn had_connected(&self, expires_ms: u64) -> bool {
self.last_connected_at_ms > expires_ms
}
pub fn tried_in_last_minute(&self, now_ms: u64) -> bool {
self.last_tried_at_ms >= now_ms.saturating_sub(60_000)
}
pub fn is_terrible(&self, now_ms: u64) -> bool {
if self.tried_in_last_minute(now_ms) {
return false;
}
if self.last_connected_at_ms == 0 && self.attempts_count >= ADDR_MAX_RETRIES {
return true;
}
if now_ms.saturating_sub(self.last_connected_at_ms) > ADDR_TIMEOUT_MS
&& (self.attempts_count >= ADDR_MAX_FAILURES)
{
return true;
}
false
}
pub fn mark_tried(&mut self, tried_at_ms: u64) {
self.last_tried_at_ms = tried_at_ms;
self.attempts_count = self.attempts_count.saturating_add(1);
}
pub fn mark_connected(&mut self, connected_at_ms: u64) {
self.last_connected_at_ms = connected_at_ms;
self.attempts_count = 0;
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct BannedAddr {
pub address: IpNetwork,
pub ban_until: u64,
pub ban_reason: String,
pub created_at: u64,
}
pub fn multiaddr_to_ip_network(multiaddr: &Multiaddr) -> Option<IpNetwork> {
for addr_component in multiaddr {
match addr_component {
Protocol::IP4(ipv4) => return Some(IpNetwork::V4(ipv4.into())),
Protocol::IP6(ipv6) => return Some(IpNetwork::V6(ipv6.into())),
_ => (),
}
}
None
}
pub fn ip_to_network(ip: IpAddr) -> IpNetwork {
match ip {
IpAddr::V4(ipv4) => IpNetwork::V4(ipv4.into()),
IpAddr::V6(ipv6) => IpNetwork::V6(ipv6.into()),
}
}