Skip to content

Commit 5d9bcbc

Browse files
authored
Add a function for SO_DOMAIN. (#779)
Add a `get_socket_domain` function for using `SO_DOMAIN` on a socket.
1 parent eb97b82 commit 5d9bcbc

File tree

5 files changed

+126
-5
lines changed

5 files changed

+126
-5
lines changed

src/backend/libc/net/syscalls.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,19 @@ pub(crate) mod sockopt {
517517
use super::{c, in6_addr_new, in_addr_new, BorrowedFd};
518518
use crate::io;
519519
use crate::net::sockopt::Timeout;
520+
#[cfg(not(any(
521+
apple,
522+
solarish,
523+
windows,
524+
target_os = "dragonfly",
525+
target_os = "emscripten",
526+
target_os = "espidf",
527+
target_os = "haiku",
528+
target_os = "netbsd",
529+
target_os = "nto",
530+
target_os = "openbsd"
531+
)))]
532+
use crate::net::AddressFamily;
520533
use crate::net::{Ipv4Addr, Ipv6Addr, SocketType};
521534
use crate::utils::as_mut_ptr;
522535
use core::time::Duration;
@@ -809,6 +822,26 @@ pub(crate) mod sockopt {
809822
getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize)
810823
}
811824

825+
#[inline]
826+
#[cfg(not(any(
827+
apple,
828+
solarish,
829+
windows,
830+
target_os = "dragonfly",
831+
target_os = "emscripten",
832+
target_os = "espidf",
833+
target_os = "haiku",
834+
target_os = "netbsd",
835+
target_os = "nto",
836+
target_os = "openbsd"
837+
)))]
838+
pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> {
839+
let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?;
840+
Ok(AddressFamily(
841+
domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?,
842+
))
843+
}
844+
812845
#[inline]
813846
pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> {
814847
setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl)

src/backend/linux_raw/c.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ pub(crate) use linux_raw_sys::{
6565
IP_MULTICAST_TTL, IP_TTL, MSG_CMSG_CLOEXEC, MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT,
6666
MSG_EOR, MSG_ERRQUEUE, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL,
6767
SCM_CREDENTIALS, SCM_RIGHTS, SHUT_RD, SHUT_RDWR, SHUT_WR, SOCK_DGRAM, SOCK_RAW, SOCK_RDM,
68-
SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_ERROR, SO_KEEPALIVE, SO_LINGER,
69-
SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO, SO_RCVTIMEO_OLD,
70-
SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO, SO_SNDTIMEO_OLD,
71-
SO_TYPE, TCP_NODELAY,
68+
SOCK_SEQPACKET, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_DOMAIN, SO_ERROR, SO_KEEPALIVE,
69+
SO_LINGER, SO_PASSCRED, SO_RCVBUF, SO_RCVTIMEO_NEW, SO_RCVTIMEO_NEW as SO_RCVTIMEO,
70+
SO_RCVTIMEO_OLD, SO_REUSEADDR, SO_SNDBUF, SO_SNDTIMEO_NEW, SO_SNDTIMEO_NEW as SO_SNDTIMEO,
71+
SO_SNDTIMEO_OLD, SO_TYPE, TCP_NODELAY,
7272
},
7373
netlink::*,
7474
};

src/backend/linux_raw/net/syscalls.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ pub(crate) mod sockopt {
920920
use super::{c, BorrowedFd};
921921
use crate::io;
922922
use crate::net::sockopt::Timeout;
923-
use crate::net::{Ipv4Addr, Ipv6Addr, SocketType};
923+
use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketType};
924924
use c::{SO_RCVTIMEO_NEW, SO_RCVTIMEO_OLD, SO_SNDTIMEO_NEW, SO_SNDTIMEO_OLD};
925925
use core::time::Duration;
926926
use linux_raw_sys::general::{__kernel_timespec, timeval};
@@ -1271,6 +1271,14 @@ pub(crate) mod sockopt {
12711271
getsockopt(fd, c::SOL_SOCKET as _, c::SO_SNDBUF).map(|size: u32| size as usize)
12721272
}
12731273

