Add support for running behind firewall and NAT
							parent
							
								
									20848303e9
								
							
						
					
					
						commit
						a194bb6c6f
					
				|  | @ -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 New Issue