Include only addresses with known working connections
This commit is contained in:
parent
1129d5b6e6
commit
1fa05837fb
2 changed files with 61 additions and 47 deletions
|
|
@ -846,7 +846,17 @@ impl TorrentStateLive {
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let mut sent_peers_live: HashSet<SocketAddr> = HashSet::new();
|
let mut sent_peers_live: HashSet<SocketAddr> = HashSet::new();
|
||||||
const MAX_SENT_PEERS: usize = 50; // As per BEP 11 we should not send more than 50 peers at once (here it also applies to fist message, should be OK as we anyhow really have more)
|
const MAX_SENT_PEERS: usize = 50; // As per BEP 11 we should not send more than 50 peers at once (here it also applies to fist message, should be OK as we anyhow really have more)
|
||||||
|
const PEX_MESSAGE_INTERVAL: Duration = Duration::from_secs(60); // As per BEP 11 recommended interval is min 60 seconds
|
||||||
|
let mut delay = Duration::from_secs(10); // Wait 10 seconds before sending the first message to assure that peer will stay with us
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
tokio::select! {
|
||||||
|
_ = tx.closed() => return Ok(()),
|
||||||
|
_ = tokio::time::sleep(delay) => {},
|
||||||
|
|
||||||
|
}
|
||||||
|
delay = PEX_MESSAGE_INTERVAL;
|
||||||
|
|
||||||
let addrs_live_to_sent = self
|
let addrs_live_to_sent = self
|
||||||
.peers
|
.peers
|
||||||
.states
|
.states
|
||||||
|
|
@ -856,7 +866,16 @@ impl TorrentStateLive {
|
||||||
let addr = peer.outgoing_address.as_ref().unwrap_or_else(|| e.key());
|
let addr = peer.outgoing_address.as_ref().unwrap_or_else(|| e.key());
|
||||||
|
|
||||||
if *addr != peer_addr {
|
if *addr != peer_addr {
|
||||||
if peer.state.is_live() && !sent_peers_live.contains(addr) {
|
let has_outgoing_connections = peer
|
||||||
|
.stats
|
||||||
|
.counters
|
||||||
|
.outgoing_connections
|
||||||
|
.load(Ordering::Relaxed)
|
||||||
|
> 0; // As per BEP 11 share only those we were able to connect
|
||||||
|
if peer.state.is_live()
|
||||||
|
&& has_outgoing_connections
|
||||||
|
&& !sent_peers_live.contains(addr)
|
||||||
|
{
|
||||||
Some(*addr)
|
Some(*addr)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -886,23 +905,16 @@ impl TorrentStateLive {
|
||||||
// and addrs_closed_to_sent are only filtered addresses from sent_peers_live
|
// and addrs_closed_to_sent are only filtered addresses from sent_peers_live
|
||||||
|
|
||||||
if !addrs_live_to_sent.is_empty() || !addrs_closed_to_sent.is_empty() {
|
if !addrs_live_to_sent.is_empty() || !addrs_closed_to_sent.is_empty() {
|
||||||
let pex_msg = extended::ut_pex::UtPex::from_addrs(&addrs_live_to_sent, &addrs_closed_to_sent);
|
debug!(peer=?peer_addr, "sending PEX with {} live ({:?})and {} closed peers", addrs_live_to_sent.len(), addrs_live_to_sent,addrs_closed_to_sent.len());
|
||||||
|
let pex_msg =
|
||||||
|
extended::ut_pex::UtPex::from_addrs(&addrs_live_to_sent, &addrs_closed_to_sent);
|
||||||
let ext_msg = extended::ExtendedMessage::UtPex(pex_msg);
|
let ext_msg = extended::ExtendedMessage::UtPex(pex_msg);
|
||||||
let msg = Message::Extended(ext_msg);
|
let msg = Message::Extended(ext_msg);
|
||||||
|
|
||||||
tx.send(WriterRequest::Message(msg))?;
|
if tx.send(WriterRequest::Message(msg)).is_ok() {
|
||||||
|
sent_peers_live.extend(&addrs_live_to_sent);
|
||||||
debug!(peer=?peer_addr, "sending PEX with {} live and {} closed peers", addrs_live_to_sent.len(), addrs_closed_to_sent.len());
|
sent_peers_live.retain(|addr| !addrs_closed_to_sent.contains(addr));
|
||||||
sent_peers_live.extend(&addrs_live_to_sent);
|
}
|
||||||
sent_peers_live.retain(|addr| !addrs_closed_to_sent.contains(addr));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
tokio::select! {
|
|
||||||
_ = tx.closed() => return Ok(()),
|
|
||||||
_ = tokio::time::sleep(Duration::from_secs(60)) => {},
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,42 +123,44 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UtPex<ByteBufOwned> {
|
impl UtPex<ByteBufOwned> {
|
||||||
|
pub fn from_addrs<'a, I, J>(addrs_live: I, addrs_closed: J) -> Self
|
||||||
pub fn from_addrs<'a, I,J>(addrs_live: I, addrs_closed: J) -> Self
|
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = &'a SocketAddr>,
|
I: IntoIterator<Item = &'a SocketAddr>,
|
||||||
J: IntoIterator<Item = &'a SocketAddr>,
|
J: IntoIterator<Item = &'a SocketAddr>,
|
||||||
{
|
{
|
||||||
|
fn addrs_to_bytes<'a, I>(addrs: I) -> (Option<ByteBufOwned>, Option<ByteBufOwned>)
|
||||||
|
|
||||||
fn addrs_to_bytes<'a,I>(addrs: I) -> (Option<ByteBufOwned>, Option<ByteBufOwned>)
|
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = &'a SocketAddr>,
|
I: IntoIterator<Item = &'a SocketAddr>,
|
||||||
{
|
{
|
||||||
let mut ipv4_addrs = BytesMut::new();
|
let mut ipv4_addrs = BytesMut::new();
|
||||||
let mut ipv6_addrs = BytesMut::new();
|
let mut ipv6_addrs = BytesMut::new();
|
||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
match addr {
|
match addr {
|
||||||
SocketAddr::V4(v4) => {
|
SocketAddr::V4(v4) => {
|
||||||
ipv4_addrs.extend_from_slice(&v4.ip().octets());
|
ipv4_addrs.extend_from_slice(&v4.ip().octets());
|
||||||
ipv4_addrs.extend_from_slice(&v4.port().to_be_bytes());
|
ipv4_addrs.extend_from_slice(&v4.port().to_be_bytes());
|
||||||
}
|
}
|
||||||
SocketAddr::V6(v6) => {
|
SocketAddr::V6(v6) => {
|
||||||
ipv6_addrs.extend_from_slice(&v6.ip().octets());
|
ipv6_addrs.extend_from_slice(&v6.ip().octets());
|
||||||
ipv6_addrs.extend_from_slice(&v6.port().to_be_bytes());
|
ipv6_addrs.extend_from_slice(&v6.port().to_be_bytes());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let freeze = |buf: BytesMut| -> Option<ByteBufOwned> {
|
||||||
|
if !buf.is_empty() {
|
||||||
|
Some(buf.freeze().into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(freeze(ipv4_addrs), freeze(ipv6_addrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
let freeze = |buf: BytesMut| -> Option<ByteBufOwned> { if !buf.is_empty() {Some(buf.freeze().into())} else {None} };
|
|
||||||
|
|
||||||
(freeze(ipv4_addrs), freeze(ipv6_addrs))
|
|
||||||
}
|
|
||||||
|
|
||||||
let (added, added6) = addrs_to_bytes(addrs_live);
|
let (added, added6) = addrs_to_bytes(addrs_live);
|
||||||
let (dropped, dropped6) = addrs_to_bytes(addrs_closed);
|
let (dropped, dropped6) = addrs_to_bytes(addrs_closed);
|
||||||
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
added,
|
added,
|
||||||
added6,
|
added6,
|
||||||
|
|
@ -166,9 +168,7 @@ impl UtPex<ByteBufOwned> {
|
||||||
dropped6,
|
dropped6,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -210,8 +210,12 @@ mod tests {
|
||||||
let a1 = "185.159.157.20:46439".parse::<SocketAddr>().unwrap();
|
let a1 = "185.159.157.20:46439".parse::<SocketAddr>().unwrap();
|
||||||
let a2 = "151.249.105.134:4240".parse::<SocketAddr>().unwrap();
|
let a2 = "151.249.105.134:4240".parse::<SocketAddr>().unwrap();
|
||||||
//IPV6
|
//IPV6
|
||||||
let aa1 = "[5be8:dde9:7f0b:d5a7:bd01:b3be:9c69:573b]:46439".parse::<SocketAddr>().unwrap();
|
let aa1 = "[5be8:dde9:7f0b:d5a7:bd01:b3be:9c69:573b]:46439"
|
||||||
let aa2 = "[f16c:f7ec:cfa2:e1c5:9a3c:cb08:801f:36b8]:4240".parse::<SocketAddr>().unwrap();
|
.parse::<SocketAddr>()
|
||||||
|
.unwrap();
|
||||||
|
let aa2 = "[f16c:f7ec:cfa2:e1c5:9a3c:cb08:801f:36b8]:4240"
|
||||||
|
.parse::<SocketAddr>()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let addrs = vec![a1, aa1, a2, aa2];
|
let addrs = vec![a1, aa1, a2, aa2];
|
||||||
let pex = UtPex::from_addrs(&addrs, &addrs);
|
let pex = UtPex::from_addrs(&addrs, &addrs);
|
||||||
|
|
@ -230,7 +234,5 @@ mod tests {
|
||||||
assert_eq!(a2, addrs2[1].addr);
|
assert_eq!(a2, addrs2[1].addr);
|
||||||
assert_eq!(aa1, addrs2[2].addr);
|
assert_eq!(aa1, addrs2[2].addr);
|
||||||
assert_eq!(aa2, addrs2[3].addr);
|
assert_eq!(aa2, addrs2[3].addr);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue