Skip to main content

dope_core/io/socket/
mod.rs

1mod addr;
2
3pub mod establishment;
4pub mod msg;
5pub mod option;
6pub mod raw;
7
8use std::{io, net};
9
10pub use addr::Addr;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13#[repr(transparent)]
14pub struct StreamSpec(Domain);
15
16impl StreamSpec {
17    pub fn for_peer(peer: &Addr) -> io::Result<Self> {
18        Ok(Self(Domain::from_raw(peer.raw().family())?))
19    }
20
21    pub(crate) const fn domain(self) -> Domain {
22        self.0
23    }
24}
25
26#[derive(Clone, Copy, Debug)]
27pub struct ListenerConfig {
28    pub reuse_addr: bool,
29    pub reuse_port: bool,
30    pub fast_open: FastOpen,
31}
32
33#[derive(Clone, Copy, Debug, PartialEq, Eq)]
34pub struct FastOpenBacklog(i32);
35
36impl FastOpenBacklog {
37    pub const fn new(backlog: i32) -> Option<Self> {
38        if backlog > 0 {
39            Some(Self(backlog))
40        } else {
41            None
42        }
43    }
44
45    pub const fn get(self) -> i32 {
46        self.0
47    }
48}
49
50/// Server-side TCP Fast Open policy.
51/// [`Required`](Self::Required) configures the listener before binding and
52/// fails creation when the platform lacks Fast Open support.
53#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
54pub enum FastOpen {
55    #[default]
56    Disabled,
57    Required {
58        backlog: FastOpenBacklog,
59    },
60}
61
62impl Default for ListenerConfig {
63    fn default() -> Self {
64        Self {
65            reuse_addr: true,
66            reuse_port: false,
67            fast_open: FastOpen::Disabled,
68        }
69    }
70}
71
72impl ListenerConfig {
73    pub fn for_datagram(addr: &net::SocketAddr) -> Self {
74        let reuse = addr.port() != 0;
75        Self {
76            reuse_addr: reuse,
77            reuse_port: reuse,
78            ..Self::default()
79        }
80    }
81
82    #[doc(hidden)]
83    pub fn for_tcp(reuse_port: bool, fast_open: FastOpen) -> Self {
84        Self {
85            reuse_addr: true,
86            reuse_port,
87            fast_open,
88        }
89    }
90
91    pub(crate) const fn fast_open_backlog(&self) -> Option<FastOpenBacklog> {
92        match self.fast_open {
93            FastOpen::Disabled => None,
94            FastOpen::Required { backlog } => Some(backlog),
95        }
96    }
97}
98
99#[derive(Clone, Copy, Debug, PartialEq, Eq)]
100pub(crate) enum Domain {
101    Inet4,
102    Inet6,
103    Unix,
104}
105
106impl Domain {
107    pub(crate) fn for_addr(addr: &net::SocketAddr) -> Self {
108        use std::net::SocketAddr;
109        match addr {
110            SocketAddr::V4(_) => Self::Inet4,
111            SocketAddr::V6(_) => Self::Inet6,
112        }
113    }
114
115    pub(crate) const fn raw(self) -> libc::c_int {
116        use libc::{AF_INET, AF_INET6};
117        match self {
118            Self::Inet4 => AF_INET,
119            Self::Inet6 => AF_INET6,
120            Self::Unix => libc::AF_UNIX,
121        }
122    }
123
124    pub(crate) fn from_raw(raw: libc::c_int) -> io::Result<Self> {
125        match raw {
126            libc::AF_INET => Ok(Self::Inet4),
127            libc::AF_INET6 => Ok(Self::Inet6),
128            libc::AF_UNIX => Ok(Self::Unix),
129            _ => Err(io::Error::new(
130                io::ErrorKind::Unsupported,
131                "unsupported socket address family",
132            )),
133        }
134    }
135}
136
137#[derive(Clone, Copy, Debug, PartialEq, Eq)]
138pub(crate) enum Kind {
139    Stream,
140    Dgram,
141}
142
143impl Kind {
144    pub(crate) const fn raw(self) -> libc::c_int {
145        use libc::{SOCK_DGRAM, SOCK_STREAM};
146        match self {
147            Self::Stream => SOCK_STREAM,
148            Self::Dgram => SOCK_DGRAM,
149        }
150    }
151}