Added support for lox-context storage through sled

This commit is contained in:
onyinyang 2023-08-01 15:09:46 -04:00
parent 20f5da98e3
commit f787253ad5
No known key found for this signature in database
GPG Key ID: 156A6435430C2036
6 changed files with 175 additions and 29 deletions

127
Cargo.lock generated
View File

@ -366,12 +366,43 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba"
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "crc64" name = "crc64"
version = "2.0.0" version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2707e3afba5e19b75d582d88bc79237418f2a2a2d673d01cf9b03633b46e98f3" checksum = "2707e3afba5e19b75d582d88bc79237418f2a2a2d673d01cf9b03633b46e98f3"
[[package]]
name = "crossbeam-epoch"
version = "0.9.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
dependencies = [
"autocfg 1.1.0",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.6"
@ -579,6 +610,16 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
"libc",
"winapi",
]
[[package]] [[package]]
name = "fuchsia-cprng" name = "fuchsia-cprng"
version = "0.1.1" version = "0.1.1"
@ -674,6 +715,15 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.7" version = "0.14.7"
@ -911,6 +961,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.8.0" version = "2.8.0"
@ -1008,6 +1067,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"serde_with", "serde_with",
"sled",
"time 0.3.28", "time 0.3.28",
"tokio", "tokio",
"zkp", "zkp",
@ -1070,6 +1130,15 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg 1.1.0",
]
[[package]] [[package]]
name = "merlin" name = "merlin"
version = "2.0.1" version = "2.0.1"
@ -1288,6 +1357,17 @@ dependencies = [
"libm", "libm",
] ]
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core 0.8.6",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -1295,7 +1375,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [ dependencies = [
"lock_api", "lock_api",
"parking_lot_core", "parking_lot_core 0.9.8",
]
[[package]]
name = "parking_lot_core"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall 0.2.16",
"smallvec",
"winapi",
] ]
[[package]] [[package]]
@ -1306,7 +1400,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall 0.3.5",
"smallvec", "smallvec",
"windows-targets", "windows-targets",
] ]
@ -1575,6 +1669,15 @@ dependencies = [
"tokio-util", "tokio-util",
] ]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.3.5"
@ -1815,6 +1918,22 @@ dependencies = [
"autocfg 1.1.0", "autocfg 1.1.0",
] ]
[[package]]
name = "sled"
version = "0.34.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935"
dependencies = [
"crc32fast",
"crossbeam-epoch",
"crossbeam-utils",
"fs2",
"fxhash",
"libc",
"log",
"parking_lot 0.11.2",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.11.0" version = "1.11.0"
@ -1878,7 +1997,7 @@ checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"redox_syscall", "redox_syscall 0.3.5",
"rustix", "rustix",
"windows-sys", "windows-sys",
] ]
@ -1969,7 +2088,7 @@ dependencies = [
"libc", "libc",
"mio", "mio",
"num_cpus", "num_cpus",
"parking_lot", "parking_lot 0.12.1",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2",

View File

@ -28,6 +28,7 @@ lox_utils = { path = "../lox-utils", version = "0.1.0"}
rdsys_backend = { path = "../rdsys-backend-api", version = "0.2"} rdsys_backend = { path = "../rdsys-backend-api", version = "0.2"}
clap = { version = "4.4.2", features = ["derive"] } clap = { version = "4.4.2", features = ["derive"] }
serde_json = "1.0.105" serde_json = "1.0.105"
sled = "0.34.7"
[dependencies.chrono] [dependencies.chrono]
version = "0.4.27" version = "0.4.27"

View File

@ -1,4 +1,6 @@
{ {
"db_path": "lox_db",
"rtype": {
"endpoint": "http://127.0.0.1:7100/resource-stream", "endpoint": "http://127.0.0.1:7100/resource-stream",
"name": "https", "name": "https",
"token": "HttpsApiTokenPlaceholder", "token": "HttpsApiTokenPlaceholder",
@ -6,4 +8,5 @@
"obfs2", "obfs2",
"scramblesuit" "scramblesuit"
] ]
}
} }

View File

