Compare commits

...

12 Commits

Author SHA1 Message Date
anon 7aec740306 compile on latest openssl 2023-10-26 18:13:42 +03:00
Jonas Herzig 21bd9dc065
Merge pull request #33 from Skgland/master
fall back to IPv4
2022-01-10 08:38:09 +01:00
Jonas Herzig eb9b605f3c
Merge pull request #29 from haslersn/docker
Add Dockerfile
2022-01-10 08:37:20 +01:00
Bennet Bleßmann f7a4d4ad29
fall back to IPv4 2021-06-15 22:25:24 +02:00
Sebastian Hasler 98b00a396b Add Dockerfile
Signed-off-by: Sebastian Hasler <sebastian.hasler@stuvus.uni-stuttgart.de>
2021-03-15 23:11:54 +01:00
Jonas Herzig cfae6178c7 Update tokio to 1.0 2021-01-17 16:48:12 +01:00
Jonas Herzig 99f702234d Update rtp to replace unmaintained rust-crypto crate 2021-01-17 16:38:09 +01:00
Jonas Herzig 2b29a631eb Update libnice to 0.3 2021-01-17 16:36:27 +01:00
Jonas Herzig 8b74065b80 Censor user password when logging Authenticate message 2020-11-25 12:48:26 +01:00
Jonas Herzig c4ef94aa16
Merge pull request #15 from seeba8/patch-1 (fixes #14)
Update libnice dependency to 0.2.1 to fix ARM compile error (#14)
2020-11-08 17:57:09 +01:00
Sebastian 5c9c7365c7
Update Cargo.lock (diff goes crazy) 2020-11-08 17:27:09 +01:00
Sebastian b5845b0819
Update libnice dependency to 0.2.1 to fix ARM compile error (#14) 2020-11-08 16:00:42 +01:00
9 changed files with 1312 additions and 857 deletions

2021
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,25 @@
[package]
name = "mumble-web-proxy"
version = "0.1.0"
version = "0.1.1"
authors = ["Jonas Herzig <me@johni0702.de>"]
edition = "2018"
[dependencies]
argparse = "0.2.2"
bytes = "0.5"
byteorder = "1.2"
bytes = "1"
byteorder = "1.5"
futures = { version = "0.3", features = ["compat", "io-compat"] }
toml = "0.5"
toml = "0.8"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "0.2", features = ["full"] }
tokio-util = { version = "0.3", features = ["codec"] }
tokio-tls = "0.3"
tokio = { version = "1", features = ["full"] }
tokio-util = { version = "0.6.10", features = ["codec"] }
tokio-native-tls = "0.3"
native-tls = "0.2"
mumble-protocol = { version = "0.3", features = ["webrtc-extensions"] }
tokio-tungstenite = "0.10"
mumble-protocol = { version = "0.4", features = ["webrtc-extensions"] }
tokio-tungstenite = "0.13"
http = "0.2"
tungstenite = "0.10"
rtp = { git = "https://github.com/johni0702/rtp", rev = "1444b3c", features = ["rfc5764-openssl"] }
libnice = "0.2"
tungstenite = "0.12"
rtp = { git = "https://git.danksquad.org/anon/rtp", branch = "dtls-srtp", features = ["rfc5764-openssl"] }
libnice = "0.3"
webrtc-sdp = "0.3"
openssl = "0.10"
[replace]
"rust-crypto:0.2.36" = { git = "https://github.com/awmath/rust-crypto.git", branch = "avx2" }

View File

@ -13,7 +13,7 @@ Note that it requires an extension to the Mumble protocol which has not yet been
#### Prerequisites
- Rust 1.39+ (e.g. via [rustup](https://rustup.rs/))
- Rust 1.45+ (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)

38
docker/Dockerfile Normal file
View File

@ -0,0 +1,38 @@
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

13
docker/README.md Normal file
View File

@ -0,0 +1,13 @@
# 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.

25
docker/entrypoint.sh Executable file
View File

@ -0,0 +1,25 @@
#!/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[@]}"

View File

@ -30,7 +30,7 @@ use std::task::Context;
use std::task::Poll;
use std::time::Duration;
use tokio::io;
use tokio::time::Delay;
use tokio::time::Sleep;
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<Delay>, // 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<Pin<Box<Sleep>>>, // 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(tokio::time::delay_for(Duration::from_millis(400)));
self.timeout = Some(Box::pin(tokio::time::sleep(Duration::from_millis(400))));
if self.active {
None
@ -471,7 +471,13 @@ impl Connection {
) -> Result<(), Error> {
match packet {
ControlPacket::Authenticate(mut message) => {
println!("MSG Authenticate: {:?}", message);
println!("MSG Authenticate: {:?}", {
let mut message = message.clone();
if message.get_password() != "" {
message.set_password("{{snip}}".to_string());
}
message
});
if message.get_webrtc() {
// strip webrtc support from the connection (we will be providing it)
message.clear_webrtc();
@ -581,8 +587,7 @@ 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 {
pin_mut!(timeout);
if let Poll::Ready(()) = timeout.poll(cx) {
if let Poll::Ready(()) = timeout.poll_unpin(cx) {
if let Some(frame) = session.set_inactive() {
self.outbound_buf.push_back(frame);
}

View File

@ -37,12 +37,6 @@ 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))

View File

@ -16,12 +16,10 @@ use serde::Deserialize;
use std::convert::Into;
use std::convert::TryInto;
use std::io::ErrorKind;
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
use std::net::ToSocketAddrs;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
use tokio::net::TcpListener;
use tokio::net::TcpStream;
use tokio_tls::TlsConnector;
use tokio_native_tls::TlsConnector;
use tokio_tungstenite::accept_hdr_async_with_config;
use tokio_util::codec::Decoder;
use tungstenite::handshake::server::{ErrorResponse, Request, Response};
@ -178,8 +176,11 @@ async fn main() -> Result<(), Error> {
println!("Resolved upstream address: {}", upstream_addr);
println!("Binding to port {}", ws_port);
let socket_addr = (Ipv6Addr::from(0), ws_port);
let mut server = TcpListener::bind(&socket_addr).await?;
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?;
println!("Waiting for client connections..");
loop {
@ -212,6 +213,7 @@ 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,