1#![forbid(unsafe_code)]
9
10pub mod config;
11mod ipfilter;
12pub mod keyexchange;
13pub mod nts_key_provider;
14pub mod observer;
15mod peer;
16mod server;
17pub mod sockets;
18pub mod spawn;
19mod system;
20pub mod tracing;
21
22use std::{error::Error, sync::Arc};
23
24use clap::Parser;
25pub use config::dynamic::ConfigUpdate;
26pub use config::Config;
27pub use observer::{ObservablePeerState, ObservableState};
28pub use system::spawn;
29pub use ipfilter::fuzz::fuzz_ipfilter;
31use tracing_subscriber::EnvFilter;
32
33use crate::config::CmdArgs;
34
35pub async fn main() -> Result<(), Box<dyn Error>> {
36 let args = CmdArgs::parse();
37 let has_log_override = args.log_filter.is_some();
38 let has_format_override = args.log_format.is_some();
39 let log_filter = args
40 .log_filter
41 .map(|this| Arc::try_unwrap(this).unwrap())
44 .unwrap_or_else(|| EnvFilter::new("info"));
45
46 let finish_tracing_init = crate::tracing::init(log_filter, args.log_format.unwrap_or_default());
49
50 let mut config = match Config::from_args(args.config, args.peers, args.servers).await {
51 Ok(c) => c,
52 Err(e) => {
53 eprintln!("There was an error loading the config: {e}");
55 std::process::exit(exitcode::CONFIG);
56 }
57 };
58
59 let tracing_state =
62 match finish_tracing_init(&mut config, has_log_override, has_format_override) {
63 Ok(s) => s,
64 Err(e) => {
65 eprintln!("Failed to complete logging setup: {e}");
67 std::process::exit(exitcode::CONFIG);
68 }
69 };
70
71 config.check();
74
75 let keyset = crate::nts_key_provider::spawn(config.keyset).await;
77
78 ::tracing::debug!("Configuration loaded, spawning daemon jobs");
79 let (main_loop_handle, channels) = crate::spawn(
80 config.system,
81 config.clock,
82 &config.peers,
83 &config.servers,
84 keyset.clone(),
85 )
86 .await?;
87
88 if let Some(nts_ke_config) = config.nts_ke {
89 let _join_handle = crate::keyexchange::spawn(nts_ke_config, keyset);
90 }
91
92 crate::observer::spawn(
93 &config.observe,
94 channels.peer_snapshots_receiver,
95 channels.server_data_receiver,
96 channels.system_snapshot_receiver,
97 )
98 .await;
99
100 crate::config::dynamic::spawn(
101 config.configure,
102 channels.config_sender,
103 tracing_state.reload_handle,
104 )
105 .await;
106
107 Ok(main_loop_handle.await??)
108}
109
110pub(crate) mod exitcode {
111 pub const SOFTWARE: i32 = 70;
115
116 pub const NOPERM: i32 = 77;
121
122 pub const CONFIG: i32 = 78;
124}