Skip to content

Commit

Permalink
Fix when the same interface has multiple ips
Browse files Browse the repository at this point in the history
IP_ADD_MEMBERSHIP fails if you try to subscribe to the same interface once again.
As get_all_ips may return the same interface when it has multiple ipv4, it will try to subscribe twice.

This commit fixes it by filtering out the same interface twice

More:

- https://stackoverflow.com/questions/49819010/ip-add-membership-fails-when-set-both-on-interface-and-its-subinterface-is-that
  • Loading branch information
bltavares committed Sep 19, 2020
1 parent 9d41c52 commit e4bcd7b
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions src/unix.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::io;
use std::mem;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
Expand Down Expand Up @@ -102,13 +103,20 @@ pub fn all_ipv4_interfaces() -> io::Result<Vec<Ipv4Addr>> {
.into_iter()
.map(reverse_interface);

let ipv4_interfaces = interfaces
.filter_map(|i| match i.ip() {
std::net::IpAddr::V4(v4) if !i.is_loopback() => Some(v4),
_ => None,
})
.collect();
Ok(ipv4_interfaces)
// We have to filter the same interface if it has multiple ips
// https://stackoverflow.com/questions/49819010/ip-add-membership-fails-when-set-both-on-interface-and-its-subinterface-is-that
let mut collected_interfaces = HashMap::with_capacity(interfaces.len());
for interface in interfaces {
if !collected_interfaces.contains_key(&interface.name) {
match interface.ip() {
std::net::IpAddr::V4(v4) if !interface.is_loopback() => {
collected_interfaces.insert(interface.name, v4);
}
_ => {}
}
}
}
Ok(collected_interfaces.into_iter().map(|(_, ip)| ip).collect())
}

impl MulticastSocket {
Expand Down

0 comments on commit e4bcd7b

Please # to comment.