summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Midjich <swehack@gmail.com>2021-05-25 22:39:00 +0200
committerStefan Midjich <swehack@gmail.com>2021-05-25 22:39:00 +0200
commit7fe5b5278cc715cdc0a7a78dda29c9c2b6791b2c (patch)
tree81542d52e1cc39daf3b523a26868dddf3412fdbd
parent7bc4ea5d34fac53d33ff2ed53bb7a70a2c1aca93 (diff)
downloadroughenough-7fe5b5278cc715cdc0a7a78dda29c9c2b6791b2c.zip
WIP: tcp listener setup.
-rw-r--r--src/bin/roughenough-server.rs5
-rw-r--r--src/config/environment.rs14
-rw-r--r--src/config/file.rs10
-rw-r--r--src/config/memory.rs6
-rw-r--r--src/config/mod.rs3
-rw-r--r--src/server.rs23
6 files changed, 60 insertions, 1 deletions
diff --git a/src/bin/roughenough-server.rs b/src/bin/roughenough-server.rs
index bb20b21..7d7ddc1 100644
--- a/src/bin/roughenough-server.rs
+++ b/src/bin/roughenough-server.rs
@@ -65,7 +65,10 @@ fn display_config(server: &Server, cfg: &dyn ServerConfig) {
info!("Online public key : {}", server.get_online_key());
info!("Max response batch size : {}", cfg.batch_size());
info!("Status updates every : {} seconds", cfg.status_interval().as_secs());
- info!("Server listening on : {}:{}", cfg.interface(), cfg.port());
+ info!("Server listening on : udp:{}:{}", cfg.interface(), cfg.port());
+ if cfg.tcp_listener() {
+ info!("Server listening on : tcp:{}:{}", cfg.interface(), cfg.port());
+ }
if let Some(hc_port) = cfg.health_check_port() {
info!("TCP health check : {}:{}", cfg.interface(), hc_port);
} else {
diff --git a/src/config/environment.rs b/src/config/environment.rs
index 434ba04..60af07e 100644
--- a/src/config/environment.rs
+++ b/src/config/environment.rs
@@ -32,6 +32,7 @@ use crate::Error;
/// batch_size | `ROUGHENOUGH_BATCH_SIZE`
/// status_interval | `ROUGHENOUGH_STATUS_INTERVAL`
/// kms_protection | `ROUGHENOUGH_KMS_PROTECTION`
+/// tcp_listener | `ROUGHENOUGH_TCP_LISTENER`
/// health_check_port | `ROUGHENOUGH_HEALTH_CHECK_PORT`
/// client_stats | `ROUGHENOUGH_CLIENT_STATS`
/// fault_percentage | `ROUGHENOUGH_FAULT_PERCENTAGE`
@@ -43,6 +44,7 @@ pub struct EnvironmentConfig {
batch_size: u8,
status_interval: Duration,
kms_protection: KmsProtection,
+ tcp_listener: bool,
health_check_port: Option<u16>,
client_stats: bool,
fault_percentage: u8,
@@ -54,6 +56,7 @@ const ROUGHENOUGH_SEED: &str = "ROUGHENOUGH_SEED";
const ROUGHENOUGH_BATCH_SIZE: &str = "ROUGHENOUGH_BATCH_SIZE";
const ROUGHENOUGH_STATUS_INTERVAL: &str = "ROUGHENOUGH_STATUS_INTERVAL";
const ROUGHENOUGH_KMS_PROTECTION: &str = "ROUGHENOUGH_KMS_PROTECTION";
+const ROUGHENOUGH_TCP_LISTENER: &str = "ROUGHENOUGH_TCP_LISTENER";
const ROUGHENOUGH_HEALTH_CHECK_PORT: &str = "ROUGHENOUGH_HEALTH_CHECK_PORT";
const ROUGHENOUGH_CLIENT_STATS: &str = "ROUGHENOUGH_CLIENT_STATS";
const ROUGHENOUGH_FAULT_PERCENTAGE: &str = "ROUGHENOUGH_FAULT_PERCENTAGE";
@@ -67,6 +70,7 @@ impl EnvironmentConfig {
batch_size: DEFAULT_BATCH_SIZE,
status_interval: DEFAULT_STATUS_INTERVAL,
kms_protection: KmsProtection::Plaintext,
+ tcp_listener: false,
health_check_port: None,
client_stats: false,
fault_percentage: 0,
@@ -107,6 +111,12 @@ impl EnvironmentConfig {
.unwrap_or_else(|_| panic!("invalid kms_protection value: {}", kms_protection));
}
+ if let Ok(mut tcp_listener) = env::var(ROUGHENOUGH_TCP_LISTENER) {
+ tcp_listener.make_ascii_lowercase();
+
+ cfg.tcp_listener = tcp_listener == "yes" || tcp_listener == "on" || tcp_listener == "true";
+ };
+
if let Ok(health_check_port) = env::var(ROUGHENOUGH_HEALTH_CHECK_PORT) {
let val: u16 = health_check_port
.parse()
@@ -156,6 +166,10 @@ impl ServerConfig for EnvironmentConfig {
&self.kms_protection
}
+ fn tcp_listener(&self) -> bool {
+ self.tcp_listener
+ }
+
fn health_check_port(&self) -> Option<u16> {
self.health_check_port
}
diff --git a/src/config/file.rs b/src/config/file.rs
index f523fed..6a8be32 100644
--- a/src/config/file.rs
+++ b/src/config/file.rs
@@ -41,6 +41,7 @@ pub struct FileConfig {
batch_size: u8,
status_interval: Duration,
kms_protection: KmsProtection,
+ tcp_listener: bool,
health_check_port: Option<u16>,
client_stats: bool,
fault_percentage: u8,
@@ -72,6 +73,7 @@ impl FileConfig {
batch_size: DEFAULT_BATCH_SIZE,
status_interval: DEFAULT_STATUS_INTERVAL,
kms_protection: KmsProtection::Plaintext,
+ tcp_listener: false,
health_check_port: None,
client_stats: false,
fault_percentage: 0,
@@ -97,6 +99,10 @@ impl FileConfig {
});
config.kms_protection = val
}
+ "tcp_listener" => {
+ let val = value.as_str().unwrap().to_ascii_lowercase();
+ config.tcp_listener = val == "yes" || val == "on" || val == "true";
+ }
"health_check_port" => {
let val = value.as_i64().unwrap() as u16;
config.health_check_port = Some(val);
@@ -147,6 +153,10 @@ impl ServerConfig for FileConfig {
&self.kms_protection
}
+ fn tcp_listener(&self) -> bool {
+ self.tcp_listener
+ }
+
fn health_check_port(&self) -> Option<u16> {
self.health_check_port
}
diff --git a/src/config/memory.rs b/src/config/memory.rs
index 2128bb6..e5dfa78 100644
--- a/src/config/memory.rs
+++ b/src/config/memory.rs
@@ -29,6 +29,7 @@ pub struct MemoryConfig {
pub batch_size: u8,
pub status_interval: Duration,
pub kms_protection: KmsProtection,
+ pub tcp_listener: bool,
pub health_check_port: Option<u16>,
pub client_stats: bool,
pub fault_percentage: u8,
@@ -44,6 +45,7 @@ impl MemoryConfig {
batch_size: DEFAULT_BATCH_SIZE,
status_interval: DEFAULT_STATUS_INTERVAL,
kms_protection: KmsProtection::Plaintext,
+ tcp_listener: false,
health_check_port: None,
client_stats: false,
fault_percentage: 0
@@ -76,6 +78,10 @@ impl ServerConfig for MemoryConfig {
&self.kms_protection
}
+ fn tcp_listener(&self) -> bool {
+ self.tcp_listener
+ }
+
fn health_check_port(&self) -> Option<u16> {
self.health_check_port
}
diff --git a/src/config/mod.rs b/src/config/mod.rs
index c7c8ae6..185d764 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -92,6 +92,9 @@ pub trait ServerConfig {
/// Defaults to "`plaintext`" (no encryption, seed is in the clear).
fn kms_protection(&self) -> &KmsProtection;
+ /// [Optional] If present the server will also serve clients over TCP on the same port.
+ fn tcp_listener(&self) -> bool;
+
/// [Optional] If present, the TCP port to respond to Google-style HTTP "legacy health check".
/// This is a *very* simplistic check, it emits a fixed HTTP response to all TCP connections.
/// https://cloud.google.com/load-balancing/docs/health-checks#legacy-health-checks
diff --git a/src/server.rs b/src/server.rs
index 3a216d1..ff57971 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -43,6 +43,7 @@ use crate::{Error, RtMessage, Tag, MIN_REQUEST_LENGTH};
const EVT_MESSAGE: Token = Token(0);
const EVT_STATUS_UPDATE: Token = Token(1);
const EVT_HEALTH_CHECK: Token = Token(2);
+const EVT_TCP_MESSAGE: Token = Token(3);
// Canned response to health check request
const HTTP_RESPONSE: &str = "HTTP/1.1 200 OK\nContent-Length: 0\nConnection: close\n\n";
@@ -63,6 +64,7 @@ pub struct Server {
cert_bytes: Vec<u8>,
socket: UdpSocket,
+ tcp_listener: Option<TcpListener>,
health_listener: Option<TcpListener>,
poll_duration: Option<Duration>,
grease: Grease,
@@ -118,6 +120,22 @@ impl Server {
poll.register(&timer, EVT_STATUS_UPDATE, Ready::readable(), PollOpt::edge())
.unwrap();
+ let tcp_listener = if config.tcp_listener() {
+ let tcp_sock_addr: SocketAddr = format!("{}:{}", config.interface(), config.port())
+ .parse()
+ .unwrap();
+
+ let listener = TcpListener::bind(&tcp_sock_addr)
+ .expect("Failed to bind TCP listener");
+
+ poll.register(&listener, EVT_TCP_MESSAGE, Ready::readable(), PollOpt::edge())
+ .unwrap();
+
+ Some(listener)
+ } else {
+ None
+ };
+
let health_listener = if let Some(hc_port) = config.health_check_port() {
let hc_sock_addr: SocketAddr = format!("{}:{}", config.interface(), hc_port)
.parse()
@@ -150,6 +168,7 @@ impl Server {
cert_bytes,
socket,
+ tcp_listener,
health_listener,
poll_duration,
@@ -218,6 +237,10 @@ impl Server {
break;
}
},
+ EVT_TCP_MESSAGE => loop {
+ info!("EVT_TCP_MESSAGE received");
+ break;
+ },
EVT_HEALTH_CHECK => self.handle_health_check(),
EVT_STATUS_UPDATE => self.handle_status_update(),
_ => unreachable!(),