windows upnp work
This commit is contained in:
@@ -26,7 +26,7 @@ struct PortMapValue {
|
||||
|
||||
struct IGDManagerInner {
|
||||
local_ip_addrs: BTreeMap<AddressType, IpAddr>,
|
||||
gateways: BTreeMap<AddressType, Arc<Gateway>>,
|
||||
gateways: BTreeMap<IpAddr, Arc<Gateway>>,
|
||||
port_maps: BTreeMap<PortMapKey, PortMapValue>,
|
||||
}
|
||||
|
||||
@@ -121,17 +121,21 @@ impl IGDManager {
|
||||
|
||||
fn find_gateway(
|
||||
inner: &mut IGDManagerInner,
|
||||
address_type: AddressType,
|
||||
local_ip: IpAddr,
|
||||
) -> Option<Arc<Gateway>> {
|
||||
if let Some(gw) = inner.gateways.get(&address_type) {
|
||||
|
||||
if let Some(gw) = inner.gateways.get(&local_ip) {
|
||||
return Some(gw.clone());
|
||||
}
|
||||
|
||||
let gateway = match address_type {
|
||||
AddressType::IPV4 => {
|
||||
match igd::search_gateway(SearchOptions::new_v4(
|
||||
let gateway = match local_ip {
|
||||
IpAddr::V4(v4) => {
|
||||
let mut opts = SearchOptions::new_v4(
|
||||
UPNP_GATEWAY_DETECT_TIMEOUT_MS as u64,
|
||||
)) {
|
||||
);
|
||||
opts.bind_addr = SocketAddr::V4(SocketAddrV4::new(v4, 0));
|
||||
|
||||
match igd::search_gateway(opts) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log_net!(debug "couldn't find ipv4 igd: {}", e);
|
||||
@@ -139,11 +143,14 @@ impl IGDManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
AddressType::IPV6 => {
|
||||
match igd::search_gateway(SearchOptions::new_v6(
|
||||
IpAddr::V6(v6) => {
|
||||
let mut opts = SearchOptions::new_v6(
|
||||
Ipv6SearchScope::LinkLocal,
|
||||
UPNP_GATEWAY_DETECT_TIMEOUT_MS as u64,
|
||||
)) {
|
||||
);
|
||||
opts.bind_addr = SocketAddr::V6(SocketAddrV6::new(v6, 0, 0, 0));
|
||||
|
||||
match igd::search_gateway(opts) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log_net!(debug "couldn't find ipv6 igd: {}", e);
|
||||
@@ -151,17 +158,18 @@ impl IGDManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
let gw = Arc::new(gateway);
|
||||
inner.gateways.insert(address_type, gw.clone());
|
||||
inner.gateways.insert(local_ip, gw.clone());
|
||||
Some(gw)
|
||||
}
|
||||
|
||||
fn get_gateway(
|
||||
inner: &mut IGDManagerInner,
|
||||
address_type: AddressType,
|
||||
local_ip: IpAddr,
|
||||
) -> Option<Arc<Gateway>> {
|
||||
if let Some(gw) = inner.gateways.get(&address_type) {
|
||||
if let Some(gw) = inner.gateways.get(&local_ip) {
|
||||
return Some(gw.clone());
|
||||
}
|
||||
None
|
||||
@@ -191,8 +199,12 @@ impl IGDManager {
|
||||
let pmk = found?;
|
||||
let _pmv = inner.port_maps.remove(&pmk).expect("key found but remove failed");
|
||||
|
||||
|
||||
// Get local ip address
|
||||
let local_ip = Self::find_local_ip(&mut inner, at)?;
|
||||
|
||||
// Find gateway
|
||||
let gw = Self::find_gateway(&mut inner, at)?;
|
||||
let gw = Self::find_gateway(&mut inner, local_ip)?;
|
||||
|
||||
// Unmap port
|
||||
match gw.remove_port(convert_llpt(llpt), mapped_port) {
|
||||
@@ -233,7 +245,7 @@ impl IGDManager {
|
||||
let local_ip = Self::find_local_ip(&mut inner, at)?;
|
||||
|
||||
// Find gateway
|
||||
let gw = Self::find_gateway(&mut inner, at)?;
|
||||
let gw = Self::find_gateway(&mut inner, local_ip)?;
|
||||
|
||||
// Get external address
|
||||
let ext_ip = match gw.get_external_ip() {
|
||||
@@ -325,14 +337,6 @@ impl IGDManager {
|
||||
|
||||
// Process full renewals
|
||||
for (k, v) in full_renews {
|
||||
|
||||
// Get gateway for address type
|
||||
let gw = match Self::get_gateway(&mut inner, k.at) {
|
||||
Some(gw) => gw,
|
||||
None => {
|
||||
return Err(eyre!("gateway missing for address type"));
|
||||
}
|
||||
};
|
||||
|
||||
// Get local ip for address type
|
||||
let local_ip = match Self::get_local_ip(&mut inner, k.at) {
|
||||
@@ -341,6 +345,14 @@ impl IGDManager {
|
||||
return Err(eyre!("local ip missing for address type"));
|
||||
}
|
||||
};
|
||||
|
||||
// Get gateway for interface
|
||||
let gw = match Self::get_gateway(&mut inner, local_ip) {
|
||||
Some(gw) => gw,
|
||||
None => {
|
||||
return Err(eyre!("gateway missing for interface"));
|
||||
}
|
||||
};
|
||||
|
||||
// Delete the mapping if it exists, ignore any errors here
|
||||
let _ = gw.remove_port(convert_llpt(k.llpt), v.mapped_port);
|
||||
@@ -370,14 +382,6 @@ impl IGDManager {
|
||||
// Process normal renewals
|
||||
for (k, mut v) in renews {
|
||||
|
||||
// Get gateway for address type
|
||||
let gw = match Self::get_gateway(&mut inner, k.at) {
|
||||
Some(gw) => gw,
|
||||
None => {
|
||||
return Err(eyre!("gateway missing for address type"));
|
||||
}
|
||||
};
|
||||
|
||||
// Get local ip for address type
|
||||
let local_ip = match Self::get_local_ip(&mut inner, k.at) {
|
||||
Some(ip) => ip,
|
||||
@@ -386,6 +390,14 @@ impl IGDManager {
|
||||
}
|
||||
};
|
||||
|
||||
// Get gateway for interface
|
||||
let gw = match Self::get_gateway(&mut inner, local_ip) {
|
||||
Some(gw) => gw,
|
||||
None => {
|
||||
return Err(eyre!("gateway missing for address type"));
|
||||
}
|
||||
};
|
||||
|
||||
let desc = this.get_description(k.llpt, k.local_port);
|
||||
match gw.add_port(convert_llpt(k.llpt), v.mapped_port, SocketAddr::new(local_ip, k.local_port), (UPNP_MAPPING_LIFETIME_MS + 999) / 1000, &desc) {
|
||||
Ok(()) => {
|
||||
|
@@ -10,7 +10,6 @@ use super::*;
|
||||
use crate::routing_table::*;
|
||||
use connection_manager::*;
|
||||
use discovery_context::*;
|
||||
use network_interfaces::*;
|
||||
use network_tcp::*;
|
||||
use protocol::tcp::RawTcpProtocolHandler;
|
||||
use protocol::udp::RawUdpProtocolHandler;
|
||||
@@ -316,7 +315,7 @@ impl Network {
|
||||
if !from.ip().is_unspecified() {
|
||||
vec![*from]
|
||||
} else {
|
||||
let addrs = self.get_usable_interface_addresses();
|
||||
let addrs = self.get_stable_interface_addresses();
|
||||
addrs
|
||||
.iter()
|
||||
.filter_map(|a| {
|
||||
@@ -358,13 +357,13 @@ impl Network {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_usable_interface_address(&self, addr: IpAddr) -> bool {
|
||||
let usable_addrs = self.get_usable_interface_addresses();
|
||||
usable_addrs.contains(&addr)
|
||||
pub fn is_stable_interface_address(&self, addr: IpAddr) -> bool {
|
||||
let stable_addrs = self.get_stable_interface_addresses();
|
||||
stable_addrs.contains(&addr)
|
||||
}
|
||||
|
||||
pub fn get_usable_interface_addresses(&self) -> Vec<IpAddr> {
|
||||
let addrs = self.unlocked_inner.interfaces.best_addresses();
|
||||
pub fn get_stable_interface_addresses(&self) -> Vec<IpAddr> {
|
||||
let addrs = self.unlocked_inner.interfaces.stable_addresses();
|
||||
let addrs: Vec<IpAddr> = addrs
|
||||
.into_iter()
|
||||
.filter(|addr| {
|
||||
@@ -377,7 +376,13 @@ impl Network {
|
||||
|
||||
// See if our interface addresses have changed, if so redo public dial info if necessary
|
||||
async fn check_interface_addresses(&self) -> EyreResult<bool> {
|
||||
if !self.unlocked_inner.interfaces.refresh().await? {
|
||||
if !self
|
||||
.unlocked_inner
|
||||
.interfaces
|
||||
.refresh()
|
||||
.await
|
||||
.wrap_err("failed to check network interfaces")?
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
@@ -723,7 +728,7 @@ impl Network {
|
||||
{
|
||||
let mut inner = self.inner.lock();
|
||||
inner.enable_ipv4 = false;
|
||||
for addr in self.get_usable_interface_addresses() {
|
||||
for addr in self.get_stable_interface_addresses() {
|
||||
if addr.is_ipv4() {
|
||||
log_net!(debug "enable address {:?} as ipv4", addr);
|
||||
inner.enable_ipv4 = true;
|
||||
|
@@ -342,7 +342,7 @@ impl Network {
|
||||
|
||||
// See if this public address is also a local interface address we haven't registered yet
|
||||
let is_interface_address = (|| {
|
||||
for ip_addr in self.get_usable_interface_addresses() {
|
||||
for ip_addr in self.get_stable_interface_addresses() {
|
||||
if pdi_addr.ip() == ip_addr {
|
||||
return true;
|
||||
}
|
||||
@@ -438,7 +438,7 @@ impl Network {
|
||||
|
||||
// See if this public address is also a local interface address
|
||||
if !registered_addresses.contains(&gsa.ip())
|
||||
&& self.is_usable_interface_address(gsa.ip())
|
||||
&& self.is_stable_interface_address(gsa.ip())
|
||||
{
|
||||
editor_local_network.register_dial_info(pdi, DialInfoClass::Direct)?;
|
||||
}
|
||||
@@ -552,7 +552,7 @@ impl Network {
|
||||
|
||||
// See if this public address is also a local interface address
|
||||
if !registered_addresses.contains(&gsa.ip())
|
||||
&& self.is_usable_interface_address(gsa.ip())
|
||||
&& self.is_stable_interface_address(gsa.ip())
|
||||
{
|
||||
editor_local_network.register_dial_info(pdi, DialInfoClass::Direct)?;
|
||||
}
|
||||
@@ -653,7 +653,7 @@ impl Network {
|
||||
}
|
||||
|
||||
// See if this public address is also a local interface address
|
||||
if self.is_usable_interface_address(pdi_addr.ip()) {
|
||||
if self.is_stable_interface_address(pdi_addr.ip()) {
|
||||
editor_local_network.register_dial_info(pdi, DialInfoClass::Direct)?;
|
||||
}
|
||||
}
|
||||
|
@@ -425,11 +425,11 @@ impl Network {
|
||||
trace!("network stopped");
|
||||
}
|
||||
|
||||
pub fn is_usable_interface_address(&self, _addr: IpAddr) -> bool {
|
||||
pub fn is_stable_interface_address(&self, _addr: IpAddr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn get_usable_interface_addresses(&self) -> Vec<IpAddr> {
|
||||
pub fn get_stable_interface_addresses(&self) -> Vec<IpAddr> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user