mirror of https://github.com/dswd/vpncloud.git
Improved port forwarding on quirky routers
This commit is contained in:
parent
ed81c0de88
commit
10ebd08dad
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
This project follows [semantic versioning](http://semver.org).
|
This project follows [semantic versioning](http://semver.org).
|
||||||
|
|
||||||
|
### Unreleased
|
||||||
|
|
||||||
|
- [changed] Improved port forwarding on quirky routers
|
||||||
|
|
||||||
|
|
||||||
### v1.2.1 (2019-12-22)
|
### v1.2.1 (2019-12-22)
|
||||||
|
|
||||||
- [fixed] Fixed a problem with service restrictions
|
- [fixed] Fixed a problem with service restrictions
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use std::{io, net::SocketAddrV4};
|
use std::{io, net::SocketAddrV4};
|
||||||
|
|
||||||
use igd::*;
|
use igd::{search_gateway, AddAnyPortError, AddPortError, Gateway, PortMappingProtocol, SearchError};
|
||||||
|
|
||||||
use super::util::{get_internal_ip, SystemTimeSource, Time, TimeSource};
|
use super::util::{get_internal_ip, SystemTimeSource, Time, TimeSource};
|
||||||
|
|
||||||
|
@ -46,54 +46,75 @@ impl PortForwarding {
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Try to activate the port forwarding
|
if let Ok((port, timeout)) = Self::get_any_forwarding(&gateway, internal_addr, port) {
|
||||||
// - First with external port = internal port and timeout
|
info!("Port-forwarding: external IP is {}", external_ip);
|
||||||
// - If the port is used, request any port
|
let external_addr = SocketAddrV4::new(external_ip, port);
|
||||||
// - If timeout is denied, try permanent forwarding
|
info!("Port-forwarding: sucessfully activated port forward on {}, timeout: {}", external_addr, timeout);
|
||||||
info!("Port-forwarding: external IP is {}", external_ip);
|
let next_extension =
|
||||||
let (external_addr, timeout) = match gateway.add_port(
|
if timeout > 0 { Some(SystemTimeSource::now() + Time::from(timeout) - 60) } else { None };
|
||||||
PortMappingProtocol::UDP,
|
Some(PortForwarding { internal_addr, external_addr, gateway, next_extension })
|
||||||
internal_addr.port(),
|
} else {
|
||||||
internal_addr,
|
None
|
||||||
LEASE_TIME,
|
}
|
||||||
DESCRIPTION
|
}
|
||||||
) {
|
|
||||||
Ok(()) => (SocketAddrV4::new(external_ip, internal_addr.port()), LEASE_TIME),
|
fn get_any_forwarding(gateway: &Gateway, addr: SocketAddrV4, port: u16) -> Result<(u16, u32), ()> {
|
||||||
Err(AddPortError::PortInUse) => {
|
if let Ok(a) = Self::get_forwarding(gateway, addr, port) {
|
||||||
match gateway.add_any_port(PortMappingProtocol::UDP, internal_addr, LEASE_TIME, DESCRIPTION) {
|
return Ok(a)
|
||||||
Ok(port) => (SocketAddrV4::new(external_ip, port), LEASE_TIME),
|
}
|
||||||
Err(AddAnyPortError::OnlyPermanentLeasesSupported) => {
|
if let Ok(a) = Self::get_forwarding(gateway, addr, 0) {
|
||||||
match gateway.add_any_port(PortMappingProtocol::UDP, internal_addr, 0, DESCRIPTION) {
|
return Ok(a)
|
||||||
Ok(port) => (SocketAddrV4::new(external_ip, port), 0),
|
}
|
||||||
Err(err) => {
|
for i in 1..5 {
|
||||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
if let Ok(a) = Self::get_forwarding(gateway, addr, port + i) {
|
||||||
return None
|
return Ok(a)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for _ in 0..5 {
|
||||||
|
if let Ok(a) = Self::get_forwarding(gateway, addr, rand::random()) {
|
||||||
|
return Ok(a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_forwarding(gateway: &Gateway, addr: SocketAddrV4, port: u16) -> Result<(u16, u32), ()> {
|
||||||
|
info!("Trying external port {}", port);
|
||||||
|
if port == 0 {
|
||||||
|
match gateway.add_any_port(PortMappingProtocol::UDP, addr, LEASE_TIME, DESCRIPTION) {
|
||||||
|
Ok(port) => Ok((port, LEASE_TIME)),
|
||||||
|
Err(AddAnyPortError::OnlyPermanentLeasesSupported) => {
|
||||||
|
match gateway.add_any_port(PortMappingProtocol::UDP, addr, 0, DESCRIPTION) {
|
||||||
|
Ok(port) => Ok((port, 0)),
|
||||||
|
Err(err) => {
|
||||||
|
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||||
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
}
|
||||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
Err(err) => {
|
||||||
return None
|
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||||
}
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(AddPortError::OnlyPermanentLeasesSupported) => {
|
} else {
|
||||||
match gateway.add_port(PortMappingProtocol::UDP, internal_addr.port(), internal_addr, 0, DESCRIPTION) {
|
match gateway.add_port(PortMappingProtocol::UDP, port, addr, LEASE_TIME, DESCRIPTION) {
|
||||||
Ok(()) => (SocketAddrV4::new(external_ip, internal_addr.port()), 0),
|
Ok(()) => Ok((port, LEASE_TIME)),
|
||||||
Err(err) => {
|
Err(AddPortError::OnlyPermanentLeasesSupported) => {
|
||||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
match gateway.add_port(PortMappingProtocol::UDP, port, addr, 0, DESCRIPTION) {
|
||||||
return None
|
Ok(()) => Ok((port, 0)),
|
||||||
|
Err(err) => {
|
||||||
|
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
}
|
||||||
error!("Port-forwarding: failed to activate port forwarding: {}", err);
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
info!("Port-forwarding: sucessfully activated port forward on {}, timeout: {}", external_addr, timeout);
|
|
||||||
let next_extension = if timeout > 0 { Some(SystemTimeSource::now() + Time::from(timeout) - 60) } else { None };
|
|
||||||
Some(PortForwarding { internal_addr, external_addr, gateway, next_extension })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_extend(&mut self) {
|
pub fn check_extend(&mut self) {
|
||||||
|
|
Loading…
Reference in New Issue