2021-07-06 18:56:36 +00:00
|
|
|
use bytes::Buf;
|
|
|
|
use bytes::BytesMut;
|
|
|
|
|
|
|
|
use crate::actor::*;
|
2021-07-15 07:13:31 +00:00
|
|
|
use crate::during;
|
2021-07-06 18:56:36 +00:00
|
|
|
use crate::error::Error;
|
2021-07-08 22:04:11 +00:00
|
|
|
use crate::error::error;
|
2021-07-15 07:13:31 +00:00
|
|
|
use crate::schemas::gatekeeper;
|
2021-07-22 08:07:49 +00:00
|
|
|
use crate::schemas::internal_protocol as P;
|
2021-07-08 22:04:11 +00:00
|
|
|
use crate::schemas::sturdy;
|
2021-07-06 18:56:36 +00:00
|
|
|
|
|
|
|
use futures::Sink;
|
|
|
|
use futures::SinkExt;
|
|
|
|
use futures::Stream;
|
|
|
|
use futures::StreamExt;
|
|
|
|
|
2021-07-21 21:29:53 +00:00
|
|
|
use preserves::error::Error as PreservesError;
|
2021-07-15 07:13:31 +00:00
|
|
|
use preserves::error::is_eof_io_error;
|
2021-07-06 18:56:36 +00:00
|
|
|
use preserves::value::BinarySource;
|
|
|
|
use preserves::value::BytesBinarySource;
|
|
|
|
use preserves::value::DomainDecode;
|
|
|
|
use preserves::value::DomainEncode;
|
|
|
|
use preserves::value::IOValue;
|
|
|
|
use preserves::value::Map;
|
2021-07-08 22:04:11 +00:00
|
|
|
use preserves::value::NestedValue;
|
2021-07-06 18:56:36 +00:00
|
|
|
use preserves::value::NoEmbeddedDomainCodec;
|
|
|
|
use preserves::value::PackedReader;
|
|
|
|
use preserves::value::PackedWriter;
|
|
|
|
use preserves::value::Reader;
|
|
|
|
use preserves::value::Writer;
|
2021-07-08 22:04:11 +00:00
|
|
|
use preserves::value::signed_integer::SignedInteger;
|
2021-07-06 18:56:36 +00:00
|
|
|
|
2021-07-21 21:29:53 +00:00
|
|
|
use preserves_schema::support::Deserialize;
|
|
|
|
use preserves_schema::support::ParseError;
|
|
|
|
|
2021-07-06 18:56:36 +00:00
|
|
|
use std::convert::TryFrom;
|
|
|
|
use std::io;
|
|
|
|
use std::pin::Pin;
|
|
|
|
use std::sync::Arc;
|
2021-07-08 22:04:11 +00:00
|
|
|
use std::sync::atomic::AtomicUsize;
|
|
|
|
use std::sync::atomic::Ordering;
|
2021-07-06 18:56:36 +00:00
|
|
|
|
|
|
|
use tokio::io::AsyncRead;
|
|
|
|
use tokio::io::AsyncReadExt;
|
|
|
|
use tokio::io::AsyncWrite;
|
|
|
|
use tokio::io::AsyncWriteExt;
|
|
|
|
|
2021-07-08 22:04:11 +00:00
|
|
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedSender, UnboundedReceiver};
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
enum RelayInput {
|
|
|
|
Eof,
|
|
|
|
Packet(Vec<u8>),
|
|
|
|
Segment(Vec<u8>),
|
|
|
|
}
|
|
|
|
|
|
|
|
enum RelayProtocol {
|
|
|
|
Input(RelayInput),
|
|
|
|
Output(sturdy::Oid, P::Event),
|
|
|
|
SyncGc(Arc<Cap>),
|
|
|
|
Flush,
|
|
|
|
}
|
|
|
|
|
2021-07-06 18:56:36 +00:00
|
|
|
struct WireSymbol {
|
2021-07-08 22:04:11 +00:00
|
|
|
oid: sturdy::Oid,
|
2021-07-22 14:53:56 +00:00
|
|
|
obj: Arc<Cap>,
|
2021-07-08 22:04:11 +00:00
|
|
|
ref_count: AtomicUsize,
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Membrane {
|
2021-07-08 22:04:11 +00:00
|
|
|
oid_map: Map<sturdy::Oid, Arc<WireSymbol>>,
|
2021-07-22 14:53:56 +00:00
|
|
|
ref_map: Map<Arc<Cap>, Arc<WireSymbol>>,
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Membranes {
|
|
|
|
exported: Membrane,
|
|
|
|
imported: Membrane,
|
2021-07-08 22:04:11 +00:00
|
|
|
next_export_oid: usize,
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub enum Input {
|
|
|
|
Packets(Pin<Box<dyn Stream<Item = Result<Vec<u8>, Error>> + Send>>),
|
|
|
|
Bytes(Pin<Box<dyn AsyncRead + Send>>),
|
|
|
|
}
|
|
|
|
|
|
|
|
pub enum Output {
|
|
|
|
Packets(Pin<Box<dyn Sink<Vec<u8>, Error = Error> + Send>>),
|
|
|
|
Bytes(Pin<Box<dyn AsyncWrite + Send>>),
|
|
|
|
}
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
type TunnelRelayRef = Arc<Ref<RelayProtocol>>;
|
|
|
|
|
2021-07-06 18:56:36 +00:00
|
|
|
// There are other kinds of relay. This one has exactly two participants connected to each other.
|
|
|
|
pub struct TunnelRelay
|
|
|
|
{
|
2021-07-22 14:53:56 +00:00
|
|
|
self_ref: TunnelRelayRef,
|
2021-07-06 18:56:36 +00:00
|
|
|
input_buffer: BytesMut,
|
2021-07-22 08:07:49 +00:00
|
|
|
inbound_assertions: Map</* remote */ P::Handle, (/* local */ Handle, Vec<Arc<WireSymbol>>)>,
|
|
|
|
outbound_assertions: Map<P::Handle, Vec<Arc<WireSymbol>>>,
|
2021-07-06 18:56:36 +00:00
|
|
|
membranes: Membranes,
|
2021-07-22 08:07:49 +00:00
|
|
|
pending_outbound: Vec<P::TurnEvent>,
|
2021-07-15 11:13:22 +00:00
|
|
|
output: UnboundedSender<LoanedItem<Vec<u8>>>,
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-08 22:04:11 +00:00
|
|
|
struct RelayEntity {
|
2021-07-22 14:53:56 +00:00
|
|
|
relay_ref: TunnelRelayRef,
|
2021-07-08 22:04:11 +00:00
|
|
|
oid: sturdy::Oid,
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
impl WireSymbol {
|
|
|
|
fn acquire(&self) {
|
2021-07-08 22:04:11 +00:00
|
|
|
self.ref_count.fetch_add(1, Ordering::SeqCst);
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn release(&self) -> bool {
|
2021-07-08 22:04:11 +00:00
|
|
|
self.ref_count.fetch_sub(1, Ordering::SeqCst) == 1
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Membrane {
|
|
|
|
fn new() -> Self {
|
|
|
|
Membrane {
|
|
|
|
oid_map: Map::new(),
|
|
|
|
ref_map: Map::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
fn insert(&mut self, oid: sturdy::Oid, obj: Arc<Cap>) -> Arc<WireSymbol> {
|
2021-07-06 18:56:36 +00:00
|
|
|
let ws = Arc::new(WireSymbol {
|
|
|
|
oid: oid.clone(),
|
|
|
|
obj: Arc::clone(&obj),
|
2021-07-08 22:04:11 +00:00
|
|
|
ref_count: AtomicUsize::new(0),
|
2021-07-06 18:56:36 +00:00
|
|
|
});
|
|
|
|
self.oid_map.insert(oid, Arc::clone(&ws));
|
|
|
|
self.ref_map.insert(obj, Arc::clone(&ws));
|
|
|
|
ws
|
|
|
|
}
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
fn acquire(&mut self, r: &Arc<Cap>) -> Arc<WireSymbol> {
|
2021-07-08 22:04:11 +00:00
|
|
|
let ws = self.ref_map.get(r).expect("WireSymbol must be present at acquire() time");
|
|
|
|
ws.acquire();
|
|
|
|
Arc::clone(ws)
|
|
|
|
}
|
|
|
|
|
2021-07-06 18:56:36 +00:00
|
|
|
fn release(&mut self, ws: &Arc<WireSymbol>) {
|
|
|
|
if ws.release() {
|
|
|
|
self.oid_map.remove(&ws.oid);
|
|
|
|
self.ref_map.remove(&ws.obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-15 07:13:31 +00:00
|
|
|
pub fn connect_stream<I, O, E, F>(
|
|
|
|
t: &mut Activation,
|
|
|
|
i: I,
|
|
|
|
o: O,
|
|
|
|
sturdyref: sturdy::SturdyRef,
|
|
|
|
initial_state: E,
|
|
|
|
mut f: F,
|
|
|
|
) where
|
|
|
|
I: 'static + Send + AsyncRead,
|
|
|
|
O: 'static + Send + AsyncWrite,
|
2021-07-21 23:05:08 +00:00
|
|
|
E: 'static + Send + std::marker::Sync,
|
2021-07-22 14:53:56 +00:00
|
|
|
F: 'static + Send + std::marker::Sync + FnMut(&mut E, &mut Activation, Arc<Cap>) -> during::DuringResult<E>
|
2021-07-15 07:13:31 +00:00
|
|
|
{
|
|
|
|
let i = Input::Bytes(Box::pin(i));
|
|
|
|
let o = Output::Bytes(Box::pin(o));
|
|
|
|
let gatekeeper = TunnelRelay::run(t, i, o, None, Some(sturdy::Oid(0.into()))).unwrap();
|
2021-07-22 14:53:56 +00:00
|
|
|
let main_entity = t.actor.create(during::entity(initial_state).on_asserted(move |state, t, a: _Any| {
|
2021-07-15 07:13:31 +00:00
|
|
|
let denotation = a.value().to_embedded()?;
|
|
|
|
f(state, t, Arc::clone(denotation))
|
|
|
|
}));
|
2021-07-22 14:53:56 +00:00
|
|
|
gatekeeper.assert(t, &gatekeeper::Resolve {
|
2021-07-15 07:13:31 +00:00
|
|
|
sturdyref,
|
2021-07-22 14:53:56 +00:00
|
|
|
observer: Cap::new(&main_entity),
|
2021-07-15 07:13:31 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-07-06 18:56:36 +00:00
|
|
|
impl TunnelRelay {
|
2021-07-08 22:04:11 +00:00
|
|
|
pub fn run(
|
|
|
|
t: &mut Activation,
|
|
|
|
i: Input,
|
|
|
|
o: Output,
|
2021-07-22 14:53:56 +00:00
|
|
|
initial_ref: Option<Arc<Cap>>,
|
2021-07-08 22:04:11 +00:00
|
|
|
initial_oid: Option<sturdy::Oid>,
|
2021-07-22 14:53:56 +00:00
|
|
|
) -> Option<Arc<Cap>> {
|
2021-07-08 22:04:11 +00:00
|
|
|
let (output_tx, output_rx) = unbounded_channel();
|
|
|
|
let mut tr = TunnelRelay {
|
2021-07-22 14:53:56 +00:00
|
|
|
self_ref: t.actor.create_inert(),
|
2021-07-06 18:56:36 +00:00
|
|
|
input_buffer: BytesMut::with_capacity(1024),
|
2021-07-08 22:04:11 +00:00
|
|
|
output: output_tx,
|
2021-07-06 18:56:36 +00:00
|
|
|
inbound_assertions: Map::new(),
|
|
|
|
outbound_assertions: Map::new(),
|
|
|
|
membranes: Membranes {
|
|
|
|
exported: Membrane::new(),
|
|
|
|
imported: Membrane::new(),
|
2021-07-08 22:04:11 +00:00
|
|
|
next_export_oid: 0,
|
2021-07-06 18:56:36 +00:00
|
|
|
},
|
|
|
|
pending_outbound: Vec::new(),
|
2021-07-08 22:04:11 +00:00
|
|
|
};
|
|
|
|
if let Some(ir) = initial_ref {
|
|
|
|
tr.membranes.export_ref(ir, true);
|
|
|
|
}
|
2021-07-22 14:53:56 +00:00
|
|
|
let result = initial_oid.map(
|
|
|
|
|io| Arc::clone(&tr.membranes.import_oid(t.actor, &tr.self_ref, io).obj));
|
|
|
|
let tr_ref = Arc::clone(&tr.self_ref);
|
|
|
|
tr_ref.become_entity(tr);
|
2021-07-15 07:13:31 +00:00
|
|
|
t.actor.add_exit_hook(&tr_ref);
|
2021-07-08 22:04:11 +00:00
|
|
|
t.actor.linked_task(crate::name!("writer"), output_loop(o, output_rx));
|
|
|
|
t.actor.linked_task(crate::name!("reader"), input_loop(i, tr_ref));
|
|
|
|
result
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 08:07:49 +00:00
|
|
|
fn handle_inbound_packet(&mut self, t: &mut Activation, p: P::Packet) -> ActorResult {
|
2021-07-21 21:29:53 +00:00
|
|
|
// tracing::trace!(packet = debug(&p), "-->");
|
2021-07-06 18:56:36 +00:00
|
|
|
match p {
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Packet::Error(b) => {
|
2021-07-06 18:56:36 +00:00
|
|
|
tracing::info!(message = debug(b.message.clone()),
|
|
|
|
detail = debug(b.detail.clone()),
|
|
|
|
"received Error from peer");
|
|
|
|
Err(*b)
|
|
|
|
},
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Packet::Turn(b) => {
|
2021-07-15 11:13:22 +00:00
|
|
|
let t = &mut Activation::new(t.actor, Arc::clone(&t.debtor));
|
2021-07-22 08:07:49 +00:00
|
|
|
let P::Turn(events) = *b;
|
|
|
|
for P::TurnEvent { oid, event } in events {
|
2021-07-08 22:04:11 +00:00
|
|
|
let target = match self.membranes.exported.oid_map.get(&sturdy::Oid(oid.0.clone())) {
|
|
|
|
Some(ws) => &ws.obj,
|
|
|
|
None => return Err(error("Cannot deliver event: nonexistent oid",
|
2021-07-22 08:07:49 +00:00
|
|
|
_Any::from(&P::TurnEvent { oid, event }))),
|
2021-07-08 22:04:11 +00:00
|
|
|
};
|
|
|
|
match event {
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Event::Assert(b) => {
|
|
|
|
let P::Assert { assertion: P::Assertion(a), handle: remote_handle } = *b;
|
2021-07-08 22:04:11 +00:00
|
|
|
let mut imported = vec![];
|
|
|
|
let imported_membrane = &mut self.membranes.imported;
|
|
|
|
a.foreach_embedded::<_, Error>(&mut |r| {
|
|
|
|
Ok(imported.push(imported_membrane.acquire(r)))
|
|
|
|
})?;
|
2021-07-22 14:53:56 +00:00
|
|
|
if let Some(local_handle) = target.assert(t, a) {
|
|
|
|
if let Some(_) = self.inbound_assertions.insert(remote_handle, (local_handle, imported)) {
|
|
|
|
return Err(error("Assertion with duplicate handle", _Any::new(false)));
|
|
|
|
}
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Event::Retract(b) => {
|
|
|
|
let P::Retract { handle: remote_handle } = *b;
|
2021-07-08 22:04:11 +00:00
|
|
|
let (local_handle, imported) = match self.inbound_assertions.remove(&remote_handle) {
|
|
|
|
None => return Err(error("Retraction of nonexistent handle", _Any::from(&remote_handle))),
|
|
|
|
Some(wss) => wss,
|
|
|
|
};
|
|
|
|
for ws in imported.into_iter() {
|
|
|
|
self.membranes.imported.release(&ws);
|
|
|
|
}
|
|
|
|
t.retract(local_handle);
|
|
|
|
}
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Event::Message(b) => {
|
|
|
|
let P::Message { body: P::Assertion(a) } = *b;
|
2021-07-08 22:04:11 +00:00
|
|
|
let imported_membrane = &mut self.membranes.imported;
|
|
|
|
a.foreach_embedded(&mut |r| {
|
|
|
|
let ws = imported_membrane.acquire(r);
|
|
|
|
match ws.ref_count.load(Ordering::SeqCst) {
|
|
|
|
1 => Err(error("Cannot receive transient reference", _Any::new(false))),
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
|
|
|
})?;
|
2021-07-22 14:53:56 +00:00
|
|
|
target.message(t, a);
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Event::Sync(b) => {
|
|
|
|
let P::Sync { peer } = *b;
|
2021-07-08 22:04:11 +00:00
|
|
|
self.membranes.imported.acquire(&peer);
|
|
|
|
struct SyncPeer {
|
2021-07-22 14:53:56 +00:00
|
|
|
tr: TunnelRelayRef,
|
|
|
|
peer: Arc<Cap>,
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
2021-07-22 14:53:56 +00:00
|
|
|
impl Entity<Synced> for SyncPeer {
|
|
|
|
fn message(&mut self, t: &mut Activation, _a: Synced) -> ActorResult {
|
|
|
|
self.peer.message(t, _Any::new(true));
|
|
|
|
t.message(&self.tr, RelayProtocol::SyncGc(
|
|
|
|
Arc::clone(&self.peer)));
|
2021-07-08 22:04:11 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let k = t.actor.create(SyncPeer {
|
|
|
|
tr: Arc::clone(&self.self_ref),
|
|
|
|
peer: Arc::clone(&peer),
|
|
|
|
});
|
2021-07-22 14:53:56 +00:00
|
|
|
t.sync(&peer.underlying, k);
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 08:07:49 +00:00
|
|
|
fn handle_outbound_event(&mut self, t: &mut Activation, event: P::Event) -> Result<P::Event, Error> {
|
|
|
|
match &event {
|
|
|
|
P::Event::Assert(b) => {
|
|
|
|
let P::Assert { assertion: P::Assertion(a), handle } = &**b;
|
2021-07-08 22:04:11 +00:00
|
|
|
let mut outbound = Vec::new();
|
|
|
|
a.foreach_embedded::<_, Error>(
|
|
|
|
&mut |r| Ok(outbound.push(self.membranes.export_ref(Arc::clone(r), true))))?;
|
|
|
|
self.outbound_assertions.insert(handle.clone(), outbound);
|
|
|
|
}
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Event::Retract(b) => {
|
|
|
|
let P::Retract { handle } = &**b;
|
2021-07-08 22:04:11 +00:00
|
|
|
if let Some(outbound) = self.outbound_assertions.remove(handle) {
|
|
|
|
for ws in outbound.into_iter() {
|
|
|
|
self.membranes.exported.release(&ws);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Event::Message(b) => {
|
|
|
|
let P::Message { body: P::Assertion(a) } = &**b;
|
2021-07-08 22:04:11 +00:00
|
|
|
a.foreach_embedded(&mut |r| {
|
|
|
|
let ws = self.membranes.export_ref(Arc::clone(r), false);
|
|
|
|
match ws.ref_count.load(Ordering::SeqCst) {
|
|
|
|
0 => Err(error("Cannot send transient reference", _Any::new(false))),
|
|
|
|
_ => Ok(())
|
|
|
|
}
|
|
|
|
})?;
|
|
|
|
},
|
2021-07-22 08:07:49 +00:00
|
|
|
P::Event::Sync(_b) => panic!("TODO not yet implemented"),
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
Ok(event)
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 08:07:49 +00:00
|
|
|
fn encode_packet(&mut self, p: P::Packet) -> Result<Vec<u8>, Error> {
|
2021-07-08 22:04:11 +00:00
|
|
|
let item = _Any::from(&p);
|
2021-07-21 21:29:53 +00:00
|
|
|
// tracing::trace!(packet = debug(&item), "<--");
|
2021-07-08 22:04:11 +00:00
|
|
|
Ok(PackedWriter::encode::<_, _Any, _>(&mut self.membranes, &item)?)
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 08:07:49 +00:00
|
|
|
pub fn send_packet(&mut self, debtor: &Arc<Debtor>, cost: usize, p: P::Packet) -> ActorResult {
|
2021-07-06 18:56:36 +00:00
|
|
|
let bs = self.encode_packet(p)?;
|
2021-07-15 11:13:22 +00:00
|
|
|
let _ = self.output.send(LoanedItem::new(debtor, cost, bs));
|
2021-07-08 22:04:11 +00:00
|
|
|
Ok(())
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-08 22:04:11 +00:00
|
|
|
impl Membranes {
|
2021-07-22 14:53:56 +00:00
|
|
|
fn export_ref(&mut self, obj: Arc<Cap>, and_acquire: bool) -> Arc<WireSymbol> {
|
2021-07-08 22:04:11 +00:00
|
|
|
let ws = match self.exported.ref_map.get(&obj) {
|
|
|
|
None => {
|
|
|
|
let oid = sturdy::Oid(SignedInteger::from(self.next_export_oid as u128));
|
|
|
|
self.next_export_oid += 1;
|
|
|
|
self.exported.insert(oid, obj)
|
|
|
|
}
|
|
|
|
Some(ws) => Arc::clone(ws)
|
|
|
|
};
|
|
|
|
if and_acquire {
|
|
|
|
ws.acquire();
|
|
|
|
}
|
|
|
|
ws
|
|
|
|
}
|
|
|
|
|
|
|
|
fn import_oid(
|
|
|
|
&mut self,
|
|
|
|
ac: &mut Actor,
|
2021-07-22 14:53:56 +00:00
|
|
|
relay_ref: &TunnelRelayRef,
|
2021-07-08 22:04:11 +00:00
|
|
|
oid: sturdy::Oid,
|
|
|
|
) -> Arc<WireSymbol> {
|
|
|
|
let obj = ac.create(RelayEntity { relay_ref: Arc::clone(relay_ref), oid: oid.clone() });
|
2021-07-22 14:53:56 +00:00
|
|
|
self.imported.insert(oid, Cap::new(&obj))
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
|
2021-07-06 18:56:36 +00:00
|
|
|
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
|
|
|
|
&mut self,
|
2021-07-08 22:04:11 +00:00
|
|
|
t: &mut Activation,
|
2021-07-22 14:53:56 +00:00
|
|
|
relay_ref: &TunnelRelayRef,
|
2021-07-06 18:56:36 +00:00
|
|
|
src: &'src mut S,
|
|
|
|
_read_annotations: bool,
|
2021-07-22 08:07:49 +00:00
|
|
|
) -> io::Result<P::_Ptr> {
|
2021-07-06 18:56:36 +00:00
|
|
|
let v: IOValue = PackedReader::new(src, NoEmbeddedDomainCodec).demand_next(false)?;
|
2021-07-08 22:04:11 +00:00
|
|
|
match sturdy::WireRef::try_from(&v)? {
|
|
|
|
sturdy::WireRef::Mine{ oid: b } => {
|
|
|
|
let oid = *b;
|
|
|
|
match self.imported.oid_map.get(&oid) {
|
|
|
|
Some(ws) => Ok(Arc::clone(&ws.obj)),
|
|
|
|
None => Ok(Arc::clone(&self.import_oid(t.actor, relay_ref, oid).obj)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sturdy::WireRef::Yours { oid: b, attenuation } => {
|
|
|
|
let oid = *b;
|
|
|
|
match self.exported.oid_map.get(&oid) {
|
|
|
|
Some(ws) => {
|
|
|
|
if attenuation.is_empty() {
|
|
|
|
Ok(Arc::clone(&ws.obj))
|
|
|
|
} else {
|
2021-07-15 07:13:31 +00:00
|
|
|
Ok(ws.obj.attenuate(&sturdy::Attenuation(attenuation))
|
|
|
|
.map_err(|e| {
|
|
|
|
io::Error::new(
|
|
|
|
io::ErrorKind::InvalidInput,
|
|
|
|
format!("Invalid capability attenuation: {:?}", e))
|
|
|
|
})?)
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-22 14:53:56 +00:00
|
|
|
None => Ok(Cap::new(&t.actor.create_inert())),
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ActivatedMembranes<'a, 'activation, 'm>(&'a mut Activation<'activation>,
|
2021-07-22 14:53:56 +00:00
|
|
|
&'m TunnelRelayRef,
|
2021-07-08 22:04:11 +00:00
|
|
|
&'m mut Membranes);
|
|
|
|
|
2021-07-22 08:07:49 +00:00
|
|
|
impl<'a, 'activation, 'm> DomainDecode<P::_Ptr> for ActivatedMembranes<'a, 'activation, 'm> {
|
2021-07-08 22:04:11 +00:00
|
|
|
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
|
|
|
|
&mut self,
|
|
|
|
src: &'src mut S,
|
|
|
|
read_annotations: bool,
|
2021-07-22 08:07:49 +00:00
|
|
|
) -> io::Result<P::_Ptr> {
|
2021-07-08 22:04:11 +00:00
|
|
|
self.2.decode_embedded(self.0, self.1, src, read_annotations)
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 08:07:49 +00:00
|
|
|
impl DomainEncode<P::_Ptr> for Membranes {
|
2021-07-06 18:56:36 +00:00
|
|
|
fn encode_embedded<W: Writer>(
|
|
|
|
&mut self,
|
|
|
|
w: &mut W,
|
2021-07-22 08:07:49 +00:00
|
|
|
d: &P::_Ptr,
|
2021-07-06 18:56:36 +00:00
|
|
|
) -> io::Result<()> {
|
2021-07-08 22:04:11 +00:00
|
|
|
w.write(&mut NoEmbeddedDomainCodec, &_Any::from(&match self.exported.ref_map.get(d) {
|
2021-07-15 07:13:31 +00:00
|
|
|
Some(ws) => sturdy::WireRef::Mine {
|
|
|
|
oid: Box::new(ws.oid.clone()),
|
|
|
|
},
|
2021-07-08 22:04:11 +00:00
|
|
|
None => match self.imported.ref_map.get(d) {
|
|
|
|
Some(ws) => {
|
2021-07-15 07:13:31 +00:00
|
|
|
if d.attenuation.is_empty() {
|
|
|
|
sturdy::WireRef::Yours {
|
|
|
|
oid: Box::new(ws.oid.clone()),
|
|
|
|
attenuation: vec![],
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// We may trust the peer to enforce attenuation on our behalf, in
|
|
|
|
// which case we can return sturdy::WireRef::Yours with an attenuation
|
|
|
|
// attached here, but for now we don't.
|
|
|
|
sturdy::WireRef::Mine {
|
|
|
|
oid: Box::new(self.export_ref(Arc::clone(d), false).oid.clone()),
|
|
|
|
}
|
|
|
|
}
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
None =>
|
2021-07-15 07:13:31 +00:00
|
|
|
sturdy::WireRef::Mine {
|
|
|
|
oid: Box::new(self.export_ref(Arc::clone(d), false).oid.clone()),
|
|
|
|
},
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
}))
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
async fn input_loop(
|
2021-07-06 18:56:36 +00:00
|
|
|
i: Input,
|
2021-07-22 14:53:56 +00:00
|
|
|
relay: TunnelRelayRef,
|
2021-07-06 18:56:36 +00:00
|
|
|
) -> ActorResult {
|
2021-07-15 11:13:22 +00:00
|
|
|
#[must_use]
|
2021-07-22 14:53:56 +00:00
|
|
|
async fn s(
|
|
|
|
relay: &TunnelRelayRef,
|
|
|
|
debtor: &Arc<Debtor>,
|
|
|
|
m: RelayInput,
|
|
|
|
) -> ActorResult {
|
2021-07-15 11:13:22 +00:00
|
|
|
debtor.ensure_clear_funds().await;
|
2021-07-22 07:56:21 +00:00
|
|
|
let relay = Arc::clone(relay);
|
2021-07-22 14:53:56 +00:00
|
|
|
external_event(&Arc::clone(&relay.mailbox), debtor, Box::new(
|
|
|
|
move |t| relay.with_entity(|e| e.message(t, RelayProtocol::Input(m)))))
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-15 11:13:22 +00:00
|
|
|
let debtor = Debtor::new(crate::name!("input-loop"));
|
|
|
|
|
2021-07-06 18:56:36 +00:00
|
|
|
match i {
|
|
|
|
Input::Packets(mut src) => {
|
|
|
|
loop {
|
|
|
|
match src.next().await {
|
|
|
|
None => {
|
2021-07-22 14:53:56 +00:00
|
|
|
s(&relay, &debtor, RelayInput::Eof).await?;
|
2021-07-06 18:56:36 +00:00
|
|
|
return Ok(());
|
|
|
|
}
|
2021-07-15 07:13:31 +00:00
|
|
|
Some(bs) => {
|
2021-07-22 14:53:56 +00:00
|
|
|
s(&relay, &debtor, RelayInput::Packet(bs?)).await?;
|
2021-07-15 07:13:31 +00:00
|
|
|
}
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Input::Bytes(mut r) => {
|
2021-07-21 21:29:53 +00:00
|
|
|
const BUFSIZE: usize = 65536;
|
|
|
|
let mut buf = BytesMut::with_capacity(BUFSIZE);
|
2021-07-06 18:56:36 +00:00
|
|
|
loop {
|
2021-07-21 21:29:53 +00:00
|
|
|
buf.reserve(BUFSIZE);
|
2021-07-15 07:13:31 +00:00
|
|
|
let n = match r.read_buf(&mut buf).await {
|
|
|
|
Ok(n) => n,
|
|
|
|
Err(e) =>
|
|
|
|
if e.kind() == io::ErrorKind::ConnectionReset {
|
2021-07-22 14:53:56 +00:00
|
|
|
s(&relay, &debtor, RelayInput::Eof).await?;
|
2021-07-15 07:13:31 +00:00
|
|
|
return Ok(());
|
|
|
|
} else {
|
|
|
|
return Err(e)?;
|
|
|
|
},
|
|
|
|
};
|
2021-07-06 18:56:36 +00:00
|
|
|
match n {
|
|
|
|
0 => {
|
2021-07-22 14:53:56 +00:00
|
|
|
s(&relay, &debtor, RelayInput::Eof).await?;
|
2021-07-06 18:56:36 +00:00
|
|
|
return Ok(());
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
while buf.has_remaining() {
|
|
|
|
let bs = buf.chunk();
|
|
|
|
let n = bs.len();
|
2021-07-22 14:53:56 +00:00
|
|
|
s(&relay, &debtor, RelayInput::Segment(bs.to_vec())).await?;
|
2021-07-06 18:56:36 +00:00
|
|
|
buf.advance(n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
async fn output_loop(
|
2021-07-08 22:04:11 +00:00
|
|
|
mut o: Output,
|
2021-07-15 11:13:22 +00:00
|
|
|
mut output_rx: UnboundedReceiver<LoanedItem<Vec<u8>>>,
|
2021-07-08 22:04:11 +00:00
|
|
|
) -> ActorResult {
|
|
|
|
loop {
|
|
|
|
match output_rx.recv().await {
|
|
|
|
None =>
|
|
|
|
return Ok(()),
|
2021-07-15 11:13:22 +00:00
|
|
|
Some(mut loaned_item) => {
|
|
|
|
match &mut o {
|
|
|
|
Output::Packets(sink) => sink.send(std::mem::take(&mut loaned_item.item)).await?,
|
|
|
|
Output::Bytes(w) => {
|
|
|
|
w.write_all(&loaned_item.item).await?;
|
|
|
|
w.flush().await?;
|
|
|
|
}
|
2021-07-15 07:13:31 +00:00
|
|
|
}
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
impl Entity<RelayProtocol> for TunnelRelay {
|
|
|
|
fn message(&mut self, t: &mut Activation, m: RelayProtocol) -> ActorResult {
|
|
|
|
match m {
|
|
|
|
RelayProtocol::Input(RelayInput::Eof) => {
|
|
|
|
t.actor.shutdown();
|
|
|
|
}
|
|
|
|
RelayProtocol::Input(RelayInput::Packet(bs)) => {
|
|
|
|
let mut src = BytesBinarySource::new(&bs);
|
|
|
|
let mut dec = ActivatedMembranes(t, &self.self_ref, &mut self.membranes);
|
|
|
|
let mut r = src.packed::<_, _Any, _>(&mut dec);
|
|
|
|
let item = P::Packet::deserialize(&mut r)?;
|
|
|
|
self.handle_inbound_packet(t, item)?;
|
|
|
|
}
|
|
|
|
RelayProtocol::Input(RelayInput::Segment(bs)) => {
|
|
|
|
self.input_buffer.extend_from_slice(&bs);
|
|
|
|
loop {
|
|
|
|
let (e, count) = {
|
|
|
|
let mut src = BytesBinarySource::new(&self.input_buffer);
|
2021-07-21 21:29:53 +00:00
|
|
|
let mut dec = ActivatedMembranes(t, &self.self_ref, &mut self.membranes);
|
|
|
|
let mut r = src.packed::<_, _Any, _>(&mut dec);
|
2021-07-22 14:53:56 +00:00
|
|
|
let e = match P::Packet::deserialize(&mut r) {
|
|
|
|
Err(ParseError::Preserves(PreservesError::Io(e)))
|
|
|
|
if is_eof_io_error(&e) =>
|
|
|
|
None,
|
|
|
|
result => Some(result?),
|
2021-07-06 18:56:36 +00:00
|
|
|
};
|
2021-07-22 14:53:56 +00:00
|
|
|
(e, r.source.index)
|
|
|
|
};
|
|
|
|
match e {
|
|
|
|
None => break,
|
|
|
|
Some(item) => {
|
|
|
|
self.input_buffer.advance(count);
|
|
|
|
self.handle_inbound_packet(t, item)?;
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-22 14:53:56 +00:00
|
|
|
}
|
|
|
|
RelayProtocol::Output(oid, event) => {
|
|
|
|
if self.pending_outbound.is_empty() {
|
|
|
|
t.message_immediate_self(&self.self_ref, RelayProtocol::Flush);
|
2021-07-12 15:41:12 +00:00
|
|
|
}
|
2021-07-22 14:53:56 +00:00
|
|
|
let turn_event = P::TurnEvent {
|
|
|
|
oid: P::Oid(oid.0),
|
|
|
|
event: self.handle_outbound_event(t, event)?,
|
|
|
|
};
|
|
|
|
self.pending_outbound.push(turn_event);
|
|
|
|
}
|
|
|
|
RelayProtocol::SyncGc(peer) => {
|
|
|
|
if let Some(ws) = self.membranes.imported.ref_map.get(&peer) {
|
|
|
|
let ws = Arc::clone(ws); // cloned to release the borrow to permit the release
|
|
|
|
self.membranes.imported.release(&ws);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RelayProtocol::Flush => {
|
|
|
|
let events = std::mem::take(&mut self.pending_outbound);
|
|
|
|
self.send_packet(&t.debtor, events.len(), P::Packet::Turn(Box::new(P::Turn(events))))?
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
fn exit_hook(&mut self, t: &mut Activation, exit_status: &Arc<ActorResult>) -> ActorResult {
|
|
|
|
if let Err(e) = &**exit_status {
|
2021-07-06 18:56:36 +00:00
|
|
|
let e = e.clone();
|
2021-07-22 08:07:49 +00:00
|
|
|
self.send_packet(&t.debtor, 1, P::Packet::Error(Box::new(e)))?;
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
2021-07-21 23:05:08 +00:00
|
|
|
Ok(())
|
2021-07-06 18:56:36 +00:00
|
|
|
}
|
|
|
|
}
|
2021-07-08 22:04:11 +00:00
|
|
|
|
2021-07-22 14:53:56 +00:00
|
|
|
impl Entity<_Any> for RelayEntity {
|
2021-07-08 22:04:11 +00:00
|
|
|
fn assert(&mut self, t: &mut Activation, a: _Any, h: Handle) -> ActorResult {
|
2021-07-22 14:53:56 +00:00
|
|
|
Ok(t.message(&self.relay_ref, RelayProtocol::Output(
|
|
|
|
self.oid.clone(),
|
|
|
|
P::Event::Assert(Box::new(P::Assert {
|
2021-07-22 08:07:49 +00:00
|
|
|
assertion: P::Assertion(a),
|
|
|
|
handle: P::Handle(h.into()),
|
2021-07-22 14:53:56 +00:00
|
|
|
})))))
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
fn retract(&mut self, t: &mut Activation, h: Handle) -> ActorResult {
|
2021-07-22 14:53:56 +00:00
|
|
|
Ok(t.message(&self.relay_ref, RelayProtocol::Output(
|
|
|
|
self.oid.clone(),
|
|
|
|
P::Event::Retract(Box::new(P::Retract {
|
2021-07-22 08:07:49 +00:00
|
|
|
handle: P::Handle(h.into()),
|
2021-07-22 14:53:56 +00:00
|
|
|
})))))
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
fn message(&mut self, t: &mut Activation, m: _Any) -> ActorResult {
|
2021-07-22 14:53:56 +00:00
|
|
|
Ok(t.message(&self.relay_ref, RelayProtocol::Output(
|
|
|
|
self.oid.clone(),
|
|
|
|
P::Event::Message(Box::new(P::Message { body: P::Assertion(m) })))))
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
2021-07-22 14:53:56 +00:00
|
|
|
fn sync(&mut self, t: &mut Activation, peer: Arc<Ref<Synced>>) -> ActorResult {
|
|
|
|
Ok(t.message(&self.relay_ref, RelayProtocol::Output(
|
|
|
|
self.oid.clone(),
|
|
|
|
P::Event::Sync(Box::new(P::Sync { peer: Cap::guard(&peer) })))))
|
2021-07-08 22:04:11 +00:00
|
|
|
}
|
|
|
|
}
|