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