This provides a clear and consistent interface for selecting TLS-related
features on both (xmpp and tokio-xmpp) crates. All feature checks have
been revamped. All working combinations have been tested (including a
connectivity test + --all-features docs build) using:
```
set -xeuo pipefail
features=(aws_lc_rs ring ktls,aws_lc_rs ktls,ring aws_lc_rs,ring aws_lc_rs,ring,ktls native-tls rustls-any-backend)
export RUSTFLAGS=" -D warnings"
cargo test --no-default-features
cargo test
for feature in ${features[@]}; do
echo ">>> BUILDING with $feature" 2>&1
# Running code or building examples cannot succeed with rustls-any-backend.
features="starttls,$feature"
if [ "$feature" != 'rustls-any-backend' ]; then
if ! cargo test --no-default-features --features="$features"; then
echo ">>> BUILD FAILED for tls feature set: $features" >&2
exit 1
fi
set +e
timeout -sINT -p -k 2 3 cargo run --no-default-features --features="$features" --example keep_connection -- test@hub.sotecware.net "$(pass xmpp/test@hub.sotecware.net)"
status="$?"
set -e
if [ $status -ne 0 ]; then
echo ">>> keep_connection did not shut down cleanly! (status: $status)" >&2
exit 1
fi
else
if ! cargo build --no-default-features --features="$feature"; then
echo ">>> BUILD FAILED for tls feature set: $features" >&2
exit 1
fi
fi
done
RUSTDOCFLAGS="--cfg docsrs" RUSTFLAGS="--cfg xmpprs_doc_build" cargo +nightly doc -Zrustdoc-map --all-features
```
65 lines
2 KiB
Rust
65 lines
2 KiB
Rust
use futures::{SinkExt, StreamExt};
|
|
use tokio::{self, io, net::TcpSocket};
|
|
|
|
#[cfg(feature = "rustls-any-backend")]
|
|
use tokio_xmpp::rustls;
|
|
use tokio_xmpp::{
|
|
minidom::Element,
|
|
parsers::stream_features::StreamFeatures,
|
|
xmlstream::{accept_stream, StreamHeader, Timeouts},
|
|
};
|
|
|
|
#[cfg(all(
|
|
feature = "rustls-any-backend",
|
|
not(any(feature = "aws_lc_rs", feature = "ring"))
|
|
))]
|
|
compile_error!("using rustls (e.g. via the ktls feature) needs an enabled rustls backend feature (either aws_lc_rs or ring).");
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), io::Error> {
|
|
#[cfg(all(feature = "aws_lc_rs", not(feature = "ring")))]
|
|
rustls::crypto::aws_lc_rs::default_provider()
|
|
.install_default()
|
|
.expect("failed to install rustls crypto provider");
|
|
|
|
#[cfg(all(feature = "ring"))]
|
|
rustls::crypto::ring::default_provider()
|
|
.install_default()
|
|
.expect("failed to install rustls crypto provider");
|
|
|
|
// TCP socket
|
|
let address = "127.0.0.1:5222".parse().unwrap();
|
|
let socket = TcpSocket::new_v4()?;
|
|
socket.bind(address)?;
|
|
|
|
let listener = socket.listen(1024)?;
|
|
|
|
// Main loop, accepts incoming connections
|
|
loop {
|
|
let (stream, _addr) = listener.accept().await?;
|
|
let stream = accept_stream(
|
|
tokio::io::BufStream::new(stream),
|
|
tokio_xmpp::parsers::ns::DEFAULT_NS,
|
|
Timeouts::default(),
|
|
)
|
|
.await?;
|
|
let stream = stream.send_header(StreamHeader::default()).await?;
|
|
let mut stream = stream
|
|
.send_features::<Element>(&StreamFeatures::default())
|
|
.await?;
|
|
|
|
tokio::spawn(async move {
|
|
while let Some(packet) = stream.next().await {
|
|
match packet {
|
|
Ok(packet) => {
|
|
println!("Received packet: {:?}", packet);
|
|
stream.send(&packet).await.unwrap();
|
|
}
|
|
Err(e) => {
|
|
eprintln!("Error: {:?}", e);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|