Fix concurrency issue around peer add and start. Fixes #1585 (#1633)

* Fix concurrency issue around peer add and start. Fixes #1585
This commit is contained in:
Ignotus Peverell 2018-10-02 07:17:29 -07:00 committed by Quentin Le Sceller
parent 0cb228d4e9
commit 85d5feafa3
2 changed files with 30 additions and 24 deletions

View file

@ -56,25 +56,29 @@ impl Peers {
/// Adds the peer to our internal peer mapping. Note that the peer is still /// Adds the peer to our internal peer mapping. Note that the peer is still
/// returned so the server can run it. /// returned so the server can run it.
pub fn add_connected(&self, p: Peer) -> Result<Arc<RwLock<Peer>>, Error> { pub fn add_connected(&self, peer: Arc<RwLock<Peer>>) -> Result<(), Error> {
debug!(LOGGER, "Saving newly connected peer {}.", p.info.addr); let peer_data: PeerData;
let peer_data = PeerData { let addr: SocketAddr;
addr: p.info.addr, {
capabilities: p.info.capabilities, let p = peer.read().unwrap();
user_agent: p.info.user_agent.clone(), peer_data = PeerData {
flags: State::Healthy, addr: p.info.addr,
last_banned: 0, capabilities: p.info.capabilities,
ban_reason: ReasonForBan::None, user_agent: p.info.user_agent.clone(),
}; flags: State::Healthy,
last_banned: 0,
ban_reason: ReasonForBan::None,
};
addr = p.info.addr.clone();
}
debug!(LOGGER, "Saving newly connected peer {}.", addr);
self.save_peer(&peer_data)?; self.save_peer(&peer_data)?;
let addr = p.info.addr.clone();
let apeer = Arc::new(RwLock::new(p));
{ {
let mut peers = self.peers.write().unwrap(); let mut peers = self.peers.write().unwrap();
peers.insert(addr, apeer.clone()); peers.insert(addr, peer.clone());
} }
Ok(apeer) Ok(())
} }
// Update the dandelion relay // Update the dandelion relay

View file

@ -178,20 +178,20 @@ impl Server {
let addr = SocketAddr::new(self.config.host, self.config.port); let addr = SocketAddr::new(self.config.host, self.config.port);
let total_diff = self.peers.total_difficulty(); let total_diff = self.peers.total_difficulty();
let peer = Peer::connect( let peer = Arc::new(RwLock::new(Peer::connect(
&mut stream, &mut stream,
self.capabilities, self.capabilities,
total_diff, total_diff,
addr, addr,
&self.handshake, &self.handshake,
self.peers.clone(), self.peers.clone(),
)?; )?));
let added = self.peers.add_connected(peer)?;
{ {
let mut peer = added.write().unwrap(); let mut peer = peer.write().unwrap();
peer.start(stream); peer.start(stream);
} }
Ok(added) self.peers.add_connected(peer.clone())?;
Ok(peer)
} }
Err(e) => { Err(e) => {
debug!( debug!(
@ -211,16 +211,18 @@ impl Server {
let total_diff = self.peers.total_difficulty(); let total_diff = self.peers.total_difficulty();
// accept the peer and add it to the server map // accept the peer and add it to the server map
let peer = Peer::accept( let peer = Arc::new(RwLock::new(Peer::accept(
&mut stream, &mut stream,
self.capabilities, self.capabilities,
total_diff, total_diff,
&self.handshake, &self.handshake,
self.peers.clone(), self.peers.clone(),
)?; )?));
let added = self.peers.add_connected(peer)?; {
let mut peer = added.write().unwrap(); let mut peer = peer.write().unwrap();
peer.start(stream); peer.start(stream);
}
self.peers.add_connected(peer)?;
Ok(()) Ok(())
} }