rust-igd icon indicating copy to clipboard operation
rust-igd copied to clipboard

Use agonistic IP parsing & Manual Tokio selection

Open stevefan1999-personal opened this issue 3 years ago • 7 comments

Should solve #52 and #47?

stevefan1999-personal avatar Jan 13 '21 14:01 stevefan1999-personal

I tried to test this with the aio example, but it didn't compile for me (OSX Big Sur). Failed at igd.

Is there something I'm doing wrong?

Partial output of : cargo run --features=aio --example aio 10.1.1.35:4321

   Compiling tokio v1.0.1
...
   Compiling igd v0.12.0 (/Users/darrin/src/t/rust-igd)
error[E0433]: failed to resolve: use of undeclared crate or module `tokio`
 --> src/aio/search.rs:6:5
  |
6 | use tokio::net::UdpSocket;
  |     ^^^^^ use of undeclared crate or module `tokio`

darrinsmart avatar Jan 13 '21 18:01 darrinsmart

Hey thanks for this. Looks like I misconfigured the CI, it was not running for pull requests. Can you push again to trigger it?

Edit: You should probably merge/rebase on master to get the changes to the github workflows

sbstp avatar Jan 13 '21 23:01 sbstp

Tokio 0.2 and especially 0.3 are obsolete at this point, there's little sense in providing support for them.

vorot93 avatar Jan 13 '21 23:01 vorot93

@vorot93 well I used this project in actix and 3.x is still using tokio 0.2 this point...maybe i misconfigured something?

stevefan1999-personal avatar Jan 15 '21 16:01 stevefan1999-personal

@stevefan1999-personal Hey, this issue is a blocker for me too, as I need support for dual-stack LAN. If needed, I can take over this PR. I can also just make my own if you'd prefer (still based off yours, yours has good work that doesn't need to be duplicated)

Silvea12 avatar Feb 19 '22 00:02 Silvea12

@Silvea12 You still interested

canewsin avatar May 29 '22 22:05 canewsin

@canewsin I jumped over to use rupnp for what I was doing instead, though I am no longer really touching IGD stuff anymore, and it's been long enough I don't remember what changes I planned to make unfortunately.

It generally looks like this crate isn't maintained anymore (last commit 17 months ago) so if I were you I'd either fork it or look elsewhere like I did.

A bit of sample code for IGD stuff in rupnp:

Code
async fn get_igd() -> Result<(Device, Service)> {
    trace!("Discovering root node");
    let discovered_devices =
        rupnp::discover(&SearchTarget::RootDevice, Duration::from_millis(5000))
            .await?
            .filter_map(|e| e.ok());
    pin!(discovered_devices);

    let root_device: Device = discovered_devices
        .next()
        .await
        .ok_or_else(|| eyre!("No root device found, maybe UPnP is disabled?"))?;

    trace!(url = %root_device.url());

    for service in root_device.services_iter() {
        trace!(service_type = %service.service_type(), service_id = service.service_id());
    }

    trace!(device = root_device.friendly_name(), "Discovering services");
    let service = root_device
        .services_iter()
        .find(|service| {
            let urn = service.service_type();
            urn.domain_name() == "schemas-upnp-org"
                && urn.typ() == "WANIPConnection"
                && urn.version() <= 2
        })
        .cloned()
        .ok_or_else(|| eyre!("IGD not supported on your router."))?;

    Ok((root_device, service))
}
and for making an IP mapping:
Code
pub async fn forward_port(port: u16) -> Result<()> {
    let (root_device, service) = get_igd().await?;

    let internal_ip = local_ip()?;

    // Lease duration is in seconds
    // NewRemoteHost being empty string/blank = wildcard
    // language=xml
    let arguments = format!(
        "<NewRemoteHost/>
<NewExternalPort>{port}</NewExternalPort>
<NewProtocol>UDP</NewProtocol>
<NewInternalPort>{port}</NewInternalPort>
<NewInternalClient>{internal_ip}</NewInternalClient>
<NewEnabled>1</NewEnabled>
<NewPortMappingDescription>NAT Punchthrough Experiment</NewPortMappingDescription>
<NewLeaseDuration>60</NewLeaseDuration>"
    );

    debug!(%internal_ip, port, "Adding port mapping");

    service
        .action(root_device.url(), "AddPortMapping", &arguments)
        .await?;

    Ok(())
}

with some help from the local-ip-address crate to help with the mapping.

So overall, not a bad replacement.

Silvea12 avatar May 29 '22 23:05 Silvea12