@@ -46,6 +46,28 @@ pub enum TlsStream {
4646 Server ( StreamOwned < ServerConnection , TcpStream > ) ,
4747}
4848
49+ // The TLS-Stream objects cannot read or write volatile, thus we need a buffer
50+ // between the VolatileSlice and the TLS stream (see ReadVolatile and
51+ // WriteVolatile implementations below). Allocating this buffer in these
52+ // function calls would make it very slow, thus we tie the buffer to the stream
53+ // with this wrapper.
54+ pub struct TlsStreamWrapper {
55+ stream : TlsStream ,
56+ // Used only in ReadVolatile and WriteVolatile
57+ buf : Vec < u8 > ,
58+ }
59+
60+ static MAX_CHUNK : usize = 1024 * 64 ;
61+
62+ impl TlsStreamWrapper {
63+ pub fn new ( stream : TlsStream ) -> Self {
64+ Self {
65+ stream,
66+ buf : Vec :: new ( ) ,
67+ }
68+ }
69+ }
70+
4971impl Read for TlsStream {
5072 fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
5173 match self {
@@ -55,6 +77,12 @@ impl Read for TlsStream {
5577 }
5678}
5779
80+ impl Read for TlsStreamWrapper {
81+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
82+ Read :: read ( & mut self . stream , buf)
83+ }
84+ }
85+
5886impl Write for TlsStream {
5987 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
6088 match self {
@@ -70,38 +98,81 @@ impl Write for TlsStream {
7098 }
7199}
72100
101+ impl Write for TlsStreamWrapper {
102+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
103+ Write :: write ( & mut self . stream , buf)
104+ }
105+ fn flush ( & mut self ) -> io:: Result < ( ) > {
106+ Write :: flush ( & mut self . stream )
107+ }
108+ }
109+
73110// Reading from or writing to these FDs would break the connection, because
74111// those reads or writes wouldn't go through rustls. But the FD is used to wait
75112// until it becomes readable.
76- impl AsFd for TlsStream {
113+ impl AsFd for TlsStreamWrapper {
77114 fn as_fd ( & self ) -> BorrowedFd < ' _ > {
78- match self {
115+ match & self . stream {
79116 TlsStream :: Client ( s) => s. get_ref ( ) . as_fd ( ) ,
80117 TlsStream :: Server ( s) => s. get_ref ( ) . as_fd ( ) ,
81118 }
82119 }
83120}
84121
85- impl ReadVolatile for TlsStream {
122+ impl ReadVolatile for TlsStreamWrapper {
86123 fn read_volatile < B : BitmapSlice > (
87124 & mut self ,
88125 vs : & mut VolatileSlice < B > ,
89126 ) -> std:: result:: Result < usize , VolatileMemoryError > {
90- let mut tmp = vec ! [ 0u8 ; vs. len( ) ] ;
91- let n = Read :: read ( self , & mut tmp[ ..] ) . unwrap ( ) ;
92- vs. copy_from ( & tmp[ ..n] ) ;
127+ let len = vs. len ( ) . min ( MAX_CHUNK ) ;
128+
129+ if len == 0 {
130+ return Ok ( 0 ) ;
131+ }
132+
133+ if self . buf . len ( ) < len {
134+ self . buf . resize ( len, 0 ) ;
135+ }
136+
137+ let buf = & mut self . buf [ ..len] ;
138+ let n =
139+ Read :: read ( & mut self . stream , & mut buf[ ..len] ) . map_err ( VolatileMemoryError :: IOError ) ?;
140+
141+ if n == 0 {
142+ return Ok ( 0 ) ;
143+ }
144+
145+ vs. copy_from ( & buf[ ..n] ) ;
146+ self . buf . clear ( ) ;
147+
93148 Ok ( n)
94149 }
95150}
96151
97- impl WriteVolatile for TlsStream {
152+ impl WriteVolatile for TlsStreamWrapper {
98153 fn write_volatile < B : BitmapSlice > (
99154 & mut self ,
100155 vs : & VolatileSlice < B > ,
101156 ) -> std:: result:: Result < usize , VolatileMemoryError > {
102- let mut tmp = vec ! [ 0u8 ; vs. len( ) ] ;
103- let n = vs. copy_to ( & mut tmp[ ..] ) ;
104- let n = Write :: write ( self , & tmp[ ..n] ) . unwrap ( ) ;
157+ let len = vs. len ( ) . min ( MAX_CHUNK ) ;
158+ if len == 0 {
159+ return Ok ( 0 ) ;
160+ }
161+
162+ if self . buf . len ( ) < len {
163+ self . buf . resize ( len, 0 ) ;
164+ }
165+
166+ let buf = & mut self . buf [ ..len] ;
167+ let n = vs. copy_to ( & mut buf[ ..len] ) ;
168+
169+ if n == 0 {
170+ return Ok ( 0 ) ;
171+ }
172+
173+ let n = Write :: write ( & mut self . stream , & buf[ ..n] ) . map_err ( VolatileMemoryError :: IOError ) ?;
174+ self . buf . clear ( ) ;
175+
105176 Ok ( n)
106177 }
107178}
@@ -130,7 +201,10 @@ impl TlsConnectionWrapper {
130201 Self { config }
131202 }
132203
133- pub fn wrap ( & self , socket : TcpStream ) -> std:: result:: Result < TlsStream , MigratableError > {
204+ pub fn wrap (
205+ & self ,
206+ socket : TcpStream ,
207+ ) -> std:: result:: Result < TlsStreamWrapper , MigratableError > {
134208 let conn = ServerConnection :: new ( self . config . clone ( ) ) . map_err ( TlsError :: RustlsError ) ?;
135209
136210 let mut tls = StreamOwned :: new ( conn, socket) ;
@@ -146,7 +220,7 @@ impl TlsConnectionWrapper {
146220 }
147221 }
148222
149- Ok ( TlsStream :: Server ( tls) )
223+ Ok ( TlsStreamWrapper :: new ( TlsStream :: Server ( tls) ) )
150224 }
151225}
152226
0 commit comments