Skip to content

Commit

Permalink
refactor!: Use a separate type for IGD errors
Browse files Browse the repository at this point in the history
This removes all the `Igd*` variants from the `Error` enum. These would
in fact never be exposed to users, since IGD errors are always caught
and logged. As such, the new `IgdError` enum is crate-private.

BREAKING CHANGE: The `IgdAddPort`, `IgdRenewPort`, `IgdSearch`, and
`IgdNotSupported` variants have been removed from `Error`. These
variants would never have been returned, but may be referenced in
matches against `Error` values.
  • Loading branch information
Chris Connelly authored and connec committed Aug 27, 2021
1 parent d53f4cb commit d9413de
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 18 deletions.
12 changes: 0 additions & 12 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,6 @@ pub enum Error {
/// Cannot assign port to endpoint
#[error("Cannot assign port to endpoint {0}")]
CannotAssignPort(u16),
/// Failure when trying to map a new port using IGD for automatic port forwarding.
#[error("Could not use IGD for automatic port forwarding")]
IgdAddPort(#[from] igd::AddAnyPortError),
/// Failure when trying to renew leasing of a port mapped using IGD.
#[error("Could not renew port mapping using IGD")]
IgdRenewPort(#[from] igd::AddPortError),
/// IGD gateway deice was not found.
#[error("Could not find the gateway device for IGD")]
IgdSearch(#[from] igd::SearchError),
/// IGD is not supported on IPv6
#[error("IGD is not supported on IPv6")]
IgdNotSupported,
/// Incorrect Public Address provided
#[error("Incorrect Public Address provided")]
IncorrectPublicAddress,
Expand Down
26 changes: 20 additions & 6 deletions src/igd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,35 @@
// specific language governing permissions and limitations relating to use of the SAFE Network
// Software.

use crate::error::{Error, Result};
use igd::SearchOptions;
use std::net::SocketAddr;
use std::time::Duration;
use tokio::sync::broadcast::{error::TryRecvError, Receiver};
use tokio::time::{self, Instant};
use tracing::{debug, info, warn};

#[derive(Debug, thiserror::Error)]
pub(crate) enum IgdError {
#[error("IGD is not supported for IPv6")]
NotSupported,

#[error(transparent)]
AddAnyPort(#[from] igd::AddAnyPortError),

#[error(transparent)]
AddPort(#[from] igd::AddPortError),

#[error(transparent)]
Search(#[from] igd::SearchError),
}

/// Automatically forwards a port and setups a tokio task to renew it periodically.
pub(crate) async fn forward_port(
ext_port: u16,
local_addr: SocketAddr,
lease_interval: Duration,
mut termination_rx: Receiver<()>,
) -> Result<()> {
) -> Result<(), IgdError> {
// Cap `lease_interval` at `u32::MAX` seconds due to limits on the IGD API. Since this is an
// outrageous length of time (~136 years) we just do so silently.
let lease_interval = lease_interval.min(Duration::from_secs(u32::MAX.into()));
Expand Down Expand Up @@ -60,7 +74,7 @@ pub(crate) async fn add_port(
ext_port: u16,
local_addr: SocketAddr,
lease_duration: u32,
) -> Result<()> {
) -> Result<(), IgdError> {
let gateway = igd::aio::search_gateway(SearchOptions::default()).await?;

debug!("IGD gateway found: {:?}", gateway);
Expand All @@ -71,7 +85,7 @@ pub(crate) async fn add_port(
SocketAddr::V4(local_addr) => local_addr,
_ => {
info!("IPv6 for IGD is not supported");
return Err(Error::IgdNotSupported);
return Err(IgdError::NotSupported);
}
};

Expand All @@ -98,7 +112,7 @@ pub(crate) async fn renew_port(
ext_port: u16,
local_addr: SocketAddr,
lease_duration: u32,
) -> Result<()> {
) -> Result<(), IgdError> {
let gateway = igd::aio::search_gateway(SearchOptions::default()).await?;

if let SocketAddr::V4(socket_addr) = local_addr {
Expand All @@ -117,6 +131,6 @@ pub(crate) async fn renew_port(
Ok(())
} else {
info!("IPv6 for IGD is not supported");
Err(Error::IgdNotSupported)
Err(IgdError::NotSupported)
}
}

0 comments on commit d9413de

Please sign in to comment.