Skip to content

Commit a92d4af

Browse files
committed
Accept hostnames for tcp:, tcp-listen:, udp:, udp-listen:
Signed-off-by: Anders Kaseorg <[email protected]>
1 parent bc738c8 commit a92d4af

File tree

1 file changed

+49
-35
lines changed

1 file changed

+49
-35
lines changed

src/net_peer.rs

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
extern crate net2;
22

33
use futures;
4-
use futures::future::Future;
4+
use futures::future::{Future, IntoFuture};
55
use futures::stream::Stream;
66
use futures::unsync::oneshot::{channel, Receiver, Sender};
77
use std;
88
use std::io::Result as IoResult;
99
use std::io::{Read, Write};
10-
use std::net::SocketAddr;
10+
use std::net::{SocketAddr, ToSocketAddrs};
1111
use tokio_io::{AsyncRead, AsyncWrite};
1212

1313
use std::cell::RefCell;
@@ -17,11 +17,11 @@ use tokio_tcp::{TcpListener, TcpStream};
1717
use tokio_udp::UdpSocket;
1818

1919
use super::L2rUser;
20-
use super::{box_up_err, peer_err_s, wouldblock, BoxedNewPeerFuture, BoxedNewPeerStream, Peer};
20+
use super::{box_up_err, wouldblock, BoxedNewPeerFuture, BoxedNewPeerStream, Peer};
2121
use super::{multi, once, ConstructParams, Options, PeerConstructor, Specifier};
2222

2323
#[derive(Debug, Clone)]
24-
pub struct TcpConnect(pub SocketAddr);
24+
pub struct TcpConnect(pub String);
2525
impl Specifier for TcpConnect {
2626
fn construct(&self, _: ConstructParams) -> PeerConstructor {
2727
once(tcp_connect_peer(&self.0))
@@ -50,7 +50,7 @@ Example: redirect websocket connections to local SSH server over IPv6
5050
);
5151

5252
#[derive(Debug, Clone)]
53-
pub struct TcpListen(pub SocketAddr);
53+
pub struct TcpListen(pub String);
5454
impl Specifier for TcpListen {
5555
fn construct(&self, p: ConstructParams) -> PeerConstructor {
5656
multi(tcp_listen_peer(&self.0, p.left_to_right))
@@ -79,10 +79,10 @@ Example: redirect TCP to a websocket
7979
);
8080

8181
#[derive(Debug, Clone)]
82-
pub struct UdpConnect(pub SocketAddr);
82+
pub struct UdpConnect(pub String);
8383
impl Specifier for UdpConnect {
8484
fn construct(&self, p: ConstructParams) -> PeerConstructor {
85-
once(udp_connect_peer(&self.0, &p.program_options))
85+
once(udp_connect_peer(&self.0, p.program_options))
8686
}
8787
specifier_boilerplate!(noglobalstate singleconnect no_subspec );
8888
}
@@ -100,10 +100,10 @@ Send and receive packets to specified UDP socket, from random UDP port
100100
);
101101

102102
#[derive(Debug, Clone)]
103-
pub struct UdpListen(pub SocketAddr);
103+
pub struct UdpListen(pub String);
104104
impl Specifier for UdpListen {
105105
fn construct(&self, p: ConstructParams) -> PeerConstructor {
106-
once(udp_listen_peer(&self.0, &p.program_options))
106+
once(udp_listen_peer(&self.0, p.program_options))
107107
}
108108
specifier_boilerplate!(noglobalstate singleconnect no_subspec );
109109
}
@@ -192,25 +192,39 @@ impl Drop for MyTcpStream {
192192
}
193193
}
194194

195-
pub fn tcp_connect_peer(addr: &SocketAddr) -> BoxedNewPeerFuture {
196-
Box::new(
195+
pub fn resolve_addr(
196+
addr_str: &str,
197+
) -> impl Future<Item = SocketAddr, Error = Box<dyn std::error::Error + 'static>> {
198+
// TODO: resolve asynchronously
199+
addr_str
200+
.to_socket_addrs()
201+
.and_then(|mut addrs| {
202+
addrs
203+
.next()
204+
.ok_or_else(|| ::simple_err(format!("No address for {}", addr_str)))
205+
})
206+
.map_err(box_up_err)
207+
.into_future()
208+
}
209+
210+
pub fn tcp_connect_peer(addr_str: &str) -> BoxedNewPeerFuture {
211+
Box::new(resolve_addr(addr_str).and_then(|addr| {
197212
TcpStream::connect(&addr)
198213
.map(|x| {
199214
info!("Connected to TCP");
200215
let x = Rc::new(x);
201216
Peer::new(MyTcpStream(x.clone(), true), MyTcpStream(x.clone(), false))
202217
})
203-
.map_err(box_up_err),
204-
) as BoxedNewPeerFuture
218+
.map_err(box_up_err)
219+
})) as BoxedNewPeerFuture
205220
}
206221

