Fix Gossip Pushes going to invalid addresses (#1858)
This commit is contained in:
parent
3822c29415
commit
07667771ef
|
@ -189,7 +189,7 @@ impl ClusterInfo {
|
||||||
.values()
|
.values()
|
||||||
.filter_map(|x| x.value.contact_info())
|
.filter_map(|x| x.value.contact_info())
|
||||||
.filter(|x| x.id != me)
|
.filter(|x| x.id != me)
|
||||||
.filter(|x| ClusterInfo::is_valid_address(&x.rpc))
|
.filter(|x| ContactInfo::is_valid_address(&x.rpc))
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ impl ClusterInfo {
|
||||||
.values()
|
.values()
|
||||||
.filter_map(|x| x.value.contact_info())
|
.filter_map(|x| x.value.contact_info())
|
||||||
.filter(|x| x.id != me)
|
.filter(|x| x.id != me)
|
||||||
.filter(|x| ClusterInfo::is_valid_address(&x.ncp))
|
.filter(|x| ContactInfo::is_valid_address(&x.ncp))
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ impl ClusterInfo {
|
||||||
.values()
|
.values()
|
||||||
.filter_map(|x| x.value.contact_info())
|
.filter_map(|x| x.value.contact_info())
|
||||||
.filter(|x| x.id != me)
|
.filter(|x| x.id != me)
|
||||||
.filter(|x| ClusterInfo::is_valid_address(&x.tvu))
|
.filter(|x| ContactInfo::is_valid_address(&x.tvu))
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ impl ClusterInfo {
|
||||||
.values()
|
.values()
|
||||||
.filter_map(|x| x.value.contact_info())
|
.filter_map(|x| x.value.contact_info())
|
||||||
.filter(|x| x.id != me)
|
.filter(|x| x.id != me)
|
||||||
.filter(|x| ClusterInfo::is_valid_address(&x.tpu))
|
.filter(|x| ContactInfo::is_valid_address(&x.tpu))
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -898,18 +898,6 @@ impl ClusterInfo {
|
||||||
}).unwrap()
|
}).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid_ip(addr: IpAddr) -> bool {
|
|
||||||
!(addr.is_unspecified() || addr.is_multicast())
|
|
||||||
// || (addr.is_loopback() && !cfg_test))
|
|
||||||
// TODO: boot loopback in production networks
|
|
||||||
}
|
|
||||||
/// port must not be 0
|
|
||||||
/// ip must be specified and not mulitcast
|
|
||||||
/// loopback ip is only allowed in tests
|
|
||||||
pub fn is_valid_address(addr: &SocketAddr) -> bool {
|
|
||||||
(addr.port() != 0) && Self::is_valid_ip(addr.ip())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spy_node() -> (NodeInfo, UdpSocket) {
|
pub fn spy_node() -> (NodeInfo, UdpSocket) {
|
||||||
let (_, gossip_socket) = bind_in_range(FULLNODE_PORT_RANGE).unwrap();
|
let (_, gossip_socket) = bind_in_range(FULLNODE_PORT_RANGE).unwrap();
|
||||||
let pubkey = Keypair::new().pubkey();
|
let pubkey = Keypair::new().pubkey();
|
||||||
|
@ -1057,6 +1045,29 @@ mod tests {
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use window::default_window;
|
use window::default_window;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cluster_spy_gossip() {
|
||||||
|
//check that gossip doesn't try to push to invalid addresses
|
||||||
|
let node = Node::new_localhost();
|
||||||
|
let (spy, _) = ClusterInfo::spy_node();
|
||||||
|
let cluster_info = Arc::new(RwLock::new(
|
||||||
|
ClusterInfo::new(node.info).expect("ClusterInfo::new"),
|
||||||
|
));
|
||||||
|
cluster_info.write().unwrap().insert_info(spy);
|
||||||
|
cluster_info
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.gossip
|
||||||
|
.refresh_push_active_set();
|
||||||
|
let reqs = cluster_info.write().unwrap().gossip_request();
|
||||||
|
//assert none of the addrs are invalid.
|
||||||
|
reqs.iter().all(|(addr, _)| {
|
||||||
|
let res = ContactInfo::is_valid_address(addr);
|
||||||
|
assert!(res);
|
||||||
|
res
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cluster_info_new() {
|
fn test_cluster_info_new() {
|
||||||
let d = NodeInfo::new_localhost(Keypair::new().pubkey(), timestamp());
|
let d = NodeInfo::new_localhost(Keypair::new().pubkey(), timestamp());
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
use bincode::serialized_size;
|
use bincode::serialized_size;
|
||||||
use bloom::Bloom;
|
use bloom::Bloom;
|
||||||
|
use contact_info::ContactInfo;
|
||||||
use crds::{Crds, VersionedCrdsValue};
|
use crds::{Crds, VersionedCrdsValue};
|
||||||
use crds_gossip_error::CrdsGossipError;
|
use crds_gossip_error::CrdsGossipError;
|
||||||
use crds_value::{CrdsValue, CrdsValueLabel};
|
use crds_value::{CrdsValue, CrdsValueLabel};
|
||||||
|
@ -177,6 +178,11 @@ impl CrdsGossipPush {
|
||||||
if new_items.get(&val.0.pubkey()).is_some() {
|
if new_items.get(&val.0.pubkey()).is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if let Some(contact) = val.1.value.contact_info() {
|
||||||
|
if !ContactInfo::is_valid_address(&contact.ncp) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
let bloom = Bloom::random(network_size, 0.1, 1024 * 8 * 4);
|
let bloom = Bloom::random(network_size, 0.1, 1024 * 8 * 4);
|
||||||
new_items.insert(val.0.pubkey(), bloom);
|
new_items.insert(val.0.pubkey(), bloom);
|
||||||
if new_items.len() == need {
|
if new_items.len() == need {
|
||||||
|
|
|
@ -8,6 +8,7 @@ extern crate solana_sdk;
|
||||||
|
|
||||||
use solana::blob_fetch_stage::BlobFetchStage;
|
use solana::blob_fetch_stage::BlobFetchStage;
|
||||||
use solana::cluster_info::{ClusterInfo, Node, NodeInfo};
|
use solana::cluster_info::{ClusterInfo, Node, NodeInfo};
|
||||||
|
use solana::contact_info::ContactInfo;
|
||||||
use solana::entry::{reconstruct_entries_from_blobs, Entry};
|
use solana::entry::{reconstruct_entries_from_blobs, Entry};
|
||||||
use solana::fullnode::{Fullnode, FullnodeReturnType};
|
use solana::fullnode::{Fullnode, FullnodeReturnType};
|
||||||
use solana::leader_scheduler::{make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig};
|
use solana::leader_scheduler::{make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig};
|
||||||
|
@ -1621,7 +1622,7 @@ fn test_broadcast_last_tick() {
|
||||||
|
|
||||||
fn mk_client(leader: &NodeInfo) -> ThinClient {
|
fn mk_client(leader: &NodeInfo) -> ThinClient {
|
||||||
let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap();
|
||||||
assert!(ClusterInfo::is_valid_address(&leader.tpu));
|
assert!(ContactInfo::is_valid_address(&leader.tpu));
|
||||||
ThinClient::new(leader.rpc, leader.tpu, transactions_socket)
|
ThinClient::new(leader.rpc, leader.tpu, transactions_socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue