Hello all,
I'm a hobbyist programmer and new to rust.
I'm trying to contribute to an issue on a rust DLNA server, hoping to get it working on MacOS.
Currently, I've boiled it down to the code below, which runs on Linux but panics on MacOS.
use std::net::{Ipv6Addr, UdpSocket};
fn ipv6() {
let addr = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0xc);
let socket = UdpSocket::bind("[::]:0").expect("couldn't bind socket");
// socket.connect((addr, 1900)).expect("unable to connect");
socket
.join_multicast_v6(&addr, 0)
.expect("couldn't join multicast");
socket
.send_to("foo ipv6".as_bytes(), (addr, 1900))
.expect("couldn't send");
}
fn ipv4() {
let socket = UdpSocket::bind("[::]:0").expect("couldn't bind socket");
socket
.connect("239.255.255.250:1900")
.expect("couldn't connect");
socket.send("foo ipv4".as_bytes()).expect("couldn't send");
}
fn main() {
ipv4();
ipv6();
}
Backtrace on MacOS:
$ RUST_BACKTRACE=1 cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.43s
Running `target/debug/udp`
thread 'main' panicked at 'couldn't connect: Os { code: 22, kind: InvalidInput, message: "Invalid argument" }', src/libcore/result.rs:1009:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:59
at src/libstd/panicking.rs:211
3: std::panicking::default_hook
at src/libstd/panicking.rs:227
4: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
at src/libstd/panicking.rs:491
5: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:398
6: std::panicking::try::do_call
at src/libstd/panicking.rs:325
7: core::char::methods::<impl char>::escape_debug
at src/libcore/panicking.rs:95
8: core::result::unwrap_failed
at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libcore/macros.rs:26
9: <core::result::Result<T, E>>::expect
at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libcore/result.rs:835
10: udp::ipv4
at src/main.rs:17
11: udp::main
at src/main.rs:24
12: std::rt::lang_start::{{closure}}
at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libstd/rt.rs:74
13: std::panicking::try::do_call
at src/libstd/rt.rs:59
at src/libstd/panicking.rs:310
14: panic_unwind::dwarf::eh::read_encoded_pointer
at src/libpanic_unwind/lib.rs:102
15: <std::panicking::begin_panic::PanicPayload<A> as core::panic::BoxMeUp>::get
at src/libstd/panicking.rs:289
at src/libstd/panic.rs:398
at src/libstd/rt.rs:58
16: std::rt::lang_start
at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libstd/rt.rs:74
17: udp::main
If I instead run only the ipv6
function on MacOS, I get:
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.76s
Running `target/debug/udp`
thread 'main' panicked at 'couldn't join multicast: Os { code: 49, kind: AddrNotAvailable, message: "Can\'t assign requested address" }', src/libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
following advice from here about specifying the interface index on MacOS, if I change it to .join_multicast_v6(&addr, 5)
(based on ifconfig -v
), or if I comment out the part about joining multicast entirely, either way I get:
$ cargo run
Compiling udp v0.1.0 (/Users/n8henrie/git/rustymedia/tmp/udp)
...
Finished dev [unoptimized + debuginfo] target(s) in 2.32s
Running `target/debug/udp`
thread 'main' panicked at 'couldn't send: Os { code: 65, kind: Other, message: "No route to host" }', src/libcore/result.rs:1009:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
So far, I've tried numerous combinations of binding to or connecting to [::]:0
vs [ffo2::c]
, but clearly I don't know what I'm doing or why this UPnP over ipv6 multicast stuff isn't working.
Any pointers on what I'm missing here? Thanks in advance.
EDIT: I also posted to r/rust's "Easy Question" thread recently and got a likely relevant response about IPV6_V6ONLY
on MacOS.