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