diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/server.rs | 43 | ||||
-rw-r--r-- | src/config/environment.rs | 2 | ||||
-rw-r--r-- | src/config/file.rs | 2 | ||||
-rw-r--r-- | src/config/mod.rs | 71 | ||||
-rw-r--r-- | src/error.rs | 2 |
5 files changed, 58 insertions, 62 deletions
diff --git a/src/bin/server.rs b/src/bin/server.rs index 4e6ec45..13a7026 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -54,7 +54,7 @@ use mio_extras::timer::Timer; use byteorder::{LittleEndian, WriteBytesExt}; use roughenough::config; -use roughenough::config::{EnvironmentConfig, FileConfig, ServerConfig}; +use roughenough::config::ServerConfig; use roughenough::keys::{LongTermKey, OnlineKey}; use roughenough::merkle::MerkleTree; use roughenough::{Error, RtMessage, Tag}; @@ -103,12 +103,7 @@ fn nonce_from_request(buf: &[u8], num_bytes: usize) -> Result<&[u8], Error> { } } - -fn polling_loop( - config: &Box<ServerConfig>, - online_key: &mut OnlineKey, - cert_bytes: &[u8], -) { +fn polling_loop(config: &Box<ServerConfig>, online_key: &mut OnlineKey, cert_bytes: &[u8]) { let response_counter = AtomicUsize::new(0); let keep_running = Arc::new(AtomicBool::new(true)); let kr = keep_running.clone(); @@ -252,35 +247,20 @@ pub fn main() { let mut args = env::args(); if args.len() != 2 { - error!("Usage: server /path/to/config.file|ENV"); + error!("Usage: server <ENV|/path/to/config.yaml>"); process::exit(1); } - let config: Box<ServerConfig> = { - let arg1 = args.nth(1).unwrap(); - if &arg1 == "ENV" { - match EnvironmentConfig::new() { - Ok(cfg) => Box::new(cfg), - Err(e) => { - error!("{:?}", e); - process::exit(1) - } - } - } else { - match FileConfig::new(&arg1) { - Ok(cfg) => Box::new(cfg), - Err(e) => { - error!("{:?}", e); - process::exit(1) - } - } - } + let arg1 = args.nth(1).unwrap(); + let config = match config::make_config(&arg1) { + Err(e) => { + error!("{:?}", e); + process::exit(1) + }, + Ok(ref cfg) if !config::is_valid_config(&cfg) => process::exit(1), + Ok(cfg) => cfg, }; - if !config::is_valid_config(&config) { - process::exit(2); - } - let mut online_key = OnlineKey::new(); let mut long_term_key = LongTermKey::new(config.seed()); let cert_bytes = long_term_key.make_cert(&online_key).encode().unwrap(); @@ -296,4 +276,3 @@ pub fn main() { info!("Done."); process::exit(0); } - diff --git a/src/config/environment.rs b/src/config/environment.rs index 7ebe588..5053517 100644 --- a/src/config/environment.rs +++ b/src/config/environment.rs @@ -18,9 +18,9 @@ use std::env; use std::net::SocketAddr; use std::time::Duration; -use Error; use config::ServerConfig; use config::{DEFAULT_BATCH_SIZE, DEFAULT_STATUS_INTERVAL}; +use Error; /// /// Obtain a Roughenough server configuration ([ServerConfig](trait.ServerConfig.html)) diff --git a/src/config/file.rs b/src/config/file.rs index 8aa8ca2..e93ee99 100644 --- a/src/config/file.rs +++ b/src/config/file.rs @@ -20,9 +20,9 @@ use std::net::SocketAddr; use std::time::Duration; use yaml_rust::YamlLoader; -use Error; use config::ServerConfig; use config::{DEFAULT_BATCH_SIZE, DEFAULT_STATUS_INTERVAL}; +use Error; /// /// Read a Roughenough server configuration ([ServerConfig](trait.ServerConfig.html)) diff --git a/src/config/mod.rs b/src/config/mod.rs index 02ab941..983338c 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -28,9 +28,11 @@ use std::net::SocketAddr; use std::time::Duration; mod file; + pub use self::file::FileConfig; mod environment; + pub use self::environment::EnvironmentConfig; use Error; @@ -44,26 +46,21 @@ pub const DEFAULT_STATUS_INTERVAL: Duration = Duration::from_secs(600); /// /// Specifies parameters needed to configure a Roughenough server. /// -/// Parameters labeled "**Required**" must are always be provided and have no default value. -/// Parameters labeled "**Optional**" provide default values that can be overridden. -/// -/// * **`interface`** - [Required] IP address or interface name for listening to client requests -/// * **`port`** - [Required] UDP port to listen for requests -/// * **`seed`** - [Required] A 32-byte hexadecimal value used to generate the server's long-term -/// key pair. **This is a secret value and must be un-guessable**, -/// treat it with care. -/// * **`batch_size`** - [Optional] The maximum number of requests to process in one batch. All -/// nonces in a batch are used to build a Merkle tree, the root of which -/// is signed. -/// Defaults to [DEFAULT_BATCH_SIZE](constant.DEFAULT_BATCH_SIZE.html) -/// * **`status_interval`** - [Optional] Amount of time between each logged status update. -/// Defaults to [DEFAULT_STATUS_INTERVAL](constant.DEFAULT_STATUS_INTERVAL.html) +/// Parameters labeled "**Required**" must always be provided and have no default value +/// while those labeled "**Optional**" provide default values that can be overridden. /// -/// Implementations of this trait obtain a valid configuration from different back- -/// end sources. +/// YAML Key | Environment Variable | Necessity | Description +/// --- | --- | --- | --- +/// `interface` | `ROUGHENOUGH_INTERFACE` | Required | IP address or interface name for listening to client requests +/// `port` | `ROUGHENOUGH_PORT` | Required | UDP port to listen for requests +/// `seed` | `ROUGHENOUGH_SEED` | Required | A 32-byte hexadecimal value used to generate the server's long-term key pair. **This is a secret value and must be un-guessable**, treat it with care. +/// `batch_size` | `ROUGHENOUGH_BATCH_SIZE` | Optional | The maximum number of requests to process in one batch. All nonces in a batch are used to build a Merkle tree, the root of which is signed. Defaults to [DEFAULT_BATCH_SIZE](constant.DEFAULT_BATCH_SIZE.html) requests per batch. +/// `status_interval` | `ROUGHENOUGH_STATUS_INTERVAL` | Optional | Number of _seconds_ between each logged status update. Default value is [DEFAULT_STATUS_INTERVAL](constant.DEFAULT_STATUS_INTERVAL.html). /// -/// See: -/// * [FileConfig](struct.FileConfig.html) +/// Implementations of this trait obtain a valid configuration from different back-end +/// sources. See: +/// * [FileConfig](struct.FileConfig.html) - configure via a YAML file +/// * [EnvironmentConfig](struct.EnvironmentConfig.html) - configure via environment vars /// pub trait ServerConfig { /// [Required] IP address or interface name to listen for client requests @@ -90,6 +87,26 @@ pub trait ServerConfig { fn socket_addr(&self) -> Result<SocketAddr, Error>; } +/// +/// Factory function to create a `ServerConfig` trait object based on the provided `arg` +/// +pub fn make_config(arg: &str) -> Result<Box<ServerConfig>, Error> { + if arg == "ENV" { + match EnvironmentConfig::new() { + Ok(cfg) => Ok(Box::new(cfg)), + Err(e) => Err(e), + } + } else { + match FileConfig::new(arg) { + Ok(cfg) => Ok(Box::new(cfg)), + Err(e) => Err(e), + } + } +} + +/// +/// Validate configuration settings +/// pub fn is_valid_config(cfg: &Box<ServerConfig>) -> bool { let mut is_valid = true; @@ -101,13 +118,6 @@ pub fn is_valid_config(cfg: &Box<ServerConfig>) -> bool { error!("interface is missing"); is_valid = false; } - match cfg.socket_addr() { - Err(e) => { - error!("{}:{}: {:?}", cfg.interface(), cfg.port(), e); - is_valid = false; - } - _ => () - } if cfg.seed().is_empty() { error!("seed value is missing"); is_valid = false; @@ -121,6 +131,15 @@ pub fn is_valid_config(cfg: &Box<ServerConfig>) -> bool { is_valid = false; } + if is_valid { + match cfg.socket_addr() { + Err(e) => { + error!("failed to create socket {}:{} {:?}", cfg.interface(), cfg.port(), e); + is_valid = false; + } + _ => (), + } + } + is_valid } - diff --git a/src/error.rs b/src/error.rs index 49102a4..b681f33 100644 --- a/src/error.rs +++ b/src/error.rs @@ -58,5 +58,3 @@ impl From<std::io::Error> for Error { Error::EncodingFailure(err) } } - - |