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
12//! # turn-types
13//!
14//! `turn-types` provides an implementation for two main things related to TURN clients and servers:
15//! 1. TURN specific STUN attributes using the [`stun-types`] crate.
16//! 2. Parsing to and from the actual data sent and received on the wire between a TURN client and
17//!    a TURN server.
18//!
19//! This is based on the following standards:
20//! - [RFC5766]: Traversal Using Relays around NAT (TURN).
21//!
22//! [RFC5766]: https://tools.ietf.org/html/rfc5766
23
24pub use stun_types as stun;
25use stun_types::message::LongTermCredentials;
26pub mod attribute;
27pub mod channel;
28pub mod message;
29pub mod tcp;
30
31/// Initialize some debugging functionality of the library.
32///
33/// It is not required to call this function, however doing so allows debug functionality of
34/// stun-types to print much more human readable descriptions of attributes and messages.
35pub fn debug_init() {
36    attribute::attributes_init();
37    message::debug_init();
38}
39
40/// Credentials used for a TURN user.
41#[derive(Debug, Clone)]
42pub struct TurnCredentials {
43    username: String,
44    password: String,
45}
46
47impl TurnCredentials {
48    /// Transform these credentials into some `LongTermCredentials` for use in a STUN context.
49    pub fn into_long_term_credentials(self, realm: &str) -> LongTermCredentials {
50        LongTermCredentials::new(self.username, self.password, realm.to_string())
51    }
52
53    /// Construct a new set of [`TurnCredentials`]
54    pub fn new(username: &str, password: &str) -> Self {
55        Self {
56            username: username.to_owned(),
57            password: password.to_owned(),
58        }
59    }
60
61    /// The username of the credentials.
62    pub fn username(&self) -> &str {
63        &self.username
64    }
65
66    /// The password of the credentials.
67    pub fn password(&self) -> &str {
68        &self.password
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use tracing::subscriber::DefaultGuard;
75    use tracing_subscriber::layer::SubscriberExt;
76    use tracing_subscriber::Layer;
77
78    pub fn test_init_log() -> DefaultGuard {
79        crate::debug_init();
80        let level_filter = std::env::var("TURN_LOG")
81            .or(std::env::var("RUST_LOG"))
82            .ok()
83            .and_then(|var| var.parse::<tracing_subscriber::filter::Targets>().ok())
84            .unwrap_or(
85                tracing_subscriber::filter::Targets::new().with_default(tracing::Level::TRACE),
86            );
87        let registry = tracing_subscriber::registry().with(
88            tracing_subscriber::fmt::layer()
89                .with_file(true)
90                .with_line_number(true)
91                .with_level(true)
92                .with_target(false)
93                .with_test_writer()
94                .with_filter(level_filter),
95        );
96        tracing::subscriber::set_default(registry)
97    }
98}