Merge changes from upstream
This commit is contained in:
commit
65e763724b
|
@ -1919,9 +1919,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.4.0"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23"
|
||||
checksum = "f58c3a1b3e418f61c25b2aeb43fc6c95eaa252b8cecdda67f401943e9e08d33f"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"chrono",
|
||||
|
@ -1936,9 +1936,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.4.0"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788"
|
||||
checksum = "d2068b437a31fc68f25dd7edc296b078f04b45145c199d8eed9866e45f1ff274"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
|
|
@ -25,7 +25,7 @@ tokio = { version = "1", features = ["full", "macros", "signal"] }
|
|||
rand = "0.8.5"
|
||||
reqwest = { version = "0.11", features = ["json", "stream"]}
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
serde_with = "3.4.0"
|
||||
serde_with = "3.5.0"
|
||||
lox-zkp = { git = "https://gitlab.torproject.org/onyinyang/lox-zkp", version = "0.8.0" }
|
||||
lox-library = { path = "../lox-library", version = "0.1.0"}
|
||||
lox_utils = { path = "../lox-utils", version = "0.1.0"}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"db_path": "lox_db"
|
||||
|
||||
},
|
||||
"lox_authority_port": 8001,
|
||||
"metrics_port": 5222,
|
||||
"bridge_config": {
|
||||
"watched_blockages": [
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -499,7 +499,23 @@ impl LoxServerContext {
|
|||
Ok(resp) => prepare_header(resp),
|
||||
Err(e) => {
|
||||
println!("Error parsing today to JSON");
|
||||
prepare_error_header(e.to_string())
|
||||
let response = json!({"error": e.to_string()});
|
||||
let val = serde_json::to_string(&response).unwrap();
|
||||
return prepare_header(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the serialized pubkeys for the Bridge Authority as an HTTP response
|
||||
pub fn send_constants(self) -> Response<Body> {
|
||||
let constants = lox_utils::LOX_SYSTEM_INFO;
|
||||
match serde_json::to_string(&constants) {
|
||||
Ok(resp) => prepare_header(resp),
|
||||
Err(e) => {
|
||||
println!("Error parsing Constants to JSON");
|
||||
let response = json!({"error": e.to_string()});
|
||||
let val = serde_json::to_string(&response).unwrap();
|
||||
prepare_header(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -710,7 +726,11 @@ impl LoxServerContext {
|
|||
pub fn advance_days_with_response_test(self, request: Bytes) -> Response<Body> {
|
||||
let req: u16 = match serde_json::from_slice(&request) {
|
||||
Ok(req) => req,
|
||||
Err(e) => return prepare_error_header(e.to_string()),
|
||||
Err(e) => {
|
||||
let response = json!({"error": e.to_string()});
|
||||
let val = serde_json::to_string(&response).unwrap();
|
||||
return prepare_header(val);
|
||||
}
|
||||
};
|
||||
self.advance_days_test(req);
|
||||
self.send_today()
|
||||
|
|
|
@ -63,6 +63,7 @@ struct Args {
|
|||
struct Config {
|
||||
db: DbConfig,
|
||||
metrics_port: u16,
|
||||
lox_authority_port: u16,
|
||||
bridge_config: BridgeConfig,
|
||||
rtype: ResourceInfo,
|
||||
}
|
||||
|
@ -121,7 +122,7 @@ async fn rdsys_request_creator(
|
|||
// Makes a request to rdsys for the full set of Resources assigned to lox every interval
|
||||
// (defined in the function)
|
||||
async fn rdsys_request(rtype: ResourceInfo, tx: mpsc::Sender<ResourceState>) {
|
||||
let mut interval = interval(Duration::from_secs(5));
|
||||
let mut interval = interval(Duration::from_secs(120));
|
||||
loop {
|
||||
interval.tick().await;
|
||||
let resources = match request_resources(
|
||||
|
@ -355,7 +356,7 @@ async fn main() {
|
|||
async move { Ok::<_, Infallible>(service) }
|
||||
});
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 8001));
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], config.lox_authority_port));
|
||||
let server = Server::bind(&addr).serve(make_service);
|
||||
let graceful = server.with_graceful_shutdown(shutdown_signal());
|
||||
println!("Listening on {}", addr);
|
||||
|
|
|
@ -22,6 +22,7 @@ pub async fn handle(
|
|||
}
|
||||
(&Method::POST, "/pubkeys") => Ok::<_, Infallible>(cloned_context.send_keys()),
|
||||
(&Method::POST, "/today") => Ok::<_, Infallible>(cloned_context.send_today()),
|
||||
(&Method::POST, "/constants") => Ok::<_, Infallible>(cloned_context.send_constants()),
|
||||
(&Method::POST, "/openreq") => Ok::<_, Infallible>({
|
||||
let bytes = body::to_bytes(req.into_body()).await.unwrap();
|
||||
cloned_context.verify_and_send_open_cred(bytes)
|
||||
|
@ -93,6 +94,7 @@ mod tests {
|
|||
fn invite(&self) -> Request<Body>;
|
||||
fn reachability(&self) -> Request<Body>;
|
||||
fn pubkeys(&self) -> Request<Body>;
|
||||
fn constants(&self) -> Request<Body>;
|
||||
fn openinvite(&self, request: proto::open_invite::Request) -> Request<Body>;
|
||||
fn trustpromo(&self, request: proto::trust_promotion::Request) -> Request<Body>;
|
||||
fn trustmigration(&self, request: proto::migration::Request) -> Request<Body>;
|
||||
|
@ -129,6 +131,14 @@ mod tests {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
fn constants(&self) -> Request<Body> {
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("http://localhost/constants")
|
||||
.body(Body::empty())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn openinvite(&self, request: proto::open_invite::Request) -> Request<Body> {
|
||||
let req_str = serde_json::to_string(&request).unwrap();
|
||||
Request::builder()
|
||||
|
@ -378,6 +388,16 @@ mod tests {
|
|||
assert_eq!(pubkey_response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_constants() {
|
||||
let th = TestHarness::new();
|
||||
let lc = LoxClientMock {};
|
||||
// Test Pubkeys
|
||||
let constant_request = lc.constants();
|
||||
let constant_response = handle(th.context.clone(), constant_request).await.unwrap();
|
||||
assert_eq!(constant_response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_lox_protocols() {
|
||||
let mut th = TestHarness::new();
|
||||
|
|
|
@ -76,8 +76,9 @@ pub fn parse_into_buckets(
|
|||
count += 1;
|
||||
} else {
|
||||
buckets.push(bucket);
|
||||
count = 0;
|
||||
bucket = [BridgeLine::default(); MAX_BRIDGES_PER_BUCKET];
|
||||
bucket[0] = bridgeline;
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
// Handle the extra buckets that were not allocated already
|
||||
|
|
|
@ -20,7 +20,7 @@ bincode = "1"
|
|||
chrono = "0.4"
|
||||
rand = { version = "0.8", features = ["std_rng"]}
|
||||
serde = "1.0.195"
|
||||
serde_with = {version = "3.4.0", features = ["json"]}
|
||||
serde_with = {version = "3.5.0", features = ["json"]}
|
||||
sha2 = "0.10"
|
||||
statistical = "1.0.0"
|
||||
lazy_static = "1"
|
||||
|
|
|
@ -25,7 +25,7 @@ use std::convert::{TryFrom, TryInto};
|
|||
use subtle::ConstantTimeEq;
|
||||
|
||||
/// Each bridge information line is serialized into this many bytes
|
||||
pub const BRIDGE_BYTES: usize = 200;
|
||||
pub const BRIDGE_BYTES: usize = 250;
|
||||
|
||||
/// The max number of bridges per bucket
|
||||
pub const MAX_BRIDGES_PER_BUCKET: usize = 3;
|
||||
|
|
|
@ -556,8 +556,24 @@ impl BridgeAuth {
|
|||
}
|
||||
res = ReplaceSuccess::Replaced
|
||||
} else if !self.bridge_table.spares.is_empty() {
|
||||
// First get the bucketnums for the replacement bridge in case it is a spare
|
||||
let mut bucketnums: Vec<u32> = Vec::new();
|
||||
for (bucketnum, _) in positions.iter() {
|
||||
bucketnums.push(*bucketnum);
|
||||
}
|
||||
// Get the first spare and remove it from the spares set.
|
||||
let spare = *self.bridge_table.spares.iter().next().unwrap();
|
||||
let mut spare = *self.bridge_table.spares.iter().next().unwrap();
|
||||
// Check that the first spare in the list of spares is not the one to be replaced
|
||||
if bucketnums.contains(&spare) {
|
||||
// If it is, take the last spare instead
|
||||
spare = *self.bridge_table.spares.iter().last().unwrap();
|
||||
// If this is the same bucketnum, there is only one spare bucket with the bridge
|
||||
// to be replaced in it, so don't replace it.
|
||||
if bucketnums.contains(&spare) {
|
||||
res = ReplaceSuccess::NotReplaced;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
self.bridge_table.spares.remove(&spare);
|
||||
self.bridge_table.recycleable_keys.push(spare);
|
||||
// Get the actual bridges from the spare bucket
|
||||
|
@ -596,6 +612,7 @@ impl BridgeAuth {
|
|||
}
|
||||
res = ReplaceSuccess::Replaced
|
||||
} else {
|
||||
println!("No available bridges");
|
||||
// If there are no available bridges that can be assigned here, the only thing
|
||||
// that can be done is return an indication that updating the gone bridge
|
||||
// didn't work.
|
||||
|
|
|
@ -1057,13 +1057,15 @@ fn test_update_bridge() {
|
|||
#[test]
|
||||
fn test_bridge_replace() {
|
||||
// Create 3 open invitation buckets and 3 spare buckets
|
||||
let cases = vec!["not found", "available", "unallocated", "failed", "spare"];
|
||||
let cases = vec!["not found", "available", "unallocated", "spare", "failed"];
|
||||
let num_buckets = 5;
|
||||
let hot_spare = 0;
|
||||
for case in cases {
|
||||
let mut th: TestHarness;
|
||||
if case != "failed" {
|
||||
if String::from(case) != "failed" {
|
||||
th = TestHarness::new();
|
||||
} else {
|
||||
th = TestHarness::new_buckets(5, 0);
|
||||
th = TestHarness::new_buckets(num_buckets, hot_spare);
|
||||
}
|
||||
|
||||
// Randomly select a bridge to replace
|
||||
|
@ -1072,6 +1074,7 @@ fn test_bridge_replace() {
|
|||
while !th.ba.bridge_table.buckets.contains_key(&num) {
|
||||
num = rand::thread_rng().gen_range(0..th.ba.bridge_table.counter);
|
||||
}
|
||||
println!("chosen num is: {:?}", num);
|
||||
let replaceable_bucket = *th.ba.bridge_table.buckets.get(&num).unwrap();
|
||||
let replacement_bridge = &replaceable_bucket[0];
|
||||
assert!(
|
||||
|
@ -1207,7 +1210,7 @@ fn test_bridge_replace() {
|
|||
"Extra spare bridges not added to unallocated bridges"
|
||||
);
|
||||
|
||||
println!("Successfully added unallocated bridgeline");
|
||||
println!("Successfully added bridgeline from spare");
|
||||
}
|
||||
"failed" => {
|
||||
// Case four: available_bridge == None and unallocated_bridges == None and spare buckets == None
|
||||
|
|
|
@ -15,7 +15,7 @@ repository = "https://gitlab.torproject.org/tpo/anti-censorship/lox.git/"
|
|||
lox-library = {path = "../lox-library", version = "0.1.0"}
|
||||
serde = "1"
|
||||
serde_json = "1.0.108"
|
||||
serde_with = "3.4.0"
|
||||
serde_with = "3.5.0"
|
||||
|
||||
|
||||
[features]
|
||||
|
|
|
@ -2,7 +2,7 @@ use lox_library::bridge_table::{
|
|||
from_scalar, BridgeLine, BridgeTable, EncryptedBucket, MAX_BRIDGES_PER_BUCKET,
|
||||
};
|
||||
use lox_library::cred::{BucketReachability, Invitation, Lox};
|
||||
use lox_library::proto;
|
||||
use lox_library::proto::{self, check_blockage, level_up, trust_promotion};
|
||||
use lox_library::{IssuerPubKey, OPENINV_LENGTH};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::serde_as;
|
||||
|
@ -75,17 +75,21 @@ pub struct PubKeys {
|
|||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct LoxSystemInfo {
|
||||
max_blockages: [u32; proto::level_up::MAX_LEVEL + 1],
|
||||
level_interval: [u32; proto::level_up::MAX_LEVEL + 1],
|
||||
level_invitations: [u32; proto::level_up::MAX_LEVEL + 1],
|
||||
min_trust_level: u32,
|
||||
pub max_level: usize,
|
||||
pub untrusted_interval: u32,
|
||||
pub max_blockages: [u32; level_up::MAX_LEVEL + 1],
|
||||
pub level_interval: [u32; level_up::MAX_LEVEL + 1],
|
||||
pub level_invitations: [u32; level_up::MAX_LEVEL + 1],
|
||||
pub min_blockage_migration_trust_level: u32,
|
||||
}
|
||||
|
||||
pub const LOX_SYSTEM_INFO: LoxSystemInfo = LoxSystemInfo {
|
||||
max_blockages: proto::level_up::MAX_BLOCKAGES,
|
||||
level_interval: proto::level_up::LEVEL_INTERVAL,
|
||||
level_invitations: proto::level_up::LEVEL_INVITATIONS,
|
||||
min_trust_level: proto::check_blockage::MIN_TRUST_LEVEL,
|
||||
max_level: level_up::MAX_LEVEL,
|
||||
untrusted_interval: trust_promotion::UNTRUSTED_INTERVAL,
|
||||
max_blockages: level_up::MAX_BLOCKAGES,
|
||||
level_interval: level_up::LEVEL_INTERVAL,
|
||||
level_invitations: level_up::LEVEL_INVITATIONS,
|
||||
min_blockage_migration_trust_level: check_blockage::MIN_TRUST_LEVEL,
|
||||
};
|
||||
|
||||
#[serde_as]
|
||||
|
|
|
@ -19,6 +19,8 @@ import init, {
|
|||
set_panic_hook, get_last_upgrade_time, get_trust_level, get_invites_remaining, get_issued_invite_expiry, get_received_invite_expiry, get_bridgelines_from_bucket} from "./pkg/lox_wasm.js";
|
||||
let pubkeys = await simple_request("/pubkeys");
|
||||
console.log("Got pubkeys: " + pubkeys);
|
||||
let constants = await simple_request("/constants");
|
||||
console.log("Got constants: " + constants);
|
||||
|
||||
// Get Lox Invitation
|
||||
let requested_invite = await init().then(() => {
|
||||
|
|
|
@ -789,19 +789,12 @@ pub fn get_bridgelines_from_bucket(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_constants() -> Result<String, JsValue> {
|
||||
match serde_json::to_string(&lox_utils::LOX_SYSTEM_INFO) {
|
||||
Ok(system_info_str) => Ok(system_info_str),
|
||||
Err(e) => Err(JsValue::from(e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn invitation_is_trusted(unspecified_invitation_str: String) -> Result<bool, JsValue> {
|
||||
match serde_json::from_str::<Invitation>(&unspecified_invitation_str) {
|
||||
Ok(_) => Ok(true),
|
||||
Err(_) => {
|
||||
let invite = unspecified_invitation_str.as_bytes();
|
||||
match lox_utils::validate(invite) {
|
||||
match serde_json::from_str::<lox_utils::Invite>(&unspecified_invitation_str){
|
||||
Ok(_) => Ok(false),
|
||||
Err(e) => Err(JsValue::from(e.to_string())),
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue