srt_protocol/options/
caller.rs

1use std::{
2    convert::TryInto,
3    net::{Ipv4Addr, Ipv6Addr},
4};
5
6use super::*;
7
8#[derive(Clone, Debug, Eq, PartialEq)]
9pub struct CallerOptions {
10    pub remote: SocketAddress,
11    pub stream_id: Option<StreamId>,
12    pub socket: SocketOptions,
13}
14
15impl CallerOptions {
16    pub fn new(
17        remote: impl TryInto<SocketAddress>,
18        stream_id: Option<&str>,
19    ) -> Result<Valid<Self>, OptionsError> {
20        let socket = Default::default();
21        Self::with(remote, stream_id, socket)
22    }
23
24    pub fn with(
25        remote: impl TryInto<SocketAddress>,
26        stream_id: Option<&str>,
27        socket: SocketOptions,
28    ) -> Result<Valid<CallerOptions>, OptionsError> {
29        let remote = remote
30            .try_into()
31            .map_err(|_| OptionsError::InvalidRemoteAddress)?;
32
33        let stream_id = match stream_id {
34            Some(s) => Some(
35                s.to_string()
36                    .try_into()
37                    .map_err(OptionsError::InvalidStreamId)?,
38            ),
39            None => None,
40        };
41
42        use SocketHost::*;
43        let local_ip = socket.connect.local.ip();
44        let local_ip = match (local_ip.is_ipv6(), &remote.host) {
45            (false, &Ipv6(_)) if local_ip == Ipv4Addr::UNSPECIFIED => Ipv6Addr::UNSPECIFIED.into(),
46            (true, &Ipv4(_)) if local_ip == Ipv6Addr::UNSPECIFIED => Ipv4Addr::UNSPECIFIED.into(),
47            _ => local_ip,
48        };
49
50        let mut options = Self {
51            remote,
52            stream_id,
53            socket,
54        };
55
56        options.socket.connect.local.set_ip(local_ip);
57
58        options.try_validate()
59    }
60}
61
62impl Validation for CallerOptions {
63    type Error = OptionsError;
64
65    fn is_valid(&self) -> Result<(), Self::Error> {
66        let local = &self.socket.connect.local;
67        use SocketHost::*;
68        let mismatch = match (&self.remote.host, local.ip().is_ipv4()) {
69            (Ipv4(ipv4), false) => Some((*ipv4).into()),
70            (Ipv6(ipv6), true) => Some((*ipv6).into()),
71            _ => None,
72        };
73        if let Some(remote_ip) = mismatch {
74            return Err(OptionsError::MismatchedAddressFamilies(
75                remote_ip,
76                local.ip(),
77            ));
78        }
79        self.socket.is_valid()?;
80        self.is_valid_composite()
81    }
82}
83
84impl CompositeValidation for CallerOptions {
85    fn is_valid_composite(&self) -> Result<(), <Self as Validation>::Error> {
86        Ok(())
87    }
88}
89
90impl OptionsOf<SocketOptions> for CallerOptions {
91    fn set_options(&mut self, value: SocketOptions) {
92        self.socket = value;
93    }
94}
95
96impl OptionsOf<Connect> for CallerOptions {
97    fn set_options(&mut self, value: Connect) {
98        self.socket.connect = value;
99    }
100}
101
102impl OptionsOf<Session> for CallerOptions {
103    fn set_options(&mut self, value: Session) {
104        self.socket.session = value;
105    }
106}
107
108impl OptionsOf<Encryption> for CallerOptions {
109    fn set_options(&mut self, value: Encryption) {
110        self.socket.encryption = value;
111    }
112}
113
114impl OptionsOf<Sender> for CallerOptions {
115    fn set_options(&mut self, value: Sender) {
116        self.socket.sender = value;
117    }
118}
119
120impl OptionsOf<Receiver> for CallerOptions {
121    fn set_options(&mut self, value: Receiver) {
122        self.socket.receiver = value;
123    }
124}