electrum_client/socks/
mod.rs1use std::io;
6use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
7use std::vec;
8
9pub use self::v4::{Socks4Listener, Socks4Stream};
10pub use self::v5::{Socks5Datagram, Socks5Listener, Socks5Stream};
11
12mod v4;
13mod v5;
14mod writev;
15
16#[derive(Debug, Clone)]
18pub enum TargetAddr {
19 Ip(SocketAddr),
21 Domain(String, u16),
26}
27
28impl ToSocketAddrs for TargetAddr {
29 type Iter = Iter;
30
31 fn to_socket_addrs(&self) -> io::Result<Iter> {
32 let inner = match *self {
33 TargetAddr::Ip(addr) => IterInner::Ip(Some(addr)),
34 TargetAddr::Domain(ref domain, port) => {
35 let it = (&**domain, port).to_socket_addrs()?;
36 IterInner::Domain(it)
37 }
38 };
39 Ok(Iter(inner))
40 }
41}
42
43enum IterInner {
44 Ip(Option<SocketAddr>),
45 Domain(vec::IntoIter<SocketAddr>),
46}
47
48pub struct Iter(IterInner);
50
51impl Iterator for Iter {
52 type Item = SocketAddr;
53
54 fn next(&mut self) -> Option<SocketAddr> {
55 match self.0 {
56 IterInner::Ip(ref mut addr) => addr.take(),
57 IterInner::Domain(ref mut it) => it.next(),
58 }
59 }
60}
61
62pub trait ToTargetAddr {
64 fn to_target_addr(&self) -> io::Result<TargetAddr>;
66}
67
68impl ToTargetAddr for TargetAddr {
69 fn to_target_addr(&self) -> io::Result<TargetAddr> {
70 Ok(self.clone())
71 }
72}
73
74impl ToTargetAddr for SocketAddr {
75 fn to_target_addr(&self) -> io::Result<TargetAddr> {
76 Ok(TargetAddr::Ip(*self))
77 }
78}
79
80impl ToTargetAddr for SocketAddrV4 {
81 fn to_target_addr(&self) -> io::Result<TargetAddr> {
82 SocketAddr::V4(*self).to_target_addr()
83 }
84}
85
86impl ToTargetAddr for SocketAddrV6 {
87 fn to_target_addr(&self) -> io::Result<TargetAddr> {
88 SocketAddr::V6(*self).to_target_addr()
89 }
90}
91
92impl ToTargetAddr for (Ipv4Addr, u16) {
93 fn to_target_addr(&self) -> io::Result<TargetAddr> {
94 SocketAddrV4::new(self.0, self.1).to_target_addr()
95 }
96}
97
98impl ToTargetAddr for (Ipv6Addr, u16) {
99 fn to_target_addr(&self) -> io::Result<TargetAddr> {
100 SocketAddrV6::new(self.0, self.1, 0, 0).to_target_addr()
101 }
102}
103
104impl ToTargetAddr for (&str, u16) {
105 fn to_target_addr(&self) -> io::Result<TargetAddr> {
106 if let Ok(addr) = self.0.parse::<Ipv4Addr>() {
108 return (addr, self.1).to_target_addr();
109 }
110
111 if let Ok(addr) = self.0.parse::<Ipv6Addr>() {
112 return (addr, self.1).to_target_addr();
113 }
114
115 Ok(TargetAddr::Domain(self.0.to_owned(), self.1))
116 }
117}
118
119impl ToTargetAddr for &str {
120 fn to_target_addr(&self) -> io::Result<TargetAddr> {
121 if let Ok(addr) = self.parse::<SocketAddrV4>() {
123 return addr.to_target_addr();
124 }
125
126 if let Ok(addr) = self.parse::<SocketAddrV6>() {
127 return addr.to_target_addr();
128 }
129
130 let mut parts_iter = self.rsplitn(2, ':');
132 let port_str = match parts_iter.next() {
133 Some(s) => s,
134 None => {
135 return Err(io::Error::new(
136 io::ErrorKind::InvalidInput,
137 "invalid socket address",
138 ))
139 }
140 };
141
142 let host = match parts_iter.next() {
143 Some(s) => s,
144 None => {
145 return Err(io::Error::new(
146 io::ErrorKind::InvalidInput,
147 "invalid socket address",
148 ))
149 }
150 };
151
152 let port: u16 = match port_str.parse() {
153 Ok(p) => p,
154 Err(_) => {
155 return Err(io::Error::new(
156 io::ErrorKind::InvalidInput,
157 "invalid port value",
158 ))
159 }
160 };
161
162 (host, port).to_target_addr()
163 }
164}