@ -1,5 +1,6 @@
use crate::lox_context; use crate::lox_context;
use chrono::prelude::*; use chrono::prelude::*;
use sled::IVec;
use std::{ use std::{
env, env,
error::Error, error::Error,
@ -17,6 +18,13 @@ pub fn read_context_from_file<P: AsRef<Path>>(
Ok(context) Ok(context)
} }
pub fn write_context_to_db(db: sled::Db, context: lox_context::LoxServerContext) {
let date = Local::now().format("%Y-%m-%d_%H:%M:%S").to_string();
let json_date = serde_json::to_vec(&date).unwrap();
let json_result = serde_json::to_vec(&context).unwrap();
let _ = db.insert(IVec::from(json_date), IVec::from(json_result));
}
pub fn write_context_to_file(context: lox_context::LoxServerContext) { pub fn write_context_to_file(context: lox_context::LoxServerContext) {
let mut date = Local::now().format("%Y-%m-%d_%H:%M:%S").to_string(); let mut date = Local::now().format("%Y-%m-%d_%H:%M:%S").to_string();
let path = "_lox.json"; let path = "_lox.json";
@ -26,7 +34,7 @@ pub fn write_context_to_file(context: lox_context::LoxServerContext) {
let _ = serde_json::to_writer(file, &context); let _ = serde_json::to_writer(file, &context);
} }
pub fn check_db_exists() -> Option<DirEntry> { pub fn check_file_exists() -> Option<DirEntry> {
let current_path = env::current_dir().expect("Unable to access current dir"); let current_path = env::current_dir().expect("Unable to access current dir");
std::fs::read_dir(current_path) std::fs::read_dir(current_path)
.expect("Couldn't read local directory") .expect("Couldn't read local directory")

View File

@ -16,7 +16,7 @@ use std::{
}; };
use zkp::ProofError; use zkp::ProofError;
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct LoxServerContext { pub struct LoxServerContext {
pub db: Arc<Mutex<BridgeDb>>, pub db: Arc<Mutex<BridgeDb>>,
pub ba: Arc<Mutex<BridgeAuth>>, pub ba: Arc<Mutex<BridgeAuth>>,

View File

@ -24,7 +24,7 @@ use std::{
}; };
mod file_reader; mod file_reader;
use file_reader::{check_db_exists, read_context_from_file, write_context_to_file}; use file_reader::write_context_to_db;
mod lox_context; mod lox_context;
mod request_handler; mod request_handler;
use request_handler::handle; use request_handler::handle;
@ -58,6 +58,12 @@ struct Args {
backup_context: Option<PathBuf>, backup_context: Option<PathBuf>,
} }
#[derive(Debug, Deserialize)]
struct Config {
db_path: String,
rtype: ResourceInfo,
}
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct ResourceInfo { struct ResourceInfo {
endpoint: String, endpoint: String,
@ -115,7 +121,7 @@ async fn parse_bridges(rdsys_tx: mpsc::Sender<Command>, mut rx: mpsc::Receiver<R
} }
async fn create_context_manager( async fn create_context_manager(
backup_context_path: Option<PathBuf>, backup_context_path: String,
context_rx: mpsc::Receiver<Command>, context_rx: mpsc::Receiver<Command>,
mut kill: broadcast::Receiver<()>, mut kill: broadcast::Receiver<()>,
) { ) {
@ -128,23 +134,33 @@ async fn create_context_manager(
// Context Manager handles the Lox BridgeDB and Bridge Authority, ensuring // Context Manager handles the Lox BridgeDB and Bridge Authority, ensuring
// that the DB can be updated from the rdsys stream and client requests // that the DB can be updated from the rdsys stream and client requests
// can be responded to with an updated BridgeDB state // can be responded to with an updated BridgeDB state
async fn context_manager(db_path: Option<PathBuf>, mut context_rx: mpsc::Receiver<Command>) { async fn context_manager(db_path: String, mut context_rx: mpsc::Receiver<Command>) {
let context: lox_context::LoxServerContext; let context: lox_context::LoxServerContext;
if let Some(existing_db) = db_path.as_deref() { let existing_db = match sled::open(db_path) {
context = read_context_from_file(existing_db).unwrap(); Ok(lox_db) => {
} else if let Some(last_modified_file) = check_db_exists() { // Check if the lox_db already exists
println!("Reading from file {:?}", last_modified_file); if lox_db.was_recovered() {
context = read_context_from_file(&last_modified_file.path()).unwrap(); // And use the last entry to populate the Lox context if so
} else { // TODO add functionality to specify the key or roll back to a previous time
let new_db = BridgeDb::new(); let ivec_context = lox_db.last().unwrap().unwrap().1;
let new_ba = BridgeAuth::new(new_db.pubkey); context = serde_json::from_slice(&ivec_context).unwrap();
context = lox_context::LoxServerContext { //Otherwise, create a new Lox context
db: Arc::new(Mutex::new(new_db)), } else {
ba: Arc::new(Mutex::new(new_ba)), let new_db = BridgeDb::new();
extra_bridges: Arc::new(Mutex::new(Vec::new())), let new_ba = BridgeAuth::new(new_db.pubkey);
to_be_replaced_bridges: Arc::new(Mutex::new(Vec::new())), context = lox_context::LoxServerContext {
db: Arc::new(Mutex::new(new_db)),
ba: Arc::new(Mutex::new(new_ba)),
extra_bridges: Arc::new(Mutex::new(Vec::new())),
to_be_replaced_bridges: Arc::new(Mutex::new(Vec::new())),
}
}
lox_db
} }
} Err(e) => {
panic!("Unable to read or create lox database! {:?}", e);
}
};
while let Some(cmd) = context_rx.recv().await { while let Some(cmd) = context_rx.recv().await {
use Command::*; use Command::*;
@ -158,7 +174,6 @@ async fn context_manager(db_path: Option<PathBuf>, mut context_rx: mpsc::Receive
if let Some(resources) = pt.1 { if let Some(resources) = pt.1 {
for resource in resources { for resource in resources {
let bridgeline = parse_resource(resource); let bridgeline = parse_resource(resource);
println!("Now it's a bridgeline: {:?}", bridgeline);
if context.to_be_replaced_bridges.lock().unwrap().len() > 0 { if context.to_be_replaced_bridges.lock().unwrap().len() > 0 {
println!("BridgeLine to be replaced: {:?}", bridgeline); println!("BridgeLine to be replaced: {:?}", bridgeline);
let res = context.replace_with_new(bridgeline); let res = context.replace_with_new(bridgeline);
@ -291,7 +306,7 @@ async fn context_manager(db_path: Option<PathBuf>, mut context_rx: mpsc::Receive
*/ */
context.allocate_leftover_bridges(); context.allocate_leftover_bridges();
context.encrypt_table(); context.encrypt_table();
write_context_to_file(context.clone()); write_context_to_db(existing_db.clone(), context.clone());
sleep(Duration::from_millis(1)).await; sleep(Duration::from_millis(1)).await;
} }
Request { req, sender } => { Request { req, sender } => {
@ -332,8 +347,8 @@ async fn main() {
let file = File::open(&args.config).expect("Could not read config file"); let file = File::open(&args.config).expect("Could not read config file");
let reader = BufReader::new(file); let reader = BufReader::new(file);
// Read the JSON contents of the file as a ResourceInfo // Read the JSON contents of the file as a ResourceInfo
let rtype: ResourceInfo = let config: Config =
serde_json::from_reader(reader).expect("Reading ResourceInfo from JSON failed."); serde_json::from_reader(reader).expect("Reading Config from JSON failed.");
let (rdsys_tx, context_rx) = mpsc::channel(32); let (rdsys_tx, context_rx) = mpsc::channel(32);
let request_tx = rdsys_tx.clone(); let request_tx = rdsys_tx.clone();
@ -361,11 +376,11 @@ async fn main() {
}); });
let context_manager = spawn(async move { let context_manager = spawn(async move {
create_context_manager(args.backup_context, context_rx, kill_context).await create_context_manager(config.db_path, context_rx, kill_context).await
}); });
let (tx, rx) = mpsc::channel(32); let (tx, rx) = mpsc::channel(32);
let rdsys_stream_handler = spawn(async { rdsys_stream(rtype, tx, kill_stream).await }); let rdsys_stream_handler = spawn(async { rdsys_stream(config.rtype, tx, kill_stream).await });
let rdsys_resource_receiver = let rdsys_resource_receiver =
spawn(async { rdsys_bridge_parser(rdsys_tx, rx, kill_parser).await }); spawn(async { rdsys_bridge_parser(rdsys_tx, rx, kill_parser).await });