Compare commits
	
		
			No commits in common. "7aec740306dce26ab7ce4f0060c176920f88d8a4" and "0d499e4fb01084cd7f90eb58a0456f7dd727542d" have entirely different histories. 
		
	
	
		
			7aec740306
			...
			0d499e4fb0
		
	
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										27
									
								
								Cargo.toml
								
								
								
								
							
							
						
						
									
										27
									
								
								Cargo.toml
								
								
								
								
							|  | @ -1,25 +1,28 @@ | |||
| [package] | ||||
| name = "mumble-web-proxy" | ||||
| version = "0.1.1" | ||||
| version = "0.1.0" | ||||
| authors = ["Jonas Herzig <me@johni0702.de>"] | ||||
| edition = "2018" | ||||
| 
 | ||||
| [dependencies] | ||||
| argparse = "0.2.2" | ||||
| bytes = "1" | ||||
| byteorder = "1.5" | ||||
| bytes = "0.5" | ||||
| byteorder = "1.2" | ||||
| futures = { version = "0.3", features = ["compat", "io-compat"] } | ||||
| toml = "0.8" | ||||
| toml = "0.5" | ||||
| serde = { version = "1.0", features = ["derive"] } | ||||
| tokio = { version = "1", features = ["full"] } | ||||
| tokio-util = { version = "0.6.10", features = ["codec"] } | ||||
| tokio-native-tls = "0.3" | ||||
| tokio = { version = "0.2", features = ["full"] } | ||||
| tokio-util = { version = "0.3", features = ["codec"] } | ||||
| tokio-tls = "0.3" | ||||
| native-tls = "0.2" | ||||
| mumble-protocol = { version = "0.4", features = ["webrtc-extensions"] } | ||||
| tokio-tungstenite = "0.13" | ||||
| mumble-protocol = { version = "0.3", features = ["webrtc-extensions"] } | ||||
| tokio-tungstenite = "0.10" | ||||
| http = "0.2" | ||||
| tungstenite = "0.12" | ||||
| rtp = { git = "https://git.danksquad.org/anon/rtp", branch = "dtls-srtp", features = ["rfc5764-openssl"] } | ||||
| libnice = "0.3" | ||||
| tungstenite = "0.10" | ||||
| rtp = { git = "https://github.com/johni0702/rtp", rev = "1444b3c", features = ["rfc5764-openssl"] } | ||||
| libnice = "0.2" | ||||
| webrtc-sdp = "0.3" | ||||
| openssl = "0.10" | ||||
| 
 | ||||
| [replace] | ||||
| "rust-crypto:0.2.36" = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" } | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ Note that it requires an extension to the Mumble protocol which has not yet been | |||
| 
 | ||||
| #### Prerequisites | ||||
| 
 | ||||
