turn_types/
lib.rs

1// Copyright (C) 2025 Matthew Waters <matthew@centricular.com>
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9#![deny(missing_debug_implementations)]
10#![deny(missing_docs)]
11#![cfg_attr(docsrs, feature(doc_cfg))]
12
13//! # turn-types
14//!
15//! `turn-types` provides an implementation for two main things related to TURN clients and servers:
16//! 1. TURN specific STUN attributes using the [stun-types] crate.
17//! 2. Parsing to and from the actual data sent and received on the wire between a TURN client and
18//!    a TURN server.
19//!
20//! This crate implements the STUN attributes and methods presented in the following standards:
21//! - [RFC5766]: Traversal Using Relays around NAT (TURN).
22//! - [RFC6062]: Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations
23//! - [RFC6156]: Traversal Using Relays around NAT (TURN) Extension for IPv6
24//! - [RFC8656]: Traversal Using Relays around NAT (TURN): Relay Extensions to Session
25//!   Traversal Utilities for NAT (STUN)
26//!
27//! [stun-types]: https://docs.rs/stun-types/latest/stun_types
28//! [RFC5766]: https://tools.ietf.org/html/rfc5766
29//! [RFC6062]: https://tools.ietf.org/html/rfc6062
30//! [RFC6156]: https://tools.ietf.org/html/rfc6156
31//! [RFC8656]: https://tools.ietf.org/html/rfc8656
32
33#![no_std]
34
35extern crate alloc;
36
37#[cfg(any(feature = "std", test))]
38extern crate std;
39
40pub use stun_types as stun;
41use stun_types::message::LongTermCredentials;
42pub mod attribute;
43pub mod channel;
44pub mod message;
45pub mod tcp;
46pub mod transmit;
47
48/// Public prelude.
49pub mod prelude {
50    pub use crate::transmit::DelayedTransmitBuild;
51}
52
53use alloc::borrow::ToOwned;
54use alloc::string::{String, ToString};
55pub use stun_types::AddressFamily;
56
57/// Initialize some debugging functionality of the library.
58///
59/// It is not required to call this function, however doing so allows debug functionality of
60/// stun-types to print much more human readable descriptions of attributes and messages.
61pub fn debug_init() {
62    attribute::attributes_init();
63    message::debug_init();
64}
65
66/// Credentials used for a TURN user.
67#[derive(Debug, Clone)]
68pub struct TurnCredentials {
69    username: String,
70    password: String,
71}
72
73impl TurnCredentials {
74    /// Transform these credentials into some `LongTermCredentials` for use in a STUN context.
75    pub fn into_long_term_credentials(self, realm: &str) -> LongTermCredentials {
76        LongTermCredentials::new(self.username, self.password, realm.to_string())
77    }
78
79    /// Construct a new set of [`TurnCredentials`]
80    pub fn new(username: &str, password: &str) -> Self {
81        Self {
82            username: username.to_owned(),
83            password: password.to_owned(),
84        }
85    }
86
87    /// The username of the credentials.
88    pub fn username(&self) -> &str {
89        &self.username
90    }
91
92    /// The password of the credentials.
93    pub fn password(&self) -> &str {
94        &self.password
95    }
96}
97
98#[cfg(test)]
99mod tests {
100    use tracing::subscriber::DefaultGuard;
101    use tracing_subscriber::layer::SubscriberExt;
102    use tracing_subscriber::Layer;
103
104    pub fn test_init_log() -> DefaultGuard {
105        crate::debug_init();
106        let level_filter = std::env::var("TURN_LOG")
107            .or(std::env::var("RUST_LOG"))
108            .ok()
109            .and_then(|var| var.parse::<tracing_subscriber::filter::Targets>().ok())
110            .unwrap_or(
111                tracing_subscriber::filter::Targets::new().with_default(tracing::Level::TRACE),
112            );
113        let registry = tracing_subscriber::registry().with(
114            tracing_subscriber::fmt::layer()
115                .with_file(true)
116                .with_line_number(true)
117                .with_level(true)
118                .with_target(false)
119                .with_test_writer()
120                .with_filter(level_filter),
121        );
122        tracing::subscriber::set_default(registry)
123    }
124}