Compare commits

..

No commits in common. "7b0718399cadf7ba5c74cb19ce28ed369c63c015" and "eb638efadf35eb09de4e5a2fc91f5fbf7703f5fb" have entirely different histories.

4 changed files with 18 additions and 93 deletions

View File

@ -442,9 +442,9 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
fn store_beacon(&mut self) -> Result<(), Error> { fn store_beacon(&mut self) -> Result<(), Error> {
if let Some(ref path) = self.config.beacon_store { if let Some(ref path) = self.config.beacon_store {
let peers: Vec<_> = self.own_addresses.choose_multiple(&mut thread_rng(), 3).cloned().collect(); let peers: Vec<_> = self.own_addresses.choose_multiple(&mut thread_rng(), 3).cloned().collect();
if let Some(path) = path.strip_prefix('|') { if path.starts_with('|') {
self.beacon_serializer self.beacon_serializer
.write_to_cmd(&peers, path) .write_to_cmd(&peers, &path[1..])
.map_err(|e| Error::BeaconIo("Failed to call beacon command", e))?; .map_err(|e| Error::BeaconIo("Failed to call beacon command", e))?;
} else { } else {
self.beacon_serializer self.beacon_serializer
@ -459,9 +459,9 @@ impl<D: Device, P: Protocol, S: Socket, TS: TimeSource> GenericCloud<D, P, S, TS
fn load_beacon(&mut self) -> Result<(), Error> { fn load_beacon(&mut self) -> Result<(), Error> {
let peers; let peers;
if let Some(ref path) = self.config.beacon_load { if let Some(ref path) = self.config.beacon_load {
if let Some(path) = path.strip_prefix('|') { if path.starts_with('|') {
self.beacon_serializer self.beacon_serializer
.read_from_cmd(path, Some(50)) .read_from_cmd(&path[1..], Some(50))
.map_err(|e| Error::BeaconIo("Failed to call beacon command", e))?; .map_err(|e| Error::BeaconIo("Failed to call beacon command", e))?;
return Ok(()) return Ok(())
} else { } else {

View File

@ -17,8 +17,8 @@ pub const DEFAULT_PORT: u16 = 3210;
fn parse_listen(addr: &str) -> SocketAddr { fn parse_listen(addr: &str) -> SocketAddr {
if let Some(addr) = addr.strip_prefix("*:") { if addr.starts_with("*:") {
let port = try_fail!(addr.parse::<u16>(), "Invalid port: {}"); let port = try_fail!(addr[2..].parse::<u16>(), "Invalid port: {}");
SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port) SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port)
} else if addr.contains(':') { } else if addr.contains(':') {
try_fail!(addr.parse::<SocketAddr>(), "Invalid address: {}: {}", addr) try_fail!(addr.parse::<SocketAddr>(), "Invalid address: {}: {}", addr)
@ -417,7 +417,7 @@ pub struct Args {
pub version: bool, pub version: bool,
/// Generate and print a key-pair and exit /// Generate and print a key-pair and exit
#[structopt(long, conflicts_with = "private_key")] #[structopt(long, conflicts_with="private_key")]
pub genkey: bool, pub genkey: bool,
/// Disable automatic port forwarding /// Disable automatic port forwarding

View File

@ -381,7 +381,7 @@ pub struct InitState<P: Payload> {
salted_node_id_hash: SaltedNodeIdHash, salted_node_id_hash: SaltedNodeIdHash,
payload: P, payload: P,
key_pair: Arc<Ed25519KeyPair>, key_pair: Arc<Ed25519KeyPair>,
trusted_keys: Arc<[Ed25519PublicKey]>, trusted_keys: Arc<Vec<Ed25519PublicKey>>,
ecdh_private_key: Option<EcdhPrivateKey>, ecdh_private_key: Option<EcdhPrivateKey>,
next_stage: u8, next_stage: u8,
close_time: usize, close_time: usize,
@ -393,7 +393,7 @@ pub struct InitState<P: Payload> {
impl<P: Payload> InitState<P> { impl<P: Payload> InitState<P> {
pub fn new( pub fn new(
node_id: NodeId, payload: P, key_pair: Arc<Ed25519KeyPair>, trusted_keys: Arc<[Ed25519PublicKey]>, node_id: NodeId, payload: P, key_pair: Arc<Ed25519KeyPair>, trusted_keys: Arc<Vec<Ed25519PublicKey>>,
algorithms: Algorithms algorithms: Algorithms
) -> Self ) -> Self
{ {
@ -449,7 +449,6 @@ impl<P: Payload> InitState<P> {
self.repeat_last_message(out); self.repeat_last_message(out);
Ok(()) Ok(())
} else { } else {
self.next_stage = CLOSING;
Err(Error::CryptoInit("Initialization timeout")) Err(Error::CryptoInit("Initialization timeout"))
} }
} }
@ -495,7 +494,9 @@ impl<P: Payload> InitState<P> {
hash == d.as_ref() hash == d.as_ref()
} }
fn send_message(&mut self, stage: u8, ecdh_public_key: Option<EcdhPublicKey>, out: &mut MsgBuffer) { fn send_message(
&mut self, stage: u8, ecdh_public_key: Option<EcdhPublicKey>, out: &mut MsgBuffer
) {
debug!("Sending init with stage={}", stage); debug!("Sending init with stage={}", stage);
assert!(out.is_empty()); assert!(out.is_empty());
let mut public_key = [0; ED25519_PUBLIC_KEY_LEN]; let mut public_key = [0; ED25519_PUBLIC_KEY_LEN];
@ -677,7 +678,7 @@ mod tests {
let key_pair = Arc::new(Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref()).unwrap()); let key_pair = Arc::new(Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref()).unwrap());
let mut public_key = [0; ED25519_PUBLIC_KEY_LEN]; let mut public_key = [0; ED25519_PUBLIC_KEY_LEN];
public_key.clone_from_slice(key_pair.public_key().as_ref()); public_key.clone_from_slice(key_pair.public_key().as_ref());
let trusted_nodes = Arc::new([public_key]); let trusted_nodes = Arc::new(vec![public_key]);
let mut node1 = [0; NODE_ID_BYTES]; let mut node1 = [0; NODE_ID_BYTES];
rng.fill(&mut node1).unwrap(); rng.fill(&mut node1).unwrap();
let mut node2 = [0; NODE_ID_BYTES]; let mut node2 = [0; NODE_ID_BYTES];
@ -713,85 +714,9 @@ mod tests {
} }
} }
#[test] // TODO Test: last message repeated when message is lost
fn lost_init_sender_recovers() {
let (mut sender, mut receiver) = create_pair();
let mut out = MsgBuffer::new(8);
sender.send_ping(&mut out);
assert_eq!(sender.stage(), STAGE_PONG);
// lost ping, sender recovers
out.clear();
sender.every_second(&mut out).unwrap();
let result = receiver.handle_init(&mut out).unwrap();
assert_eq!(receiver.stage(), STAGE_PENG);
assert_eq!(result, InitResult::Continue);
// lost pong, sender recovers
out.clear();
receiver.every_second(&mut out).unwrap();
let result = sender.handle_init(&mut out).unwrap();
assert_eq!(sender.stage(), WAITING_TO_CLOSE);
match result {
InitResult::Success { .. } => {
// lost peng, sender recovers
out.clear();
}
InitResult::Continue => unreachable!()
};
sender.every_second(&mut out).unwrap();
let result = receiver.handle_init(&mut out).unwrap();
assert_eq!(receiver.stage(), CLOSING);
match result {
InitResult::Success { .. } => assert!(out.is_empty()),
InitResult::Continue => unreachable!()
}
}
#[test] // TODO Test: timeout after 5 retries
fn lost_init_receiver_recovers() {
let (mut sender, mut receiver) = create_pair();
let mut out = MsgBuffer::new(8);
sender.send_ping(&mut out);
assert_eq!(sender.stage(), STAGE_PONG);
let result = receiver.handle_init(&mut out).unwrap();
assert_eq!(receiver.stage(), STAGE_PENG);
assert_eq!(result, InitResult::Continue);
// lost pong, receiver recovers
out.clear();
sender.every_second(&mut out).unwrap();
receiver.handle_init(&mut out).unwrap();
let result = sender.handle_init(&mut out).unwrap();
assert_eq!(sender.stage(), WAITING_TO_CLOSE);
match result {
InitResult::Success { .. } => {
// lost peng, sender recovers
out.clear();
}
InitResult::Continue => unreachable!()
};
receiver.every_second(&mut out).unwrap();
sender.handle_init(&mut out).unwrap();
let result = receiver.handle_init(&mut out).unwrap();
assert_eq!(receiver.stage(), CLOSING);
match result {
InitResult::Success { .. } => assert!(out.is_empty()),
InitResult::Continue => unreachable!()
}
}
#[test]
fn timeout() {
let (mut sender, _receiver) = create_pair();
let mut out = MsgBuffer::new(8);
sender.send_ping(&mut out);
assert_eq!(sender.stage(), STAGE_PONG);
for _ in 0..5 {
out.clear();
sender.every_second(&mut out).unwrap();
}
out.clear();
assert!(sender.every_second(&mut out).is_err());
assert_eq!(sender.stage(), CLOSING);
}
// TODO Test: duplicated message or replay attacks // TODO Test: duplicated message or replay attacks

View File

@ -70,7 +70,7 @@ pub struct Config {
pub struct Crypto { pub struct Crypto {
node_id: NodeId, node_id: NodeId,
key_pair: Arc<Ed25519KeyPair>, key_pair: Arc<Ed25519KeyPair>,
trusted_keys: Arc<[Ed25519PublicKey]>, trusted_keys: Arc<Vec<Ed25519PublicKey>>,
algorithms: Algorithms algorithms: Algorithms
} }
@ -124,7 +124,7 @@ impl Crypto {
speeds.into_iter().map(|(a, s)| format!("{}: {:.1} MiB/s", a, s)).collect::<Vec<_>>().join(", ") speeds.into_iter().map(|(a, s)| format!("{}: {:.1} MiB/s", a, s)).collect::<Vec<_>>().join(", ")
); );
} }
Ok(Self { node_id, key_pair: Arc::new(key_pair), trusted_keys: trusted_keys.into_boxed_slice().into(), algorithms: algos }) Ok(Self { node_id, key_pair: Arc::new(key_pair), trusted_keys: Arc::new(trusted_keys), algorithms: algos })
} }
pub fn generate_keypair(password: Option<&str>) -> (String, String) { pub fn generate_keypair(password: Option<&str>) -> (String, String) {
@ -215,7 +215,7 @@ pub struct PeerCrypto<P: Payload> {
impl<P: Payload> PeerCrypto<P> { impl<P: Payload> PeerCrypto<P> {
pub fn new( pub fn new(
node_id: NodeId, init_payload: P, key_pair: Arc<Ed25519KeyPair>, trusted_keys: Arc<[Ed25519PublicKey]>, node_id: NodeId, init_payload: P, key_pair: Arc<Ed25519KeyPair>, trusted_keys: Arc<Vec<Ed25519PublicKey>>,
algorithms: Algorithms algorithms: Algorithms
) -> Self ) -> Self
{ {