Skip to main content

dope_core/backend/uring/ops/
bootstrap.rs

1use std::{io, net};
2
3use crate::{
4    backend::uring::{descriptor, ops::reservation},
5    driver::{self, ops},
6    io::{fd::handles, socket},
7};
8
9impl<'d> ops::Bootstrap<'d> for driver::Context<'_, 'd> {
10    fn bind_listener_slot(
11        &mut self,
12        addr: net::SocketAddr,
13        backlog: i32,
14        config: &socket::ListenerConfig,
15    ) -> io::Result<(handles::Descriptor<'d>, net::SocketAddr)> {
16        bind(self, addr, socket::Kind::Stream, config, Some(backlog))
17    }
18
19    fn bind_datagram_slot_raw(
20        &mut self,
21        addr: net::SocketAddr,
22    ) -> io::Result<(handles::Descriptor<'d>, net::SocketAddr)> {
23        use crate::io::socket::ListenerConfig;
24
25        let config = ListenerConfig::for_datagram(&addr);
26        bind(self, addr, socket::Kind::Dgram, &config, None)
27    }
28}
29
30fn bind<'d>(
31    driver: &mut driver::Context<'_, 'd>,
32    addr: net::SocketAddr,
33    kind: socket::Kind,
34    config: &socket::ListenerConfig,
35    backlog: Option<i32>,
36) -> io::Result<(handles::Descriptor<'d>, net::SocketAddr)> {
37    let domain = socket::Domain::for_addr(&addr);
38    if backlog.is_some() {
39        let handle = descriptor::Handle::blocking(domain, kind)?;
40        return bind_handle(driver, addr, config, backlog, handle);
41    }
42    let handle = descriptor::Handle::nonblocking(domain, kind)?;
43    bind_handle(driver, addr, config, backlog, handle)
44}
45
46fn bind_handle<'d>(
47    driver: &mut driver::Context<'_, 'd>,
48    addr: net::SocketAddr,
49    config: &socket::ListenerConfig,
50    backlog: Option<i32>,
51    handle: descriptor::Handle,
52) -> io::Result<(handles::Descriptor<'d>, net::SocketAddr)> {
53    handle.apply_reuse(config)?;
54    if let Some(backlog) = config.fast_open_backlog() {
55        handle.setsockopt_raw(libc::IPPROTO_TCP, libc::TCP_FASTOPEN, backlog.get())?;
56    }
57    handle.bind(&socket::Addr::from_std(addr))?;
58    if let Some(backlog) = backlog {
59        handle.listen(backlog)?;
60    }
61    let actual = handle.local_addr()?;
62    let descriptor = reservation::Vacant::install_handle(driver, handle)?;
63    Ok((descriptor, actual))
64}