1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use crate::smtp::net::tls::TlsCapable;
use crate::smtp::net::tls::TlsProvider;
use crate::smtp::net::Connector;
use crate::smtp::net::TlsMode;
use crate::{smtp::net::ConnectionConfiguration, SyncFuture};
use async_std::io;
use async_std::net::{TcpStream, ToSocketAddrs};
use samotop_core::common::Pin;
use samotop_core::io::tls::MayBeTls;
#[derive(Debug)]
pub struct TcpConnector<TLS> {
pub tls_mode: TlsMode,
pub provider: TLS,
}
impl<TLS: Default> Default for TcpConnector<TLS> {
fn default() -> Self {
Self {
tls_mode: TlsMode::StartTls,
provider: TLS::default(),
}
}
}
impl<TLS> Connector for TcpConnector<TLS>
where
TLS: TlsProvider + Sync + Send + 'static,
{
type Stream = TlsCapable;
fn connect<'s, 'c, 'a, C: ConnectionConfiguration + Sync>(
&'s self,
configuration: &'c C,
) -> SyncFuture<'a, io::Result<Self::Stream>>
where
's: 'a,
'c: 'a,
{
Box::pin(async move {
let mut to = configuration.address();
let timeout = configuration.timeout();
let addr = to.to_socket_addrs().await?.next().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!("No address resolved for {}", to),
)
})?;
let stream = io::timeout(timeout, TcpStream::connect(addr)).await?;
to.find(':').map(|i| to.split_off(i));
let stream = Box::new(stream);
let mut stream = match self.provider.get_tls_upgrade() {
Some(u) => TlsCapable::enabled(stream, u, to),
None => TlsCapable::plaintext(stream),
};
match self.tls_mode {
TlsMode::Tls => Pin::new(&mut stream).encrypt(),
TlsMode::StartTls => { }
}
Ok(stream)
})
}
}