srt_protocol/options/
socket.rs

1use super::*;
2
3#[derive(Clone, Debug, Default, Eq, PartialEq)]
4pub struct SocketOptions {
5    pub connect: Connect,
6    pub session: Session,
7    pub encryption: Encryption,
8    pub sender: Sender,
9    pub receiver: Receiver,
10}
11
12impl SocketOptions {
13    pub fn new() -> Valid<Self> {
14        Self::default().try_validate().unwrap()
15    }
16}
17
18impl Validation for SocketOptions {
19    type Error = OptionsError;
20
21    fn is_valid(&self) -> Result<(), Self::Error> {
22        self.connect.is_valid()?;
23        self.session.is_valid()?;
24        self.encryption.is_valid()?;
25        self.sender.is_valid()?;
26        self.receiver.is_valid()?;
27        self.is_valid_composite()
28    }
29}
30
31impl CompositeValidation for SocketOptions {
32    fn is_valid_composite(&self) -> Result<(), <Self as Validation>::Error> {
33        // There is a restriction that the receiver buffer size (SRTO_RCVBUF) must not be greater than
34        // SRTO_FC (#700). Therefore, it is recommended to set the value of SRTO_FC first, and then the
35        // value of SRTO_RCVBUF.
36        if self.receiver.buffer_size
37            > self.sender.flow_control_window_size * self.session.max_segment_size
38        {
39            return Err(OptionsError::ReceiveBufferTooLarge {
40                buffer: self.receiver.buffer_size,
41                max_segment: self.session.max_segment_size,
42                flow_control_window: self.sender.flow_control_window_size,
43            });
44        }
45
46        if self.connect.udp_recv_buffer_size
47            > self.sender.flow_control_window_size * self.session.max_segment_size
48        {
49            return Err(OptionsError::UdpReceiveBufferTooLarge {
50                udp_buffer: self.connect.udp_recv_buffer_size,
51                max_segment: self.session.max_segment_size,
52                flow_control_window: self.sender.flow_control_window_size,
53            });
54        }
55
56        if self.connect.udp_send_buffer_size
57            > self.sender.flow_control_window_size * self.session.max_segment_size
58        {
59            return Err(OptionsError::UdpSenderBufferTooLarge {
60                udp_buffer: self.connect.udp_send_buffer_size,
61                max_segment: self.session.max_segment_size,
62                flow_control_window: self.sender.flow_control_window_size,
63            });
64        }
65
66        Ok(())
67    }
68}
69
70impl OptionsOf<Connect> for SocketOptions {
71    fn set_options(&mut self, value: Connect) {
72        self.connect = value;
73    }
74}
75
76impl OptionsOf<Session> for SocketOptions {
77    fn set_options(&mut self, value: Session) {
78        self.session = value;
79    }
80}
81
82impl OptionsOf<Encryption> for SocketOptions {
83    fn set_options(&mut self, value: Encryption) {
84        self.encryption = value;
85    }
86}
87
88impl OptionsOf<Sender> for SocketOptions {
89    fn set_options(&mut self, value: Sender) {
90        self.sender = value;
91    }
92}
93
94impl OptionsOf<Receiver> for SocketOptions {
95    fn set_options(&mut self, value: Receiver) {
96        self.receiver = value;
97    }
98}
99
100#[cfg(test)]
101mod test {
102    use std::time::Duration;
103
104    use super::*;
105
106    use assert_matches::assert_matches;
107
108    #[test]
109    fn test() -> Result<(), OptionsError> {
110        let _ = SocketOptions::new()
111            .with(Connect {
112                timeout: Duration::from_secs(1),
113                ..Default::default()
114            })?
115            .with(Session {
116                peer_idle_timeout: Duration::from_secs(20),
117                ..Default::default()
118            })?
119            .with(Encryption {
120                key_size: KeySize::AES192,
121                passphrase: Some("this is a passphrase".into()),
122                ..Default::default()
123            })?
124            .with(Sender {
125                buffer_size: ByteCount(1000000),
126                ..Default::default()
127            })?
128            .with(Receiver {
129                buffer_size: ByteCount(1000000),
130                ..Default::default()
131            })?;
132
133        let _ = SocketOptions {
134            connect: Connect {
135                timeout: Duration::from_secs(1),
136                ..Default::default()
137            },
138            session: Session {
139                peer_idle_timeout: Duration::from_secs(20),
140                ..Default::default()
141            },
142            encryption: Encryption {
143                key_size: KeySize::AES192,
144                passphrase: Some("this is a passphrase".into()),
145                ..Default::default()
146            },
147            sender: Sender {
148                buffer_size: ByteCount(1000000),
149                ..Default::default()
150            },
151            receiver: Receiver {
152                buffer_size: ByteCount(1000000),
153                ..Default::default()
154            },
155        }
156        .try_validate()?;
157
158        assert_eq!(
159            SocketOptions::new().set(|op| {
160                op.connect.udp_recv_buffer_size = ByteCount(1500 * 10_000 + 1);
161                op.session.max_segment_size = PacketSize(1500);
162                op.sender.flow_control_window_size = PacketCount(10_000);
163            }),
164            Err(OptionsError::UdpReceiveBufferTooLarge {
165                udp_buffer: ByteCount(1500 * 10_000 + 1),
166                max_segment: PacketSize(1500),
167                flow_control_window: PacketCount(10_000),
168            })
169        );
170        assert_matches!(
171            SocketOptions::new().set(|op| {
172                op.connect.udp_recv_buffer_size = ByteCount(1500 * 10_000);
173                op.session.max_segment_size = PacketSize(1500);
174                op.sender.flow_control_window_size = PacketCount(10_000);
175            }),
176            Ok(_)
177        );
178
179        assert_eq!(
180            SocketOptions::new().set(|op| {
181                op.connect.udp_send_buffer_size = ByteCount(1500 * 10_000 + 1);
182                op.session.max_segment_size = PacketSize(1500);
183                op.sender.flow_control_window_size = PacketCount(10_000);
184            }),
185            Err(OptionsError::UdpSenderBufferTooLarge {
186                udp_buffer: ByteCount(1500 * 10_000 + 1),
187                max_segment: PacketSize(1500),
188                flow_control_window: PacketCount(10_000),
189            })
190        );
191        assert_matches!(
192            SocketOptions::new().set(|op| {
193                op.connect.udp_send_buffer_size = ByteCount(1500 * 10_000);
194                op.session.max_segment_size = PacketSize(1500);
195                op.sender.flow_control_window_size = PacketCount(10_000);
196            }),
197            Ok(_)
198        );
199
200        Ok(())
201    }
202}