mirror of
https://github.com/Revertron/Alfis
synced 2024-11-07 09:20:31 +00:00
Improved peer reconnection code.
This commit is contained in:
parent
93d688c479
commit
483be5215a
@ -177,7 +177,7 @@ impl Blockchain {
|
||||
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() {
|
||||
return None;
|
||||
}
|
||||
@ -193,14 +193,21 @@ impl Blockchain {
|
||||
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 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) {
|
||||
return Some(transaction.data);
|
||||
return Some(transaction);
|
||||
}
|
||||
}
|
||||
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> {
|
||||
self.last_block.clone()
|
||||
}
|
||||
|
17
src/main.rs
17
src/main.rs
@ -248,10 +248,23 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
||||
let guard = context.lock().unwrap();
|
||||
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 {
|
||||
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 { .. } => {}
|
||||
|
@ -88,28 +88,8 @@ impl Network {
|
||||
poll.registry().reregister(&mut server, SERVER, Interest::READABLE).expect("Error reregistering server");
|
||||
}
|
||||
token => {
|
||||
match peers.get_mut_peer(&token) {
|
||||
Some(_peer) => {
|
||||
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"); }
|
||||
if !handle_connection_event(context.clone(), &mut peers, &poll.registry(), &event) {
|
||||
let _ = peers.close_peer(poll.registry(), &token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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()) {
|
||||
return Ok(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
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 {
|
||||
// Try to reregister connection
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>, ()> {
|
||||
@ -233,7 +209,7 @@ fn read_message(stream: &mut TcpStream) -> Result<Vec<u8>, ()> {
|
||||
}
|
||||
};
|
||||
trace!("Payload size is {}", data_size);
|
||||
if data_size > MAX_PACKET_SIZE {
|
||||
if data_size > MAX_PACKET_SIZE || data_size == 0 {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,10 @@ impl Peer {
|
||||
&mut self.stream
|
||||
}
|
||||
|
||||
pub fn set_stream(&mut self, stream: TcpStream) {
|
||||
self.stream = stream;
|
||||
}
|
||||
|
||||
pub fn get_state(&self) -> &State {
|
||||
&self.state
|
||||
}
|
||||
@ -48,6 +52,10 @@ impl Peer {
|
||||
self.state.disabled()
|
||||
}
|
||||
|
||||
pub fn is_inbound(&self) -> bool {
|
||||
self.inbound
|
||||
}
|
||||
|
||||
/// If loopback address then we care about ip and port.
|
||||
/// If regular address then we only care about the ip and ignore the port.
|
||||
pub fn equals(&self, addr: &SocketAddr) -> bool {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::net::SocketAddr;
|
||||
use std::net::{SocketAddr, Shutdown};
|
||||
use mio::{Token, Interest, Registry};
|
||||
use mio::net::TcpStream;
|
||||
use crate::p2p::{Peer, State, Message};
|
||||
@ -32,8 +32,23 @@ impl Peers {
|
||||
self.peers.get_mut(token)
|
||||
}
|
||||
|
||||
pub fn remove_peer(&mut self, token: &Token) -> Option<Peer> {
|
||||
self.peers.remove(token)
|
||||
pub fn close_peer(&mut self, registry: &Registry, token: &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>) {
|
||||
@ -41,7 +56,8 @@ impl Peers {
|
||||
// TODO make it return error if these peers are wrong and seem like an attack
|
||||
for peer in peers.iter() {
|
||||
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
|
||||
}
|
||||
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) {
|
||||
@ -124,4 +157,25 @@ impl Peers {
|
||||
}
|
||||
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 {
|
||||
match self {
|
||||
State::Error => { true }
|
||||
@ -46,4 +53,11 @@ impl State {
|
||||
_ => { false }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn need_reconnect(&self) -> bool {
|
||||
match self {
|
||||
State::Offline { from } => { from.elapsed().as_secs() > 60 }
|
||||
_ => { false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,10 +99,10 @@
|
||||
</ul>
|
||||
<p class="menu-label">Domain management</p>
|
||||
<ul class="menu-list">
|
||||
<li><a onclick="openTab(this, 'dom_new')">Create domain</a></li>
|
||||
<li><a onclick="openTab(this, 'dom_edit')">Manage 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_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>
|
||||
</div>
|
||||
</div><!--column-->
|
||||
@ -145,17 +145,23 @@
|
||||
|
||||
<div class="content is-hidden" id="dom_new">
|
||||
<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">
|
||||
<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 class="columns">
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<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>
|
||||
|
||||
@ -168,7 +174,7 @@
|
||||
<button class="button is-success" id="add_record_button" onclick="showNewRecordDialog();">Add record</button>
|
||||
</div>
|
||||
<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>
|
||||
</form>
|
||||
|
Loading…
Reference in New Issue
Block a user