1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 use optee_utee_sys as raw;
19 use std::io;
20 use std::io::ErrorKind;
21 use std::ptr;
22 
23 pub struct TcpStream {
24     pub handle: raw::TEE_iSocketHandle,
25 }
26 
27 impl TcpStream {
connect_with_ip_version( address: &str, port: u16, ip_version: raw::TEE_ipSocket_ipVersion, ) -> std::io::Result<Self>28     fn connect_with_ip_version(
29         address: &str,
30         port: u16,
31         ip_version: raw::TEE_ipSocket_ipVersion,
32     ) -> std::io::Result<Self> {
33         use std::ffi::CString;
34         unsafe {
35             let addr = match CString::new(address) {
36                 Ok(addr) => addr,
37                 Err(_) => return Err(io::Error::new(ErrorKind::Other, "Invalid address")),
38             };
39             let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
40             let mut protocol_error: u32 = 0;
41             let mut setup = raw::TEE_tcpSocket_Setup {
42                 ipVersion: ip_version,
43                 server_addr: addr.as_ptr() as _,
44                 server_port: port,
45             };
46             let ret = ((*raw::TEE_tcpSocket).open)(
47                 &mut handle,
48                 &mut setup as *mut raw::TEE_tcpSocket_Setup as _,
49                 &mut protocol_error,
50             );
51             match ret {
52                 raw::TEE_SUCCESS => Ok(Self { handle }),
53                 raw::TEE_ERROR_CANCEL => {
54                     Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
55                 }
56                 raw::TEE_ERROR_OUT_OF_MEMORY => {
57                     Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_OUT_OF_MEMORY"))
58                 }
59                 raw::TEE_ERROR_BAD_PARAMETERS => {
60                     Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_BAD_PARAMETERS"))
61                 }
62                 raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
63                     ErrorKind::TimedOut,
64                     "TEE_ISOCKET_ERROR_TIMEOUT",
65                 )),
66                 raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
67                     ErrorKind::ConnectionAborted,
68                     "TEE_ERROR_COMMUNICATION",
69                 )),
70                 raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
71                     ErrorKind::Other,
72                     "TEE_ISOCKET_ERROR_PROTOCOL",
73                 )),
74                 raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
75                     ErrorKind::Other,
76                     format!("TEE_ISOCKET_WARNING_PROTOCOL: {}", protocol_error),
77                 )),
78                 _ => panic!("Unexpected return value"),
79             }
80         }
81     }
82 
connect_v4(address: &str, port: u16) -> std::io::Result<Self>83     pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
84         Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
85     }
86 
connect_v6(address: &str, port: u16) -> std::io::Result<Self>87     pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
88         Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
89     }
90 
connect(address: &str, port: u16) -> std::io::Result<Self>91     pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
92         Self::connect_v4(address, port)
93     }
94 }
95 
96 impl Drop for TcpStream {
drop(&mut self)97     fn drop(&mut self) {
98         // Ignore any errors on close.
99         unsafe {
100             ((*raw::TEE_tcpSocket).close)(self.handle);
101         }
102     }
103 }
104 
105 impl std::io::Read for TcpStream {
read(&mut self, buf: &mut [u8]) -> std::io::Result<usize>106     fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
107         let mut length: u32 = buf.len() as _;
108         let ret = unsafe {
109             ((*raw::TEE_tcpSocket).recv)(
110                 self.handle,
111                 buf.as_mut_ptr() as _,
112                 &mut length,
113                 raw::TEE_TIMEOUT_INFINITE,
114             )
115         };
116 
117         match ret {
118             raw::TEE_SUCCESS => Ok(length as _),
119             raw::TEE_ERROR_CANCEL => {
120                 Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
121             }
122             raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
123                 ErrorKind::TimedOut,
124                 "TEE_ISOCKET_ERROR_TIMEOUT",
125             )),
126             raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
127                 ErrorKind::ConnectionAborted,
128                 "TEE_ERROR_COMMUNICATION",
129             )),
130             raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
131                 ErrorKind::ConnectionAborted,
132                 "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
133             )),
134             raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
135                 ErrorKind::Other,
136                 "TEE_ISOCKET_ERROR_PROTOCOL",
137             )),
138             raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
139                 ErrorKind::Other,
140                 "TEE_ISOCKET_WARNING_PROTOCOL",
141             )),
142             _ => panic!("Unexpected return value"),
143         }
144     }
145 }
146 
147 impl std::io::Write for TcpStream {
write(&mut self, buf: &[u8]) -> std::io::Result<usize>148     fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
149         let mut length: u32 = buf.len() as _;
150         let ret = unsafe {
151             ((*raw::TEE_tcpSocket).send)(
152                 self.handle,
153                 buf.as_ptr() as *const u8 as _,
154                 &mut length,
155                 raw::TEE_TIMEOUT_INFINITE,
156             )
157         };
158 
159         match ret {
160             raw::TEE_SUCCESS => Ok(length as _),
161             raw::TEE_ERROR_CANCEL => {
162                 Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
163             }
164             raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
165                 ErrorKind::TimedOut,
166                 "TEE_ISOCKET_ERROR_TIMEOUT",
167             )),
168             raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
169                 ErrorKind::ConnectionAborted,
170                 "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
171             )),
172             raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
173                 ErrorKind::Other,
174                 "TEE_ISOCKET_ERROR_PROTOCOL",
175             )),
176             raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
177                 ErrorKind::Other,
178                 "TEE_ISOCKET_WARNING_PROTOCOL",
179             )),
180             raw::TEE_ISOCKET_ERROR_LARGE_BUFFER => Err(io::Error::new(
181                 ErrorKind::Other,
182                 "TEE_ISOCKET_ERROR_LARGE_BUFFER",
183             )),
184             _ => panic!("Unexpected return value"),
185         }
186     }
187 
flush(&mut self) -> std::io::Result<()>188     fn flush(&mut self) -> std::io::Result<()> {
189         Ok(())
190     }
191 }
192 
193 pub struct UdpSocket {
194     pub handle: raw::TEE_iSocketHandle,
195 }
196 
197 impl UdpSocket {
connect_with_ip_version( address: &str, port: u16, ip_version: raw::TEE_ipSocket_ipVersion, ) -> std::io::Result<Self>198     fn connect_with_ip_version(
199         address: &str,
200         port: u16,
201         ip_version: raw::TEE_ipSocket_ipVersion,
202     ) -> std::io::Result<Self> {
203         use std::ffi::CString;
204         unsafe {
205             let addr = match CString::new(address) {
206                 Ok(addr) => addr,
207                 Err(_) => return Err(io::Error::new(ErrorKind::Other, "Invalid address")),
208             };
209             let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
210             let mut protocol_error: u32 = 0;
211             let mut setup = raw::TEE_udpSocket_Setup {
212                 ipVersion: ip_version,
213                 server_addr: addr.as_ptr() as _,
214                 server_port: port,
215             };
216             let ret = ((*raw::TEE_udpSocket).open)(
217                 &mut handle,
218                 &mut setup as *mut raw::TEE_udpSocket_Setup as _,
219                 &mut protocol_error,
220             );
221             match ret {
222                 raw::TEE_SUCCESS => Ok(Self { handle }),
223                 raw::TEE_ERROR_CANCEL => {
224                     Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
225                 }
226                 raw::TEE_ERROR_OUT_OF_MEMORY => {
227                     Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_OUT_OF_MEMORY"))
228                 }
229                 raw::TEE_ERROR_BAD_PARAMETERS => {
230                     Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_BAD_PARAMETERS"))
231                 }
232                 raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
233                     ErrorKind::TimedOut,
234                     "TEE_ISOCKET_ERROR_TIMEOUT",
235                 )),
236                 raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
237                     ErrorKind::ConnectionAborted,
238                     "TEE_ERROR_COMMUNICATION",
239                 )),
240                 raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
241                     ErrorKind::Other,
242                     "TEE_ISOCKET_ERROR_PROTOCOL",
243                 )),
244                 raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
245                     ErrorKind::Other,
246                     format!("TEE_ISOCKET_WARNING_PROTOCOL: {}", protocol_error),
247                 )),
248                 _ => panic!("Unexpected return value"),
249             }
250         }
251     }
252 
connect_v4(address: &str, port: u16) -> std::io::Result<Self>253     pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
254         Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
255     }
256 
connect_v6(address: &str, port: u16) -> std::io::Result<Self>257     pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
258         Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
259     }
260 
connect(address: &str, port: u16) -> std::io::Result<Self>261     pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
262         Self::connect_v4(address, port)
263     }
264 }
265 
266 impl Drop for UdpSocket {
drop(&mut self)267     fn drop(&mut self) {
268         // Ignore any errors on close.
269         unsafe {
270             ((*raw::TEE_udpSocket).close)(self.handle);
271         }
272     }
273 }
274 
275 impl std::io::Read for UdpSocket {
read(&mut self, buf: &mut [u8]) -> std::io::Result<usize>276     fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
277         let mut length: u32 = buf.len() as _;
278         let ret = unsafe {
279             ((*raw::TEE_udpSocket).recv)(
280                 self.handle,
281                 buf.as_mut_ptr() as _,
282                 &mut length,
283                 raw::TEE_TIMEOUT_INFINITE,
284             )
285         };
286 
287         match ret {
288             raw::TEE_SUCCESS => Ok(length as _),
289             raw::TEE_ERROR_CANCEL => {
290                 Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
291             }
292             raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
293                 ErrorKind::TimedOut,
294                 "TEE_ISOCKET_ERROR_TIMEOUT",
295             )),
296             raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
297                 ErrorKind::ConnectionAborted,
298                 "TEE_ERROR_COMMUNICATION",
299             )),
300             raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
301                 ErrorKind::ConnectionAborted,
302                 "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
303             )),
304             raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
305                 ErrorKind::Other,
306                 "TEE_ISOCKET_ERROR_PROTOCOL",
307             )),
308             raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
309                 ErrorKind::Other,
310                 "TEE_ISOCKET_WARNING_PROTOCOL",
311             )),
312             _ => panic!("Unexpected return value"),
313         }
314     }
315 }
316 
317 impl std::io::Write for UdpSocket {
write(&mut self, buf: &[u8]) -> std::io::Result<usize>318     fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
319         let mut length: u32 = buf.len() as _;
320         let ret = unsafe {
321             ((*raw::TEE_udpSocket).send)(
322                 self.handle,
323                 buf.as_ptr() as *const u8 as _,
324                 &mut length,
325                 raw::TEE_TIMEOUT_INFINITE,
326             )
327         };
328 
329         match ret {
330             raw::TEE_SUCCESS => Ok(length as _),
331             raw::TEE_ERROR_CANCEL => {
332                 Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
333             }
334             raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
335                 ErrorKind::TimedOut,
336                 "TEE_ISOCKET_ERROR_TIMEOUT",
337             )),
338             raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
339                 ErrorKind::ConnectionAborted,
340                 "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
341             )),
342             raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
343                 ErrorKind::Other,
344                 "TEE_ISOCKET_ERROR_PROTOCOL",
345             )),
346             raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
347                 ErrorKind::Other,
348                 "TEE_ISOCKET_WARNING_PROTOCOL",
349             )),
350             raw::TEE_ISOCKET_ERROR_LARGE_BUFFER => Err(io::Error::new(
351                 ErrorKind::Other,
352                 "TEE_ISOCKET_ERROR_LARGE_BUFFER",
353             )),
354             _ => panic!("Unexpected return value"),
355         }
356     }
357 
flush(&mut self) -> std::io::Result<()>358     fn flush(&mut self) -> std::io::Result<()> {
359         Ok(())
360     }
361 }
362