Improved peer reconnection code.
This commit is contained in:
@@ -177,7 +177,7 @@ impl Blockchain {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_domain_info(&self, domain: &str) -> Option<String> {
|
pub fn get_domain_transaction(&self, domain: &str) -> Option<Transaction> {
|
||||||
if domain.is_empty() {
|
if domain.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -193,14 +193,21 @@ impl Blockchain {
|
|||||||
let pub_key = Bytes::from_bytes(statement.read::<Vec<u8>>(5).unwrap().as_slice());
|
let pub_key = Bytes::from_bytes(statement.read::<Vec<u8>>(5).unwrap().as_slice());
|
||||||
let signature = Bytes::from_bytes(statement.read::<Vec<u8>>(6).unwrap().as_slice());
|
let signature = Bytes::from_bytes(statement.read::<Vec<u8>>(6).unwrap().as_slice());
|
||||||
let transaction = Transaction { identity, confirmation, method, data, pub_key, signature };
|
let transaction = Transaction { identity, confirmation, method, data, pub_key, signature };
|
||||||
debug!("Got transaction: {:?}", &transaction);
|
debug!("Found transaction for domain {}: {:?}", domain, &transaction);
|
||||||
if transaction.check_for(domain) {
|
if transaction.check_for(domain) {
|
||||||
return Some(transaction.data);
|
return Some(transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_domain_info(&self, domain: &str) -> Option<String> {
|
||||||
|
match self.get_domain_transaction(domain) {
|
||||||
|
None => { None }
|
||||||
|
Some(transaction) => { Some(transaction.data) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn last_block(&self) -> Option<Block> {
|
pub fn last_block(&self) -> Option<Block> {
|
||||||
self.last_block.clone()
|
self.last_block.clone()
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-2
@@ -248,10 +248,23 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
|||||||
let guard = context.lock().unwrap();
|
let guard = context.lock().unwrap();
|
||||||
guard.get_keystore()
|
guard.get_keystore()
|
||||||
};
|
};
|
||||||
create_domain(miner.clone(), name, records, &keystore);
|
let transaction = { context.lock().unwrap().blockchain.get_domain_transaction(&name) };
|
||||||
|
match transaction {
|
||||||
|
None => {
|
||||||
|
create_domain(miner.clone(), name, records, &keystore);
|
||||||
|
}
|
||||||
|
Some(transaction) => {
|
||||||
|
if transaction.pub_key == keystore.get_public() {
|
||||||
|
create_domain(miner.clone(), name, records, &keystore);
|
||||||
|
} else {
|
||||||
|
warn!("Tried to mine not owned domain!");
|
||||||
|
let _ = web_view.eval(&format!("showWarning('{}');", "You cannot change domain that you don't own!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!("Error in DNS records for domain!");
|
warn!("Error in DNS records for domain!");
|
||||||
web_view.eval(&format!("showWarning('{}');", "Something wrong with your records! Please, correct the error and try again."));
|
let _ = web_view.eval(&format!("showWarning('{}');", "Something wrong with your records! Please, correct the error and try again."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ChangeDomain { .. } => {}
|
ChangeDomain { .. } => {}
|
||||||
|
|||||||
+8
-32
@@ -88,28 +88,8 @@ impl Network {
|
|||||||
poll.registry().reregister(&mut server, SERVER, Interest::READABLE).expect("Error reregistering server");
|
poll.registry().reregister(&mut server, SERVER, Interest::READABLE).expect("Error reregistering server");
|
||||||
}
|
}
|
||||||
token => {
|
token => {
|
||||||
match peers.get_mut_peer(&token) {
|
if !handle_connection_event(context.clone(), &mut peers, &poll.registry(), &event) {
|
||||||
Some(_peer) => {
|
let _ = peers.close_peer(poll.registry(), &token);
|
||||||
match handle_connection_event(context.clone(), &mut peers, &poll.registry(), &event) {
|
|
||||||
Ok(result) => {
|
|
||||||
if !result {
|
|
||||||
match peers.remove_peer(&token) {
|
|
||||||
None => {}
|
|
||||||
Some(mut peer) => {
|
|
||||||
let stream = peer.get_stream();
|
|
||||||
let _ = poll.registry().deregister(stream);
|
|
||||||
let _ = stream.shutdown(Shutdown::Both);
|
|
||||||
info!("Peer connection {:?} has shut down", &peer.get_addr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_err) => {
|
|
||||||
peers.remove_peer(&token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => { warn!("Odd event from poll"); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,9 +106,9 @@ impl Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, registry: &Registry, event: &Event) -> io::Result<bool> {
|
fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, registry: &Registry, event: &Event) -> bool {
|
||||||
if event.is_error() || (event.is_read_closed() && event.is_write_closed()) {
|
if event.is_error() || (event.is_read_closed() && event.is_write_closed()) {
|
||||||
return Ok(false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.is_readable() {
|
if event.is_readable() {
|
||||||
@@ -168,14 +148,10 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => { return Ok(false); }
|
Err(_) => { return false; }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Try to reregister connection
|
return false;
|
||||||
let peer = peers.get_mut_peer(&event.token()).expect("Error getting peer for connection");
|
|
||||||
let mut stream = peer.get_stream();
|
|
||||||
registry.reregister(stream, event.token(), Interest::READABLE);
|
|
||||||
return Ok(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +196,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_message(stream: &mut TcpStream) -> Result<Vec<u8>, ()> {
|
fn read_message(stream: &mut TcpStream) -> Result<Vec<u8>, ()> {
|
||||||
@@ -233,7 +209,7 @@ fn read_message(stream: &mut TcpStream) -> Result<Vec<u8>, ()> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
trace!("Payload size is {}", data_size);
|
trace!("Payload size is {}", data_size);
|
||||||
if data_size > MAX_PACKET_SIZE {
|
if data_size > MAX_PACKET_SIZE || data_size == 0 {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ impl Peer {
|
|||||||
&mut self.stream
|
&mut self.stream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_stream(&mut self, stream: TcpStream) {
|
||||||
|
self.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_state(&self) -> &State {
|
pub fn get_state(&self) -> &State {
|
||||||
&self.state
|
&self.state
|
||||||
}
|
}
|
||||||
@@ -48,6 +52,10 @@ impl Peer {
|
|||||||
self.state.disabled()
|
self.state.disabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_inbound(&self) -> bool {
|
||||||
|
self.inbound
|
||||||
|
}
|
||||||
|
|
||||||
/// If loopback address then we care about ip and port.
|
/// If loopback address then we care about ip and port.
|
||||||
/// If regular address then we only care about the ip and ignore the port.
|
/// If regular address then we only care about the ip and ignore the port.
|
||||||
pub fn equals(&self, addr: &SocketAddr) -> bool {
|
pub fn equals(&self, addr: &SocketAddr) -> bool {
|
||||||
|
|||||||
+58
-4
@@ -1,5 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::SocketAddr;
|
use std::net::{SocketAddr, Shutdown};
|
||||||
use mio::{Token, Interest, Registry};
|
use mio::{Token, Interest, Registry};
|
||||||
use mio::net::TcpStream;
|
use mio::net::TcpStream;
|
||||||
use crate::p2p::{Peer, State, Message};
|
use crate::p2p::{Peer, State, Message};
|
||||||
@@ -32,8 +32,23 @@ impl Peers {
|
|||||||
self.peers.get_mut(token)
|
self.peers.get_mut(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_peer(&mut self, token: &Token) -> Option<Peer> {
|
pub fn close_peer(&mut self, registry: &Registry, token: &Token) {
|
||||||
self.peers.remove(token)
|
let mut peer = self.peers.get_mut(token);
|
||||||
|
match peer {
|
||||||
|
Some(mut peer) => {
|
||||||
|
let mut stream = peer.get_stream();
|
||||||
|
let _ = stream.shutdown(Shutdown::Both);
|
||||||
|
registry.deregister(stream);
|
||||||
|
info!("Peer connection {:?} has shut down", &peer.get_addr());
|
||||||
|
|
||||||
|
if !peer.disabled() && !peer.is_inbound() {
|
||||||
|
peer.set_state(State::offline());
|
||||||
|
} else {
|
||||||
|
self.peers.remove(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_peers_from_exchange(&mut self, peers: Vec<String>) {
|
pub fn add_peers_from_exchange(&mut self, peers: Vec<String>) {
|
||||||
@@ -41,7 +56,8 @@ impl Peers {
|
|||||||
// TODO make it return error if these peers are wrong and seem like an attack
|
// TODO make it return error if these peers are wrong and seem like an attack
|
||||||
for peer in peers.iter() {
|
for peer in peers.iter() {
|
||||||
let addr: SocketAddr = peer.parse().expect(&format!("Error parsing peer {}", peer));
|
let addr: SocketAddr = peer.parse().expect(&format!("Error parsing peer {}", peer));
|
||||||
if addr.ip().is_loopback() {
|
if skip_addr(&addr) {
|
||||||
|
info!("Skipping address from exchange: {}", &addr);
|
||||||
continue; // Return error in future
|
continue; // Return error in future
|
||||||
}
|
}
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
@@ -101,6 +117,23 @@ impl Peers {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (token, peer) in self.peers.iter_mut() {
|
||||||
|
if peer.get_state().need_reconnect() {
|
||||||
|
let addr = peer.get_addr();
|
||||||
|
match TcpStream::connect(addr.clone()) {
|
||||||
|
Ok(mut stream) => {
|
||||||
|
registry.register(&mut stream, token.clone(), Interest::WRITABLE).unwrap();
|
||||||
|
peer.set_state(State::Connecting);
|
||||||
|
peer.set_stream(stream);
|
||||||
|
info!("Created connection to peer {}", &addr);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error connecting to peer {}: {}", &addr, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect_new_peers(&mut self, registry: &Registry, unique_token: &mut Token) {
|
pub fn connect_new_peers(&mut self, registry: &Registry, unique_token: &mut Token) {
|
||||||
@@ -125,3 +158,24 @@ impl Peers {
|
|||||||
self.new_peers.clear();
|
self.new_peers.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn skip_addr(addr: &SocketAddr) -> bool {
|
||||||
|
if addr.ip().is_loopback() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
match addr {
|
||||||
|
SocketAddr::V4(addr) => {
|
||||||
|
if addr.ip().is_private() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SocketAddr::V6(addr) => {
|
||||||
|
// TODO uncomment when stabilized
|
||||||
|
// if addr.ip().is_unique_local() {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
@@ -36,6 +36,13 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_idle(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
State::Idle { .. } => { true }
|
||||||
|
_ => { false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn disabled(&self) -> bool {
|
pub fn disabled(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
State::Error => { true }
|
State::Error => { true }
|
||||||
@@ -46,4 +53,11 @@ impl State {
|
|||||||
_ => { false }
|
_ => { false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn need_reconnect(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
State::Offline { from } => { from.elapsed().as_secs() > 60 }
|
||||||
|
_ => { false }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-14
@@ -99,10 +99,10 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<p class="menu-label">Domain management</p>
|
<p class="menu-label">Domain management</p>
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
<li><a onclick="openTab(this, 'dom_new')">Create domain</a></li>
|
<li><a onclick="openTab(this, 'dom_new')">Mine domain</a></li>
|
||||||
<li><a onclick="openTab(this, 'dom_edit')">Manage domain</a></li>
|
<!--<li><a onclick="openTab(this, 'dom_edit')">Manage domain</a></li>
|
||||||
<li><a onclick="openTab(this, 'dom_renew')">Renew domain</a></li>
|
<li><a onclick="openTab(this, 'dom_renew')">Renew domain</a></li>
|
||||||
<li><a onclick="openTab(this, 'dom_transfer')">Transfer domain</a></li>
|
<li><a onclick="openTab(this, 'dom_transfer')">Transfer domain</a></li>-->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div><!--column-->
|
</div><!--column-->
|
||||||
@@ -145,17 +145,23 @@
|
|||||||
|
|
||||||
<div class="content is-hidden" id="dom_new">
|
<div class="content is-hidden" id="dom_new">
|
||||||
<form action="#">
|
<form action="#">
|
||||||
<div class="field">
|
|
||||||
<label class="label">New domain name</label>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" type="text" placeholder="example.ygg" id="new_domain" oninput="onDomainChange(this)">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field">
|
<div class="columns">
|
||||||
<label class="label">Domain tags (will be used for search)</label>
|
<div class="column">
|
||||||
<div class="control">
|
<div class="field">
|
||||||
<input class="input" type="text" placeholder="blog, community, friendship" id="new_domain_tags">
|
<label class="label">Domain name</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" type="text" placeholder="example.ygg" id="new_domain" oninput="onDomainChange(this)">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Domain tags (will be used for search)</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" type="text" placeholder="blog, community, friendship" id="new_domain_tags">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -168,7 +174,7 @@
|
|||||||
<button class="button is-success" id="add_record_button" onclick="showNewRecordDialog();">Add record</button>
|
<button class="button is-success" id="add_record_button" onclick="showNewRecordDialog();">Add record</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button class="button is-link" id="new_domain_button" onclick="createDomain();" disabled>Create domain</button>
|
<button class="button is-link" id="new_domain_button" onclick="createDomain();" disabled>Mine domain</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user