This commit is contained in:
2026-01-26 13:53:51 -05:00
parent e1eff49be9
commit 53ed4775ae
19 changed files with 565 additions and 350 deletions

46
src/net/conversion.rs Normal file
View File

@@ -0,0 +1,46 @@
use crate::net::{
ClientMsg, ServerMsg,
data::{ClientMsgInst, ServerMsgInst},
};
impl From<ClientMsg> for ClientMsgInst {
fn from(value: ClientMsg) -> Self {
match value {
ClientMsg::CreateAccount(v) => Self::CreateAccountV0(v),
ClientMsg::RequestMsgs => Self::RequestMsgsV0,
ClientMsg::SendMsg(v) => Self::SendMsgV0(v),
}
}
}
impl From<ClientMsgInst> for ClientMsg {
fn from(value: ClientMsgInst) -> Self {
match value {
ClientMsgInst::CreateAccountV0(v) => Self::CreateAccount(v),
ClientMsgInst::RequestMsgsV0 => Self::RequestMsgs,
ClientMsgInst::SendMsgV0(v) => Self::SendMsg(v),
}
}
}
impl From<ServerMsg> for ServerMsgInst {
fn from(value: ServerMsg) -> Self {
match value {
ServerMsg::AccountCreated(v) => Self::AccountCreatedV0(v),
ServerMsg::LoadMsg(v) => Self::LoadMsgV0(v),
ServerMsg::LoadMsgs(v) => Self::LoadMsgsV0(v),
ServerMsg::ServerError(v) => Self::ServerErrorV0(v),
}
}
}
impl From<ServerMsgInst> for ServerMsg {
fn from(value: ServerMsgInst) -> Self {
match value {
ServerMsgInst::AccountCreatedV0(v) => Self::AccountCreated(v),
ServerMsgInst::LoadMsgV0(v) => Self::LoadMsg(v),
ServerMsgInst::LoadMsgsV0(v) => Self::LoadMsgs(v),
ServerMsgInst::ServerErrorV0(v) => Self::ServerError(v),
}
}
}

67
src/net/data.rs Normal file
View File

@@ -0,0 +1,67 @@
use rand::TryRngCore;
#[repr(u32)]
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub enum ClientMsgInst {
CreateAccountV0(CreateAccountV0) = 0,
RequestMsgsV0 = 1,
SendMsgV0(SendMsgV0) = 2,
}
#[repr(u32)]
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub enum ServerMsgInst {
AccountCreatedV0(AccountCreatedV0) = 0,
LoadMsgV0(LoadMsgV0) = 1,
LoadMsgsV0(Vec<LoadMsgV0>) = 2,
ServerErrorV0(ServerErrorV0) = 3,
}
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub struct CreateAccountV0 {
pub username: String,
pub password: String,
pub login_key: LoginKeyV0,
}
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub struct AccountCreatedV0 {}
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub struct LoginKeyV0(Vec<u8>);
impl LoginKeyV0 {
pub const BIT_LEN: usize = 1024;
pub const BYTE_LEN: usize = Self::BIT_LEN / 8;
pub fn new() -> Self {
let mut key = [0u8; Self::BYTE_LEN];
rand::rngs::OsRng
.try_fill_bytes(&mut key)
.expect("failed to generate random key");
Self(key.to_vec())
}
}
impl From<Vec<u8>> for LoginKeyV0 {
fn from(value: Vec<u8>) -> Self {
Self(value)
}
}
#[derive(Debug, Clone, bitcode::Encode, bitcode::Decode)]
pub struct SendMsgV0 {
pub content: String,
}
#[derive(Debug, Clone, bitcode::Encode, bitcode::Decode)]
pub struct LoadMsgV0 {
pub content: String,
pub user: String,
}
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub enum ServerErrorV0 {
NotLoggedIn,
UnknownUsername,
InvalidPassword,
UsernameTaken,
}

View File

