Skip to content

Commit

Permalink
Add support for port or complete api socketaddr (#411)
Browse files Browse the repository at this point in the history
* Add support for port or complete api socketaddr

* Add ip:port doc for api listen setting
  • Loading branch information
madninja authored Apr 7, 2023
1 parent b0218dc commit 933a1ce
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 37 deletions.
5 changes: 3 additions & 2 deletions config/settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ keypair = "/etc/helium_gateway/gateway_key.bin"
# The address to listen on for the (semtech) packet forwarder
listen = "127.0.0.1:1680"

# The local port to serve the local grpc on.
# Do NOT expose this port outside of the host network for security
# The local port to serve the local grpc on. Supports both a simple port number
# or full ip:port listen address. Do NOT expose this port outside of the host
# network for security
api = 4467

# The default region to use until a region is received from the Helium network.
Expand Down
14 changes: 8 additions & 6 deletions src/api/client.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::{connect_uri, AddGatewayReq, GatewayStakingMode, PubkeyReq, RegionReq, RouterReq};
use super::{AddGatewayReq, GatewayStakingMode, PubkeyReq, RegionReq, RouterReq};
use crate::{
error::Error, packet_router::RouterStatus, settings::StakingMode, PublicKey, Region, Result,
TxnEnvelope,
error::Error,
packet_router::RouterStatus,
settings::{ListenAddress, StakingMode},
PublicKey, Region, Result, TxnEnvelope,
};
use helium_proto::{services::local::Client, BlockchainTxnAddGatewayV1};
use std::convert::TryFrom;
Expand All @@ -12,9 +14,9 @@ pub struct LocalClient {
}

impl LocalClient {
pub async fn new(port: u16) -> Result<Self> {
let uri = connect_uri(port);
let endpoint = Endpoint::from_shared(uri).unwrap();
pub async fn new(address: &ListenAddress) -> Result<Self> {
let uri = http::Uri::try_from(address)?;
let endpoint = Endpoint::from_shared(uri.to_string()).unwrap();
let client = Client::connect(endpoint)
.await
.map_err(Error::local_client_connect)?;
Expand Down
11 changes: 0 additions & 11 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
mod client;
mod server;

const LISTEN_ADDR: &str = "127.0.0.1";

pub use client::LocalClient;
pub use helium_proto::{
services::local::{
Expand All @@ -13,15 +11,6 @@ pub use helium_proto::{
};
pub use server::LocalServer;

pub fn listen_addr(port: u16) -> String {
format!("{LISTEN_ADDR}:{port}")
}

pub fn connect_uri(port: u16) -> String {
let listen_addr = listen_addr(port);
format!("http://{listen_addr}")
}

use crate::{Error, Result};

impl TryFrom<RouterRes> for crate::packet_router::RouterStatus {
Expand Down
15 changes: 7 additions & 8 deletions src/api/server.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::{
listen_addr, AddGatewayReq, AddGatewayRes, PubkeyReq, PubkeyRes, RegionReq, RegionRes,
RouterReq, RouterRes,
AddGatewayReq, AddGatewayRes, PubkeyReq, PubkeyRes, RegionReq, RegionRes, RouterReq, RouterRes,
};
use crate::{
packet_router, region_watcher, settings::StakingMode, Error, Keypair, PublicKey, Result,
Expand All @@ -21,7 +20,7 @@ pub struct LocalServer {
packet_router: packet_router::MessageSender,
keypair: Arc<Keypair>,
onboarding_key: PublicKey,
listen_port: u16,
listen_addr: SocketAddr,
}

impl LocalServer {
Expand All @@ -33,19 +32,19 @@ impl LocalServer {
Ok(Self {
keypair: settings.keypair.clone(),
onboarding_key: settings.onboarding_key(),
listen_port: settings.api,
listen_addr: (&settings.api).try_into()?,
region_watch,
packet_router,
})
}

pub async fn run(self, shutdown: &triggered::Listener) -> Result {
let addr: SocketAddr = listen_addr(self.listen_port).parse().unwrap();
tracing::Span::current().record("listen", addr.to_string());
info!(listen = %addr, "starting");
let listen_addr = self.listen_addr;
tracing::Span::current().record("listen", &listen_addr.to_string());
info!(listen = %listen_addr, "starting");
TransportServer::builder()
.add_service(Server::new(self))
.serve_with_shutdown(addr, shutdown.clone())
.serve_with_shutdown(listen_addr, shutdown.clone())
.map_err(Error::from)
.await
}
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct Cmd {

impl Cmd {
pub async fn run(&self, settings: Settings) -> Result {
let mut client = LocalClient::new(settings.api).await?;
let mut client = LocalClient::new(&settings.api).await?;

let txn = client
.add_gateway(&self.owner, &self.payer, &self.mode)
Expand Down
12 changes: 6 additions & 6 deletions src/cmd/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,16 @@ impl fmt::Display for InfoKey {
}
}
struct InfoCache {
port: u16,
address: settings::ListenAddress,
public_keys: Option<(PublicKey, PublicKey)>,
region: Option<Option<Region>>,
router: Option<RouterStatus>,
}

impl InfoCache {
fn new(port: u16) -> Self {
fn new(address: settings::ListenAddress) -> Self {
Self {
port,
address,
public_keys: None,
region: None,
router: None,
Expand All @@ -76,7 +76,7 @@ impl InfoCache {
if let Some(public_keys) = &self.public_keys {
return Ok(public_keys.clone());
}
let mut client = LocalClient::new(self.port).await?;
let mut client = LocalClient::new(&self.address).await?;
let public_keys = client.pubkey().await?;
self.public_keys = Some(public_keys.clone());
Ok(public_keys)
Expand All @@ -96,7 +96,7 @@ impl InfoCache {
if let Some(maybe_region) = self.region {
return Ok(maybe_region);
}
let mut client = LocalClient::new(self.port).await?;
let mut client = LocalClient::new(&self.address).await?;
let region = client.region().await?;
let maybe_region = if region.is_unknown() {
None
Expand All @@ -111,7 +111,7 @@ impl InfoCache {
if let Some(router) = &self.router {
return Ok(router.clone());
}
let mut client = LocalClient::new(self.port).await?;
let mut client = LocalClient::new(&self.address).await?;
let router = client.router().await?;
self.router = Some(router.clone());
Ok(router)
Expand Down
75 changes: 72 additions & 3 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct Settings {
/// The listening network port for the grpc / jsonrpc API.
/// Default 4467
#[serde(default = "default_api")]
pub api: u16,
pub api: ListenAddress,
/// The location of the keypair binary file for the gateway. If the keyfile
/// is not found there a new one is generated and saved in that location.
pub keypair: Arc<Keypair>,
Expand Down Expand Up @@ -139,8 +139,8 @@ fn default_listen() -> String {
"127.0.0.1:1680".to_string()
}

fn default_api() -> u16 {
4467
fn default_api() -> ListenAddress {
ListenAddress::Address("127.0.0.1:4467".to_string())
}

fn default_poc_interval() -> u64 {
Expand Down Expand Up @@ -187,6 +187,75 @@ impl fmt::Display for StakingMode {
}
}

#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
#[serde(untagged)]
pub enum ListenAddress {
Port(u16),
Address(String),
}

impl TryFrom<&ListenAddress> for std::net::SocketAddr {
type Error = crate::Error;
fn try_from(value: &ListenAddress) -> std::result::Result<Self, Self::Error> {
match value {
ListenAddress::Address(str) => Ok(str.parse()?),
ListenAddress::Port(v) => Ok(format!("127.0.0.1:{v}").parse()?),
}
}
}

impl TryFrom<&ListenAddress> for http::Uri {
type Error = crate::Error;
fn try_from(value: &ListenAddress) -> std::result::Result<Self, Self::Error> {
match value {
ListenAddress::Address(str) => Ok(Uri::from_str(&format!("http://{str}"))?),
ListenAddress::Port(v) => Ok(Uri::from_str(&format!("http://127.0.0.1:{v}"))?),
}
}
}

// pub mod api {
// use serde::de;

// pub fn deserialize<'de, D>(deserializer: D) -> std::result::Result<String, D::Error>
// where
// D: de::Deserializer<'de>,
// {
// struct _Visitor;

// impl<'de> de::Visitor<'de> for _Visitor {
// type Value = String;
// fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
// formatter.write_str("api listen port or address")
// }

// fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
// where
// E: de::Error,
// {
// Ok(format!("127.0.0.1:{v}"))
// }

// fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
// where
// E: de::Error,
// {
// Ok(format!("127.0.0.1:{v}"))
// }

// fn visit_str<E>(self, value: &str) -> std::result::Result<Self::Value, E>
// where
// E: de::Error,
// {
// Ok(value.to_string())
// }
// }

// eprintln!("visiting");
// deserializer.deserialize_any(_Visitor)
// }
// }

pub mod log_level {
use serde::de::{self, Deserialize, Deserializer, Visitor};
use std::fmt;
Expand Down

0 comments on commit 933a1ce

Please sign in to comment.