Skip to content

Commit

Permalink
first step for sans-io
Browse files Browse the repository at this point in the history
  • Loading branch information
Frank Lee committed Jan 4, 2025
1 parent ebbcb27 commit 7eaf9d0
Show file tree
Hide file tree
Showing 33 changed files with 280 additions and 135 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Generated by Cargo
# will have compiled files and executables
/target/
**/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Expand Down
26 changes: 7 additions & 19 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
[package]
name = "bluefin"
[workspace]
members = ["bluefin", "bluefin-proto"]
resolver = "2"

[workspace.package]
version = "0.1.6"
edition = "2021"
description = "An experimental, secure, P2P, transport-layer protocol."
Expand All @@ -8,7 +11,7 @@ repository = "https://github.com/franklee26/bluefin"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
[workspace.dependencies]
local-ip-address = "0.6.3"
rand = "0.8.5"
rstest = "0.23.0"
Expand All @@ -18,22 +21,7 @@ console-subscriber = "0.4.1"
libc = "0.2.164"
socket2 = "0.5.8"

[dev-dependencies]
local-ip-address = "0.6.3"
rstest = "0.23.0"

[lib]
name = "bluefin"

[[bin]]
name = "client"
path = "src/bin/client.rs"

[[bin]]
name = "server"
path = "src/bin/server.rs"

[lints.rust]
[workspace.lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly)', 'cfg(kani)'] }

[profile.release]
Expand Down
8 changes: 8 additions & 0 deletions bluefin-proto/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "bluefin-proto"
version = "0.1.0"
edition = "2021"

[dependencies]
thiserror = "2.0.9"
rand = "0.9.0-beta.1"
7 changes: 7 additions & 0 deletions bluefin-proto/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/// The endpoint host type
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BluefinHost {
PackLeader,
PackFollower,
Client,
}
3 changes: 3 additions & 0 deletions src/core/error.rs → bluefin-proto/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ pub enum BluefinError {

#[error("`{0}`")]
TimedOut(String),

#[error("`{0}`")]
InvalidState(String),
}

/// Allows us to convert from std::io::Error to Bluefin errors. This is mostly a quality
Expand Down
1 change: 1 addition & 0 deletions bluefin-proto/src/handshake/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod state_machine;
116 changes: 116 additions & 0 deletions bluefin-proto/src/handshake/state_machine.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
use crate::context::BluefinHost;
use crate::error::BluefinError;
use crate::BluefinResult;
use rand::{rng, Rng};
use std::cmp::PartialEq;
use std::collections::VecDeque;

#[derive(Eq, Debug, PartialEq)]
enum State {
ServerStart,
PendingAccept,
RecvClientHello,
SentServerHello,
RecvClientAck,
ClientStart,
RequestingAccept,
SentClientHello,
RecvServerHello,
SentClientAck,
Conn,
}

struct PendingAccept {
src_conn_id: u32,
packet_number: u64,
}

impl PendingAccept {
pub fn new() -> PendingAccept {
Self {
src_conn_id: rng().random(),
packet_number: rng().random(),
}
}
}

pub struct Transmit {
src_conn_id: u32,
packet_number: u64,
}

impl Transmit {
pub fn new() -> Transmit {
Self {
src_conn_id: rng().random(),
packet_number: rng().random(),
}
}
}

pub struct HandshakeHandler {
state: State,
pending_accepts: VecDeque<PendingAccept>,
transmit_queue: VecDeque<Transmit>,
}

impl HandshakeHandler {
pub fn new(host_type: BluefinHost) -> HandshakeHandler {
let pending_accepts = VecDeque::new();
let transmit_queue = VecDeque::new();
match host_type {
BluefinHost::Client => Self {
state: State::ClientStart,
pending_accepts,
transmit_queue,
},
BluefinHost::PackLeader => Self {
state: State::ServerStart,
pending_accepts,
transmit_queue,
},
_ => todo!(),
}
}

/// This initiates the handshake. For the pack leader we enqueue a pending accept request,
/// which indicates that the server is ready to accept a connection. Each pending accept request
/// represents one potential Bluefin connection. For the client we enqueue a transmit request
/// which represents a client-hello packet to be sent on the wire.
pub fn begin(&mut self) -> BluefinResult<()> {
match &self.state {
// Push a pending accept, transition into PendingAccept state and wait
State::ServerStart => {
self.pending_accepts.push_back(PendingAccept::new());
self.state = State::PendingAccept;
Ok(())
}
// Push an accept request into the transmit queue, transition into RequestingAccept
// state and wait.
State::ClientStart => {
self.transmit_queue.push_back(Transmit::new());
self.state = State::RequestingAccept;
Ok(())
}
// It is not valid to call this function and be in any state other than ServerStart
// or ClientStart. Fail here.
other => Err(BluefinError::InvalidState(format!(
"Cannot begin handshake at state: {:?}",
other
))),
}
}

pub fn poll_tx_client_hello(&mut self) -> BluefinResult<Option<Transmit>> {
if self.state != State::RequestingAccept {
return Err(BluefinError::InvalidState(
"Cannot poll tx client hello".to_string(),
));
}
Ok(self.transmit_queue.pop_front())
}

pub fn handle(&mut self) -> BluefinResult<()> {
Ok(())
}
}
7 changes: 7 additions & 0 deletions bluefin-proto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use crate::error::BluefinError;

