Giter VIP home page Giter VIP logo

Comments (7)

jsydliuqing avatar jsydliuqing commented on June 11, 2024 1

Hi @EstebanBorai ,

Supplementary Information:

1.Can you check the output from ifconfig?
A:
$ sudo ip netns exec ns0 ifconfig
veth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.80.10 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::b87c:bcff:fe65:ef76 prefixlen 64 scopeid 0x20
ether ba:7c:bc:65:ef:76 txqueuelen 1000 (以太网)
RX packets 229 bytes 27434 (27.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 463 bytes 25562 (25.5 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

$ ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::9cf5:bcff:fe1a:b3b8 prefixlen 64 scopeid 0x20
ether 6a:2c:4d:34:44:10 txqueuelen 1000 (以太网)
RX packets 514 bytes 21988 (21.9 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 75 bytes 10928 (10.9 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

br-c23034e83273: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
inet6 fe80::42:faff:fed3:a101 prefixlen 64 scopeid 0x20
ether 02:42:fa:d3:a1:01 txqueuelen 0 (以太网)
RX packets 29 bytes 3228 (3.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 87241 bytes 18084048 (18.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:7fff:fedb:8ee prefixlen 64 scopeid 0x20
ether 02:42:7f:db:08:ee txqueuelen 0 (以太网)
RX packets 372769 bytes 148146869 (148.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 400780 bytes 340925162 (340.9 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.119 netmask 255.255.248.0 broadcast 192.168.7.255
inet6 fe80::3e4f:72f:6826:9529 prefixlen 64 scopeid 0x20
ether 56:6f:81:7f:00:8b txqueuelen 1000 (以太网)
RX packets 14809847 bytes 8713412808 (8.7 GB)
RX errors 0 dropped 496504 overruns 0 frame 0
TX packets 9378993 bytes 14889855580 (14.8 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

ens7: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.17 netmask 255.255.248.0 broadcast 192.168.7.255
inet6 fe80::2581:4548:56c8:b69e prefixlen 64 scopeid 0x20
ether 56:6f:81:7f:00:35 txqueuelen 1000 (以太网)
RX packets 4245525 bytes 583538856 (583.5 MB)
RX errors 0 dropped 496504 overruns 0 frame 0
TX packets 134210 bytes 21766228 (21.7 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1000 (本地环回)
RX packets 555192 bytes 1088226330 (1.0 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 555192 bytes 1088226330 (1.0 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

2.Can you see your network interfaces using list_afinet_netifas?
A:
rust code as following:
let ipaddr = local_ip_address::list_afinet_netifas().unwrap();
println!("ipaddr:{:?}", ipaddr);
Output:
ipaddr:[("lo", 127.0.0.1), ("veth0", 192.168.80.10), ("veth0", fe80::b87c:bcff:fe65:ef76)]

3.In order to find the default network interface for local IP address, we use netlink by sending a packet to the local network, given the error message we can discard the source of the issue is the missing C header in your system. Do you have a custom configuration?
A: No, i don't have any custom configuration.

By the way, Maybe, I can use list_afinet_netifas to achieve the goal of obtaining the local IP address. hahaha..
(I will read linux.rs code and try to find the answer!)

from local-ip-address.

jsydliuqing avatar jsydliuqing commented on June 11, 2024 1

Hi @EstebanBorai ,

I found the root cause.
Root cause:
In ns0 virtual network space, i don't add the default route. Looks like as:

$ sudo ip netns exec ns0 ip route
192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10 

So, this is the reason why the error 'err.error == -libc::ENETUNREACH' occurred.

When i add the default route into ns0, the rust program can work normally.

$ sudo ip netns exec ns0 ip route add default via 192.168.80.1 dev veth0
$ sudo ip netns exec ns0 ip route
default via 192.168.80.1 dev veth0 
192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10 
$ sudo ip netns exec ns0 target/debug/measure-device 
This is my local IP address: 192.168.80.10

My solution:

fn get_local_ip() -> Result<IpAddr, local_ip_address::Error> {
    use local_ip_address::{list_afinet_netifas, local_ip, Error};
    let lip = local_ip();
    match lip {
        Ok(ip) => Ok(ip),
        Err(_error) => {
            let s_lip = list_afinet_netifas();
            match s_lip {
                Ok(v_lip) => {
                    match v_lip
                        .iter()
                        .find(|(_, ip)| ip != &IpAddr::V4("127.0.0.1".parse().unwrap()))
                    {
                        Some((_, ip)) => Ok(ip.clone()),
                        _ => Err(Error::LocalIpAddressNotFound),
                    }
                }
                Err(error) => Err(error),
            }
        }
    }
}

Another question:
Why can't Rmt::GetAddr be used instead of Rmt::GetRoute to retrieve local IP address by Netlink socket?
Such as the examples/getips.rs code of neli-0.6.4.

from local-ip-address.

EstebanBorai avatar EstebanBorai commented on June 11, 2024 1

Hi @EstebanBorai ,

I found the root cause.

Root cause:

In ns0 virtual network space, i don't add the default route.  Looks like as:

$ sudo ip netns exec ns0 ip route

192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10 

So, this is the reason why the error 'err.error == -libc::ENETUNREACH' occurred.

When i add the default route into ns0, the rust program can work normally.


$ sudo ip netns exec ns0 ip route add default via 192.168.80.1 dev veth0

$ sudo ip netns exec ns0 ip route

default via 192.168.80.1 dev veth0 

192.168.80.0/24 dev veth0 proto kernel scope link src 192.168.80.10 

$ sudo ip netns exec ns0 target/debug/measure-device 

This is my local IP address: 192.168.80.10

My solution:


fn get_local_ip() -> Result<IpAddr, local_ip_address::Error> {

    use local_ip_address::{list_afinet_netifas, local_ip, Error};

    let lip = local_ip();

    match lip {

        Ok(ip) => Ok(ip),

        Err(_error) => {

            let s_lip = list_afinet_netifas();

            match s_lip {

                Ok(v_lip) => {

                    match v_lip

                        .iter()

                        .find(|(_, ip)| ip != &IpAddr::V4("127.0.0.1".parse().unwrap()))

                    {

                        Some((_, ip)) => Ok(ip.clone()),

                        _ => Err(Error::LocalIpAddressNotFound),

                    }

                }

                Err(error) => Err(error),

            }

        }

    }

}

Another question:

Why can't Rmt::GetAddr be used instead of Rmt::GetRoute to retrieve local IP address by Netlink socket?

Such as the examples/getips.rs code of neli-0.6.4.

Hi @jsydliuqing!

This is great progress on debugging, thanks so much for taking the time!

These constants are mapped to Netlink's message header type's in libc here:

https://docs.rs/neli/0.6.4/src/neli/consts/rtnl.rs.html#409-458

Which you can find documentation for each of them in the Linux manual pages here: https://man7.org/linux/man-pages/man7/rtnetlink.7.html

I think we could use a fallback on attempting to find localhost via Rmt::GetAddr if current approach fails.

I dont have a strong opinion on sticking with Rmt::GetRoute but I think its important to keep consistent behavior with current minor (semver) version.

Are you willing to open a PR using this approach in case local IP is
not found on Linux?

from local-ip-address.

jsydliuqing avatar jsydliuqing commented on June 11, 2024 1

Hi @EstebanBorai !
I open a PR , please review it. Thanks!

from local-ip-address.

jsydliuqing avatar jsydliuqing commented on June 11, 2024 1

This issue has been fixed in version v0.6.1!

from local-ip-address.

EstebanBorai avatar EstebanBorai commented on June 11, 2024

Hi @jsydliuqing!

Thanks for opening this issue, theres many reasons on why you could have this issue.
In order to narrow down the range of possible causes, can you try the following?

  1. Can you check the output from ifconfig?
  2. Can you see your network interfaces using list_afinet_netifas?
  3. In order to find the default network interface for local IP address, we use netlink by sending a packet to the local network (Source), given the error message we can discard the source of the issue is the missing C header in your system. Do you have a custom configuration?

Hope these tests help you find out more details.

from local-ip-address.

jsydliuqing avatar jsydliuqing commented on June 11, 2024

Hi @EstebanBorai !

I use gdb debug the rust program. Find the error code in linux.rs file and line 210.
The code:

    for response in netlink_socket.iter(false) {
        let header: Nlmsghdr<Rtm, Rtmsg> = response.map_err(|err| {
            if let Nlmsgerr(ref err) = err {
                if err.error == -libc::ENETUNREACH {
                    return Error::LocalIpAddressNotFound;  // Here is error!
                }
            }
            Error::StrategyError(format!(
                "An error occurred retrieving Netlink's socket response: {err}",
            ))
        })?;
    ...    
    }

As you say: given the error message we can discard the source of the issue is the missing C header in your system.
I don't think it is root cause.
Because, i use "target/debug/your-rust-demo" instead of "sudo ip netns exec ns0 target/debug/your-rust-demo", it can get the right local ip address.

$ ../target/debug/measure-device 
This is my local IP address: 192.168.0.119

$ sudo ip netns exec ns0 ../target/debug/measure-device  
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: LocalIpAddressNotFound', measure-device/src/main.rs:29:52
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace_

from local-ip-address.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.