Skip to content
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

Socket::ttl and Socket::set_ttl don't work with IPv6 sockets. #418

Open
dvolodin7 opened this issue Mar 24, 2023 · 3 comments
Open

Socket::ttl and Socket::set_ttl don't work with IPv6 sockets. #418

dvolodin7 opened this issue Mar 24, 2023 · 3 comments

Comments

@dvolodin7
Copy link

ttl and set_ttl methods return an error on IPv6 sockets.

Current implementations are limited to IPv4 only:

pub fn ttl(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL).map(|ttl| ttl as u32)
        }
    }
}

and

 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
     unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL, ttl as c_int) }
}

For IPv6 address family the proper implementations should be like

pub fn ttl(&self) -> io::Result<u32> {
        unsafe {
            getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IP_TTL).map(|ttl| ttl as u32)
        }
    }
}

and

 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
     unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IPV6, sys::IP_TTL, ttl as c_int) }
}

Unfortunately, I haven't found a reliable way to get the address family/domain of the socket instance, something like

pub fn domain(&self) -> io::Result<Domain>

So the possible solutions are:

  1. To implement Socket::domain method, which is very system-dependent and may include:
  • Socket::local_addr check, which may fail for unbound sockets on some systems
  • Using getsockopt with SO_DOMAIN option, which is not available on some systems.
  1. Add methods like Socket::ttl_v6 and Socket::set_ttl_v6 - and leave the problem of detecting the proper address family to a library user.
@Thomasdezeeuw
Copy link
Collaborator

Basically the same issue as #413, we need IPv4 and IPv6 versions.

We should just give everything in the IPPROTO_IP group (

socket2/src/socket.rs

Lines 1077 to 1082 in 4c55898

/// Socket options for IPv4 sockets, get/set using `IPPROTO_IP`.
///
/// Additional documentation can be found in documentation of the OS.
/// * Linux: <https://man7.org/linux/man-pages/man7/ip.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
impl Socket {
) a _ipv4 suffix. Same for IPPROTO_IPV6 (

socket2/src/socket.rs

Lines 1529 to 1534 in 4c55898

/// Socket options for IPv6 sockets, get/set using `IPPROTO_IPV6`.
///
/// Additional documentation can be found in documentation of the OS.
/// * Linux: <https://man7.org/linux/man-pages/man7/ipv6.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options>
impl Socket {
).

@dvolodin7
Copy link
Author

Looks like a proper solution.

@famfo
Copy link

famfo commented Aug 1, 2023

The IPv6 equivalent of IP_TTL is IPV6_UNICAST_HOPS (by RFC 3493). The option is implemented in socket2.
Finding that option took me very long, so I think some more documentation would be required.

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

3 participants