pub mod context;
pub mod error;
pub mod handshake;

pub type BluefinResult<T> = Result<T, BluefinError>;
31 changes: 31 additions & 0 deletions bluefin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "bluefin"
version.workspace = true
edition.workspace = true
description.workspace = true
license.workspace = true
repository.workspace = true

[dependencies]
bluefin-proto = { path = "../bluefin-proto" }
local-ip-address = { workspace = true }
rand = { workspace = true }
rstest = { workspace = true }
tokio = { workspace = true, features = ["full", "tracing"] }
libc = { workspace = true }
socket2 = { workspace = true }

[dev-dependencies]
local-ip-address = "0.6.3"
rstest = "0.24.0"

[[bin]]
name = "client"
path = "src/bin/client.rs"

[[bin]]
name = "server"
path = "src/bin/server.rs"

[lints]
workspace = true
6 changes: 3 additions & 3 deletions src/bin/client.rs → bluefin/src/bin/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use std::{
time::Duration,
};

use bluefin::{
core::error::BluefinError, net::client::BluefinClient, utils::common::BluefinResult,
};
use bluefin::net::client::BluefinClient;
use bluefin_proto::error::BluefinError;
use bluefin_proto::BluefinResult;
use tokio::{spawn, time::sleep};

#[cfg_attr(coverage_nightly, coverage(off))]
Expand Down
3 changes: 2 additions & 1 deletion src/bin/server.rs → bluefin/src/bin/server.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![cfg_attr(coverage_nightly, feature(coverage_attribute))]
use bluefin::{net::server::BluefinServer, utils::common::BluefinResult};
use bluefin::net::server::BluefinServer;
use bluefin_proto::BluefinResult;
use std::{
cmp::{max, min},
net::{Ipv4Addr, SocketAddrV4},
Expand Down
5 changes: 3 additions & 2 deletions src/core/header.rs → bluefin/src/core/header.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::utils::common::BluefinResult;
use bluefin_proto::error::BluefinError;
use bluefin_proto::BluefinResult;

use super::{error::BluefinError, Serialisable};
use super::Serialisable;

/// 4 bits reserved for PacketType => 16 possible packet types
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
Expand Down
4 changes: 1 addition & 3 deletions src/core/mod.rs → bluefin/src/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use error::BluefinError;
use bluefin_proto::error::BluefinError;

pub mod context;
pub mod error;
pub mod header;
pub mod packet;

Expand Down
8 changes: 5 additions & 3 deletions src/core/packet.rs → bluefin/src/core/packet.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{core::header::BluefinHeader, utils::common::BluefinResult};
use crate::core::header::BluefinHeader;
use bluefin_proto::error::BluefinError;
use bluefin_proto::BluefinResult;

use super::{error::BluefinError, header::PacketType, Serialisable};
use super::{header::PacketType, Serialisable};

#[derive(Clone, Debug)]
pub struct BluefinPacket {
Expand Down Expand Up @@ -153,10 +155,10 @@ impl BluefinPacketBuilder {
#[cfg(test)]
mod tests {
use crate::core::{
error::BluefinError,
header::{BluefinHeader, BluefinSecurityFields, PacketType},
Serialisable,
};
use bluefin_proto::error::BluefinError;

use super::BluefinPacket;

Expand Down
File renamed without changes.
File renamed without changes.
12 changes: 5 additions & 7 deletions src/net/ack_handler.rs → bluefin/src/net/ack_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ use std::{
time::Duration,
};

use tokio::{sync::RwLock, time::sleep};

use crate::{
core::{error::BluefinError, packet::BluefinPacket},
utils::{
common::BluefinResult,
window::{SlidingWindow, SlidingWindowConsumeResult},
},
core::packet::BluefinPacket,
utils::window::{SlidingWindow, SlidingWindowConsumeResult},
};
use bluefin_proto::error::BluefinError;
use bluefin_proto::BluefinResult;
use tokio::{sync::RwLock, time::sleep};

#[derive(Clone)]
pub(crate) struct AckBuffer {
Expand Down
Loading

0 comments on commit 7eaf9d0

Please sign in to comment.