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

search_gateway() fails on dual-stack LAN

Open darrinsmart opened this issue 4 years ago • 2 comments

This is possibly a similar issue to #47. However in this case no special IPv6 support is desired, just the ability to map a IPv4 port.

$ cargo run --features=aio --example aio 10.1.1.129:4321
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `target/debug/examples/aio '10.1.1.129:4321'`
06:17:20 [DEBUG] (1) igd::aio::search: sending broadcast request to: 239.255.255.250:1900 on interface: Ok(V4(0.0.0.0:53615))
06:17:20 [DEBUG] (1) igd::aio::search: received broadcast response from: 10.1.1.1:1900
06:17:20 [DEBUG] (1) igd::aio::search: handling broadcast response from: 10.1.1.1:1900
Faild to find IGD: Invalid response

A look with tshark shows this packet going out to 239.255.255.250:

Simple Service Discovery Protocol
    M-SEARCH * HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): M-SEARCH * HTTP/1.1\r\n]
            [M-SEARCH * HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: M-SEARCH
        Request URI: *
        Request Version: HTTP/1.1
    Host:239.255.255.250:1900\r\n
    ST:urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n
    Man:"ssdp:discover"\r\n
    MX:3\r\n
    \r\n
    [Full request URI: http://239.255.255.250:1900*]
    [HTTP request 1/1]

and the response from my OpenWRT router at 10.1.1.1:

Simple Service Discovery Protocol
    HTTP/1.1 200 OK\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 200 OK\r\n]
            [HTTP/1.1 200 OK\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Response Version: HTTP/1.1
        Status Code: 200
        [Status Code Description: OK]
        Response Phrase: OK
    CACHE-CONTROL: max-age=120\r\n
    ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n
    USN: uuid:2569469e-5c8a-49c7-a65b-f83ef5f2a517::urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n
    EXT:\r\n
    SERVER: OpenWRT/19.07-SNAPSHOT UPnP/1.1 MiniUPnPd/2.1.20191006\r\n
    LOCATION: http://[fdb6:cbcf:8a09::1]:5000/rootDesc.xml\r\n
    OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01\r\n
    01-NLS: 1592621464\r\n
    BOOTID.UPNP.ORG: 1592621464\r\n
    CONFIGID.UPNP.ORG: 1337\r\n
    \r\n
    [HTTP response 1/1]

Note the location field has a IPv6 address. It looks like MiniUPnPd sends two responses - both from 10.1.1.1 - the first one with the IPv6 address and another with the IPv4 address:

Simple Service Discovery Protocol
    HTTP/1.1 200 OK\r\n
        [Expert Info (Chat/Sequence): HTTP/1.1 200 OK\r\n]
            [HTTP/1.1 200 OK\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Response Version: HTTP/1.1
        Status Code: 200
        [Status Code Description: OK]
        Response Phrase: OK
    CACHE-CONTROL: max-age=120\r\n
    ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n
    USN: uuid:2569469e-5c8a-49c7-a65b-f83ef5f2a517::urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n
    EXT:\r\n
    SERVER: OpenWRT/19.07-SNAPSHOT UPnP/1.1 MiniUPnPd/2.1.20191006\r\n
    LOCATION: http://10.1.1.1:5000/rootDesc.xml\r\n
    OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01\r\n
    01-NLS: 1592621464\r\n
    BOOTID.UPNP.ORG: 1592621464\r\n
    CONFIGID.UPNP.ORG: 1337\r\n
    \r\n
    [HTTP response 2/2]
    [Prev response in frame: 2]

And I think the bug is that the library is seeing the IPv6 response first and failing. It it not waiting for the IPv4 response.

For comparison, this is what the miniupnpc test client discovers:

$ upnpc -P
upnpc : miniupnpc library test client, version 2.1.
 (c) 2005-2018 Thomas Bernard.
Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
for more information.
List of UPNP devices found on the network :
 desc: http://10.1.1.1:5000/rootDesc.xml
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

 desc: http://[fdb6:cbcf:8a09::1]:5000/rootDesc.xml
 st: urn:schemas-upnp-org:device:InternetGatewayDevice:1

Found valid IGD : http://10.1.1.1:5000/ctl/IPConn
Local LAN ip address : fdb6:cbcf:8a09:0:d065:6971:abe7:e483
Presentation URL found:
            http://10.1.1.1/

darrinsmart avatar Jun 21 '20 06:06 darrinsmart

I found some interesting fact surrounding multicast address maybe?

On Windows machine, if you started Wireshark/Npcap to capture packets, the interface metric actually favors Wireshark (because it needs to be high up enough to capture traffic of course) but for some reason Npcap didn't forward the multicast to the main interface, thus the packet never had a chance to go to my main router.

I've experience similar problem of you, and if anyone having the same issue and also on Windows, this might be a special case worth checking out.

I have to specifically listen on my local address that's listed on my main interface to get around with this. The brute force solution would be to find all possible interfaces, listen and send IGD request to all of them, and then randomly select any valid/ok result.

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

I solved this issue using the "local_ip_address" crate and passing the local ip it resolves to the search_gateway function: image

danielstuart14 avatar Feb 11 '23 13:02 danielstuart14