| - Rust 1.45+ (e.g. via [rustup](https://rustup.rs/)) | ||||
| - Rust 1.39+ (e.g. via [rustup](https://rustup.rs/)) | ||||
| - libnice development headers (`libnice-devel` on Fedora, `libnice-dev` on Debian) | ||||
| - OpenSSL development headers (`openssl-devel` on Fedora, `libssl-dev` on Debian) | ||||
| - clang (`clang` on Fedora and Debian) | ||||
|  |  | |||
|  | @ -1,38 +0,0 @@ | |||
| FROM rust:1.48-alpine AS build | ||||
| 
 | ||||
| ARG REV=master | ||||
| 
 | ||||
| RUN apk add --no-cache \ | ||||
|     clang-libs \ | ||||
|     curl \ | ||||
|     libc-dev \ | ||||
|     libnice-dev \ | ||||
|     openssl-dev \ | ||||
|     ; | ||||
| WORKDIR /src | ||||
| RUN curl https://codeload.github.com/Johni0702/mumble-web-proxy/tar.gz/$REV \ | ||||
|     | tar -xzf - --strip-components 1 | ||||
| RUN echo -e '\n[dependencies."async-trait"]\ndefault-features = false' >> Cargo.toml | ||||
| RUN RUSTFLAGS="-C target-feature=-crt-static" cargo install --path . | ||||
| 
 | ||||
| FROM alpine | ||||
| 
 | ||||
| RUN apk add --no-cache \ | ||||
|     bash \ | ||||
|     libgcc \ | ||||
|     libnice \ | ||||
|     ; | ||||
| COPY --from=build /usr/local/cargo/bin/mumble-web-proxy /mumble-web-proxy | ||||
| COPY entrypoint.sh /entrypoint.sh | ||||
| 
 | ||||
| ENV MWP_LISTEN_WS=64737 | ||||
| ENV MWP_SERVER=mumble-server:64738 | ||||
| ENV MWP_ACCEPT_INVALID_CERTIFICATE= | ||||
| ENV MWP_ICE_PORT_MIN= | ||||
| ENV MWP_ICE_PORT_MAX= | ||||
| ENV MWP_ICE_IPV4= | ||||
| ENV MWP_ICE_IPV6= | ||||
| 
 | ||||
| CMD ["/entrypoint.sh"] | ||||
| USER 1000 | ||||
| EXPOSE 64737 | ||||
|  | @ -1,13 +0,0 @@ | |||
| # mumble-web-proxy OCI image | ||||
| 
 | ||||
| This directory provides files to build a mumble-web-proxy OCI image. | ||||
| The image is based on Alpine Linux and is less than 30 MiB in size. | ||||
| One can use [Docker](https://www.docker.com/) in order to build the image, | ||||
| as follows. | ||||
| 
 | ||||
| ``` | ||||
| docker build --build-arg REV=master -t mumble-web-proxy . | ||||
| ``` | ||||
| 
 | ||||
| `master` can be replaced by any revision (i.e. branch, tag or commit hash) of | ||||
| this repository. | ||||
|  | @ -1,25 +0,0 @@ | |||
| #!/usr/bin/env bash | ||||
| 
 | ||||
| cmd=("/mumble-web-proxy" "--listen-ws=$MWP_LISTEN_WS" "--server=$MWP_SERVER") | ||||
| 
 | ||||
| if [ "$MWP_ACCEPT_INVALID_CERTIFICATE" = true ]; then | ||||
|   cmd+=("--accept-invalid-certificate") | ||||
| fi | ||||
| 
 | ||||
| if [ -n "$MWP_ICE_PORT_MIN" ]; then | ||||
|   cmd+=("--ice-port-min=$MWP_ICE_PORT_MIN") | ||||
| fi | ||||
| 
 | ||||
| if [ -n "$MWP_ICE_PORT_MAX" ]; then | ||||
|   cmd+=("--ice-port-max=$MWP_ICE_PORT_MAX") | ||||
| fi | ||||
| 
 | ||||
| if [ -n "$MWP_ICE_IPV4" ]; then | ||||
|   cmd+=("--ice-ipv4=$MWP_ICE_IPV4") | ||||
| fi | ||||
| 
 | ||||
| if [ -n "$MWP_ICE_IPV6" ]; then | ||||
|   cmd+=("--ice-ipv6=$MWP_ICE_IPV6") | ||||
| fi | ||||
| 
 | ||||
| exec "${cmd[@]}" | ||||
|  | @ -30,7 +30,7 @@ use std::task::Context; | |||
| use std::task::Poll; | ||||
| use std::time::Duration; | ||||
| use tokio::io; | ||||
| use tokio::time::Sleep; | ||||
| use tokio::time::Delay; | ||||
| use webrtc_sdp::attribute_type::SdpAttribute; | ||||
| 
 | ||||
| use crate::error::Error; | ||||
|  | @ -39,10 +39,10 @@ use crate::Config; | |||
| type SessionId = u32; | ||||
| 
 | ||||
| struct User { | ||||
|     session: u32,                     // mumble session id
 | ||||
|     ssrc: u32,                        // ssrc id
 | ||||
|     active: bool,                     // whether the user is currently transmitting audio
 | ||||
|     timeout: Option<Pin<Box<Sleep>>>, // assume end of transmission if silent until then
 | ||||
|     session: u32,           // mumble session id
 | ||||
|     ssrc: u32,              // ssrc id
 | ||||
|     active: bool,           // whether the user is currently transmitting audio
 | ||||
|     timeout: Option<Delay>, // assume end of transmission if silent until then
 | ||||
|     start_voice_seq_num: u64, | ||||
|     highest_voice_seq_num: u64, | ||||
|     rtp_seq_num_offset: u32, // u32 because we also derive the timestamp from it
 | ||||
|  | @ -70,7 +70,7 @@ impl User { | |||
|     } | ||||
| 
 | ||||
|     fn set_active(&mut self, target: u8) -> Option<Frame> { | ||||
|         self.timeout = Some(Box::pin(tokio::time::sleep(Duration::from_millis(400)))); | ||||
|         self.timeout = Some(tokio::time::delay_for(Duration::from_millis(400))); | ||||
| 
 | ||||
|         if self.active { | ||||
|             None | ||||
|  | @ -471,13 +471,7 @@ impl Connection { | |||
|     ) -> Result<(), Error> { | ||||
|         match packet { | ||||
|             ControlPacket::Authenticate(mut message) => { | ||||
|                 println!("MSG Authenticate: {:?}", { | ||||
|                     let mut message = message.clone(); | ||||
|                     if message.get_password() != "" { | ||||
|                         message.set_password("{{snip}}".to_string()); | ||||
|                     } | ||||
|                     message | ||||
|                 }); | ||||
|                 println!("MSG Authenticate: {:?}", message); | ||||
|                 if message.get_webrtc() { | ||||
|                     // strip webrtc support from the connection (we will be providing it)
 | ||||
|                     message.clear_webrtc(); | ||||
|  | @ -587,7 +581,8 @@ impl Future for Connection { | |||
|             // (same applies to the other futures directly below it)
 | ||||
|             for session in self.sessions.values_mut() { | ||||
|                 if let Some(timeout) = &mut session.timeout { | ||||
|                     if let Poll::Ready(()) = timeout.poll_unpin(cx) { | ||||
|                     pin_mut!(timeout); | ||||
|                     if let Poll::Ready(()) = timeout.poll(cx) { | ||||
|                         if let Some(frame) = session.set_inactive() { | ||||
|                             self.outbound_buf.push_back(frame); | ||||
|                         } | ||||
|  |  | |||
|  | @ -37,6 +37,12 @@ impl From<native_tls::Error> for Error { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<tokio::time::Error> for Error { | ||||
|     fn from(e: tokio::time::Error) -> Self { | ||||
|         Error::Misc(Box::new(e)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<rtp::Error> for Error { | ||||
|     fn from(e: rtp::Error) -> Self { | ||||
|         Error::Misc(Box::new(e)) | ||||
|  |  | |||
							
								
								
									
										14
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										14
									
								
								src/main.rs
								
								
								
								
							|  | @ -16,10 +16,12 @@ use serde::Deserialize; | |||
| use std::convert::Into; | ||||
| use std::convert::TryInto; | ||||
| use std::io::ErrorKind; | ||||
| use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs}; | ||||
| use std::net::Ipv4Addr; | ||||
| use std::net::Ipv6Addr; | ||||
| use std::net::ToSocketAddrs; | ||||
| use tokio::net::TcpListener; | ||||
| use tokio::net::TcpStream; | ||||
| use tokio_native_tls::TlsConnector; | ||||
| use tokio_tls::TlsConnector; | ||||
| use tokio_tungstenite::accept_hdr_async_with_config; | ||||
| use tokio_util::codec::Decoder; | ||||
| use tungstenite::handshake::server::{ErrorResponse, Request, Response}; | ||||
|  | @ -176,11 +178,8 @@ async fn main() -> Result<(), Error> { | |||
|     println!("Resolved upstream address: {}", upstream_addr); | ||||
| 
 | ||||
|     println!("Binding to port {}", ws_port); | ||||
|     let ipv6_socket_addr = (Ipv6Addr::UNSPECIFIED, ws_port); | ||||
|     let ipv4_socket_addr = (Ipv4Addr::UNSPECIFIED, ws_port); | ||||
|     let socket_addrs = [SocketAddr::from(ipv6_socket_addr), SocketAddr::from(ipv4_socket_addr)]; | ||||
| 
 | ||||
|     let server = TcpListener::bind(&socket_addrs[..]).await?; | ||||
|     let socket_addr = (Ipv6Addr::from(0), ws_port); | ||||
|     let mut server = TcpListener::bind(&socket_addr).await?; | ||||
| 
 | ||||
|     println!("Waiting for client connections.."); | ||||
|     loop { | ||||
|  | @ -213,7 +212,6 @@ async fn main() -> Result<(), Error> { | |||
|             max_send_queue: Some(10), // can be fairly small as voice is using WebRTC instead
 | ||||
|             max_message_size: Some(0x7f_ffff), // maximum size accepted by Murmur
 | ||||
|             max_frame_size: Some(0x7f_ffff), // maximum size accepted by Murmur
 | ||||
|             accept_unmasked_frames: false, // browsers should comply with RFC 6455
 | ||||
|         }; | ||||
|         fn header_callback( | ||||
|             _req: &Request, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue