feat: WarzonePhone lossy VoIP protocol — Phase 1 complete
Rust workspace with 7 crates implementing a custom VoIP protocol designed for extremely lossy connections (5-70% loss, 100-500kbps, 300-800ms RTT). 89 tests passing across all crates. Crates: - wzp-proto: Wire format, traits, adaptive quality controller, jitter buffer, session FSM - wzp-codec: Opus encoder/decoder (audiopus), Codec2 stubs, adaptive switching, resampling - wzp-fec: RaptorQ fountain codes, interleaving, block management (proven 30-70% loss recovery) - wzp-crypto: X25519+ChaCha20-Poly1305, Warzone identity compatible, anti-replay, rekeying - wzp-transport: QUIC via quinn with DATAGRAM frames, path monitoring, signaling streams - wzp-relay: Integration stub (Phase 2) - wzp-client: Integration stub (Phase 2) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
67
crates/wzp-proto/src/error.rs
Normal file
67
crates/wzp-proto/src/error.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
use thiserror::Error;
|
||||
|
||||
/// Errors from audio codec operations.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CodecError {
|
||||
#[error("encode failed: {0}")]
|
||||
EncodeFailed(String),
|
||||
#[error("decode failed: {0}")]
|
||||
DecodeFailed(String),
|
||||
#[error("unsupported profile transition from {from:?} to {to:?}")]
|
||||
UnsupportedTransition {
|
||||
from: crate::CodecId,
|
||||
to: crate::CodecId,
|
||||
},
|
||||
}
|
||||
|
||||
/// Errors from FEC operations.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum FecError {
|
||||
#[error("source block is full (max {max} symbols)")]
|
||||
BlockFull { max: usize },
|
||||
#[error("decode impossible: need {needed} symbols, have {have}")]
|
||||
InsufficientSymbols { needed: usize, have: usize },
|
||||
#[error("invalid block id {0}")]
|
||||
InvalidBlock(u8),
|
||||
#[error("internal FEC error: {0}")]
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
/// Errors from cryptographic operations.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CryptoError {
|
||||
#[error("decryption failed (bad key or tampered data)")]
|
||||
DecryptionFailed,
|
||||
#[error("invalid public key")]
|
||||
InvalidPublicKey,
|
||||
#[error("rekey failed: {0}")]
|
||||
RekeyFailed(String),
|
||||
#[error("anti-replay: duplicate or old packet (seq={seq})")]
|
||||
ReplayDetected { seq: u16 },
|
||||
#[error("internal crypto error: {0}")]
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
/// Errors from transport operations.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum TransportError {
|
||||
#[error("connection lost")]
|
||||
ConnectionLost,
|
||||
#[error("datagram too large: {size} bytes (max {max})")]
|
||||
DatagramTooLarge { size: usize, max: usize },
|
||||
#[error("connection timeout after {ms}ms")]
|
||||
Timeout { ms: u64 },
|
||||
#[error("io error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("internal transport error: {0}")]
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
/// Errors from obfuscation layer.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ObfuscationError {
|
||||
#[error("obfuscation failed: {0}")]
|
||||
Failed(String),
|
||||
#[error("deobfuscation failed: invalid framing")]
|
||||
InvalidFraming,
|
||||
}
|
||||
Reference in New Issue
Block a user