Skip to content

zone_id is required for link-local ipv6 addresses #15688

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
arjantop opened this issue Jul 15, 2014 · 5 comments
Closed

zone_id is required for link-local ipv6 addresses #15688

arjantop opened this issue Jul 15, 2014 · 5 comments

Comments

@arjantop
Copy link
Contributor

There is currently no way to specify a zone id (enp7s0 in this case)

Example:

use std::io::net::udp::UdpSocket;
use std::io::net::ip::{Ipv6Addr, SocketAddr};

fn main() {
    // fe80::52e5:49ff:feba:bae8%enp7s0
    let addr = SocketAddr { ip: Ipv6Addr(0xfe80, 0, 0, 0, 0x52e5, 0x49ff, 0xfeba, 0xbae8), port: 34254 };
    let mut socket = match UdpSocket::bind(addr) {
        Ok(s) => s,
        Err(e) => fail!("couldn't bind socket: {}", e),
    };
}

Error:

task '<main>' failed at 'couldn't bind socket: invalid argument (Invalid argument)', ipv6.rs:9

http://en.wikipedia.org/wiki/IPv6_address#Link-local_addresses_and_zone_indices

@alexcrichton
Copy link
Member

Could you give an example of how one might do this in C?

@alexcrichton
Copy link
Member

As in, I've never heard of this before, so I'm keen to learn what we need to do to make up for this!

@huonw huonw added A-libs and removed A-iOS labels Jul 16, 2014
@arjantop
Copy link
Contributor Author

I just learned of this also.
From the "research" I did all you have to do is set a sin6_scope_id field to a chosen interface index. I have no knowledge of windows APIs but I guess it's similar.

@jhark
Copy link

jhark commented Jul 31, 2014

From the Linux ipv6 man page:

struct sockaddr_in6 {
    sa_family_t     sin6_family;   /* AF_INET6 */
    in_port_t       sin6_port;     /* port number */
    uint32_t        sin6_flowinfo; /* IPv6 flow information */
    struct in6_addr sin6_addr;     /* IPv6 address */
    uint32_t        sin6_scope_id; /* Scope ID (new in 2.4) */
};

At the moment Rust has Ipv6Addr, which corresponds to in6_addr, and SocketAddr, which is conceptually the same thing as sockaddr_in6 but missing the scope ID (and flow info but as far as I know that isn't used for anything).

Despite the fact that the scope ID is part of the 'socket address' struct in C, it makes more sense to bundle it with the struct/class used to represent IPv6 addresses in my opinion -- link-local IPv6 addresses are totally meaningless without it and the value of the scope ID can be safely ignored for all other address classes. As a point of reference this is what Boost does.

Something like this:

struct Ipv4Addr { address }
struct Ipv6Addr { address, scopeID }
enum IpAddr { Ipv4Addr, Ipv6Addr }
struct SockAddr { IpAddr, port }

Just to clarify, the scope ID is just used to indicate which interface of the local machine a link-local address is valid for and is never transmitted on the wire.

@steveklabnik
Copy link
Member

Nowadays, we have

pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }

and

                #[derive(Copy, Clone)] pub struct sockaddr_in6 {
                    pub sin6_family: sa_family_t,
                    pub sin6_port: in_port_t,
                    pub sin6_flowinfo: u32,
                    pub sin6_addr: in6_addr,
                    pub sin6_scope_id: u32,
                }

So, this would seem to be resolved.

bors added a commit to rust-lang-ci/rust that referenced this issue Nov 13, 2023
…ge, r=Veykril

Make rustc_layout_scalar_valid_range attributes work for non-decimal literals

Closes rust-lang/rust-analyzer#15687
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants