Merge "Fragmentation and reassembly of large messages" into main
diff --git a/lib.rs b/lib.rs
index d76cdb8..5c602d0 100644
--- a/lib.rs
+++ b/lib.rs
@@ -20,8 +20,8 @@
keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS},
ta::{AuthGraphTa, Role},
};
+use authgraph_wire::fragmentation::{Fragmenter, Reassembler, PLACEHOLDER_MORE_TO_COME};
use core::cell::RefCell;
-use dice_policy as _; // TODO: remove once dice_policy legitimately included in build
use log::{debug, error, info};
use secretkeeper_core::ta::SecretkeeperTa;
use tipc::{
@@ -83,9 +83,38 @@
}
}
+/// Break a response into fragments and send back to HAL service.
+fn fragmented_send(handle: &Handle, full_rsp: Vec<u8>) -> tipc::Result<()> {
+ for rsp_frag in Fragmenter::new(&full_rsp, MAX_MSG_SIZE) {
+ handle.send(&SkMessage(rsp_frag))?;
+ }
+ Ok(())
+}
+
+/// Process an incoming request that may arrive in fragments.
+fn fragmented_process<T>(
+ handle: &Handle,
+ msg: &[u8],
+ pending: &mut Reassembler,
+ process: T,
+) -> tipc::Result<MessageResult>
+where
+ T: Fn(&[u8]) -> Vec<u8>,
+{
+ // Accumulate request fragments until able to feed complete request to `process`.
+ if let Some(full_req) = pending.accumulate(msg) {
+ let full_rsp = process(&full_req);
+ fragmented_send(handle, full_rsp)?;
+ } else {
+ handle.send(&SkMessage(PLACEHOLDER_MORE_TO_COME.to_vec()))?;
+ }
+ Ok(MessageResult::MaintainConnection)
+}
+
/// Implementation of the TIPC service for AuthGraph.
struct AuthGraphService {
ta: Rc<RefCell<AuthGraphTa>>,
+ pending_req: RefCell<Reassembler>,
}
impl tipc::Service for AuthGraphService {
@@ -110,16 +139,16 @@
) -> tipc::Result<MessageResult> {
debug!("Received an AuthGraph message");
- // TODO: handle messages that need splitting
- let rsp = self.ta.borrow_mut().process(&msg.0);
- handle.send(&SkMessage(rsp))?;
- Ok(MessageResult::MaintainConnection)
+ fragmented_process(handle, &msg.0, &mut self.pending_req.borrow_mut(), |req| {
+ self.ta.borrow_mut().process(req)
+ })
}
}
/// Implementation of the TIPC service for Secretkeeper.
struct SecretkeeperService {
ta: Rc<RefCell<SecretkeeperTa>>,
+ pending_req: RefCell<Reassembler>,
}
impl tipc::Service for SecretkeeperService {
@@ -144,10 +173,9 @@
) -> tipc::Result<MessageResult> {
debug!("Received a SecretKeeper message");
- // TODO: handle messages that need splitting
- let rsp = self.ta.borrow_mut().process(&msg.0);
- handle.send(&SkMessage(rsp))?;
- Ok(MessageResult::MaintainConnection)
+ fragmented_process(handle, &msg.0, &mut self.pending_req.borrow_mut(), |req| {
+ self.ta.borrow_mut().process(req)
+ })
}
}
@@ -241,8 +269,8 @@
Role::Sink,
)));
- let ag_service = AuthGraphService { ta: ag_ta };
- let sk_service = SecretkeeperService { ta: sk_ta.clone() };
+ let ag_service = AuthGraphService { ta: ag_ta, pending_req: Default::default() };
+ let sk_service = SecretkeeperService { ta: sk_ta.clone(), pending_req: Default::default() };
let bl_service = BootloaderService { ta: sk_ta };
// Handle multiple TIPC services, one service per port.
diff --git a/rules.mk b/rules.mk
index 07977a9..265128e 100644
--- a/rules.mk
+++ b/rules.mk
@@ -27,6 +27,7 @@
MODULE_LIBRARY_DEPS += \
trusty/user/base/lib/authgraph-rust/boringssl \
trusty/user/base/lib/authgraph-rust/core \
+ trusty/user/base/lib/authgraph-rust/wire \
trusty/user/base/lib/secretkeeper/comm \
trusty/user/base/lib/secretkeeper/core \
trusty/user/base/lib/secretkeeper/dice_policy \