client(datastore): mark peers not returned by server as disabled

pull/76/head
Jake McGinty 2021-05-10 00:02:03 +09:00
parent 9d4eb80177
commit 88ae2aba17
2 changed files with 18 additions and 9 deletions

View File

@ -86,22 +86,31 @@ impl DataStore {
/// ///
/// Note, however, that this does not prevent a compromised server from adding a new /// Note, however, that this does not prevent a compromised server from adding a new
/// peer under its control, of course. /// peer under its control, of course.
pub fn add_peers(&mut self, new_peers: Vec<Peer>) -> Result<(), Error> { pub fn update_peers(&mut self, current_peers: Vec<Peer>) -> Result<(), Error> {
let peers = match &mut self.contents { let peers = match &mut self.contents {
Contents::V1 { ref mut peers, .. } => peers, Contents::V1 { ref mut peers, .. } => peers,
}; };
for new_peer in new_peers { for new_peer in current_peers.iter() {
if let Some(existing_peer) = peers.iter_mut().find(|p| p.ip == new_peer.ip) { if let Some(existing_peer) = peers.iter_mut().find(|p| p.ip == new_peer.ip) {
if existing_peer.public_key != new_peer.public_key { if existing_peer.public_key != new_peer.public_key {
return Err( return Err(
"PINNING ERROR: New peer has same IP but different public key.".into(), "PINNING ERROR: New peer has same IP but different public key.".into(),
); );
} else { } else {
*existing_peer = new_peer; *existing_peer = new_peer.clone();
} }
} else { } else {
peers.push(new_peer); peers.push(new_peer.clone());
}
}
for existing_peer in peers.iter_mut() {
if !current_peers
.iter()
.any(|p| p.public_key == existing_peer.public_key)
{
existing_peer.contents.is_disabled = true;
} }
} }
@ -166,7 +175,7 @@ mod tests {
assert_eq!(0, store.peers().len()); assert_eq!(0, store.peers().len());
assert_eq!(0, store.cidrs().len()); assert_eq!(0, store.cidrs().len());
store.add_peers(BASE_PEERS.to_owned()).unwrap(); store.update_peers(BASE_PEERS.to_owned()).unwrap();
store.set_cidrs(BASE_CIDRS.to_owned()); store.set_cidrs(BASE_CIDRS.to_owned());
store.write().unwrap(); store.write().unwrap();
} }
@ -188,13 +197,13 @@ mod tests {
DataStore::open_with_path(&dir.path().join("peer_store.json"), false).unwrap(); DataStore::open_with_path(&dir.path().join("peer_store.json"), false).unwrap();
// Should work, since peer is unmodified. // Should work, since peer is unmodified.
store.add_peers(BASE_PEERS.clone()).unwrap(); store.update_peers(BASE_PEERS.clone()).unwrap();
let mut modified = BASE_PEERS.clone(); let mut modified = BASE_PEERS.clone();
modified[0].contents.public_key = "foo".to_string(); modified[0].contents.public_key = "foo".to_string();
// Should NOT work, since peer is unmodified. // Should NOT work, since peer is unmodified.
assert!(store.add_peers(modified).is_err()); assert!(store.update_peers(modified).is_err());
} }
#[test] #[test]
@ -205,7 +214,7 @@ mod tests {
DataStore::open_with_path(&dir.path().join("peer_store.json"), false).unwrap(); DataStore::open_with_path(&dir.path().join("peer_store.json"), false).unwrap();
// Should work, since peer is unmodified. // Should work, since peer is unmodified.
store.add_peers(vec![]).unwrap(); store.update_peers(vec![]).unwrap();
assert_eq!(store.peers(), &*BASE_PEERS); assert_eq!(store.peers(), &*BASE_PEERS);
} }
} }

View File

@ -474,7 +474,7 @@ fn fetch(
println!("{}", " peers are already up to date.".green()); println!("{}", " peers are already up to date.".green());
} }
store.set_cidrs(cidrs); store.set_cidrs(cidrs);
store.add_peers(peers)?; store.update_peers(peers)?;
store.write()?; store.write()?;
Ok(()) Ok(())