diff --git a/src/full.rs b/src/full.rs index e9ca6bf..7b89c1c 100644 --- a/src/full.rs +++ b/src/full.rs @@ -29,6 +29,7 @@ use bincode::{ use super::{ Peer, TunnelReader, + TunnelReadProv, TunnelReaderError, TunnelReaderNoRep, TunnelWriterExt, @@ -91,7 +92,7 @@ pub trait GenTunnelTraits { /// Reply writer use only to include a reply envelope type RW : TunnelWriterExt; type REP : ReplyProvider::Address>>; - type SP : SymProvider; + type SP : SymProvider + Clone; type TNR : TunnelNoRep; type EP : ErrorProvider; } @@ -118,6 +119,13 @@ pub struct Full { pub reply_once_buf_size : usize, pub _p : PhantomData, } +pub struct FullReadProv { + pub me : TT::P, + pub limiter_proto_r : TT::LR, + pub sym_prov : TT::SP, + pub _p : PhantomData, +} + type Shadows = CompExtW>,LW>; //type Shadows

= CompExtW>,LW>; @@ -274,6 +282,7 @@ pub fn clone_shadows_keys

TunnelNoRep for Full { + type ReadProv = FullReadProv; type P = TT::P; type W = FullW::Address>, MultipleErrorInfo, TT::P, TT::LW,TT::RW>; type TR = FullR::Address>, MultipleErrorInfo, TT::P, TT::LR>; @@ -484,8 +493,99 @@ impl TunnelNoRep for Full { }, } } + + fn new_tunnel_read_prov (&self) -> Self::ReadProv { + FullReadProv { + me : self.me.clone(), + limiter_proto_r : self.limiter_proto_r.clone(), + sym_prov : self.sym_prov.clone(), + _p : PhantomData, + } + } +} +impl TunnelReadProv for FullReadProv { + type T = Full; + fn new_reader (&mut self) -> ::TR { + let s = self.me.new_shadr(); + FullR { + error_code : None, + state: TunnelState::TunnelState, + current_cache_id: None, + current_reply_info: None, + current_error_info: None, + next_proxy_peer : None, + tunnel_id : None, // TODO useless remove?? + shad : CompExtR(s,self.limiter_proto_r.clone()), + content_limiter : self.limiter_proto_r.clone(), + need_content_limiter : false, + read_cache : false, + } + } + + fn new_dest_reader (&mut self, mut or : ::TR, r : &mut R) -> Result::DR>> { + Ok(match or.state { + TunnelState::TunnelState => { + None + }, + TunnelState::QueryOnce => { + Some(DestFull { + origin_read : or, + kind : DestFullKind::Id, + }) + }, + TunnelState::QueryCached => { + // same as query once because no bidirect cache yet (only replycache route use cache and we + // do not resend) and previous cache id in origin read + Some(DestFull { + origin_read : or, + kind : DestFullKind::Id, + }) + }, + TunnelState::ReplyOnce => { + + // TODO this is awkward : move key reading into or method to avoid those lifetime related + // copies TODO duplicate code move in function + let mut current_error_info = or.current_error_info; + or.current_error_info = None; + let mut current_reply_info = or.current_reply_info; + or.current_reply_info = None; + let mut ks : Vec>; + { + let mut inr = CompExtRInner(r, &mut or); + let len : usize = bin_decode(&mut inr, Infinite).map_err(|e|BincErr(e))?; + ks = Vec::with_capacity(len); + for _ in 0..len { + current_error_info.as_mut().unwrap().read_read_info(&mut inr)?;// should always be init. + current_reply_info.as_mut().unwrap().read_read_info(&mut inr)?;// should always be init. + // TODO replace unwrap by return + let k : &Vec = current_reply_info.as_ref().ok_or(IoError::new(IoErrorKind::Other, "unparsed reply info"))? + .get_reply_key().as_ref().ok_or(IoError::new(IoErrorKind::Other, "no reply key for reply info : wrong reply info"))?; + ks.push (k.clone()); + } + } + let cr = new_dest_cached_reader_ext(ks.into_iter().map(|k|self.sym_prov.new_sym_reader(k)).collect(), self.limiter_proto_r.clone()); + + or.current_reply_info = current_reply_info; + or.current_error_info = current_error_info; + or.read_end(r)?; + Some(DestFull { + origin_read : or, + kind : DestFullKind::Multi(cr), + }) + }, + TunnelState::ReplyCached => { + None + }, + TunnelState::QErrorCached => { + None + }, + }) + } } + + + impl Tunnel for Full { // reply info info needed to established conn type RI = MultipleReplyInfo<::Address>; diff --git a/src/lib.rs b/src/lib.rs index e7354c4..2537aae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -123,8 +123,8 @@ pub trait TunnelReaderExt : ExtRead { /// Tunnel trait could be in a single tunnel impl, but we use multiple to separate concerns a bit /// When a tunnel implement multiple trait it has property of all trait ('new_writer' of a /// TunnelNoRep if Tunnel trait is also implemented will write necessary info for reply). -pub trait TunnelNoRep { -// type ReadProv : TunnelReadProv, +pub trait TunnelNoRep : Sized { + type ReadProv : TunnelReadProv; /// Peer with their address and their asym shadow scheme type P : Peer; /// actual writer (tunnel logic using tunnel writer) @@ -149,17 +149,19 @@ pub trait TunnelNoRep { fn new_proxy_writer (&mut self, Self::TR, &::Address) -> Result<(Self::PW, ::Address)>; fn new_dest_reader (&mut self, Self::TR, &mut R) -> Result; - //fn new_tunnel_read_prov (&self) -> Self::ReadProv; + fn new_tunnel_read_prov (&self) -> Self::ReadProv; } -/* + /// Subset of TunelReader for reading without reverence to cache or route provider /// Can be use directly with a read stream without accessing a central tunnel impl. pub trait TunnelReadProv { - type TR : TunnelReaderNoRep; - type DR : TunnelReaderExt; - fn new_reader (&mut self) -> Self::TR; - fn new_dest_reader (&mut self, Self::TR, &mut R) -> Result; -}*/ + type T : TunnelNoRep; + fn new_reader (&mut self) -> ::TR; + /// same as tunnel dest reader but not mandatory (for instance we do not want to share cache + /// informations) + fn new_dest_reader (&mut self, ::TR, &mut R) -> Result::DR>>; +} + /// tunnel with reply pub trait Tunnel : TunnelNoRep where Self::TR : TunnelReader { // reply info info needed to established conn -> TODO type reply info looks useless : we create reply diff --git a/src/nope.rs b/src/nope.rs index fda9ece..dcee67d 100644 --- a/src/nope.rs +++ b/src/nope.rs @@ -6,6 +6,7 @@ use readwrite_comp::{ use super::{ TunnelWriter, TunnelNoRep, + TunnelReadProv, TunnelWriterExt, TunnelReaderExt, TunnelCache, @@ -257,6 +258,7 @@ impl

TunnelNope

{ } } impl

TunnelNoRep for TunnelNope

{ + type ReadProv = Self; type P = P; type W = Nope; type TR = Nope; @@ -268,4 +270,12 @@ impl

TunnelNoRep for TunnelNope

{ fn new_writer_with_route (&mut self, _ : &[&Self::P]) -> Self::W {Nope} fn new_proxy_writer (&mut self, _ : Self::TR, _ : &::Address) -> Result<(Self::PW,::Address)> {panic!("Nope do not implement that")} fn new_dest_reader (&mut self, _ : Self::TR, _ : &mut R) -> Result {Ok(Nope)} + fn new_tunnel_read_prov (&self) -> Self::ReadProv {TunnelNope::new()} } +impl

TunnelReadProv for TunnelNope

{ + type T = Self; + fn new_reader (&mut self) -> ::TR { Nope } + fn new_dest_reader (&mut self, _ : ::TR, _ : &mut R) -> Result::DR>> { Ok(Some(Nope)) } +} + +