1use crate::{
2 dns,
3 error::Error,
4 socket::{
5 CipherSuite, PeerVerification, Socket, SocketFamily, SocketOption, SocketProtocol,
6 SocketType, SplitSocketHandle,
7 },
8 CancellationToken, LteLink,
9};
10use core::net::SocketAddr;
11
12pub struct TlsStream {
13 inner: Socket,
14}
15
16macro_rules! impl_receive {
17 () => {
18 pub async fn receive<'buf>(&self, buf: &'buf mut [u8]) -> Result<&'buf mut [u8], Error> {
21 self.receive_with_cancellation(buf, &Default::default())
22 .await
23 }
24
25 pub async fn receive_with_cancellation<'buf>(
28 &self,
29 buf: &'buf mut [u8],
30 token: &CancellationToken,
31 ) -> Result<&'buf mut [u8], Error> {
32 let max_receive_len = 1024.min(buf.len());
33 let received_bytes = self
34 .socket()
35 .receive(&mut buf[..max_receive_len], token)
36 .await?;
37 Ok(&mut buf[..received_bytes])
38 }
39
40 pub async fn receive_exact<'buf>(
46 &self,
47 buf: &'buf mut [u8],
48 ) -> Result<(), (Error, &'buf mut [u8])> {
49 self.receive_exact_with_cancellation(buf, &Default::default())
50 .await
51 }
52
53 pub async fn receive_exact_with_cancellation<'buf>(
59 &self,
60 buf: &'buf mut [u8],
61 token: &CancellationToken,
62 ) -> Result<(), (Error, &'buf mut [u8])> {
63 let mut received_bytes = 0;
64
65 while received_bytes < buf.len() {
66 match self
67 .receive_with_cancellation(&mut buf[received_bytes..], token)
68 .await
69 {
70 Ok(received_data) => received_bytes += received_data.len(),
71 Err(e) => return Err((e.into(), &mut buf[..received_bytes])),
72 }
73 }
74
75 Ok(())
76 }
77 };
78}
79
80macro_rules! impl_write {
81 () => {
82 pub async fn write(&self, buf: &[u8]) -> Result<(), Error> {
84 self.write_with_cancellation(buf, &Default::default()).await
85 }
86
87 pub async fn write_with_cancellation(
89 &self,
90 buf: &[u8],
91 token: &CancellationToken,
92 ) -> Result<(), Error> {
93 let mut written_bytes = 0;
94
95 while written_bytes < buf.len() {
96 let max_write_len = 1024.min(buf.len() - written_bytes);
98 written_bytes += self
99 .socket()
100 .write(&buf[written_bytes..][..max_write_len], token)
101 .await?;
102 }
103
104 Ok(())
105 }
106 };
107}
108
109impl TlsStream {
110 pub async fn connect(
122 hostname: &str,
123 port: u16,
124 peer_verify: PeerVerification,
125 security_tags: &[u32],
126 ciphers: Option<&[CipherSuite]>,
127 resume_sessions: bool,
128 ) -> Result<Self, Error> {
129 Self::connect_with_cancellation(
130 hostname,
131 port,
132 peer_verify,
133 security_tags,
134 ciphers,
135 resume_sessions,
136 &Default::default(),
137 )
138 .await
139 }
140
141 pub async fn connect_with_cancellation(
154 hostname: &str,
155 port: u16,
156 peer_verify: PeerVerification,
157 security_tags: &[u32],
158 ciphers: Option<&[CipherSuite]>,
159 resume_sessions: bool,
160 token: &CancellationToken,
161 ) -> Result<Self, Error> {
162 if security_tags.is_empty() {
163 return Err(Error::NoSecurityTag);
164 }
165
166 let lte_link = LteLink::new().await?;
167
168 let ip = dns::get_host_by_name_with_cancellation(hostname, token).await?;
169 let addr = SocketAddr::from((ip, port));
170
171 token.as_result()?;
172
173 let family = match addr {
174 SocketAddr::V4(_) => SocketFamily::Ipv4,
175 SocketAddr::V6(_) => SocketFamily::Ipv6,
176 };
177
178 let socket = Socket::create(family, SocketType::Stream, SocketProtocol::Tls1v2).await?;
179 socket.set_option(SocketOption::TlsPeerVerify(peer_verify.as_integer()))?;
180 socket.set_option(SocketOption::TlsSessionCache(resume_sessions as _))?;
181 socket.set_option(SocketOption::TlsTagList(security_tags))?;
182 socket.set_option(SocketOption::TlsHostName(hostname))?;
183 if let Some(ciphers) = ciphers {
184 socket.set_option(SocketOption::TlsCipherSuiteList(unsafe {
185 core::slice::from_raw_parts(ciphers.as_ptr() as *const i32, ciphers.len())
186 }))?;
187 }
188
189 match unsafe { socket.connect(addr, token).await } {
190 Ok(_) => {
191 lte_link.deactivate().await?;
192 Ok(TlsStream { inner: socket })
193 }
194 Err(e) => {
195 socket.deactivate().await?;
196 lte_link.deactivate().await?;
197 Err(e)
198 }
199 }
200 }
201
202 pub fn as_raw_fd(&self) -> i32 {
204 self.inner.as_raw_fd()
205 }
206
207 fn socket(&self) -> &Socket {
208 &self.inner
209 }
210
211 pub async fn split_owned(self) -> Result<(OwnedTlsReadStream, OwnedTlsWriteStream), Error> {
213 let (read_split, write_split) = self.inner.split().await?;
214
215 Ok((
216 OwnedTlsReadStream { stream: read_split },
217 OwnedTlsWriteStream {
218 stream: write_split,
219 },
220 ))
221 }
222
223 pub fn split(&self) -> (TlsReadStream<'_>, TlsWriteStream<'_>) {
225 (
226 TlsReadStream { socket: self },
227 TlsWriteStream { socket: self },
228 )
229 }
230
231 impl_receive!();
232 impl_write!();
233
234 pub async fn deactivate(self) -> Result<(), Error> {
237 self.inner.deactivate().await?;
238 Ok(())
239 }
240}
241
242crate::embedded_io_macros::impl_error_trait!(TlsStream, Error, <>);
243crate::embedded_io_macros::impl_read_trait!(TlsStream, <>);
244crate::embedded_io_macros::impl_write_trait!(TlsStream, <>);
245
246pub struct TlsReadStream<'a> {
248 socket: &'a TlsStream,
249}
250
251impl TlsReadStream<'_> {
252 fn socket(&self) -> &Socket {
253 &self.socket.inner
254 }
255
256 impl_receive!();
257}
258
259crate::embedded_io_macros::impl_error_trait!(TlsReadStream<'a>, Error, <'a>);
260crate::embedded_io_macros::impl_read_trait!(TlsReadStream<'a>, <'a>);
261
262pub struct TlsWriteStream<'a> {
264 socket: &'a TlsStream,
265}
266
267impl TlsWriteStream<'_> {
268 fn socket(&self) -> &Socket {
269 &self.socket.inner
270 }
271
272 impl_write!();
273}
274
275crate::embedded_io_macros::impl_error_trait!(TlsWriteStream<'a>, Error, <'a>);
276crate::embedded_io_macros::impl_write_trait!(TlsWriteStream<'a>, <'a>);
277
278pub struct OwnedTlsReadStream {
280 stream: SplitSocketHandle,
281}
282
283impl OwnedTlsReadStream {
284 fn socket(&self) -> &Socket {
285 &self.stream
286 }
287
288 impl_receive!();
289
290 pub async fn deactivate(self) -> Result<(), Error> {
293 self.stream.deactivate().await?;
294 Ok(())
295 }
296}
297
298crate::embedded_io_macros::impl_error_trait!(OwnedTlsReadStream, Error, <>);
299crate::embedded_io_macros::impl_read_trait!(OwnedTlsReadStream, <>);
300
301pub struct OwnedTlsWriteStream {
303 stream: SplitSocketHandle,
304}
305
306impl OwnedTlsWriteStream {
307 fn socket(&self) -> &Socket {
308 &self.stream
309 }
310
311 impl_write!();
312
313 pub async fn deactivate(self) -> Result<(), Error> {
316 self.stream.deactivate().await?;
317 Ok(())
318 }
319}
320
321crate::embedded_io_macros::impl_error_trait!(OwnedTlsWriteStream, Error, <>);
322crate::embedded_io_macros::impl_write_trait!(OwnedTlsWriteStream, <>);