207-
pub fn tcp_listen_peer(addr: &SocketAddr, l2r: L2rUser) -> BoxedNewPeerStream {
208-
let bound = match TcpListener::bind(&addr) {
209-
Ok(x) => x,
210-
Err(e) => return peer_err_s(e),
211-
};
222+
pub fn tcp_listen_peer(addr_str: &str, l2r: L2rUser) -> BoxedNewPeerStream {
212223
use tk_listen::ListenExt;
213-
Box::new(
224+
Box::new(resolve_addr(addr_str).and_then(|addr| {
225+
TcpListener::bind(&addr).map_err(box_up_err)
226+
}).into_stream().map(move |bound| {
227+
let l2r = l2r.clone();
214228
bound
215229
.incoming()
216230
.sleep_on_error(::std::time::Duration::from_millis(500))
@@ -229,8 +243,8 @@ pub fn tcp_listen_peer(addr: &SocketAddr, l2r: L2rUser) -> BoxedNewPeerStream {
229243
let x = Rc::new(x);
230244
Peer::new(MyTcpStream(x.clone(), true), MyTcpStream(x.clone(), false))
231245
})
232-
.map_err(|()| ::simple_err2("unreachable error?")),
233-
) as BoxedNewPeerStream
246+
.map_err(|()| ::simple_err2("unreachable error?"))
247+
}).flatten()) as BoxedNewPeerStream
234248
}
235249

236250
#[derive(Debug)]
@@ -323,14 +337,14 @@ pub fn get_udp(addr: &SocketAddr, opts: &Rc<Options>) -> IoResult<UdpSocket> {
323337
UdpSocket::from_std(u, &tokio_reactor::Handle::default())
324338
}
325339

326-
pub fn udp_connect_peer(addr: &SocketAddr, opts: &Rc<Options>) -> BoxedNewPeerFuture {
327-
let za = get_zero_address(addr);
340+
pub fn udp_connect_peer(addr_str: &str, opts: Rc<Options>) -> BoxedNewPeerFuture {
341+
Box::new(resolve_addr(addr_str).and_then(move |addr| {
342+
let za = get_zero_address(&addr);
328343

329-
Box::new(futures::future::result(
330-
get_udp(&za, opts)
344+
get_udp(&za, &opts)
331345
.and_then(|x| {
332-
x.connect(addr)?;
333-
apply_udp_options(&x, opts)?;
346+
x.connect(&addr)?;
347+
apply_udp_options(&x, &opts)?;
334348

335349
let h1 = UdpPeerHandle(Rc::new(RefCell::new(UdpPeer {
336350
s: x,
@@ -340,15 +354,15 @@ pub fn udp_connect_peer(addr: &SocketAddr, opts: &Rc<Options>) -> BoxedNewPeerFu
340354
let h2 = h1.clone();
341355
Ok(Peer::new(h1, h2))
342356
})
343-
.map_err(box_up_err),
344-
)) as BoxedNewPeerFuture
357+
.map_err(box_up_err)
358+
})) as BoxedNewPeerFuture
345359
}
346360

347-
pub fn udp_listen_peer(addr: &SocketAddr, opts: &Rc<Options>) -> BoxedNewPeerFuture {
348-
Box::new(futures::future::result(
349-
get_udp(addr, opts)
361+
pub fn udp_listen_peer(addr_str: &str, opts: Rc<Options>) -> BoxedNewPeerFuture {
362+
Box::new(resolve_addr(addr_str).and_then(move |addr| {
363+
get_udp(&addr, &opts)
350364
.and_then(|x| {
351-
apply_udp_options(&x, opts)?;
365+
apply_udp_options(&x, &opts)?;
352366
let h1 = UdpPeerHandle(Rc::new(RefCell::new(UdpPeer {
353367
s: x,
354368
state: Some(UdpPeerState::WaitingForAddress(channel())),
@@ -357,8 +371,8 @@ pub fn udp_listen_peer(addr: &SocketAddr, opts: &Rc<Options>) -> BoxedNewPeerFut
357371
let h2 = h1.clone();
358372
Ok(Peer::new(h1, h2))
359373
})
360-
.map_err(box_up_err),
361-
)) as BoxedNewPeerFuture
374+
.map_err(box_up_err)
375+
})) as BoxedNewPeerFuture
362376
}
363377

364378
impl Read for UdpPeerHandle {

0 commit comments

Comments
 (0)