dope-core 0.9.1

The manifold runtime
Documentation
use std::error;
use std::fmt::{self, Display, Formatter};
use std::io::{Error, ErrorKind};

const SYN_BACKLOG_FLOOR: u32 = 4096;
const SOMAXCONN_FLOOR: u32 = 4096;

#[derive(Debug)]
pub struct Snapshot {
    pub syncookies: bool,
    pub max_syn_backlog: u32,
    pub somaxconn: u32,
    pub rlimit_nofile: u64,
}

impl Snapshot {
    pub fn check_slots(&self, requested_slots: u32) -> Result<(), Mismatch> {
        if u64::from(requested_slots) > self.rlimit_nofile {
            return Err(Mismatch::NoFileTooLow {
                requested: requested_slots,
                rlimit: self.rlimit_nofile,
            });
        }
        if !self.syncookies && self.max_syn_backlog < SYN_BACKLOG_FLOOR {
            return Err(Mismatch::SynFloodVulnerable {
                backlog: self.max_syn_backlog,
                expected: SYN_BACKLOG_FLOOR,
            });
        }
        if self.somaxconn < SOMAXCONN_FLOOR {
            return Err(Mismatch::SomaxconnTooLow {
                requested: SOMAXCONN_FLOOR,
                kernel: self.somaxconn,
            });
        }
        Ok(())
    }
}

#[derive(Debug)]
pub enum Mismatch {
    NoFileTooLow { requested: u32, rlimit: u64 },
    SomaxconnTooLow { requested: u32, kernel: u32 },
    SynFloodVulnerable { backlog: u32, expected: u32 },
}

impl Display for Mismatch {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
        match self {
            Self::NoFileTooLow { requested, rlimit } => write!(
                formatter,
                "RLIMIT_NOFILE ({rlimit}) below configured fixed_file_slots ({requested}); raise the limit or lower the slot count"
            ),
            Self::SomaxconnTooLow { requested, kernel } => write!(
                formatter,
                "somaxconn ({kernel}) below required floor ({requested}); raise it to {requested}"
            ),
            Self::SynFloodVulnerable { backlog, expected } => write!(
                formatter,
                "SYN-flood vulnerable: syncookies off and max_syn_backlog ({backlog}) below floor ({expected})"
            ),
        }
    }
}

impl error::Error for Mismatch {}

impl From<Mismatch> for Error {
    fn from(mismatch: Mismatch) -> Self {
        Error::new(ErrorKind::InvalidInput, mismatch)
    }
}