diff --git a/src/router/device.rs b/src/router/device.rs index 3670cb5..0d5224e 100644 --- a/src/router/device.rs +++ b/src/router/device.rs @@ -44,6 +44,7 @@ pub struct EncryptionState { pub struct DecryptionState, R: Callback, K: KeyCallback> { pub key: [u8; 32], pub keypair: Weak, + pub confirmed: AtomicBool, pub protector: spin::Mutex, pub peer: Weak>, pub death: Instant, // time when the key can no longer be used for decryption diff --git a/src/router/peer.rs b/src/router/peer.rs index 0598b3a..50713b2 100644 --- a/src/router/peer.rs +++ b/src/router/peer.rs @@ -265,6 +265,7 @@ impl, R: Callback, K: KeyCallback> Peer, R: Callback, K: KeyCallback< while !peer.stopped.load(Ordering::Acquire) { match buf.try_lock() { None => (), - Some(buf) => { - if buf.status != Status::Waiting { - // consume + Some(buf) => match buf.status { + Status::Done => { + // cast + let (header, packet) = + match LayoutVerified::new_from_prefix(&buf.msg[..]) { + Some(v) => v, + None => continue, + }; + let header: LayoutVerified<&[u8], TransportHeader> = header; + + // obtain strong reference to decryption state + let state = if let Some(state) = state.upgrade() { + state + } else { + break; + }; + + // check for replay + if !state.protector.lock().update(header.f_counter.get()) { + break; + } + + // check for confirms key + if state.confirmed.swap(true, Ordering::SeqCst) { + // TODO: confirm key + } + + // write packet to TUN device + + // trigger callback + debug_assert!( + packet.len() >= CHACHA20_POLY1305.nonce_len(), + "this should be checked earlier in the pipeline" + ); + (device.event_recv)( + &peer.opaque, + packet.len() > CHACHA20_POLY1305.nonce_len(), + true, + ); break; } - } + Status::Fault => break, + _ => (), + }, }; thread::park(); } @@ -125,12 +164,32 @@ pub fn worker_outbound, R: Callback, K: KeyCallback while !peer.stopped.load(Ordering::Acquire) { match buf.try_lock() { None => (), - Some(buf) => { - if buf.status != Status::Waiting { - // consume + Some(buf) => match buf.status { + Status::Done => { + // cast + let (header, packet) = + match LayoutVerified::new_from_prefix(&buf.msg[..]) { + Some(v) => v, + None => continue, + }; + let header: LayoutVerified<&[u8], TransportHeader> = header; + + // write to UDP device + let xmit = false; + + // trigger callback + (device.event_send)( + &peer.opaque, + buf.msg.len() + > CHACHA20_POLY1305.nonce_len() + + mem::size_of::(), + xmit, + ); break; } - } + Status::Fault => break, + _ => (), + }, }; thread::park(); }