diff --git a/src/network/error.rs b/src/network/error.rs new file mode 100644 index 000000000..d255cb043 --- /dev/null +++ b/src/network/error.rs @@ -0,0 +1,41 @@ +use io::IoError; +use rlp::*; + +#[derive(Debug, Copy, Clone)] +pub enum DisconnectReason +{ + DisconnectRequested, + //TCPError, + //BadProtocol, + UselessPeer, + //TooManyPeers, + //DuplicatePeer, + //IncompatibleProtocol, + //NullIdentity, + //ClientQuit, + //UnexpectedIdentity, + //LocalIdentity, + //PingTimeout, +} + +#[derive(Debug)] +pub enum NetworkError { + Auth, + BadProtocol, + PeerNotFound, + Disconnect(DisconnectReason), + Io(IoError), +} + +impl From for NetworkError { + fn from(_err: DecoderError) -> NetworkError { + NetworkError::Auth + } +} + +impl From for NetworkError { + fn from(err: IoError) -> NetworkError { + NetworkError::Io(err) + } +} + diff --git a/src/network/node.rs b/src/network/node.rs new file mode 100644 index 000000000..5c08e0a66 --- /dev/null +++ b/src/network/node.rs @@ -0,0 +1,83 @@ +use std::net::{SocketAddr, ToSocketAddrs}; +use std::hash::{Hash, Hasher}; +use std::str::{FromStr}; +use hash::*; +use rlp::*; +use time::Tm; +use error::*; + +/// Node public key +pub type NodeId = H512; + +#[derive(Debug)] +/// Noe address info +pub struct NodeEndpoint { + /// IP(V4 or V6) address + pub address: SocketAddr, + /// Address as string (can be host name). + pub address_str: String, + /// Conneciton port. + pub udp_port: u16 +} + +impl NodeEndpoint { + /// Create endpoint from string. Performs name resolution if given a host name. + fn from_str(s: &str) -> Result { + let address = s.to_socket_addrs().map(|mut i| i.next()); + match address { + Ok(Some(a)) => Ok(NodeEndpoint { + address: a, + address_str: s.to_string(), + udp_port: a.port() + }), + Ok(_) => Err(UtilError::AddressResolve(None)), + Err(e) => Err(UtilError::AddressResolve(Some(e))) + } + } +} + +#[derive(PartialEq, Eq, Copy, Clone)] +pub enum PeerType { + Required, + Optional +} + +pub struct Node { + pub id: NodeId, + pub endpoint: NodeEndpoint, + pub peer_type: PeerType, + pub last_attempted: Option, +} + +impl FromStr for Node { + type Err = UtilError; + fn from_str(s: &str) -> Result { + let (id, endpoint) = if &s[0..8] == "enode://" && s.len() > 136 && &s[136..137] == "@" { + (try!(NodeId::from_str(&s[8..136])), try!(NodeEndpoint::from_str(&s[137..]))) + } + else { + (NodeId::new(), try!(NodeEndpoint::from_str(s))) + }; + + Ok(Node { + id: id, + endpoint: endpoint, + peer_type: PeerType::Optional, + last_attempted: None, + }) + } +} + +impl PartialEq for Node { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} +impl Eq for Node { } + +impl Hash for Node { + fn hash(&self, state: &mut H) where H: Hasher { + self.id.hash(state) + } +} +