pub fn check_integrity(&self) -> Result<(), Error> {
        if self.config_type.is_local() {
            if self.local.is_empty() {
                let err = Error::new(
                    ErrorKind::MissingField,
                    "missing `locals` for client configuration",
                    None,
                );
                return Err(err);
            }

            for local_config in &self.local {
                local_config.config.check_integrity()?;
            }

            // Balancer related checks
            if let Some(rtt) = self.balancer.max_server_rtt {
                if rtt.as_secs() == 0 {
                    let err = Error::new(ErrorKind::Invalid, "balancer.max_server_rtt must be > 0", None);
                    return Err(err);
                }
            }

            if let Some(intv) = self.balancer.check_interval {
                if intv.as_secs() == 0 {
                    let err = Error::new(ErrorKind::Invalid, "balancer.check_interval must be > 0", None);
                    return Err(err);
                }
            }
        }

        if self.config_type.is_server() && self.server.is_empty() {
            let err = Error::new(
                ErrorKind::MissingField,
                "missing any valid servers in configuration",
                None,
            );
            return Err(err);
        }

        #[cfg(feature = "local-online-config")]
        if self.config_type.is_online_config() && self.server.is_empty() {
            let err = Error::new(
                ErrorKind::MissingField,
                "missing any valid servers in configuration",
                None,
            );
            return Err(err);
        }

        if self.config_type.is_manager() && self.manager.is_none() {
            let err = Error::new(
                ErrorKind::MissingField,
                "missing `manager_addr` and `manager_port` in configuration",
                None,
            );
            return Err(err);
        }

        for inst in &self.server {
            let server = &inst.config;

            // Plugin shouldn't be an empty string
            if let Some(plugin) = server.plugin() {
                if plugin.plugin.trim().is_empty() {
                    let err = Error::new(ErrorKind::Malformed, "`plugin` shouldn't be an empty string", None);
                    return Err(err);
                }
            }

            // Server's domain name shouldn't be an empty string
            match server.addr() {
                ServerAddr::SocketAddr(sa) => {
                    if sa.port() == 0 {
                        let err = Error::new(ErrorKind::Malformed, "`server_port` shouldn't be 0", None);
                        return Err(err);
                    }

                    if self.config_type.is_local() {
                        // Only server could bind to INADDR_ANY
                        let ip = sa.ip();
                        if ip.is_unspecified() {
                            let err = Error::new(
                                ErrorKind::Malformed,
                                "`server` shouldn't be an unspecified address (INADDR_ANY)",
                                None,
                            );
                            return Err(err);
                        }
                    }

                    #[cfg(feature = "local-online-config")]
                    if self.config_type.is_online_config() {
                        // Only server could bind to INADDR_ANY
                        let ip = sa.ip();
                        if ip.is_unspecified() {
                            let err = Error::new(
                                ErrorKind::Malformed,
                                "`server` shouldn't be an unspecified address (INADDR_ANY)",
                                None,
                            );
                            return Err(err);
                        }
                    }
                }
                ServerAddr::DomainName(dn, port) => {
                    if dn.is_empty() || *port == 0 {
                        let err = Error::new(
                            ErrorKind::Malformed,
                            "`server` shouldn't be an empty string, `server_port` shouldn't be 0",
                            None,
                        );
                        return Err(err);
                    }
                }
            }

            // Users' key must match key length
            if let Some(user_manager) = server.user_manager() {
                #[cfg(feature = "aead-cipher-2022")]
                if server.method().is_aead_2022() {
                    use shadowsocks::config::method_support_eih;
                    if user_manager.user_count() > 0 && !method_support_eih(server.method()) {
                        let err = Error::new(
                            ErrorKind::Invalid,
                            "server method doesn't support Extended Identity Header (EIH), remove `users`",
                            Some(format!("method {}", server.method())),
                        );
                        return Err(err);
                    }
                }

                let key_len = server.method().key_len();
                for user in user_manager.users_iter() {
                    if user.key().len() != key_len {
                        let err = Error::new(
                            ErrorKind::Malformed,
                            "`users[].password` length must be exactly the same as method's key length",
                            None,
                        );
                        return Err(err);
                    }
                }
            }
        }

        Ok(())
    }
Check if all required fields are already set
crates/shadowsocks-service/src/config.rs