pub struct SessionManager<T> { /* private fields */ }Implementations§
Source§impl<T> SessionManager<T>where
T: ServiceHandler,
impl<T> SessionManager<T>where
T: ServiceHandler,
pub fn new(options: SessionManagerOptions<T>) -> Arc<Self>
Sourcepub fn get_session_or_default<'a, 'b>(
&'a self,
key: &'b Identifier,
) -> ReadLock<'b, 'a, Identifier, Table<Identifier, Session>>
pub fn get_session_or_default<'a, 'b>( &'a self, key: &'b Identifier, ) -> ReadLock<'b, 'a, Identifier, Table<Identifier, Session>>
Get session for addr.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
// get_session always creates a new session if it doesn't exist
{
assert!(sessions.get_session(&addr).get_ref().is_none());
}
// get_session always creates a new session if it doesn't exist
{
let lock = sessions.get_session_or_default(&addr);
let session = lock.get_ref().unwrap();
match session {
Session::New { .. } => {},
_ => panic!("Expected new session"),
}
}
sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on();
{
let lock = sessions.get_session(&addr);
let session = lock.get_ref().unwrap();
match session {
Session::Authenticated { username, allocate_port, allocate_channels, .. } => {
assert_eq!(username, "test");
assert_eq!(allocate_port, &None);
assert_eq!(allocate_channels.len(), 0);
}
_ => panic!("Expected authenticated session"),
}
}pub fn get_session<'a, 'b>( &'a self, key: &'b Identifier, ) -> ReadLock<'b, 'a, Identifier, Table<Identifier, Session>>
Sourcepub async fn get_password(
&self,
addr: &Identifier,
username: &str,
algorithm: PasswordAlgorithm,
) -> Option<Password>
pub async fn get_password( &self, addr: &Identifier, username: &str, algorithm: PasswordAlgorithm, ) -> Option<Password>
Get digest for addr.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
// First call get_session to create a new session
{
sessions.get_session(&addr);
}
assert_eq!(pollster::block_on(sessions.get_password(&addr, "test1", PasswordAlgorithm::Md5)), None);
// Create a new session for the next test
{
sessions.get_session(&addr);
}
assert_eq!(sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on(), Some(digest));
// The third call should return cached digest
assert_eq!(sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on(), Some(digest));pub fn allocated(&self) -> usize
Sourcepub fn allocate(&self, addr: &Identifier, lifetime: Option<u32>) -> Option<u16>
pub fn allocate(&self, addr: &Identifier, lifetime: Option<u32>) -> Option<u16>
Assign a port number to the session.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on();
{
let lock = sessions.get_session(&addr);
let session = lock.get_ref().unwrap();
match session {
Session::Authenticated { username, allocate_port, allocate_channels, .. } => {
assert_eq!(username, "test");
assert_eq!(allocate_port, &None);
assert_eq!(allocate_channels.len(), 0);
}
_ => panic!("Expected authenticated session"),
}
}
let port = sessions.allocate(&addr, None).unwrap();
{
let lock = sessions.get_session(&addr);
let session = lock.get_ref().unwrap();
match session {
Session::Authenticated { username, allocate_port, allocate_channels, .. } => {
assert_eq!(username, "test");
assert_eq!(allocate_port, &Some(port));
assert_eq!(allocate_channels.len(), 0);
}
_ => panic!("Expected authenticated session"),
}
}
assert_eq!(sessions.allocate(&addr, None), Some(port));Sourcepub fn create_permission(
&self,
addr: &Identifier,
endpoint: &SocketAddr,
ports: &[u16],
) -> bool
pub fn create_permission( &self, addr: &Identifier, endpoint: &SocketAddr, ports: &[u16], ) -> bool
Create permission for session.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let endpoint = "127.0.0.1:3478".parse().unwrap();
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let peer_addr = Identifier {
source: "127.0.0.1:8081".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on();
sessions.get_password(&peer_addr, "test", PasswordAlgorithm::Md5).block_on();
let port = sessions.allocate(&addr, None).unwrap();
let peer_port = sessions.allocate(&peer_addr, None).unwrap();
assert!(!sessions.create_permission(&addr, &endpoint, &[port]));
assert!(sessions.create_permission(&addr, &endpoint, &[peer_port]));
assert!(!sessions.create_permission(&peer_addr, &endpoint, &[peer_port]));
assert!(sessions.create_permission(&peer_addr, &endpoint, &[port]));Sourcepub fn bind_channel(
&self,
addr: &Identifier,
endpoint: &SocketAddr,
port: u16,
channel: u16,
) -> bool
pub fn bind_channel( &self, addr: &Identifier, endpoint: &SocketAddr, port: u16, channel: u16, ) -> bool
Binding a channel to the session.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let endpoint = "127.0.0.1:3478".parse().unwrap();
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let peer_addr = Identifier {
source: "127.0.0.1:8081".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on();
sessions.get_password(&peer_addr, "test", PasswordAlgorithm::Md5).block_on();
let port = sessions.allocate(&addr, None).unwrap();
let peer_port = sessions.allocate(&peer_addr, None).unwrap();
{
assert_eq!(
match sessions.get_session(&addr).get_ref().unwrap() {
Session::Authenticated { allocate_channels, .. } => allocate_channels.len(),
_ => panic!("Expected authenticated session"),
},
0
);
}
{
assert_eq!(
match sessions.get_session(&peer_addr).get_ref().unwrap() {
Session::Authenticated { allocate_channels, .. } => allocate_channels.len(),
_ => panic!("Expected authenticated session"),
},
0
);
}
assert!(sessions.bind_channel(&addr, &endpoint, peer_port, 0x4000));
assert!(sessions.bind_channel(&peer_addr, &endpoint, port, 0x4000));
{
assert_eq!(
match sessions.get_session(&addr).get_ref().unwrap() {
Session::Authenticated { allocate_channels, .. } => allocate_channels.clone(),
_ => panic!("Expected authenticated session"),
},
vec![0x4000]
);
}
{
assert_eq!(
match sessions.get_session(&peer_addr).get_ref().unwrap() {
Session::Authenticated { allocate_channels, .. } => allocate_channels.clone(),
_ => panic!("Expected authenticated session"),
},
vec![0x4000]
);
}Sourcepub fn get_channel_relay_address(
&self,
addr: &Identifier,
channel: u16,
) -> Option<Endpoint>
pub fn get_channel_relay_address( &self, addr: &Identifier, channel: u16, ) -> Option<Endpoint>
Gets the peer of the current session bound channel.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let endpoint = "127.0.0.1:3478".parse().unwrap();
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let peer_addr = Identifier {
source: "127.0.0.1:8081".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on();
sessions.get_password(&peer_addr, "test", PasswordAlgorithm::Md5).block_on();
let port = sessions.allocate(&addr, None).unwrap();
let peer_port = sessions.allocate(&peer_addr, None).unwrap();
assert!(sessions.bind_channel(&addr, &endpoint, peer_port, 0x4000));
assert!(sessions.bind_channel(&peer_addr, &endpoint, port, 0x4000));
assert_eq!(
sessions
.get_channel_relay_address(&addr, 0x4000)
.unwrap()
.endpoint,
endpoint
);
assert_eq!(
sessions
.get_channel_relay_address(&peer_addr, 0x4000)
.unwrap()
.endpoint,
endpoint
);Sourcepub fn get_relay_address(
&self,
addr: &Identifier,
port: u16,
) -> Option<Endpoint>
pub fn get_relay_address( &self, addr: &Identifier, port: u16, ) -> Option<Endpoint>
Get the address of the port binding.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let endpoint = "127.0.0.1:3478".parse().unwrap();
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let peer_addr = Identifier {
source: "127.0.0.1:8081".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on();
sessions.get_password(&peer_addr, "test", PasswordAlgorithm::Md5).block_on();
let port = sessions.allocate(&addr, None).unwrap();
let peer_port = sessions.allocate(&peer_addr, None).unwrap();
assert!(sessions.create_permission(&addr, &endpoint, &[peer_port]));
assert!(sessions.create_permission(&peer_addr, &endpoint, &[port]));
assert_eq!(
sessions
.get_relay_address(&addr, peer_port)
.unwrap()
.endpoint,
endpoint
);
assert_eq!(
sessions
.get_relay_address(&peer_addr, port)
.unwrap()
.endpoint,
endpoint
);Sourcepub fn refresh(&self, addr: &Identifier, lifetime: u32) -> bool
pub fn refresh(&self, addr: &Identifier, lifetime: u32) -> bool
Refresh the session for addr.
§Test
use turn_server::service::session::*;
use turn_server::service::*;
use turn_server::codec::message::attributes::PasswordAlgorithm;
use turn_server::codec::crypto::Password;
use pollster::FutureExt;
#[derive(Clone)]
struct ServiceHandlerTest;
impl ServiceHandler for ServiceHandlerTest {
async fn get_password(&self, username: &str, algorithm: PasswordAlgorithm) -> Option<Password> {
if username == "test" {
Some(turn_server::codec::crypto::generate_password(username, "test", "test", algorithm))
} else {
None
}
}
}
let addr = Identifier {
source: "127.0.0.1:8080".parse().unwrap(),
interface: "127.0.0.1:3478".parse().unwrap(),
};
let digest = Password::Md5([
174, 238, 187, 253, 117, 209, 73, 157, 36, 56, 143, 91, 155, 16, 224,
239,
]);
let sessions = SessionManager::new(SessionManagerOptions {
port_range: (49152..65535).into(),
handler: ServiceHandlerTest,
});
// get_session always creates a new session if it doesn't exist
{
let lock = sessions.get_session_or_default(&addr);
let session = lock.get_ref().unwrap();
match session {
Session::New { .. } => {},
_ => panic!("Expected new session"),
}
}
sessions.get_password(&addr, "test", PasswordAlgorithm::Md5).block_on();
{
let lock = sessions.get_session(&addr);
let expires = match lock.get_ref().unwrap() {
Session::Authenticated { expires, .. } => *expires,
_ => panic!("Expected authenticated session"),
};
assert!(expires == 600 || expires == 601 || expires == 602);
}
assert!(sessions.refresh(&addr, 0));
// After refresh with lifetime 0, session should be removed
{
assert!(sessions.get_session(&addr).get_ref().is_none());
}Auto Trait Implementations§
impl<T> !Freeze for SessionManager<T>
impl<T> !RefUnwindSafe for SessionManager<T>
impl<T> Send for SessionManager<T>where
T: Send,
impl<T> Sync for SessionManager<T>where
T: Sync,
impl<T> Unpin for SessionManager<T>where
T: Unpin,
impl<T> UnwindSafe for SessionManager<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
Wrap the input message
T in a tonic::Request