Skip to content

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

@dvolodin7

Description

@dvolodin7

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions