socks/
lib.rs

1//! SOCKS proxy clients
2#![doc(html_root_url="https://docs.rs/socks/0.3.0")]
3#![warn(missing_docs)]
4
5extern crate byteorder;
6
7#[cfg(unix)]
8extern crate libc;
9#[cfg(windows)]
10extern crate winapi;
11
12use std::io;
13use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
14use std::vec;
15
16pub use v4::{Socks4Stream, Socks4Listener};
17pub use v5::{Socks5Stream, Socks5Listener, Socks5Datagram};
18
19mod v4;
20mod v5;
21mod writev;
22
23/// A description of a connection target.
24#[derive(Debug, Clone)]
25pub enum TargetAddr {
26    /// Connect to an IP address.
27    Ip(SocketAddr),
28    /// Connect to a fully qualified domain name.
29    ///
30    /// The domain name will be passed along to the proxy server and DNS lookup
31    /// will happen there.
32    Domain(String, u16),
33}
34
35impl ToSocketAddrs for TargetAddr {
36    type Iter = Iter;
37
38    fn to_socket_addrs(&self) -> io::Result<Iter> {
39        let inner = match *self {
40            TargetAddr::Ip(addr) => IterInner::Ip(Some(addr)),
41            TargetAddr::Domain(ref domain, port) => {
42                let it = (&**domain, port).to_socket_addrs()?;
43                IterInner::Domain(it)
44            }
45        };
46        Ok(Iter(inner))
47    }
48}
49
50enum IterInner {
51    Ip(Option<SocketAddr>),
52    Domain(vec::IntoIter<SocketAddr>),
53}
54
55/// An iterator over `SocketAddr`s associated with a `TargetAddr`.
56pub struct Iter(IterInner);
57
58impl Iterator for Iter {
59    type Item = SocketAddr;
60
61    fn next(&mut self) -> Option<SocketAddr> {
62        match self.0 {
63            IterInner::Ip(ref mut addr) => addr.take(),
64            IterInner::Domain(ref mut it) => it.next(),
65        }
66    }
67}
68
69/// A trait for objects that can be converted to `TargetAddr`.
70pub trait ToTargetAddr {
71    /// Converts the value of `self` to a `TargetAddr`.
72    fn to_target_addr(&self) -> io::Result<TargetAddr>;
73}
74
75impl ToTargetAddr for TargetAddr {
76    fn to_target_addr(&self) -> io::Result<TargetAddr> {
77        Ok(self.clone())
78    }
79}
80
81impl ToTargetAddr for SocketAddr {
82    fn to_target_addr(&self) -> io::Result<TargetAddr> {
83        Ok(TargetAddr::Ip(*self))
84    }
85}
86
87impl ToTargetAddr for SocketAddrV4 {
88    fn to_target_addr(&self) -> io::Result<TargetAddr> {
89        SocketAddr::V4(*self).to_target_addr()
90    }
91}
92
93impl ToTargetAddr for SocketAddrV6 {
94    fn to_target_addr(&self) -> io::Result<TargetAddr> {
95        SocketAddr::V6(*self).to_target_addr()
96    }
97}
98
99impl ToTargetAddr for (Ipv4Addr, u16) {
100    fn to_target_addr(&self) -> io::Result<TargetAddr> {
101        SocketAddrV4::new(self.0, self.1).to_target_addr()
102    }
103}
104
105impl ToTargetAddr for (Ipv6Addr, u16) {
106    fn to_target_addr(&self) -> io::Result<TargetAddr> {
107        SocketAddrV6::new(self.0, self.1, 0, 0).to_target_addr()
108    }
109}
110
111impl<'a> ToTargetAddr for (&'a str, u16) {
112    fn to_target_addr(&self) -> io::Result<TargetAddr> {
113        // try to parse as an IP first
114        if let Ok(addr) = self.0.parse::<Ipv4Addr>() {
115            return (addr, self.1).to_target_addr();
116        }
117
118        if let Ok(addr) = self.0.parse::<Ipv6Addr>() {
119            return (addr, self.1).to_target_addr();
120        }
121
122        Ok(TargetAddr::Domain(self.0.to_owned(), self.1))
123    }
124}
125
126impl<'a> ToTargetAddr for &'a str {
127    fn to_target_addr(&self) -> io::Result<TargetAddr> {
128        // try to parse as an IP first
129        if let Ok(addr) = self.parse::<SocketAddrV4>() {
130            return addr.to_target_addr();
131        }
132
133        if let Ok(addr) = self.parse::<SocketAddrV6>() {
134            return addr.to_target_addr();
135        }
136
137        // split the string by ':' and convert the second part to u16
138        let mut parts_iter = self.rsplitn(2, ':');
139        let port_str = match parts_iter.next() {
140            Some(s) => s,
141            None => {
142                return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid socket address"))
143            }
144        };
145
146        let host = match parts_iter.next() {
147            Some(s) => s,
148            None => {
149                return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid socket address"))
150            }
151        };
152
153        let port: u16 = match port_str.parse() {
154            Ok(p) => p,
155            Err(_) => return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid port value")),
156        };
157
158        (host, port).to_target_addr()
159    }
160}