Add support for running behind firewall and NAT
This commit is contained in:
parent
20848303e9
commit
a194bb6c6f
73
Cargo.lock
generated
73
Cargo.lock
generated
|
@ -74,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -291,11 +291,53 @@ dependencies = [
|
|||
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gio-sys"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glib-sys"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "handy_async"
|
||||
version = "0.2.13"
|
||||
|
@ -381,21 +423,28 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "libnice"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/johni0702/rust-libnice?rev=f60d748#f60d748c03ef1027e95e82a09a2beba7c98bb32d"
|
||||
source = "git+https://github.com/johni0702/rust-libnice?rev=1053c81#1053c81b549011b783dd33c1ce7967477800b783"
|
||||
dependencies = [
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libnice-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libnice-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrtc-sdp 0.1.0 (git+https://github.com/nils-ohlmeier/rsdparsa/?rev=ccf6249)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libnice-sys"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bindgen 0.42.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -495,7 +544,7 @@ dependencies = [
|
|||
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libnice 0.1.0 (git+https://github.com/johni0702/rust-libnice?rev=f60d748)",
|
||||
"libnice 0.1.0 (git+https://github.com/johni0702/rust-libnice?rev=1053c81)",
|
||||
"mumble-protocol 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -987,7 +1036,7 @@ name = "sha-1"
|
|||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1469,7 +1518,7 @@ dependencies = [
|
|||
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||
"checksum bindgen 0.42.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e0f199ccbabf5e9f9e13a3096534e80c9ce37aee440789dafaa47190e283245c"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
"checksum block-buffer 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "509de513cca6d92b6aacf9c61acfe7eaa160837323a81068d690cc1f8e5740da"
|
||||
"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d"
|
||||
"checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591"
|
||||
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
|
||||
|
@ -1497,7 +1546,11 @@ dependencies = [
|
|||
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
||||
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"
|
||||
"checksum gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6975ada29f7924dc1c90b30ed3b32d777805a275556c05e420da4fbdc22eb250"
|
||||
"checksum glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a333edf5b9f1411c246ef14e7881b087255f04c56dbef48c64a0cb039b4b340"
|
||||
"checksum glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3573351e846caed9f11207b275cd67bc07f0c2c94fb628e5d7c92ca056c7882d"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08475e4a08f27e6e2287005950114735ed61cec2cb8c1187682a5aec8c69b715"
|
||||
"checksum handy_async 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "165d5c5434dd3b9b3b3fa7ad58a895f13ee34f9aa42f3e5d13bc0ac544be7232"
|
||||
"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
|
||||
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
|
||||
|
@ -1509,8 +1562,8 @@ dependencies = [
|
|||
"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0"
|
||||
"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
|
||||
"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
|
||||
"checksum libnice 0.1.0 (git+https://github.com/johni0702/rust-libnice?rev=f60d748)" = "<none>"
|
||||
"checksum libnice-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c14f86d71d491b61486e5609bc6d5c5acf5d3f34e399b4881dde51c3e53f7cd"
|
||||
"checksum libnice 0.1.0 (git+https://github.com/johni0702/rust-libnice?rev=1053c81)" = "<none>"
|
||||
"checksum libnice-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4076d4216144459cf21253dd351471bb58e0cbbb0e47f93768bb7d4428ccb149"
|
||||
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
|
|
|
@ -18,7 +18,7 @@ tokio-tungstenite = "0.6"
|
|||
tungstenite = "0.6"
|
||||
rtp = { git = "https://github.com/johni0702/rtp", rev = "ee8be93", features = ["openssl", "tokio"] }
|
||||
# libnice = "0.2"
|
||||
libnice = { git = "https://github.com/johni0702/rust-libnice", rev = "f60d748" }
|
||||
libnice = { git = "https://github.com/johni0702/rust-libnice", rev = "1053c81" }
|
||||
# webrtc-sdp = "0.2"
|
||||
webrtc-sdp = { git = "https://github.com/nils-ohlmeier/rsdparsa/", rev = "ccf6249" }
|
||||
openssl = "0.10"
|
||||
|
|
|
@ -39,11 +39,9 @@ mumble-web-proxy --listen-ws 64737 --server mumbleserver:64738
|
|||
```
|
||||
|
||||
#### Firewalls or NAT
|
||||
Note: Not yet implemented.
|
||||
|
||||
If your mumble-web-proxy is running behind a firewall or NAT, you need to allocate a range of ports to it which it can use for ICE connection establishment.
|
||||
```
|
||||
mumble-web-proxy --listen-ws 64737 --server mumbleserver:64738 --ice-start 20000 --ice-end 21000
|
||||
mumble-web-proxy --listen-ws 64737 --server mumbleserver:64738 --ice-port-min 20000 --ice-port-max 21000
|
||||
```
|
||||
For NATs, you additionally need to provide it with its publicly reachable IP address(es):
|
||||
```
|
||||
|
|
|
@ -22,6 +22,7 @@ use rtp::rfc5764::{DtlsSrtp, DtlsSrtpHandshakeResult};
|
|||
use rtp::traits::{ReadPacket, WritePacket};
|
||||
use std::collections::BTreeMap;
|
||||
use std::ffi::CString;
|
||||
use std::net::IpAddr;
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::io;
|
||||
use tokio::prelude::*;
|
||||
|
@ -30,6 +31,7 @@ use webrtc_sdp::attribute_type::SdpAttribute;
|
|||
|
||||
use error::Error;
|
||||
use utils::EitherS;
|
||||
use Config;
|
||||
|
||||
type SessionId = u32;
|
||||
|
||||
|
@ -82,6 +84,7 @@ impl User {
|
|||
}
|
||||
|
||||
pub struct Connection {
|
||||
config: Config,
|
||||
inbound_client: Box<Stream<Item = ControlPacket<Serverbound>, Error = Error>>,
|
||||
outbound_client: Box<Sink<SinkItem = ControlPacket<Clientbound>, SinkError = Error>>,
|
||||
inbound_server: Box<Stream<Item = ControlPacket<Clientbound>, Error = Error>>,
|
||||
|
@ -109,6 +112,7 @@ pub struct Connection {
|
|||
|
||||
impl Connection {
|
||||
pub fn new<CSi, CSt, SSi, SSt>(
|
||||
config: Config,
|
||||
client_sink: CSi,
|
||||
client_stream: CSt,
|
||||
server_sink: SSi,
|
||||
|
@ -135,6 +139,7 @@ impl Connection {
|
|||
let cert = cert_builder.build();
|
||||
|
||||
Self {
|
||||
config,
|
||||
inbound_client: Box::new(client_stream),
|
||||
outbound_client: Box::new(client_sink),
|
||||
inbound_server: Box::new(server_stream),
|
||||
|
@ -192,7 +197,13 @@ impl Connection {
|
|||
agent.set_software("mumble-web-proxy");
|
||||
|
||||
// Setup ICE stream
|
||||
let mut stream = match agent.stream_builder(1).build() {
|
||||
let mut stream = match {
|
||||
let mut builder = agent.stream_builder(1);
|
||||
if self.config.min_port != 1 || self.config.max_port != u16::max_value() {
|
||||
builder.set_port_range(self.config.min_port, self.config.max_port);
|
||||
}
|
||||
builder.build()
|
||||
} {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => {
|
||||
return stream::once(Err(io::Error::new(io::ErrorKind::Other, err).into()));
|
||||
|
@ -531,12 +542,24 @@ impl Future for Connection {
|
|||
|
||||
// Poll ice stream for new candidates
|
||||
if let Some((_, stream)) = &mut self.ice {
|
||||
if let Async::Ready(Some(candidate)) = stream.poll()? {
|
||||
let candidate = format!("candidate:{}", candidate.to_string());
|
||||
println!("Local ice candidate: {}", candidate);
|
||||
if let Async::Ready(Some(mut candidate)) = stream.poll()? {
|
||||
println!("Local ice candidate: {}", candidate.to_string());
|
||||
|
||||
// Map to public addresses (if configured)
|
||||
let config = &self.config;
|
||||
match (&mut candidate.address, config.public_v4, config.public_v6) {
|
||||
(IpAddr::V4(addr), Some(public), _) => {
|
||||
*addr = public;
|
||||
}
|
||||
(IpAddr::V6(addr), _, Some(public)) => {
|
||||
*addr = public;
|
||||
}
|
||||
_ => {} // non configured
|
||||
};
|
||||
|
||||
// Got a new candidate, send it to the client
|
||||
let mut msg = msgs::IceCandidate::new();
|
||||
msg.set_content(candidate.to_string());
|
||||
msg.set_content(format!("candidate:{}", candidate.to_string()));
|
||||
let frame = Frame::Client(msg.into());
|
||||
self.stream_to_be_sent = Some(Box::new(stream::once(Ok(frame))));
|
||||
continue 'poll;
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -19,6 +19,7 @@ extern crate tokio_tungstenite;
|
|||
extern crate tungstenite;
|
||||
extern crate webrtc_sdp;
|
||||
|
||||
use argparse::StoreOption;
|
||||
use argparse::StoreTrue;
|
||||
use argparse::{ArgumentParser, Store};
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
|
@ -30,6 +31,7 @@ use mumble_protocol::control::RawControlPacket;
|
|||
use mumble_protocol::Clientbound;
|
||||
use std::convert::Into;
|
||||
use std::convert::TryInto;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::net::Ipv6Addr;
|
||||
use std::net::ToSocketAddrs;
|
||||
use tokio::net::TcpListener;
|
||||
|
@ -48,10 +50,24 @@ mod utils;
|
|||
use connection::Connection;
|
||||
use error::Error;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Config {
|
||||
pub min_port: u16,
|
||||
pub max_port: u16,
|
||||
pub public_v4: Option<Ipv4Addr>,
|
||||
pub public_v6: Option<Ipv6Addr>,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut ws_port = 0_u16;
|
||||
let mut upstream = "".to_string();
|
||||
let mut accept_invalid_certs = false;
|
||||
let mut config = Config {
|
||||
min_port: 1,
|
||||
max_port: u16::max_value(),
|
||||
public_v4: None,
|
||||
public_v6: None,
|
||||
};
|
||||
|
||||
{
|
||||
let mut ap = ArgumentParser::new();
|
||||
|
@ -76,6 +92,26 @@ fn main() {
|
|||
"Connect to upstream server even when its certificate is invalid.
|
||||
Only ever use this if know that your server is using a self-signed certificate!",
|
||||
);
|
||||
ap.refer(&mut config.min_port).add_option(
|
||||
&["--ice-port-min"],
|
||||
Store,
|
||||
"Minimum port number to use for ICE host candidates.",
|
||||
);
|
||||
ap.refer(&mut config.max_port).add_option(
|
||||
&["--ice-port-max"],
|
||||
Store,
|
||||
"Maximum port number to use for ICE host candidates.",
|
||||
);
|
||||
ap.refer(&mut config.public_v4).add_option(
|
||||
&["--ice-ipv4"],
|
||||
StoreOption,
|
||||
"Set a public IPv4 address to be used for ICE host candidates.",
|
||||
);
|
||||
ap.refer(&mut config.public_v6).add_option(
|
||||
&["--ice-ipv6"],
|
||||
StoreOption,
|
||||
"Set a public IPv6 address to be used for ICE host candidates.",
|
||||
);
|
||||
ap.parse_args_or_exit();
|
||||
}
|
||||
|
||||
|
@ -138,6 +174,7 @@ fn main() {
|
|||
.from_err();
|
||||
|
||||
// Once both are done, begin proxy duty
|
||||
let config = config.clone();
|
||||
let f = client
|
||||
.join(server)
|
||||
.and_then(move |(client, server)| {
|
||||
|
@ -164,7 +201,13 @@ fn main() {
|
|||
let server_sink = server_sink.sink_from_err();
|
||||
let server_stream = server_stream.from_err();
|
||||
|
||||
Connection::new(client_sink, client_stream, server_sink, server_stream)
|
||||
Connection::new(
|
||||
config,
|
||||
client_sink,
|
||||
client_stream,
|
||||
server_sink,
|
||||
server_stream,
|
||||
)
|
||||
})
|
||||
.or_else(move |err| {
|
||||
if err.is_connection_closed() {
|
||||
|
|
Loading…
Reference in a new issue