Skip to content

Commit

Permalink
add tcp tos and options for advanced users
Browse files Browse the repository at this point in the history
  • Loading branch information
Vixea committed Jan 4, 2024
1 parent d0b9211 commit a5d63c3
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 9 deletions.
1 change: 1 addition & 0 deletions alvr/client_core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ fn connection_pipeline(
Duration::from_secs(1),
settings.connection.stream_port,
settings.connection.stream_protocol,
settings.dscp,
settings.connection.client_send_buffer_bytes,
settings.connection.client_recv_buffer_bytes,
)
Expand Down
1 change: 1 addition & 0 deletions alvr/server/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ fn connection_pipeline(
client_ip,
settings.connection.stream_port,
settings.connection.stream_protocol,
settings.dscp,
settings.connection.server_send_buffer_bytes,
settings.connection.server_recv_buffer_bytes,
settings.connection.packet_size as _,
Expand Down
38 changes: 38 additions & 0 deletions alvr/session/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,30 @@ For now works only on Windows+Nvidia"#
pub statistics_history_size: usize,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
#[repr(u8)]
#[schema(gui = "button_group")]
pub enum DropProbability {
Low = 0x01,
Medium = 0x10,
High = 0x11,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
pub enum DscpTos {
BestEffort,

ClassSelector(#[schema(gui(slider(min = 1, max = 7)))] u8),

AssuredForwarding {
#[schema(gui(slider(min = 1, max = 4)))]
class: u8,
drop_probability: DropProbability,
},

ExpeditedForwarding,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
pub struct RawEventsConfig {
#[schema(flag = "real-time")]
Expand Down Expand Up @@ -1066,6 +1090,7 @@ pub struct Settings {
pub audio: AudioConfig,
pub headset: HeadsetConfig,
pub connection: ConnectionConfig,
pub dscp: Option<DscpTos>,
pub logging: LoggingConfig,
pub steamvr_launcher: SteamvrLauncher,
pub capture: CaptureConfig,
Expand Down Expand Up @@ -1496,6 +1521,19 @@ pub fn session_settings_default() -> SettingsDefault {
packet_size: 1400,
statistics_history_size: 256,
},
dscp: OptionalDefault {
set: false,
content: DscpTosDefault {
ClassSelector: 7,
AssuredForwarding: DscpTosAssuredForwardingDefault {
class: 4,
drop_probability: DropProbabilityDefault {
variant: DropProbabilityDefaultVariant::Low,
},
},
variant: DscpTosDefaultVariant::ExpeditedForwarding,
},
},
logging: LoggingConfigDefault {
gui_collapsed: false,
client_log_report_level: SwitchDefault {
Expand Down
6 changes: 5 additions & 1 deletion alvr/sockets/src/backend/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::LOCAL_IP;

use super::{SocketReader, SocketWriter};
use alvr_common::{anyhow::Result, con_bail, ConResult, HandleTryAgain, ToCon};
use alvr_session::SocketBufferSize;
use alvr_session::{DscpTos, SocketBufferSize};
use std::{
io::Read,
io::Write,
Expand All @@ -13,12 +13,16 @@ use std::{
pub fn bind(
timeout: Duration,
port: u16,
dscp: Option<DscpTos>,
send_buffer_bytes: SocketBufferSize,
recv_buffer_bytes: SocketBufferSize,
) -> Result<TcpListener> {
let socket = TcpListener::bind((LOCAL_IP, port))?.into();

crate::set_socket_buffers(&socket, send_buffer_bytes, recv_buffer_bytes).ok();

crate::set_dscp(&socket, dscp);

socket.set_read_timeout(Some(timeout))?;

Ok(socket.into())
Expand Down
6 changes: 4 additions & 2 deletions alvr/sockets/src/backend/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::LOCAL_IP;

use super::{SocketReader, SocketWriter};
use alvr_common::{anyhow::Result, ConResult, HandleTryAgain};
use alvr_session::SocketBufferSize;
use alvr_session::{DscpTos, SocketBufferSize};
use socket2::{MaybeUninitSlice, Socket};
use std::{
ffi::c_int,
Expand All @@ -15,13 +15,15 @@ use std::{
// let tokio set all the internal parameters it needs from the start.
pub fn bind(
port: u16,
dscp: Option<DscpTos>,
send_buffer_bytes: SocketBufferSize,
recv_buffer_bytes: SocketBufferSize,
) -> Result<UdpSocket> {
let socket = UdpSocket::bind((LOCAL_IP, port))?.into();

crate::set_socket_buffers(&socket, send_buffer_bytes, recv_buffer_bytes).ok();
socket.set_tos(0b101110).ok();

crate::set_dscp(&socket, dscp);

Ok(socket.into())
}
Expand Down
1 change: 1 addition & 0 deletions alvr/sockets/src/control_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub fn get_server_listener(timeout: Duration) -> Result<TcpListener> {
let listener = tcp::bind(
timeout,
CONTROL_PORT,
None,
SocketBufferSize::Default,
SocketBufferSize::Default,
)?;
Expand Down
22 changes: 21 additions & 1 deletion alvr/sockets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ mod control_socket;
mod stream_socket;

use alvr_common::{anyhow::Result, info};
use alvr_session::SocketBufferSize;
use alvr_session::{SocketBufferSize, DscpTos};
use socket2::Socket;
use std::{
net::{IpAddr, Ipv4Addr},
time::Duration,
Expand Down Expand Up @@ -69,3 +70,22 @@ fn set_socket_buffers(

Ok(())
}


fn set_dscp(socket: &Socket, dscp: Option<DscpTos>) {
// https://en.wikipedia.org/wiki/Differentiated_services
#[cfg(target_os = "linux")]
if let Some(dscp) = dscp {
let tos = match dscp {
DscpTos::BestEffort => 0,
DscpTos::ClassSelector(precedence) => precedence << 3,
DscpTos::AssuredForwarding {
class,
drop_probability,
} => (class << 3) | drop_probability as u8,
DscpTos::ExpeditedForwarding => 0b101110,
};

socket.set_tos((tos << 2) as u32).ok();
}
}
17 changes: 12 additions & 5 deletions alvr/sockets/src/stream_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::backend::{tcp, udp, SocketReader, SocketWriter};
use alvr_common::{
anyhow::Result, debug, parking_lot::Mutex, AnyhowToCon, ConResult, HandleTryAgain, ToCon,
};
use alvr_session::{SocketBufferSize, SocketProtocol};
use alvr_session::{DscpTos, SocketBufferSize, SocketProtocol};
use serde::{de::DeserializeOwned, Serialize};
use std::{
cmp::Ordering,
Expand Down Expand Up @@ -271,16 +271,21 @@ impl StreamSocketBuilder {
timeout: Duration,
port: u16,
stream_socket_config: SocketProtocol,
stream_tos_config: Option<DscpTos>,
send_buffer_bytes: SocketBufferSize,
recv_buffer_bytes: SocketBufferSize,
) -> Result<Self> {
Ok(match stream_socket_config {
SocketProtocol::Udp => {
StreamSocketBuilder::Udp(udp::bind(port, send_buffer_bytes, recv_buffer_bytes)?)
}
SocketProtocol::Udp => StreamSocketBuilder::Udp(udp::bind(
port,
stream_tos_config,
send_buffer_bytes,
recv_buffer_bytes,
)?),
SocketProtocol::Tcp => StreamSocketBuilder::Tcp(tcp::bind(
timeout,
port,
stream_tos_config,
send_buffer_bytes,
recv_buffer_bytes,
)?),
Expand Down Expand Up @@ -327,14 +332,16 @@ impl StreamSocketBuilder {
client_ip: IpAddr,
port: u16,
protocol: SocketProtocol,
dscp: Option<DscpTos>,
send_buffer_bytes: SocketBufferSize,
recv_buffer_bytes: SocketBufferSize,
max_packet_size: usize,
) -> ConResult<StreamSocket> {
let (send_socket, receive_socket): (Box<dyn SocketWriter>, Box<dyn SocketReader>) =
match protocol {
SocketProtocol::Udp => {
let socket = udp::bind(port, send_buffer_bytes, recv_buffer_bytes).to_con()?;
let socket =
udp::bind(port, dscp, send_buffer_bytes, recv_buffer_bytes).to_con()?;
let (send_socket, receive_socket) =
udp::connect(&socket, client_ip, port, timeout).to_con()?;

Expand Down

0 comments on commit a5d63c3

Please sign in to comment.