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
crate::ix!();
pub trait MaybeDiscourageAndDisconnect {
fn maybe_discourage_and_disconnect(self: Arc<Self>,
pnode: Amo<Box<dyn NodeInterface>>,
peer: &mut Peer) -> bool;
}
impl MaybeDiscourageAndDisconnect for PeerManager {
/**
| Maybe disconnect a peer and discourage
| future connections from its address.
|
| -----------
| @param[in] pnode
|
| The node to check.
| ----------
| @param[in] peer
|
| The peer object to check.
|
| -----------
| @return
|
| True if the peer was marked for disconnection
| in this function
|
*/
fn maybe_discourage_and_disconnect(self: Arc<Self>,
pnode: Amo<Box<dyn NodeInterface>>,
peer: &mut Peer) -> bool {
{
let mut guard = peer.misbehavior.lock();
// There's nothing to do if the
// m_should_discourage flag isn't set
if !guard.should_discourage {
return false;
}
guard.should_discourage = false;
}
if pnode.get().has_permission(NetPermissionFlags::NoBan) {
// We never disconnect or discourage
// peers for bad behavior if they have
// NetPermissionFlags::NoBan
// permission
log_printf!(
"Warning: not punishing noban peer %d!\n",
peer.id
);
return false;
}
if pnode.get().is_manual_conn() {
// We never disconnect or discourage
// manual peers for bad behavior
log_printf!(
"Warning: not punishing manually connected peer %d!\n",
peer.id
);
return false;
}
if pnode.get().addr().is_local() {
// We disconnect local peers for bad
// behavior but don't discourage
// (since that would discourage all
// peers on the same local address)
log_print!(
LogFlags::NET,
"Warning: disconnecting but not discouraging %s peer %d!\n",
match pnode.inbound_onion {
true => "inbound onion",
false => "local"
},
peer.id
);
pnode.get().mark_for_disconnect();
return true;
}
// Normal case: Disconnect the peer and
// discourage all nodes sharing the
// address
log_print!(
LogFlags::NET,
"Disconnecting and discouraging peer %d!\n",
peer.id
);
if self.banman.is_some() {
self.banman.get_mut().discourage(&pnode.get().service().base);
}
let node = pnode.get();
let netaddr = &node.service().base;
self.connman.get_mut()
.disconnect_node_with_netaddr(netaddr);
true
}
}