1274+
#[inline]
1275+
pub(crate) fn get_socket_domain(fd: BorrowedFd<'_>) -> io::Result<AddressFamily> {
1276+
let domain: c::c_int = getsockopt(fd, c::SOL_SOCKET as _, c::SO_DOMAIN)?;
1277+
Ok(AddressFamily(
1278+
domain.try_into().map_err(|_| io::Errno::OPNOTSUPP)?,
1279+
))
1280+
}
1281+
12741282
#[inline]
12751283
pub(crate) fn set_ip_ttl(fd: BorrowedFd<'_>, ttl: u32) -> io::Result<()> {
12761284
setsockopt(fd, c::IPPROTO_IP as _, c::IP_TTL, ttl)

src/net/sockopt.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66
#![doc(alias = "getsockopt")]
77
#![doc(alias = "setsockopt")]
88

9+
#[cfg(not(any(
10+
apple,
11+
solarish,
12+
windows,
13+
target_os = "dragonfly",
14+
target_os = "emscripten",
15+
target_os = "espidf",
16+
target_os = "haiku",
17+
target_os = "netbsd",
18+
target_os = "nto",
19+
target_os = "openbsd"
20+
)))]
21+
use crate::net::AddressFamily;
922
use crate::net::{Ipv4Addr, Ipv6Addr, SocketType};
1023
use crate::{backend, io};
1124
use backend::c;
@@ -712,6 +725,57 @@ pub fn get_socket_send_buffer_size<Fd: AsFd>(fd: Fd) -> io::Result<usize> {
712725
backend::net::syscalls::sockopt::get_socket_send_buffer_size(fd.as_fd())
713726
}
714727

728+
/// `getsockopt(fd, SOL_SOCKET, SO_DOMAIN)`
729+
///
730+
/// # References
731+
/// - [POSIX `getsockopt`]
732+
/// - [POSIX `sys/socket.h`]
733+
/// - [Linux `getsockopt`]
734+
/// - [Linux `socket`]
735+
/// - [Winsock2 `getsockopt`]
736+
/// - [Winsock2 `SOL_SOCKET` options]
737+
/// - [Apple]
738+
/// - [FreeBSD]
739+
/// - [NetBSD]
740+
/// - [OpenBSD]
741+
/// - [DragonFly BSD]
742+
/// - [illumos]
743+
/// - [glibc `getsockopt`]
744+
/// - [glibc `SOL_SOCKET` Options]
745+
///
746+
/// [POSIX `getsockopt`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html
747+
/// [POSIX `sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
748+
/// [Linux `getsockopt`]: https://man7.org/linux/man-pages/man2/getsockopt.2.html
749+
/// [Linux `socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
750+
/// [Winsock2 `getsockopt`]: https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-getsockopt
751+
/// [Winsock2 `SOL_SOCKET` options]: https://docs.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options
752+
/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getsockopt.2.html
753+
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsockopt&sektion=2
754+
/// [NetBSD]: https://man.netbsd.org/getsockopt.2
755+
/// [OpenBSD]: https://man.openbsd.org/getsockopt.2
756+
/// [DragonFly BSD]: https://man.dragonflybsd.org/?command=getsockopt&section=2
757+
/// [illumos]: https://illumos.org/man/3SOCKET/getsockopt
758+
/// [glibc `getsockopt`]: https://www.gnu.org/software/libc/manual/html_node/Socket-Option-Functions.html
759+
/// [glibc `SOL_SOCKET` options]: https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html
760+
// TODO: OpenBSD and Solarish support submitted upstream: https://github.com/rust-lang/libc/pull/3316
761+
#[cfg(not(any(
762+
apple,
763+
solarish,
764+
windows,
765+
target_os = "dragonfly",
766+
target_os = "emscripten",
767+
target_os = "espidf",
768+
target_os = "haiku",
769+
target_os = "netbsd",
770+
target_os = "nto",
771+
target_os = "openbsd"
772+
)))]
773+
#[inline]
774+
#[doc(alias = "SO_DOMAIN")]
775+
pub fn get_socket_domain<Fd: AsFd>(fd: Fd) -> io::Result<AddressFamily> {
776+
backend::net::syscalls::sockopt::get_socket_domain(fd.as_fd())
777+
}
778+
715779
/// `setsockopt(fd, IPPROTO_IP, IP_TTL, ttl)`
716780
///
717781
/// # References

tests/net/sockopt.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ fn test_sockopts_ipv4() {
4141
rustix::net::sockopt::get_socket_send_buffer_size(&s).unwrap(),
4242
0
4343
);
44+
#[cfg(not(any(
45+
apple,
46+
solarish,
47+
windows,
48+
target_os = "dragonfly",
49+
target_os = "emscripten",
50+
target_os = "espidf",
51+
target_os = "haiku",
52+
target_os = "netbsd",
53+
target_os = "nto",
54+
target_os = "openbsd"
55+
)))]
56+
assert_eq!(
57+
rustix::net::sockopt::get_socket_domain(&s).unwrap(),
58+
AddressFamily::INET
59+
);
4460

4561
// Set a timeout.
4662
rustix::net::sockopt::set_socket_timeout(

0 commit comments

Comments
 (0)