1#![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#[derive(Debug, Clone)]
25pub enum TargetAddr {
26 Ip(SocketAddr),
28 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
55pub 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
69pub trait ToTargetAddr {
71 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 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 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 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}