Skip to content

Commit

Permalink
More config fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
iduartgomez committed Jun 3, 2024
1 parent 1f5f785 commit 6262db3
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 47 deletions.
89 changes: 55 additions & 34 deletions crates/core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ impl Default for ConfigArgs {
port: Some(default_gateway_port()),
public_address: None,
public_port: None,
is_gateway: false,
},
ws_api: WebsocketApiArgs {
address: Some(default_address()),
Expand All @@ -99,8 +100,8 @@ impl Default for ConfigArgs {
impl ConfigArgs {
fn read_config(dir: &PathBuf) -> std::io::Result<Option<Config>> {
if dir.exists() {
let mut dir = std::fs::read_dir(dir)?;
let config_args = dir.find_map(|f| {
let mut read_dir = std::fs::read_dir(dir)?;
let config_args = read_dir.find_map(|f| {
if let Ok(f) = f {
let filename = f.file_name().to_string_lossy().into_owned();
let ext = filename.rsplit('.').next().map(|s| s.to_owned());
Expand All @@ -123,32 +124,38 @@ impl ConfigArgs {
None
});
match config_args {
Some((filename, ext)) => match ext.as_str() {
"toml" => {
let mut file = File::open(&*filename)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
let mut config = toml::from_str::<Config>(&content).map_err(|e| {
std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string())
})?;
let (_, transport_keypair) =
Self::read_transport_keypair(config.secrets_dir())?;
config.transport_keypair = transport_keypair;
Ok(Some(config))
}
"json" => {
let mut file = File::open(&*filename)?;
let mut config = serde_json::from_reader::<_, Config>(&mut file)?;
let (_, transport_keypair) =
Self::read_transport_keypair(config.secrets_dir())?;
config.transport_keypair = transport_keypair;
Ok(Some(config))
Some((filename, ext)) => {
tracing::info!(
"Reading configuration file: {:?}",
dir.join(&filename).with_extension(&ext)
);
match ext.as_str() {
"toml" => {
let mut file = File::open(&*filename)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
let mut config = toml::from_str::<Config>(&content).map_err(|e| {
std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string())
})?;
let (_, transport_keypair) =
Self::read_transport_keypair(config.secrets_dir())?;
config.transport_keypair = transport_keypair;
Ok(Some(config))
}
"json" => {
let mut file = File::open(&*filename)?;
let mut config = serde_json::from_reader::<_, Config>(&mut file)?;
let (_, transport_keypair) =
Self::read_transport_keypair(config.secrets_dir())?;
config.transport_keypair = transport_keypair;
Ok(Some(config))
}
ext => Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("Invalid configuration file extension: {}", ext),
)),
}
ext => Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("Invalid configuration file extension: {}", ext),
)),
},
}
None => Ok(None),
}
} else {
Expand Down Expand Up @@ -196,7 +203,7 @@ impl ConfigArgs {
Self::read_config(path)?
} else {
// find default application dir to see if there is a config file
let dir = ConfigPathsArgs::config_dir()?;
let dir = ConfigPathsArgs::config_dir(self.id.as_deref())?;
Self::read_config(&dir).ok().flatten()
};

Expand Down Expand Up @@ -302,6 +309,7 @@ impl ConfigArgs {
log_level: self.log_level.unwrap_or(tracing::log::LevelFilter::Info),
config_paths: Arc::new(config_paths),
gateways,
is_gateway: self.network_listener.is_gateway,
};

fs::create_dir_all(&this.config_dir())?;
Expand Down Expand Up @@ -399,7 +407,6 @@ pub struct Config {
pub network_api: NetworkApiConfig,
#[serde(flatten)]
pub ws_api: WebsocketApiConfig,
// TODO:
#[serde(skip)]
pub transport_keypair: TransportKeypair,
#[serde(rename = "transport_keypair")]
Expand All @@ -412,6 +419,7 @@ pub struct Config {
pub(crate) peer_id: Option<PeerId>,
#[serde(skip)]
pub(crate) gateways: Vec<GatewayConfig>,
pub(crate) is_gateway: bool,
}

impl Config {
Expand Down Expand Up @@ -451,6 +459,11 @@ pub struct NetworkArgs {
skip_serializing_if = "Option::is_none"
)]
pub public_port: Option<u16>,

/// Whether the node is a gateway or not.
/// If the node is a gateway, it will be able to accept connections from other nodes.
#[arg(long)]
pub is_gateway: bool,
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -565,11 +578,17 @@ impl ConfigPathsArgs {
Ok(app_data_dir)
}

pub fn config_dir() -> std::io::Result<PathBuf> {
pub fn config_dir(id: Option<&str>) -> std::io::Result<PathBuf> {
let project_dir = ProjectDirs::from(QUALIFIER, ORGANIZATION, APPLICATION)
.ok_or(std::io::ErrorKind::NotFound)?;
let config_data_dir: PathBuf = if cfg!(any(test, debug_assertions)) {
std::env::temp_dir().join("freenet").join("config")
let config_data_dir: PathBuf = if cfg!(any(test, debug_assertions)) || id.is_some() {
std::env::temp_dir()
.join(if let Some(id) = id {
format!("freenet-{id}")
} else {
"freenet".into()
})
.join("config")
} else {
project_dir.config_dir().into()
};
Expand Down Expand Up @@ -629,7 +648,7 @@ impl ConfigPathsArgs {
event_log,
config_dir: match self.config_dir {
Some(dir) => dir,
None => Self::config_dir()?,
None => Self::config_dir(id)?,
},
})
}
Expand Down Expand Up @@ -797,7 +816,7 @@ struct Gateways {

#[derive(Debug, Serialize, Deserialize)]
pub struct GatewayConfig {
/// Address of the gateway. It can be either a URL or an IP address and port.
/// Address of the gateway. It can be either a hostname or an IP address and port.
pub address: Address,

/// Path to the public key of the gateway in PEM format.
Expand All @@ -807,7 +826,9 @@ pub struct GatewayConfig {

#[derive(Debug, Serialize, Deserialize)]
pub enum Address {
#[serde(rename = "hostname")]
Hostname(String),
#[serde(rename = "host_address")]
HostAddress(SocketAddr),
}

Expand Down
10 changes: 6 additions & 4 deletions crates/core/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use freenet_stdlib::{
prelude::{ContractKey, RelatedContracts, WrappedState},
};

use pkcs1::DecodeRsaPublicKey;
use rsa::pkcs8::DecodePublicKey;
use serde::{Deserialize, Serialize};
use tracing::Instrument;

Expand Down Expand Up @@ -122,18 +122,20 @@ impl NodeConfig {
let mut buf = String::new();
key_file.read_to_string(&mut buf)?;

let pub_key = rsa::RsaPublicKey::from_pkcs1_pem(&buf)?;
let pub_key = rsa::RsaPublicKey::from_public_key_pem(&buf)?;

let address = match address {
crate::config::Address::Hostname(_) => todo!("impl resolution of hostname to ip"),
crate::config::Address::Hostname(hostname) => {
todo!("impl resolution of hostname to ip: {hostname}")
}
crate::config::Address::HostAddress(addr) => *addr,
};
let peer_id = PeerId::new(address, TransportPublicKey::from(pub_key));
gateways.push(InitPeerNode::new(peer_id, Location::from_address(&address)));
}
Ok(NodeConfig {
should_connect: true,
is_gateway: false,
is_gateway: config.is_gateway,
key_pair: config.transport_keypair.clone(),
gateways,
peer_id: config.peer_id.clone(),
Expand Down
20 changes: 13 additions & 7 deletions crates/core/src/operations/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use super::{OpError, OpInitialization, OpOutcome, Operation, OperationResult};
use crate::client_events::HostResult;
use crate::dev_tool::Location;
use crate::message::{NetMessageV1, NodeEvent};
use crate::node::ConnectionError;
use crate::ring::Ring;
use crate::transport::TransportPublicKey;
use crate::{
Expand Down Expand Up @@ -707,6 +706,10 @@ where
};
let gateways = gateways.to_vec();
tokio::task::spawn(async move {
if gateways.is_empty() {
tracing::warn!("No gateways available, aborting join procedure");
return;
}
loop {
if op_manager.ring.open_connections() == 0 {
tracing::info!(
Expand Down Expand Up @@ -754,12 +757,15 @@ pub(crate) async fn join_ring_request<CM>(
where
CM: NetworkBridge + Send,
{
if !op_manager.ring.should_accept(
gateway.location.unwrap_or_else(Location::random),
Some(&gateway.peer),
) {
// ensure that we still want to connect AND reserve an spot implicitly
return Err(OpError::ConnError(ConnectionError::FailedConnectOp));
if op_manager.ring.num_connections() > 0 {
use crate::node::ConnectionError;
if !op_manager.ring.should_accept(
gateway.location.unwrap_or_else(Location::random),
Some(&gateway.peer),
) {
// ensure that we still want to connect AND reserve an spot implicitly
return Err(OpError::ConnError(ConnectionError::FailedConnectOp));
}
}
let tx_id = Transaction::new::<ConnectMsg>();
tracing::info!(%gateway.peer, %peer_pub_key, "Attempting network join");
Expand Down
5 changes: 4 additions & 1 deletion crates/core/src/ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,10 @@ impl Ring {
let mut live_tx = None;
let mut pending_conn_adds = VecDeque::new();
'outer: loop {
//
if self.get_peer_key().is_none() {
tokio::time::sleep(Duration::from_secs(1)).await;
continue;
}
loop {
match missing_candidates.try_recv() {
Ok(missing_candidate) => {
Expand Down
4 changes: 3 additions & 1 deletion crates/core/src/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ impl<'a> NetEventLog<'a> {
}

pub fn from_outbound_msg(msg: &'a NetMessage, ring: &'a Ring) -> Either<Self, Vec<Self>> {
let peer_id = ring.get_peer_key().unwrap();
let Some(peer_id) = ring.get_peer_key() else {
return Either::Right(vec![]);
};
let kind = match msg {
NetMessage::V1(NetMessageV1::Connect(connect::ConnectMsg::Response {
msg:
Expand Down

0 comments on commit 6262db3

Please sign in to comment.