You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by yu...@apache.org on 2025/02/07 08:23:30 UTC
(incubator-teaclave-trustzone-sdk) branch main updated (3aa0c94 -> 3fcbb3e)
This is an automated email from the ASF dual-hosted git repository.
yuanz pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git
from 3aa0c94 Update OP-TEE to 4.5.0 for setup
new a709820 optee-utee: refactoring net module
new 3fcbb3e examples: update tcp_client-rs and udp_socket-rs to support no_std
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
README.md | 4 +-
ci/ci.sh | 4 +-
examples/tcp_client-rs/host/Cargo.toml | 1 +
examples/tcp_client-rs/host/Makefile | 5 -
examples/tcp_client-rs/host/src/main.rs | 62 +++-
examples/tcp_client-rs/proto/Cargo.toml | 1 +
examples/tcp_client-rs/proto/src/lib.rs | 18 +-
examples/tcp_client-rs/ta/Cargo.toml | 3 +-
examples/tcp_client-rs/ta/Makefile | 9 +-
examples/tcp_client-rs/ta/src/main.rs | 64 +++-
examples/udp_socket-rs/host/Makefile | 5 -
examples/udp_socket-rs/host/src/main.rs | 52 ++-
examples/udp_socket-rs/proto/Cargo.toml | 1 +
examples/udp_socket-rs/proto/src/lib.rs | 20 +-
examples/udp_socket-rs/ta/Cargo.toml | 4 +-
examples/udp_socket-rs/ta/Makefile | 9 +-
examples/udp_socket-rs/ta/src/main.rs | 59 +++-
optee-utee/src/lib.rs | 2 -
optee-utee/src/net.rs | 361 ---------------------
optee-utee/src/net/error.rs | 62 ++++
.../src/main.rs => optee-utee/src/net/mod.rs | 16 +-
optee-utee/src/net/optee.rs | 202 ++++++++++++
optee-utee/src/net/optee_no_std.rs | 150 +++++++++
optee-utee/src/net/optee_std.rs | 146 +++++++++
optee-utee/src/net/socket.rs | 102 ++++++
tests/optee-qemuv8.sh | 11 +-
26 files changed, 902 insertions(+), 471 deletions(-)
delete mode 100644 optee-utee/src/net.rs
create mode 100644 optee-utee/src/net/error.rs
copy optee-teec/systest/src/main.rs => optee-utee/src/net/mod.rs (72%)
create mode 100644 optee-utee/src/net/optee.rs
create mode 100644 optee-utee/src/net/optee_no_std.rs
create mode 100644 optee-utee/src/net/optee_std.rs
create mode 100644 optee-utee/src/net/socket.rs
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org
(incubator-teaclave-trustzone-sdk) 01/02: optee-utee: refactoring net module
Posted by yu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
yuanz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git
commit a7098204742df4b788d42bd7f062e278c8801a8c
Author: ivila <39...@qq.com>
AuthorDate: Fri Jan 17 12:43:44 2025 +0800
optee-utee: refactoring net module
- introduce the Socket struct for performing socket operations within TEE.
- introduce the SocketAdapter trait to support various implementations of the
GP TEE Sockets API.
- introduce a predefined optee module for TCP and UDP support in OP-TEE
compatible TEE OS.
Signed-off-by: ivila <39...@qq.com>
Reviewed-by: Yuan Zhuang <yu...@apache.org>
Reviewed-by: Sumit Garg <su...@linaro.org>
---
optee-utee/src/lib.rs | 2 -
optee-utee/src/net.rs | 361 -------------------------------------
optee-utee/src/net/error.rs | 62 +++++++
optee-utee/src/net/mod.rs | 30 +++
optee-utee/src/net/optee.rs | 202 +++++++++++++++++++++
optee-utee/src/net/optee_no_std.rs | 150 +++++++++++++++
optee-utee/src/net/optee_std.rs | 146 +++++++++++++++
optee-utee/src/net/socket.rs | 102 +++++++++++
8 files changed, 692 insertions(+), 363 deletions(-)
diff --git a/optee-utee/src/lib.rs b/optee-utee/src/lib.rs
index 679339c..af65778 100644
--- a/optee-utee/src/lib.rs
+++ b/optee-utee/src/lib.rs
@@ -64,6 +64,4 @@ pub mod time;
pub mod arithmetical;
pub mod extension;
pub mod uuid;
-
-#[cfg(target_os = "optee")]
pub mod net;
diff --git a/optee-utee/src/net.rs b/optee-utee/src/net.rs
deleted file mode 100644
index ea859b5..0000000
--- a/optee-utee/src/net.rs
+++ /dev/null
@@ -1,361 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use optee_utee_sys as raw;
-use std::io;
-use std::io::ErrorKind;
-use std::ptr;
-
-pub struct TcpStream {
- pub handle: raw::TEE_iSocketHandle,
-}
-
-impl TcpStream {
- fn connect_with_ip_version(
- address: &str,
- port: u16,
- ip_version: raw::TEE_ipSocket_ipVersion,
- ) -> std::io::Result<Self> {
- use std::ffi::CString;
- unsafe {
- let addr = match CString::new(address) {
- Ok(addr) => addr,
- Err(_) => return Err(io::Error::new(ErrorKind::Other, "Invalid address")),
- };
- let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
- let mut protocol_error: u32 = 0;
- let mut setup = raw::TEE_tcpSocket_Setup {
- ipVersion: ip_version,
- server_addr: addr.as_ptr() as _,
- server_port: port,
- };
- let ret = ((*raw::TEE_tcpSocket).open)(
- &mut handle,
- &mut setup as *mut raw::TEE_tcpSocket_Setup as _,
- &mut protocol_error,
- );
- match ret {
- raw::TEE_SUCCESS => Ok(Self { handle }),
- raw::TEE_ERROR_CANCEL => {
- Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
- }
- raw::TEE_ERROR_OUT_OF_MEMORY => {
- Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_OUT_OF_MEMORY"))
- }
- raw::TEE_ERROR_BAD_PARAMETERS => {
- Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_BAD_PARAMETERS"))
- }
- raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
- ErrorKind::TimedOut,
- "TEE_ISOCKET_ERROR_TIMEOUT",
- )),
- raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ERROR_COMMUNICATION",
- )),
- raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_PROTOCOL",
- )),
- raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- format!("TEE_ISOCKET_WARNING_PROTOCOL: {}", protocol_error),
- )),
- _ => panic!("Unexpected return value"),
- }
- }
- }
-
- pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
- Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
- }
-
- pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
- Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
- }
-
- pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
- Self::connect_v4(address, port)
- }
-}
-
-impl Drop for TcpStream {
- fn drop(&mut self) {
- // Ignore any errors on close.
- unsafe {
- ((*raw::TEE_tcpSocket).close)(self.handle);
- }
- }
-}
-
-impl std::io::Read for TcpStream {
- fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
- let mut length: u32 = buf.len() as _;
- let ret = unsafe {
- ((*raw::TEE_tcpSocket).recv)(
- self.handle,
- buf.as_mut_ptr() as _,
- &mut length,
- raw::TEE_TIMEOUT_INFINITE,
- )
- };
-
- match ret {
- raw::TEE_SUCCESS => Ok(length as _),
- raw::TEE_ERROR_CANCEL => {
- Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
- }
- raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
- ErrorKind::TimedOut,
- "TEE_ISOCKET_ERROR_TIMEOUT",
- )),
- raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ERROR_COMMUNICATION",
- )),
- raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
- )),
- raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_PROTOCOL",
- )),
- raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_WARNING_PROTOCOL",
- )),
- _ => panic!("Unexpected return value"),
- }
- }
-}
-
-impl std::io::Write for TcpStream {
- fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
- let mut length: u32 = buf.len() as _;
- let ret = unsafe {
- ((*raw::TEE_tcpSocket).send)(
- self.handle,
- buf.as_ptr() as *const u8 as _,
- &mut length,
- raw::TEE_TIMEOUT_INFINITE,
- )
- };
-
- match ret {
- raw::TEE_SUCCESS => Ok(length as _),
- raw::TEE_ERROR_CANCEL => {
- Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
- }
- raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
- ErrorKind::TimedOut,
- "TEE_ISOCKET_ERROR_TIMEOUT",
- )),
- raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
- )),
- raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_PROTOCOL",
- )),
- raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_WARNING_PROTOCOL",
- )),
- raw::TEE_ISOCKET_ERROR_LARGE_BUFFER => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_LARGE_BUFFER",
- )),
- _ => panic!("Unexpected return value"),
- }
- }
-
- fn flush(&mut self) -> std::io::Result<()> {
- Ok(())
- }
-}
-
-pub struct UdpSocket {
- pub handle: raw::TEE_iSocketHandle,
-}
-
-impl UdpSocket {
- fn connect_with_ip_version(
- address: &str,
- port: u16,
- ip_version: raw::TEE_ipSocket_ipVersion,
- ) -> std::io::Result<Self> {
- use std::ffi::CString;
- unsafe {
- let addr = match CString::new(address) {
- Ok(addr) => addr,
- Err(_) => return Err(io::Error::new(ErrorKind::Other, "Invalid address")),
- };
- let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
- let mut protocol_error: u32 = 0;
- let mut setup = raw::TEE_udpSocket_Setup {
- ipVersion: ip_version,
- server_addr: addr.as_ptr() as _,
- server_port: port,
- };
- let ret = ((*raw::TEE_udpSocket).open)(
- &mut handle,
- &mut setup as *mut raw::TEE_udpSocket_Setup as _,
- &mut protocol_error,
- );
- match ret {
- raw::TEE_SUCCESS => Ok(Self { handle }),
- raw::TEE_ERROR_CANCEL => {
- Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
- }
- raw::TEE_ERROR_OUT_OF_MEMORY => {
- Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_OUT_OF_MEMORY"))
- }
- raw::TEE_ERROR_BAD_PARAMETERS => {
- Err(io::Error::new(ErrorKind::Other, "TEE_ERROR_BAD_PARAMETERS"))
- }
- raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
- ErrorKind::TimedOut,
- "TEE_ISOCKET_ERROR_TIMEOUT",
- )),
- raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ERROR_COMMUNICATION",
- )),
- raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_PROTOCOL",
- )),
- raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- format!("TEE_ISOCKET_WARNING_PROTOCOL: {}", protocol_error),
- )),
- _ => panic!("Unexpected return value"),
- }
- }
- }
-
- pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
- Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
- }
-
- pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
- Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
- }
-
- pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
- Self::connect_v4(address, port)
- }
-}
-
-impl Drop for UdpSocket {
- fn drop(&mut self) {
- // Ignore any errors on close.
- unsafe {
- ((*raw::TEE_udpSocket).close)(self.handle);
- }
- }
-}
-
-impl std::io::Read for UdpSocket {
- fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
- let mut length: u32 = buf.len() as _;
- let ret = unsafe {
- ((*raw::TEE_udpSocket).recv)(
- self.handle,
- buf.as_mut_ptr() as _,
- &mut length,
- raw::TEE_TIMEOUT_INFINITE,
- )
- };
-
- match ret {
- raw::TEE_SUCCESS => Ok(length as _),
- raw::TEE_ERROR_CANCEL => {
- Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
- }
- raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
- ErrorKind::TimedOut,
- "TEE_ISOCKET_ERROR_TIMEOUT",
- )),
- raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ERROR_COMMUNICATION",
- )),
- raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
- )),
- raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_PROTOCOL",
- )),
- raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_WARNING_PROTOCOL",
- )),
- _ => panic!("Unexpected return value"),
- }
- }
-}
-
-impl std::io::Write for UdpSocket {
- fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
- let mut length: u32 = buf.len() as _;
- let ret = unsafe {
- ((*raw::TEE_udpSocket).send)(
- self.handle,
- buf.as_ptr() as *const u8 as _,
- &mut length,
- raw::TEE_TIMEOUT_INFINITE,
- )
- };
-
- match ret {
- raw::TEE_SUCCESS => Ok(length as _),
- raw::TEE_ERROR_CANCEL => {
- Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
- }
- raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
- ErrorKind::TimedOut,
- "TEE_ISOCKET_ERROR_TIMEOUT",
- )),
- raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
- ErrorKind::ConnectionAborted,
- "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
- )),
- raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_PROTOCOL",
- )),
- raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_WARNING_PROTOCOL",
- )),
- raw::TEE_ISOCKET_ERROR_LARGE_BUFFER => Err(io::Error::new(
- ErrorKind::Other,
- "TEE_ISOCKET_ERROR_LARGE_BUFFER",
- )),
- _ => panic!("Unexpected return value"),
- }
- }
-
- fn flush(&mut self) -> std::io::Result<()> {
- Ok(())
- }
-}
diff --git a/optee-utee/src/net/error.rs b/optee-utee/src/net/error.rs
new file mode 100644
index 0000000..b62ece2
--- /dev/null
+++ b/optee-utee/src/net/error.rs
@@ -0,0 +1,62 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use optee_utee_sys as raw;
+
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum SocketError {
+ ErrorProtocol(u32),
+ RemoteClosed,
+ Timeout,
+ OutOfResource,
+ WarningProtocol(u32),
+ LargeBuffer,
+ Hostname,
+ Tee(crate::ErrorKind),
+ Unknown(u32),
+}
+
+impl SocketError {
+ pub fn from_raw_error(code: u32, protocol_error: u32) -> Self {
+ match code {
+ raw::TEE_ISOCKET_ERROR_PROTOCOL => Self::ErrorProtocol(protocol_error),
+ raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Self::RemoteClosed,
+ raw::TEE_ISOCKET_ERROR_TIMEOUT => Self::Timeout,
+ raw::TEE_ISOCKET_ERROR_OUT_OF_RESOURCES => Self::OutOfResource,
+ raw::TEE_ISOCKET_ERROR_LARGE_BUFFER => Self::LargeBuffer,
+ raw::TEE_ISOCKET_WARNING_PROTOCOL => Self::WarningProtocol(protocol_error),
+ raw::TEE_ISOCKET_ERROR_HOSTNAME => Self::Hostname,
+ raw::TEE_ERROR_CANCEL
+ | raw::TEE_ERROR_COMMUNICATION
+ | raw::TEE_ERROR_OUT_OF_MEMORY
+ | raw::TEE_ERROR_BAD_PARAMETERS => Self::Tee(crate::Error::from_raw_error(code).kind()),
+ _ => Self::Unknown(code),
+ }
+ }
+}
+
+impl core::fmt::Display for SocketError {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ write!(f, "{:?}", self)
+ }
+}
+
+impl From<crate::Error> for SocketError {
+ fn from(value: crate::Error) -> Self {
+ Self::Tee(value.kind())
+ }
+}
diff --git a/optee-utee/src/net/mod.rs b/optee-utee/src/net/mod.rs
new file mode 100644
index 0000000..045453d
--- /dev/null
+++ b/optee-utee/src/net/mod.rs
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+mod error;
+mod optee;
+mod socket;
+
+pub use error::SocketError;
+pub use optee::{Setup, TcpAdapter, TcpStream, UdpAdapter, UdpSocket};
+pub use socket::{Socket, SocketAdapter};
+
+#[cfg(target_os = "optee")]
+mod optee_std;
+
+mod optee_no_std;
+pub use optee_no_std::{StdCompatConnect, StdCompatRead, StdCompatWrite};
diff --git a/optee-utee/src/net/optee.rs b/optee-utee/src/net/optee.rs
new file mode 100644
index 0000000..b198319
--- /dev/null
+++ b/optee-utee/src/net/optee.rs
@@ -0,0 +1,202 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use alloc::ffi::CString;
+use core::ptr;
+use optee_utee_sys as raw;
+
+use super::{Socket, SocketAdapter, SocketError};
+
+/// A setup parameter used for OP-TEE.
+pub struct Setup {
+ addr: CString,
+ port: u16,
+ version: raw::TEE_ipSocket_ipVersion,
+}
+
+impl Setup {
+ pub(crate) fn new(
+ addr: &str,
+ port: u16,
+ version: raw::TEE_ipSocket_ipVersion,
+ ) -> crate::Result<Self> {
+ Ok(Self {
+ addr: CString::new(addr).map_err(|_| crate::ErrorKind::BadParameters)?,
+ port,
+ version,
+ })
+ }
+ /// Construct a new IPv4 target parameter using the address and port. It
+ /// will return `BadParameters` if the address contains a `\0` character in
+ /// the middle.
+ pub fn new_v4(addr: &str, port: u16) -> crate::Result<Self> {
+ Self::new(addr, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
+ }
+ /// Construct a new IPv6 target parameter using the address and port. It
+ /// will return `BadParameters` if the address contains a `\0` character in
+ /// the middle.
+ pub fn new_v6(addr: &str, port: u16) -> crate::Result<Self> {
+ Self::new(addr, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_6)
+ }
+}
+
+/// An adapter for TCP sockets in OP-TEE. Typically, it is not used directly,
+/// but can be employed for wrapper operations, such as traffic control within
+/// the TEE.
+pub struct TcpAdapter(raw::TEE_iSocketHandle);
+/// An adapter for UDP sockets in OP-TEE. Typically, it is not used directly,
+/// but can be employed for wrapper operations, such as traffic control within
+/// the TEE.
+pub struct UdpAdapter(raw::TEE_iSocketHandle);
+/// A TcpStream that is compatible with OP-TEE.
+pub type TcpStream = Socket<TcpAdapter>;
+/// A UdpSocket that is compatible with OP-TEE.
+pub type UdpSocket = Socket<UdpAdapter>;
+
+fn handle_socket_operation_error(handle: raw::TEE_iSocketHandle, code: u32) -> SocketError {
+ match code {
+ raw::TEE_ISOCKET_ERROR_PROTOCOL => {
+ let protocol_error = unsafe { ((*raw::TEE_tcpSocket).error)(handle) };
+ SocketError::ErrorProtocol(protocol_error)
+ }
+ raw::TEE_ISOCKET_WARNING_PROTOCOL => {
+ let protocol_error = unsafe { ((*raw::TEE_tcpSocket).error)(handle) };
+ SocketError::WarningProtocol(protocol_error)
+ }
+ _ => SocketError::from_raw_error(code, 0),
+ }
+}
+
+impl SocketAdapter for TcpAdapter {
+ type Setup = Setup;
+ type Handle = Self;
+
+ fn open(setup: Self::Setup) -> Result<Self::Handle, SocketError> {
+ let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
+ let mut protocol_error: u32 = 0;
+ let mut setup = raw::TEE_tcpSocket_Setup {
+ ipVersion: setup.version,
+ server_addr: setup.addr.as_ptr() as _,
+ server_port: setup.port,
+ };
+ let ret = unsafe {
+ ((*raw::TEE_tcpSocket).open)(
+ &mut handle,
+ &mut setup as *mut raw::TEE_tcpSocket_Setup as _,
+ &mut protocol_error,
+ )
+ };
+ match ret {
+ raw::TEE_SUCCESS => Ok(Self(handle)),
+ _ => Err(SocketError::from_raw_error(ret, protocol_error)),
+ }
+ }
+ fn send(handle: &mut Self::Handle, buf: &[u8], timeout: u32) -> Result<usize, SocketError> {
+ let mut length: u32 = buf.len() as _;
+ let ret = unsafe {
+ ((*raw::TEE_tcpSocket).send)(
+ handle.0,
+ buf.as_ptr() as *const u8 as _,
+ &mut length,
+ timeout,
+ )
+ };
+ match ret {
+ raw::TEE_SUCCESS => Ok(length as usize),
+ _ => Err(handle_socket_operation_error(handle.0, ret)),
+ }
+ }
+ fn recv(handle: &mut Self::Handle, buf: &mut [u8], timeout: u32) -> Result<usize, SocketError> {
+ let mut length: u32 = buf.len() as _;
+ let ret = unsafe {
+ ((*raw::TEE_tcpSocket).recv)(handle.0, buf.as_mut_ptr() as _, &mut length, timeout)
+ };
+ match ret {
+ raw::TEE_SUCCESS => Ok(length as usize),
+ _ => Err(handle_socket_operation_error(handle.0, ret)),
+ }
+ }
+}
+
+impl Drop for TcpAdapter {
+ fn drop(&mut self) {
+ // Ignore any errors on close.
+ unsafe {
+ ((*raw::TEE_tcpSocket).close)(self.0);
+ }
+ }
+}
+
+impl SocketAdapter for UdpAdapter {
+ type Setup = Setup;
+ type Handle = Self;
+
+ fn open(setup: Self::Setup) -> Result<Self::Handle, SocketError> {
+ let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
+ let mut protocol_error: u32 = 0;
+ let mut setup = raw::TEE_udpSocket_Setup {
+ ipVersion: setup.version,
+ server_addr: setup.addr.as_ptr() as _,
+ server_port: setup.port,
+ };
+ let ret = unsafe {
+ ((*raw::TEE_udpSocket).open)(
+ &mut handle,
+ &mut setup as *mut raw::TEE_udpSocket_Setup as _,
+ &mut protocol_error,
+ )
+ };
+ match ret {
+ raw::TEE_SUCCESS => Ok(Self(handle)),
+ _ => Err(SocketError::from_raw_error(ret, protocol_error)),
+ }
+ }
+ fn send(handle: &mut Self::Handle, buf: &[u8], timeout: u32) -> Result<usize, SocketError> {
+ let mut length: u32 = buf.len() as _;
+ let ret = unsafe {
+ ((*raw::TEE_udpSocket).send)(
+ handle.0,
+ buf.as_ptr() as *const u8 as _,
+ &mut length,
+ timeout,
+ )
+ };
+ match ret {
+ raw::TEE_SUCCESS => Ok(length as usize),
+ _ => Err(handle_socket_operation_error(handle.0, ret)),
+ }
+ }
+ fn recv(handle: &mut Self::Handle, buf: &mut [u8], timeout: u32) -> Result<usize, SocketError> {
+ let mut length: u32 = buf.len() as _;
+ let ret = unsafe {
+ ((*raw::TEE_udpSocket).recv)(handle.0, buf.as_mut_ptr() as _, &mut length, timeout)
+ };
+ match ret {
+ raw::TEE_SUCCESS => Ok(length as usize),
+ _ => Err(handle_socket_operation_error(handle.0, ret)),
+ }
+ }
+}
+
+impl Drop for UdpAdapter {
+ fn drop(&mut self) {
+ // Ignore any errors on close.
+ unsafe {
+ ((*raw::TEE_udpSocket).close)(self.0);
+ }
+ }
+}
diff --git a/optee-utee/src/net/optee_no_std.rs b/optee-utee/src/net/optee_no_std.rs
new file mode 100644
index 0000000..dff4648
--- /dev/null
+++ b/optee-utee/src/net/optee_no_std.rs
@@ -0,0 +1,150 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+use super::{Setup, Socket, SocketAdapter, SocketError};
+
+/// A trait used for convenience; import it so that the code remains consistent
+/// with the std version (with the only difference being the return error type).
+///
+/// Take TcpStream as example:
+/// ```no_run
+/// use optee_utee::net::TcpStream;
+///
+/// fn connect_without_compact_trait(host: &str, port: u16) -> Result<TcpStream, SocketError> {
+/// let setup = Setup::new_v4(host, port)?;
+/// TcpStream::open(setup)
+/// }
+///
+/// fn connect_with_compact_trait(host: &str, port: u16) -> Result<TcpStream, SocketError> {
+/// use optee_utee::net::StdCompatConnect;
+///
+/// TcpStream::connect_v4(host, port)
+/// }
+/// ```
+pub trait StdCompatConnect: Sized {
+ fn connect_v4(address: &str, port: u16) -> Result<Self, SocketError>;
+ fn connect_v6(address: &str, port: u16) -> Result<Self, SocketError>;
+ fn connect(address: &str, port: u16) -> Result<Self, SocketError> {
+ Self::connect_v4(address, port)
+ }
+}
+
+/// A trait used for convenience; import it so that the code remains consistent
+/// with the std version (with the only difference being the return error type).
+///
+/// Take TcpStream as example:
+/// ```no_run
+/// use optee_utee::net::TcpStream;
+///
+/// fn write_without_compact_trait(stream: &mut Stream, mut buf: &[u8]) -> Result<usize, SocketError> {
+/// use optee_utee::ErrorKind;
+///
+/// while !buf.is_empty() {
+/// match stream.send(buf) {
+/// Ok(0) => return Err(SocketError::Tee(ErrorKind::Generic)),
+/// Ok(n) => buf = &buf[n..],
+/// Err(e) => return Err(e),
+/// }
+/// }
+/// Ok(())
+/// }
+///
+/// fn write_with_compact_trait(stream: &mut Stream, buf: &[u8]) -> Result<usize, SocketError> {
+/// use optee_utee::net::StdCompatWrite;
+///
+/// stream.write_all(buf)
+/// }
+/// ```
+pub trait StdCompatWrite {
+ fn write(&mut self, buf: &[u8]) -> Result<usize, SocketError>;
+ fn write_all(&mut self, mut buf: &[u8]) -> Result<(), SocketError> {
+ while !buf.is_empty() {
+ match self.write(buf)? {
+ 0 => return Err(SocketError::Tee(crate::ErrorKind::Generic)),
+ n => buf = &buf[n..],
+ }
+ }
+ Ok(())
+ }
+}
+
+/// A trait used for convenience; import it so that the code remains consistent
+/// with the std version (with the only difference being the return error type).
+///
+/// Take TcpStream as example:
+/// ```no_run
+/// use optee_utee::net::TcpStream;
+///
+/// fn read_without_compact_trait(stream: &mut Stream, mut buf: &mut [u8]) -> Result<usize, SocketError> {
+/// use optee_utee::ErrorKind;
+///
+/// while !buf.is_empty() {
+/// match stream.recv(buf) {
+/// Ok(0) => break;
+/// Ok(n) => buf = &mut buf[n..],
+/// Err(e) => return Err(e),
+/// }
+/// }
+/// if !buf.is_empty() {
+/// return Err(SocketError::Tee(ErrorKind::Generic));
+/// }
+/// Ok(())
+/// }
+///
+/// fn read_with_compact_trait(stream: &mut Stream, buf: &mut [u8]) -> Result<usize, SocketError> {
+/// use optee_utee::net::StdCompatRead;
+///
+/// stream.read_exact(buf)
+/// }
+/// ```
+pub trait StdCompatRead {
+ fn read(&mut self, buf: &mut [u8]) -> Result<usize, SocketError>;
+ fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<(), SocketError> {
+ while !buf.is_empty() {
+ match self.read(buf)? {
+ 0 => break,
+ n => buf = &mut buf[n..],
+ }
+ }
+ if !buf.is_empty() {
+ return Err(SocketError::Tee(crate::ErrorKind::Generic));
+ }
+ Ok(())
+ }
+}
+
+impl<T: SocketAdapter<Setup = Setup>> StdCompatConnect for Socket<T> {
+ fn connect_v4(address: &str, port: u16) -> Result<Self, SocketError> {
+ let setup = Setup::new_v4(address, port)?;
+ Self::open(setup)
+ }
+ fn connect_v6(address: &str, port: u16) -> Result<Self, SocketError> {
+ let setup = Setup::new_v6(address, port)?;
+ Self::open(setup)
+ }
+}
+
+impl<T: SocketAdapter<Setup = Setup>> StdCompatWrite for Socket<T> {
+ fn write(&mut self, buf: &[u8]) -> Result<usize, SocketError> {
+ self.send(buf)
+ }
+}
+
+impl<T: SocketAdapter<Setup = Setup>> StdCompatRead for Socket<T> {
+ fn read(&mut self, buf: &mut [u8]) -> Result<usize, SocketError> {
+ self.recv(buf)
+ }
+}
diff --git a/optee-utee/src/net/optee_std.rs b/optee-utee/src/net/optee_std.rs
new file mode 100644
index 0000000..e1aa2fb
--- /dev/null
+++ b/optee-utee/src/net/optee_std.rs
@@ -0,0 +1,146 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use optee_utee_sys as raw;
+
+use super::optee::Setup;
+use super::SocketError;
+use super::{TcpStream, UdpSocket};
+use alloc::format;
+
+impl TcpStream {
+ fn connect_with_ip_version(
+ address: &str,
+ port: u16,
+ ip_version: raw::TEE_ipSocket_ipVersion,
+ ) -> std::io::Result<Self> {
+ let setup = Setup::new(address, port, ip_version)
+ .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Invalid address"))?;
+ Ok(Self::open(setup).map_err(|err| Into::<std::io::Error>::into(err))?)
+ }
+ pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
+ Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
+ }
+ pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
+ Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_6)
+ }
+ pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
+ Self::connect_v4(address, port)
+ }
+}
+
+impl std::io::Read for TcpStream {
+ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+ match self.recv(buf) {
+ Ok(v) => Ok(v as usize),
+ Err(err) => Err(Into::<std::io::Error>::into(err)),
+ }
+ }
+}
+
+impl std::io::Write for TcpStream {
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+ match self.send(buf) {
+ Ok(v) => Ok(v as usize),
+ Err(err) => Err(Into::<std::io::Error>::into(err)),
+ }
+ }
+ fn flush(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+}
+
+impl UdpSocket {
+ fn connect_with_ip_version(
+ address: &str,
+ port: u16,
+ ip_version: raw::TEE_ipSocket_ipVersion,
+ ) -> std::io::Result<Self> {
+ let setup = Setup::new(address, port, ip_version)
+ .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Invalid address"))?;
+ Ok(Self::open(setup).map_err(|err| Into::<std::io::Error>::into(err))?)
+ }
+ pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
+ Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
+ }
+ pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
+ Self::connect_with_ip_version(address, port, raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_6)
+ }
+ pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
+ Self::connect_v4(address, port)
+ }
+}
+
+impl std::io::Read for UdpSocket {
+ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+ match self.recv(buf) {
+ Ok(v) => Ok(v as usize),
+ Err(err) => Err(Into::<std::io::Error>::into(err)),
+ }
+ }
+}
+
+impl std::io::Write for UdpSocket {
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+ match self.send(buf) {
+ Ok(v) => Ok(v as usize),
+ Err(err) => Err(Into::<std::io::Error>::into(err)),
+ }
+ }
+ fn flush(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+}
+
+// This is implemented to save developers from having to make numerous map_err
+// calls.
+impl Into<std::io::Error> for SocketError {
+ fn into(self) -> std::io::Error {
+ use std::io::{Error, ErrorKind};
+ match self {
+ SocketError::ErrorProtocol(protocol_error) => Error::new(
+ ErrorKind::Other,
+ format!("TEE_ISOCKET_ERROR_PROTOCOL: 0x{:08X}", protocol_error),
+ ),
+ SocketError::RemoteClosed => Error::new(
+ ErrorKind::ConnectionAborted,
+ "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
+ ),
+ SocketError::Timeout => Error::new(ErrorKind::TimedOut, "TEE_ISOCKET_ERROR_TIMEOUT"),
+ SocketError::OutOfResource => {
+ Error::new(ErrorKind::Other, "TEE_ISOCKET_ERROR_OUT_OF_RESOURCES")
+ }
+ SocketError::LargeBuffer => {
+ Error::new(ErrorKind::Other, "TEE_ISOCKET_ERROR_LARGE_BUFFER")
+ }
+ SocketError::WarningProtocol(protocol_error) => Error::new(
+ ErrorKind::Other,
+ format!("TEE_ISOCKET_WARNING_PROTOCOL: 0x{:08X}", protocol_error),
+ ),
+ SocketError::Hostname => Error::new(ErrorKind::Other, "TEE_ISOCKET_ERROR_HOSTNAME"),
+ SocketError::Tee(kind) => match kind {
+ crate::ErrorKind::OutOfMemory => {
+ Error::new(ErrorKind::OutOfMemory, "TEE_ERROR_OUT_OF_MEMORY")
+ }
+ _ => Error::new(ErrorKind::Other, kind.as_str()),
+ },
+ SocketError::Unknown(code) => {
+ Error::new(ErrorKind::Other, format!("Unknown: {:08X}", code))
+ }
+ }
+ }
+}
diff --git a/optee-utee/src/net/socket.rs b/optee-utee/src/net/socket.rs
new file mode 100644
index 0000000..ac3d43b
--- /dev/null
+++ b/optee-utee/src/net/socket.rs
@@ -0,0 +1,102 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use optee_utee_sys as raw;
+
+use super::SocketError;
+use core::time::Duration;
+
+/// A trait designed to accommodate various implementations of GP TEE Sockets
+/// API.
+///
+/// An implementation of this trait is responsible for handling all
+/// protocol-related tasks, including but not limited to:
+/// * Defining its own Setup type and using it to establish a new connection;
+/// * Sending and receiving data over the connection, while managing protocol
+/// errors (such as permitting certain warnings but raising others).
+pub trait SocketAdapter: Sized {
+ type Setup;
+ type Handle;
+
+ fn open(setup: Self::Setup) -> Result<Self::Handle, SocketError>;
+ fn send(handle: &mut Self::Handle, buf: &[u8], timeout: u32) -> Result<usize, SocketError>;
+ fn recv(handle: &mut Self::Handle, buf: &mut [u8], timeout: u32) -> Result<usize, SocketError>;
+}
+
+/// A struct used for socket operations.
+pub struct Socket<T: SocketAdapter> {
+ handle: T::Handle,
+ recv_timeout: u32,
+ send_timeout: u32,
+}
+
+impl<T: SocketAdapter> Socket<T> {
+ /// create a new connection, and then sending and receiving data over it.
+ pub fn open(setup: T::Setup) -> Result<Self, SocketError> {
+ let handle = T::open(setup)?;
+ Ok(Self {
+ handle,
+ recv_timeout: raw::TEE_TIMEOUT_INFINITE,
+ send_timeout: raw::TEE_TIMEOUT_INFINITE,
+ })
+ }
+ /// set timeout of recv operation.
+ pub fn set_recv_timeout_in_milli(&mut self, milliseconds: u32) {
+ self.recv_timeout = milliseconds;
+ }
+ /// set timeout of send operation.
+ pub fn set_send_timeout_in_milli(&mut self, milliseconds: u32) {
+ self.send_timeout = milliseconds;
+ }
+ /// a wrapper of `set_recv_timeout_in_milli`, similar to `set_read_timeout`
+ /// in std::net::TcpStream, it will set timeout to `TEE_TIMEOUT_INFINITE`
+ /// if `Option::None` is provided.
+ pub fn set_recv_timeout(&mut self, dur: Option<Duration>) -> crate::Result<()> {
+ let milliseconds = convert_duration_option_to_timeout(dur)?;
+ self.set_recv_timeout_in_milli(milliseconds);
+ Ok(())
+ }
+ /// a wrapper of `set_send_timeout_in_milli`, similar to
+ /// `set_write_timeout` in std::net::TcpStream, it will set timeout to
+ /// `TEE_TIMEOUT_INFINITE` if `Option::None` is provided.
+ pub fn set_send_timeout(&mut self, dur: Option<Duration>) -> crate::Result<()> {
+ let milliseconds = convert_duration_option_to_timeout(dur)?;
+ self.set_send_timeout_in_milli(milliseconds);
+ Ok(())
+ }
+ /// send data, similar to `write` in `io::Write`
+ pub fn send(&mut self, buf: &[u8]) -> Result<usize, SocketError> {
+ T::send(&mut self.handle, buf, self.send_timeout)
+ }
+ /// recv data, similar to `read` in `io::Read`
+ pub fn recv(&mut self, buf: &mut [u8]) -> Result<usize, SocketError> {
+ T::recv(&mut self.handle, buf, self.recv_timeout)
+ }
+}
+
+fn convert_duration_option_to_timeout(dur: Option<Duration>) -> crate::Result<u32> {
+ match dur {
+ None => Ok(raw::TEE_TIMEOUT_INFINITE),
+ Some(v) => {
+ let milliseconds = v.as_millis();
+ if milliseconds > (u32::MAX as u128) {
+ return Err(crate::ErrorKind::BadParameters.into());
+ }
+ Ok(milliseconds as u32)
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org
(incubator-teaclave-trustzone-sdk) 02/02: examples: update tcp_client-rs and udp_socket-rs to support no_std
Posted by yu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
yuanz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git
commit 3fcbb3eda15a6ac71132ff0a69ed080429d3e9cd
Author: ivila <39...@qq.com>
AuthorDate: Mon Jan 20 15:14:14 2025 +0800
examples: update tcp_client-rs and udp_socket-rs to support no_std
- add ipv6 call in tcp_client-rs and udp_socket-rs
- enable no_std run of tcp_client-rs and udp_socket-rs in ci
Signed-off-by: ivila <39...@qq.com>
Reviewed-by: Yuan Zhuang <yu...@apache.org>
Reviewed-by: Sumit Garg <su...@linaro.org>
---
README.md | 4 +--
ci/ci.sh | 4 +--
examples/tcp_client-rs/host/Cargo.toml | 1 +
examples/tcp_client-rs/host/Makefile | 5 ---
examples/tcp_client-rs/host/src/main.rs | 62 ++++++++++++++++++++++++++++----
examples/tcp_client-rs/proto/Cargo.toml | 1 +
examples/tcp_client-rs/proto/src/lib.rs | 18 +++++-----
examples/tcp_client-rs/ta/Cargo.toml | 3 +-
examples/tcp_client-rs/ta/Makefile | 9 ++---
examples/tcp_client-rs/ta/src/main.rs | 64 +++++++++++++++++++++++++--------
examples/udp_socket-rs/host/Makefile | 5 ---
examples/udp_socket-rs/host/src/main.rs | 52 +++++++++++++++++++--------
examples/udp_socket-rs/proto/Cargo.toml | 1 +
examples/udp_socket-rs/proto/src/lib.rs | 20 ++++++-----
examples/udp_socket-rs/ta/Cargo.toml | 4 +--
examples/udp_socket-rs/ta/Makefile | 9 ++---
examples/udp_socket-rs/ta/src/main.rs | 59 +++++++++++++++++++++++-------
tests/optee-qemuv8.sh | 11 ++----
18 files changed, 230 insertions(+), 102 deletions(-)
diff --git a/README.md b/README.md
index 7a13199..3b608be 100644
--- a/README.md
+++ b/README.md
@@ -81,8 +81,8 @@ branch (`main`), please refer to the
- **Common**: See
[Overview of OP-TEE Rust Examples](https://teaclave.apache.org/trustzone-sdk-docs/overview-of-optee-rust-examples/).
-- **`no-std`**: Excludes `test_serde`, `test_tcp_client`, `test_udp_socket`,
- `test_message_passing_interface`, `test_tls_client`, `test_tls_server`.
+- **`no-std`**: Excludes `test_serde`, `test_message_passing_interface`,
+ `test_tls_client`, `test_tls_server`.
## Quick Start with the OP-TEE Repo for QEMUv8
diff --git a/ci/ci.sh b/ci/ci.sh
index c58a03f..e10916f 100755
--- a/ci/ci.sh
+++ b/ci/ci.sh
@@ -35,13 +35,13 @@ pushd ../tests
./test_signature_verification.sh
./test_supp_plugin.sh
./test_error_handling.sh
+./test_tcp_client.sh
+./test_udp_socket.sh
# Run std only tests
if [ "$STD" ]; then
./test_serde.sh
./test_message_passing_interface.sh
- ./test_tcp_client.sh
- ./test_udp_socket.sh
./test_tls_client.sh
./test_tls_server.sh
./test_eth_wallet.sh
diff --git a/examples/tcp_client-rs/host/Cargo.toml b/examples/tcp_client-rs/host/Cargo.toml
index c8f3610..8c314d5 100644
--- a/examples/tcp_client-rs/host/Cargo.toml
+++ b/examples/tcp_client-rs/host/Cargo.toml
@@ -28,6 +28,7 @@ edition = "2018"
libc = "0.2.48"
proto = { path = "../proto" }
optee-teec = { path = "../../../optee-teec" }
+tiny_http = "0.12.0"
[profile.release]
lto = true
diff --git a/examples/tcp_client-rs/host/Makefile b/examples/tcp_client-rs/host/Makefile
index 7675483..75a545f 100644
--- a/examples/tcp_client-rs/host/Makefile
+++ b/examples/tcp_client-rs/host/Makefile
@@ -24,12 +24,7 @@ LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
OUT_DIR := $(CURDIR)/target/$(TARGET)/release
-ifeq ($(STD),)
-all:
- @echo "Please \`export STD=y\` then rerun \`source environment\` to build the STD version"
-else
all: host strip
-endif
host:
@cargo build --target $(TARGET_HOST) --release --config $(LINKER_CFG)
diff --git a/examples/tcp_client-rs/host/src/main.rs b/examples/tcp_client-rs/host/src/main.rs
index 75624db..6a0acdf 100644
--- a/examples/tcp_client-rs/host/src/main.rs
+++ b/examples/tcp_client-rs/host/src/main.rs
@@ -15,13 +15,33 @@
// specific language governing permissions and limitations
// under the License.
-use optee_teec::ParamNone;
-use optee_teec::{Context, Operation, Session, Uuid};
-use proto::{Command, UUID};
+use std::net::{Ipv6Addr, SocketAddr, SocketAddrV6};
+use std::thread;
-fn tcp_client(session: &mut Session) -> optee_teec::Result<()> {
- let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone, ParamNone);
+use optee_teec::{Context, Operation, ParamType, Session, Uuid};
+use optee_teec::{ParamNone, ParamTmpRef, ParamValue};
+use proto::{Command, IpVersion, UUID};
+
+fn tcp_client(
+ session: &mut Session,
+ address: &str,
+ port: u16,
+ ip_version: IpVersion,
+ host_name: &str,
+) -> optee_teec::Result<()> {
+ println!("Test on: {}", address);
+
+ let http_data = format!("GET / HTTP/1.0\r\nHost: {}\r\n\r\n", host_name);
+ let mut operation = Operation::new(
+ 0,
+ ParamTmpRef::new_input(address.as_bytes()),
+ ParamValue::new(port as u32, ip_version as u32, ParamType::ValueInput),
+ ParamTmpRef::new_input(http_data.as_bytes()),
+ ParamNone,
+ );
session.invoke_command(Command::Start as u32, &mut operation)?;
+
+ println!("Success");
Ok(())
}
@@ -30,8 +50,36 @@ fn main() -> optee_teec::Result<()> {
let uuid = Uuid::parse_str(UUID).unwrap();
let mut session = ctx.open_session(uuid)?;
- tcp_client(&mut session)?;
+ // test ipv4
+ const IPV4_HOST: &str = "teaclave.apache.org";
+ // Use the host directly to also check its domain name resolving capability.
+ tcp_client(&mut session, IPV4_HOST, 80, IpVersion::V4, IPV4_HOST)?;
+
+ // test ipv6
+ let addr = SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 0, 0, 0));
+ let server = tiny_http::Server::http(addr).unwrap();
+ let listen_addr = server.server_addr().to_ip().unwrap();
+ let ip = listen_addr.ip().to_string();
+ let port = listen_addr.port();
+
+ let child = thread::spawn(move || {
+ for request in server.incoming_requests() {
+ println!(
+ "received request! method: {:?}, url: {:?}, headers: {:?}",
+ request.method(),
+ request.url(),
+ request.headers()
+ );
+
+ let response = tiny_http::Response::from_string("hello world");
+ request.respond(response).unwrap();
+ break;
+ }
+ });
+ // Use the IP address directly to ensure we're actually trying an IPv6
+ // address.
+ tcp_client(&mut session, &ip, port, IpVersion::V6, &ip)?;
+ let _ = child.join();
- println!("Success");
Ok(())
}
diff --git a/examples/tcp_client-rs/proto/Cargo.toml b/examples/tcp_client-rs/proto/Cargo.toml
index b76ceb2..4a173c8 100644
--- a/examples/tcp_client-rs/proto/Cargo.toml
+++ b/examples/tcp_client-rs/proto/Cargo.toml
@@ -25,6 +25,7 @@ description = "Data structures and functions shared by host and TA."
edition = "2018"
[dependencies]
+num_enum = { version = "0.7.3", default-features = false }
[build-dependencies]
uuid = { version = "1.8", default-features = false }
diff --git a/examples/tcp_client-rs/proto/src/lib.rs b/examples/tcp_client-rs/proto/src/lib.rs
index 7679b2d..9034643 100644
--- a/examples/tcp_client-rs/proto/src/lib.rs
+++ b/examples/tcp_client-rs/proto/src/lib.rs
@@ -14,20 +14,22 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
+#![no_std]
+use num_enum::{FromPrimitive, TryFromPrimitive, IntoPrimitive};
+#[derive(FromPrimitive, IntoPrimitive)]
+#[repr(u32)]
pub enum Command {
Start,
+ #[default]
Unknown,
}
-impl From<u32> for Command {
- #[inline]
- fn from(value: u32) -> Command {
- match value {
- 0 => Command::Start,
- _ => Command::Unknown,
- }
- }
+#[derive(TryFromPrimitive, IntoPrimitive)]
+#[repr(u32)]
+pub enum IpVersion {
+ V4 = 1,
+ V6 = 2,
}
pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/examples/tcp_client-rs/ta/Cargo.toml b/examples/tcp_client-rs/ta/Cargo.toml
index fce4cb4..5f71c19 100644
--- a/examples/tcp_client-rs/ta/Cargo.toml
+++ b/examples/tcp_client-rs/ta/Cargo.toml
@@ -28,6 +28,7 @@ edition = "2018"
proto = { path = "../proto" }
optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
optee-utee = { path = "../../../optee-utee" }
+cfg_block = "0.2.0"
[build-dependencies]
proto = { path = "../proto" }
@@ -35,5 +36,5 @@ optee-utee-build = { path = "../../../optee-utee-build" }
[profile.release]
panic = "abort"
-lto = false
+lto = true
opt-level = 1
diff --git a/examples/tcp_client-rs/ta/Makefile b/examples/tcp_client-rs/ta/Makefile
index 42d9236..e69d885 100644
--- a/examples/tcp_client-rs/ta/Makefile
+++ b/examples/tcp_client-rs/ta/Makefile
@@ -29,15 +29,12 @@ TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
OUT_DIR := $(CURDIR)/target/$(TARGET)/release
-ifeq ($(STD),)
-all:
- @echo "Please \`export STD=y\` then rerun \`source environment\` to build the STD version"
-else
+BUILDER = $(if $(STD),xargo,cargo)
+
all: ta strip sign
-endif
ta:
- @xargo build --target $(TARGET) --release --config $(LINKER_CFG)
+ @$(BUILDER) build --target $(TARGET) --release --config $(LINKER_CFG)
strip: ta
@$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta
diff --git a/examples/tcp_client-rs/ta/src/main.rs b/examples/tcp_client-rs/ta/src/main.rs
index bc3a2b8..ddd9293 100644
--- a/examples/tcp_client-rs/ta/src/main.rs
+++ b/examples/tcp_client-rs/ta/src/main.rs
@@ -15,16 +15,28 @@
// specific language governing permissions and limitations
// under the License.
+#![cfg_attr(not(target_os = "optee"), no_std)]
#![no_main]
+cfg_block::cfg_block! {
+ // In Teaclave, if target_os = "optee", the codes is compiled with std.
+ // Otherwise, no-std
+ if #[cfg(target_os = "optee")] {
+ use std::io::{Read, Write};
+ } else {
+ extern crate alloc;
+ use optee_utee::net::{StdCompatConnect, StdCompatWrite, StdCompatRead};
+ use alloc::vec::Vec;
+ use alloc::string::String;
+ }
+}
+
use optee_utee::net::TcpStream;
use optee_utee::{
ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
};
use optee_utee::{Error, ErrorKind, Parameters, Result};
-use proto::Command;
-use std::io::Read;
-use std::io::Write;
+use proto::{Command, IpVersion};
#[ta_create]
fn create() -> Result<()> {
@@ -49,35 +61,59 @@ fn destroy() {
}
#[ta_invoke_command]
-fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
trace_println!("[+] TA invoke command");
match Command::from(cmd_id) {
Command::Start => {
- tcp_client();
- Ok(())
+ use core::convert::TryFrom;
+
+ let mut param0 = unsafe { params.0.as_memref()? };
+ let param1 = unsafe { params.1.as_value()? };
+ let mut param2 = unsafe { params.2.as_memref()? };
+
+ let address = core::str::from_utf8(param0.buffer()).unwrap();
+ let port = param1.a() as u16;
+ let ip_version =
+ IpVersion::try_from(param1.b()).map_err(|_| ErrorKind::BadParameters)?;
+ let http_data = param2.buffer();
+
+ tcp_client(address, port, ip_version, http_data)
}
_ => Err(Error::new(ErrorKind::BadParameters)),
}
}
-fn tcp_client() {
- let mut stream = TcpStream::connect("teaclave.apache.org", 80).unwrap();
- stream
- .write_all(b"GET / HTTP/1.0\r\nHost: teaclave.apache.org\r\n\r\n")
- .unwrap();
+fn tcp_client(address: &str, port: u16, ip_version: IpVersion, http_data: &[u8]) -> Result<()> {
+ let mut stream = match ip_version {
+ IpVersion::V4 => TcpStream::connect_v4(address, port),
+ IpVersion::V6 => TcpStream::connect_v6(address, port),
+ }
+ .map_err(|err| {
+ trace_println!("failed to connect to {}:{} due to {:?}", address, port, err);
+ ErrorKind::Generic
+ })?;
+
+ stream.set_send_timeout_in_milli(60 * 1000);
+ stream.set_recv_timeout_in_milli(60 * 1000);
+
+ stream.write_all(http_data).map_err(|err| {
+ trace_println!("failed to write_all due to {:?}", err);
+ ErrorKind::Generic
+ })?;
let mut response = Vec::new();
let mut chunk = [0u8; 1024];
loop {
match stream.read(&mut chunk) {
Ok(0) => break,
Ok(n) => response.extend_from_slice(&chunk[..n]),
- Err(_) => {
- trace_println!("Error");
- panic!();
+ Err(err) => {
+ trace_println!("failed to read due to {:?}", err);
+ return Err(ErrorKind::Generic.into());
}
}
}
trace_println!("{}", String::from_utf8_lossy(&response));
+ Ok(())
}
include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/udp_socket-rs/host/Makefile b/examples/udp_socket-rs/host/Makefile
index 90b6d44..734ed5c 100644
--- a/examples/udp_socket-rs/host/Makefile
+++ b/examples/udp_socket-rs/host/Makefile
@@ -24,12 +24,7 @@ LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
OUT_DIR := $(CURDIR)/target/$(TARGET)/release
-ifeq ($(STD),)
-all:
- @echo "Please \`export STD=y\` then rerun \`source environment\` to build the STD version"
-else
all: host strip
-endif
host:
@cargo build --target $(TARGET_HOST) --release --config $(LINKER_CFG)
diff --git a/examples/udp_socket-rs/host/src/main.rs b/examples/udp_socket-rs/host/src/main.rs
index 5e1db59..62076cc 100644
--- a/examples/udp_socket-rs/host/src/main.rs
+++ b/examples/udp_socket-rs/host/src/main.rs
@@ -14,28 +14,44 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
-
-use optee_teec::ParamNone;
-use optee_teec::{Context, Operation, Session, Uuid};
-use proto::{Command, UUID};
-use std::net::UdpSocket;
+use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, UdpSocket};
use std::str;
use std::thread;
-fn udp_socket(session: &mut Session) -> optee_teec::Result<()> {
- let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone, ParamNone);
- session.invoke_command(Command::Start as u32, &mut operation)?;
- Ok(())
-}
+use optee_teec::{Context, Operation, Uuid};
+use optee_teec::{ParamNone, ParamTmpRef, ParamValue};
+use proto::{Command, IpVersion, UUID};
-fn main() -> optee_teec::Result<()> {
- let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
+fn udp_socket(ip_version: IpVersion) {
+ let addr: SocketAddr = match ip_version {
+ IpVersion::V4 => SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0)),
+ IpVersion::V6 => SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 0, 0, 0)),
+ };
+ let socket = UdpSocket::bind(addr).unwrap();
+ let local_addr = socket.local_addr().unwrap();
+ println!("Test on: {}", local_addr);
- let mut ctx = Context::new()?;
- let uuid = Uuid::parse_str(UUID).unwrap();
let child = thread::spawn(move || {
+ let mut ctx = Context::new().unwrap();
+ let uuid = Uuid::parse_str(UUID).unwrap();
let mut session = ctx.open_session(uuid).unwrap();
- udp_socket(&mut session).unwrap();
+
+ let ip = local_addr.ip().to_string();
+ let port = local_addr.port();
+ let mut operation = Operation::new(
+ 0,
+ ParamTmpRef::new_input(ip.as_bytes()),
+ ParamValue::new(
+ port as u32,
+ ip_version as u32,
+ optee_teec::ParamType::ValueInput,
+ ),
+ ParamNone,
+ ParamNone,
+ );
+ session
+ .invoke_command(Command::Start as u32, &mut operation)
+ .unwrap();
});
let mut buf = [0; 100];
@@ -47,5 +63,11 @@ fn main() -> optee_teec::Result<()> {
let _ = child.join();
println!("Success");
+}
+
+fn main() -> optee_teec::Result<()> {
+ udp_socket(IpVersion::V4);
+ udp_socket(IpVersion::V6);
+
Ok(())
}
diff --git a/examples/udp_socket-rs/proto/Cargo.toml b/examples/udp_socket-rs/proto/Cargo.toml
index b76ceb2..4a173c8 100644
--- a/examples/udp_socket-rs/proto/Cargo.toml
+++ b/examples/udp_socket-rs/proto/Cargo.toml
@@ -25,6 +25,7 @@ description = "Data structures and functions shared by host and TA."
edition = "2018"
[dependencies]
+num_enum = { version = "0.7.3", default-features = false }
[build-dependencies]
uuid = { version = "1.8", default-features = false }
diff --git a/examples/udp_socket-rs/proto/src/lib.rs b/examples/udp_socket-rs/proto/src/lib.rs
index 7679b2d..88fa36b 100644
--- a/examples/udp_socket-rs/proto/src/lib.rs
+++ b/examples/udp_socket-rs/proto/src/lib.rs
@@ -14,20 +14,22 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
+#![no_std]
+use num_enum::{FromPrimitive, IntoPrimitive, TryFromPrimitive};
+#[derive(FromPrimitive, IntoPrimitive)]
+#[repr(u32)]
pub enum Command {
- Start,
+ Start = 1,
+ #[default]
Unknown,
}
-impl From<u32> for Command {
- #[inline]
- fn from(value: u32) -> Command {
- match value {
- 0 => Command::Start,
- _ => Command::Unknown,
- }
- }
+#[derive(TryFromPrimitive, IntoPrimitive)]
+#[repr(u32)]
+pub enum IpVersion {
+ V4 = 1,
+ V6 = 2,
}
pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/examples/udp_socket-rs/ta/Cargo.toml b/examples/udp_socket-rs/ta/Cargo.toml
index ba7d6d4..5f71c19 100644
--- a/examples/udp_socket-rs/ta/Cargo.toml
+++ b/examples/udp_socket-rs/ta/Cargo.toml
@@ -25,10 +25,10 @@ description = "An example of Rust OP-TEE TrustZone SDK."
edition = "2018"
[dependencies]
-libc = { path = "../../../rust/libc" }
proto = { path = "../proto" }
optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
optee-utee = { path = "../../../optee-utee" }
+cfg_block = "0.2.0"
[build-dependencies]
proto = { path = "../proto" }
@@ -36,5 +36,5 @@ optee-utee-build = { path = "../../../optee-utee-build" }
[profile.release]
panic = "abort"
-lto = false
+lto = true
opt-level = 1
diff --git a/examples/udp_socket-rs/ta/Makefile b/examples/udp_socket-rs/ta/Makefile
index 42d9236..e69d885 100644
--- a/examples/udp_socket-rs/ta/Makefile
+++ b/examples/udp_socket-rs/ta/Makefile
@@ -29,15 +29,12 @@ TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
OUT_DIR := $(CURDIR)/target/$(TARGET)/release
-ifeq ($(STD),)
-all:
- @echo "Please \`export STD=y\` then rerun \`source environment\` to build the STD version"
-else
+BUILDER = $(if $(STD),xargo,cargo)
+
all: ta strip sign
-endif
ta:
- @xargo build --target $(TARGET) --release --config $(LINKER_CFG)
+ @$(BUILDER) build --target $(TARGET) --release --config $(LINKER_CFG)
strip: ta
@$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta
diff --git a/examples/udp_socket-rs/ta/src/main.rs b/examples/udp_socket-rs/ta/src/main.rs
index 867c9d8..c187797 100644
--- a/examples/udp_socket-rs/ta/src/main.rs
+++ b/examples/udp_socket-rs/ta/src/main.rs
@@ -15,16 +15,29 @@
// specific language governing permissions and limitations
// under the License.
+#![cfg_attr(not(target_os = "optee"), no_std)]
#![no_main]
+cfg_block::cfg_block! {
+ // In Teaclave, if target_os = "optee", the codes is compiled with std.
+ // Otherwise, no-std
+ if #[cfg(target_os = "optee")] {
+ use std::io::{Read, Write};
+ } else {
+ extern crate alloc;
+ use optee_utee::net::{StdCompatConnect, StdCompatWrite, StdCompatRead};
+ use alloc::vec::Vec;
+ use alloc::string::String;
+ }
+}
+
+use core::convert::TryFrom;
use optee_utee::net::UdpSocket;
use optee_utee::{
ta_close_session, ta_create, ta_destroy, ta_invoke_command, ta_open_session, trace_println,
};
use optee_utee::{Error, ErrorKind, Parameters, Result};
-use proto::Command;
-use std::io::Read;
-use std::io::Write;
+use proto::{Command, IpVersion};
#[ta_create]
fn create() -> Result<()> {
@@ -49,20 +62,41 @@ fn destroy() {
}
#[ta_invoke_command]
-fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
trace_println!("[+] TA invoke command");
match Command::from(cmd_id) {
Command::Start => {
- udp_socket();
- Ok(())
+ let mut param0 = unsafe { params.0.as_memref()? };
+ let param1 = unsafe { params.1.as_value()? };
+
+ let address = core::str::from_utf8(param0.buffer()).unwrap();
+ let port = param1.a() as u16;
+ let ip_version =
+ IpVersion::try_from(param1.b()).map_err(|_| ErrorKind::BadParameters)?;
+
+ udp_socket(address, port, ip_version)
}
_ => Err(Error::new(ErrorKind::BadParameters)),
}
}
-fn udp_socket() {
- let mut stream = UdpSocket::connect("127.0.0.1", 34254).unwrap();
- stream.write_all(b"[TA]: Hello, Teaclave!").unwrap();
+fn udp_socket(address: &str, port: u16, ip_version: IpVersion) -> Result<()> {
+ let mut stream = match ip_version {
+ IpVersion::V4 => UdpSocket::connect_v4(address, port),
+ IpVersion::V6 => UdpSocket::connect_v6(address, port),
+ }
+ .map_err(|err| {
+ trace_println!("failed to connect to {}:{} due to {:?}", address, port, err);
+ ErrorKind::Generic
+ })?;
+
+ stream.set_send_timeout_in_milli(60 * 1000);
+ stream.set_recv_timeout_in_milli(60 * 1000);
+
+ stream.write_all(b"[TA]: Hello, Teaclave!").map_err(|err| {
+ trace_println!("failed to write_all due to {:?}", err);
+ ErrorKind::Generic
+ })?;
let mut response = Vec::new();
let mut chunk = [0u8; 1024];
@@ -74,13 +108,14 @@ fn udp_socket() {
response.extend_from_slice(&chunk[..n]);
break;
}
- Err(_) => {
- trace_println!("Error");
- panic!();
+ Err(err) => {
+ trace_println!("failed to read due to {:?}", err);
+ return Err(ErrorKind::Generic.into());
}
}
}
trace_println!("{}", String::from_utf8_lossy(&response));
+ Ok(())
}
include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/tests/optee-qemuv8.sh b/tests/optee-qemuv8.sh
index 0b8cd44..2a44e21 100755
--- a/tests/optee-qemuv8.sh
+++ b/tests/optee-qemuv8.sh
@@ -17,13 +17,6 @@
# specific language governing permissions and limitations
# under the License.
-# std examples: tcp_client, udp_socket, tls_client, tls_server needs the external network
-if [ "$STD" ]; then
- EXTERNAL_NETWORK_PARAMS=" \
- -netdev user,id=vmnic,hostfwd=:127.0.0.1:54433-:4433 \
- -device virtio-net-device,netdev=vmnic"
-fi
-
cd $1 && ./qemu-system-aarch64 \
-nodefaults \
-nographic \
@@ -37,4 +30,6 @@ cd $1 && ./qemu-system-aarch64 \
-append 'console=ttyAMA0,38400 keep_bootcon root=/dev/vda2' \
-kernel Image -no-acpi \
-fsdev local,id=fsdev0,path=$(pwd)/../shared,security_model=none \
- -device virtio-9p-device,fsdev=fsdev0,mount_tag=host $EXTERNAL_NETWORK_PARAMS
\ No newline at end of file
+ -device virtio-9p-device,fsdev=fsdev0,mount_tag=host \
+ -netdev user,id=vmnic,hostfwd=:127.0.0.1:54433-:4433 \
+ -device virtio-net-device,netdev=vmnic
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org