flv_util/
socket_helpers.rs

1use std::fmt;
2use std::io::Error as IoError;
3use std::io::ErrorKind;
4use std::convert::TryFrom;
5use std::net::SocketAddr;
6use std::net::ToSocketAddrs;
7use std::net::Ipv4Addr;
8use std::net::IpAddr;
9
10use log::debug;
11use log::error;
12
13//
14// Structures
15//
16#[derive(Debug, PartialEq, Clone)]
17pub struct ServerAddress {
18    pub host: String,
19    pub port: u16,
20}
21
22impl ServerAddress {
23
24    pub fn new<S>(host: S,port: u16) -> Self where S: Into<String>{
25        Self {
26            host: host.into(),
27            port
28        }
29    }
30}
31
32impl fmt::Display for ServerAddress {
33    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34        write!(f, "{}:{}", self.host, self.port)
35    }
36}
37
38impl TryFrom<String> for ServerAddress {
39    type Error = IoError;
40
41    fn try_from(host_port: String) -> Result<Self, Self::Error> {
42        let v: Vec<&str> = host_port.split(':').collect();
43
44        if v.len() != 2 {
45            return Err(IoError::new(
46                ErrorKind::InvalidInput,
47                format!("invalid host:port format {}", host_port).as_str(),
48            ));
49        }
50
51        Ok(ServerAddress {
52            host: v[0].to_string(),
53            port: v[1]
54                .parse::<u16>()
55                .map_err(|err| IoError::new(ErrorKind::InvalidData, format!("{}", err)))?,
56        })
57    }
58}
59
60impl TryFrom<ServerAddress> for SocketAddr {
61    type Error = IoError;
62
63    fn try_from(endpoint: ServerAddress) -> Result<Self, Self::Error> {
64        host_port_to_socket_addr(&endpoint.host, endpoint.port)
65    }
66}
67
68// converts a host/port to SocketAddress
69pub fn server_to_socket_addr(server_addr: &ServerAddress) -> Result<SocketAddr, IoError> {
70    host_port_to_socket_addr(&server_addr.host, server_addr.port)
71}
72
73// converts a host/port to SocketAddress
74pub fn host_port_to_socket_addr(host: &str, port: u16) -> Result<SocketAddr, IoError> {
75    let addr_string = format!("{}:{}", host, port);
76    string_to_socket_addr(&addr_string)
77}
78
79/// convert string to socket addr
80pub fn string_to_socket_addr(addr_string: &str) -> Result<SocketAddr, IoError> {
81    debug!("resolving host: {}",addr_string);
82    match addr_string.to_socket_addrs() {
83        Err(err) => {
84            error!("error resolving addr: {} {}",addr_string,err);
85            Err(err)
86        },
87        Ok(mut addrs_iter) => {
88            match addrs_iter.next() {
89                Some(addr) => {
90                    debug!("resolved: {}",addr);
91                    Ok(addr)
92                },
93                None => {
94                    error!("error resolving addr: {}",addr_string);
95                    Err(IoError::new(
96                        ErrorKind::InvalidInput,
97                        format!("host/port cannot be resolved {}", addr_string).as_str(),
98                    ))
99                }
100            }
101        }
102    
103    }
104
105
106}
107
108#[derive(Debug, PartialEq, Clone)]
109pub enum EndPointEncryption {
110    PLAINTEXT,
111}
112
113impl Default for EndPointEncryption {
114    fn default() -> Self {
115        EndPointEncryption::PLAINTEXT
116    }
117}
118
119impl fmt::Display for EndPointEncryption {
120    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121        write!(f, "Plain")
122    }
123}
124
125#[derive(Debug, PartialEq, Clone)]
126pub struct EndPoint {
127    pub addr: SocketAddr,
128    pub encryption: EndPointEncryption,
129}
130
131impl EndPoint {
132    /// Build endpoint for local server
133    pub fn local_end_point(port: u16) -> Self {
134        Self {
135            addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port),
136            encryption: EndPointEncryption::default(),
137        }
138    }
139
140    /// listen on 0.0.0.0
141    pub fn all_end_point(port: u16) -> Self {
142        Self {
143            addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), port),
144            encryption: EndPointEncryption::default(),
145        }
146    }
147}
148
149impl From<SocketAddr> for EndPoint {
150    fn from(addr: SocketAddr) -> Self {
151        EndPoint {
152            addr,
153            encryption: EndPointEncryption::default(),
154        }
155    }
156}
157
158impl TryFrom<&str> for EndPoint {
159    type Error = IoError;
160
161    fn try_from(value: &str) -> Result<Self, Self::Error> {
162        string_to_socket_addr(value).map(|addr| EndPoint {
163            addr,
164            encryption: EndPointEncryption::PLAINTEXT,
165        })
166    }
167}
168
169impl fmt::Display for EndPoint {
170    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171        write!(f, "{} {}", self.addr, self.encryption)
172    }
173}