@@ -1,96 +1,22 @@
use bincode::config::Configuration;
mod conversion;
mod data;
mod msg;
mod no_cert;
mod request;
mod transfer;
pub use data::{ClientMsgInst, ServerMsgInst};
pub use msg::*;
pub use no_cert::*;
use rand::{TryRngCore, rngs::OsRng};
pub use request::*;
pub use transfer::*;
pub const SERVER_NAME: &str = "openworm";
pub const BINCODE_CONFIG: Configuration = bincode::config::standard();
#[derive(Debug, bincode::Encode, bincode::Decode)]
pub enum ClientMsg {
SendMsg(NetClientMsg),
RequestMsgs,
CreateAccount {
username: String,
password: String,
device: LoginKey,
},
Login {
username: String,
password: String,
},
}
#[derive(Debug, bincode::Encode, bincode::Decode)]
pub enum ServerMsg {
SendMsg(NetServerMsg),
LoadMsgs(Vec<NetServerMsg>),
Login { username: String },
Error(ServerError),
}
#[derive(Debug, bincode::Encode, bincode::Decode)]
pub enum ServerError {
NotLoggedIn,
UnknownUsername,
InvalidPassword,
UsernameTaken,
}
impl From<ServerError> for ServerMsg {
fn from(value: ServerError) -> Self {
Self::Error(value)
}
}
pub type ServerResp<T> = Result<T, String>;
#[derive(Debug, Clone, bincode::Encode, bincode::Decode)]
pub struct NetClientMsg {
pub content: String,
}
#[derive(Debug, Clone, bincode::Encode, bincode::Decode)]
pub struct NetServerMsg {
pub content: String,
pub user: String,
}
impl From<NetServerMsg> for ServerMsg {
fn from(value: NetServerMsg) -> Self {
Self::SendMsg(value)
}
}
pub fn install_crypto_provider() {
quinn::rustls::crypto::ring::default_provider()
.install_default()
.unwrap();
}
#[derive(Debug, bincode::Encode, bincode::Decode)]
pub struct LoginKey([u8; LoginKey::BYTE_LEN]);
impl LoginKey {
pub const BIT_LEN: usize = 1024;
pub const BYTE_LEN: usize = Self::BIT_LEN / 8;
pub fn new() -> Self {
let mut key = [0u8; Self::BYTE_LEN];
OsRng
.try_fill_bytes(&mut key)
.expect("failed to generate random key");
Self(key)
}
}
impl TryFrom<Vec<u8>> for LoginKey {
type Error = ();
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
Ok(Self(value.try_into().map_err(|_| ())?))
}
}

29
src/net/msg.rs Normal file
View File

@@ -0,0 +1,29 @@
use super::data::*;
#[derive(Debug)]
pub enum ClientMsg {
CreateAccount(CreateAccount),
RequestMsgs,
SendMsg(SendMsg),
}
#[derive(Debug)]
pub enum ServerMsg {
AccountCreated(AccountCreated),
LoadMsg(LoadMsg),
LoadMsgs(Vec<LoadMsg>),
ServerError(ServerError),
}
pub type LoginKey = LoginKeyV0;
pub type SendMsg = SendMsgV0;
pub type LoadMsg = LoadMsgV0;
pub type ServerError = ServerErrorV0;
pub type CreateAccount = CreateAccountV0;
pub type AccountCreated = AccountCreatedV0;
impl From<CreateAccount> for ClientMsg {
fn from(value: CreateAccount) -> Self {
Self::CreateAccount(value)
}
}

32
src/net/request.rs Normal file
View File

@@ -0,0 +1,32 @@
use std::num::NonZeroU32;
use crate::net::{ClientMsgInst, ServerMsgInst};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, bitcode::Encode, bitcode::Decode)]
pub struct RequestId(NonZeroU32);
impl RequestId {
pub const fn first() -> Self {
Self(NonZeroU32::MAX)
}
pub const fn next(&mut self) -> Self {
self.0 = match self.0.checked_add(1) {
Some(v) => v,
None => NonZeroU32::MIN,
};
*self
}
}
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub struct ClientRequestMsg {
pub request_id: Option<RequestId>,
pub msg: ClientMsgInst,
}
#[derive(Debug, bitcode::Encode, bitcode::Decode)]
pub struct ServerRespMsg {
pub request_id: Option<RequestId>,
pub msg: ServerMsgInst,
}

View File

@@ -1,6 +1,5 @@
use std::sync::Arc;
use crate::net::BINCODE_CONFIG;
use quinn::Connection;
use tokio::io::{AsyncReadExt as _, AsyncWriteExt};
use tracing::Instrument as _;
@@ -17,8 +16,8 @@ pub trait RecvHandler<M>: Send + Sync + 'static {
}
pub type SendResult = Result<(), ()>;
pub async fn send_uni<M: bincode::Encode>(conn: &Connection, msg: M) -> SendResult {
let bytes = bincode::encode_to_vec(msg, BINCODE_CONFIG).unwrap();
pub async fn send_uni<M: bitcode::Encode>(conn: &Connection, msg: M) -> SendResult {
let bytes = bitcode::encode(&msg);
let mut send = conn.open_uni().await.map_err(|_| ())?;
send.write_u64(bytes.len() as u64).await.map_err(|_| ())?;
@@ -34,7 +33,7 @@ pub enum DisconnectReason {
Other(String),
}
pub async fn recv_uni<M: bincode::Decode<()>>(
pub async fn recv_uni<M: bitcode::DecodeOwned>(
conn: Connection,
handler: Arc<impl RecvHandler<M>>,
) -> DisconnectReason {
@@ -58,7 +57,7 @@ pub async fn recv_uni<M: bincode::Decode<()>>(
async move {
let len = recv.read_u64().await.unwrap();
let bytes = recv.read_to_end(len as usize).await.unwrap();
let (msg, _) = bincode::decode_from_slice::<M, _>(&bytes, BINCODE_CONFIG).unwrap();
let msg = bitcode::decode::<M>(&bytes).unwrap();
handler.msg(msg).await;
}
.instrument(tracing::info_span!("request")),