Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Eval EXEC <[email protected]>
  • Loading branch information
eval-exec committed Jan 16, 2025
1 parent 250d957 commit 11d3c5e
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 4 deletions.
1 change: 1 addition & 0 deletions ckb-bin/src/subcommand/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use ckb_build_info::Version;
use ckb_launcher::Launcher;
use ckb_logger::info;
use ckb_logger::warn;
use ckb_network::multiaddr::Multiaddr;
use ckb_resource::{Resource, TemplateContext};

use ckb_stop_handler::{broadcast_exit_signals, wait_all_ckb_services_exit};
Expand Down
11 changes: 11 additions & 0 deletions network/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ impl NetworkState {
.collect()
}

/// After onion service created,
/// ckb use this method to add onion address to public_addr
pub fn add_public_addr(&self, addr: Multiaddr) {
self.public_addrs.write().insert(addr);
}

pub(crate) fn connection_status(&self) -> ConnectionStatus {
self.peer_registry.read().connection_status()
}
Expand Down Expand Up @@ -1329,6 +1335,11 @@ impl NetworkController {
self.network_state.add_node(&self.p2p_control, address)
}

/// Add a public_addr to NetworkState.public_addrs
pub fn add_public_addr(&self, public_addr: Multiaddr) {
self.network_state.add_public_addr(public_addr)
}

/// Disconnect session with peer id
pub fn remove_node(&self, peer_id: &PeerId) {
if let Some(session_id) = self
Expand Down
27 changes: 25 additions & 2 deletions util/app-config/src/configs/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,32 @@ pub struct ProxyConfig {

/// Onion related config options
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
pub struct OnionConfig {
// like: socks5://username:[email protected]:1080
pub onion_url: Option<String>,
// Automatically create Tor onion service, default: true
#[serde(default = "default_listen_on_onion")]
pub listen_on_onion: bool,
// onion service target, if CKB's p2p listen address not on default 127.0.0.1:8115, you should set this
pub onion_service_target: Option<String>,
// Tor server url: like: 127.0.0.1:9050
pub onion_server: Option<String>,
// path to store onion private key, default is ./data/network/onion/onion_private_key
pub onion_private_key_path: Option<String>,
// tor controllr url, example: 127.0.0.1:9050
#[serde(default = "default_tor_controller")]
pub tor_controller: String,
// tor controller hashed password
pub tor_password: Option<String>,
}

/// By default, allow ckb to listen on onion address
const fn default_listen_on_onion() -> bool {
true
}

/// By default, use tor controller on "127.0.0.1:9051"
fn default_tor_controller() -> String {
"127.0.0.1:9051".to_string()
}

/// Chain synchronization config options.
Expand Down
93 changes: 91 additions & 2 deletions util/launcher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! ckb launcher is helps to launch ckb node.
use ckb_app_config::{
BlockAssemblerConfig, ExitCode, RpcConfig, RpcModule, RunArgs, SupportProtocol,
BlockAssemblerConfig, ExitCode, RpcConfig, RpcModule, RunArgs, SupportProtocol, Url,
};
use ckb_async_runtime::Handle;
use ckb_block_filter::filter::BlockFilter as BlockFilterService;
Expand All @@ -12,13 +12,14 @@ use ckb_chain::ChainController;
use ckb_channel::Receiver;
use ckb_jsonrpc_types::ScriptHashType;
use ckb_light_client_protocol_server::LightClientProtocol;
use ckb_logger::info;
use ckb_logger::internal::warn;
use ckb_logger::{error, info};
use ckb_network::{
observe_listen_port_occupancy, CKBProtocol, Flags, NetworkController, NetworkService,
NetworkState, SupportProtocols,
};
use ckb_network_alert::alert_relayer::AlertRelayer;
use ckb_onion::OnionServiceConfig;
use ckb_resource::Resource;
use ckb_rpc::{RpcServer, ServiceBuilder};
use ckb_shared::shared_builder::{SharedBuilder, SharedPackage};
Expand All @@ -29,6 +30,7 @@ use ckb_tx_pool::service::TxVerificationResult;
use ckb_types::prelude::*;
use ckb_verification::GenesisVerifier;
use ckb_verification_traits::Verifier;
use std::net::{Ipv4Addr, SocketAddr};
use std::sync::Arc;

const SECP256K1_BLAKE160_SIGHASH_ALL_ARG_LEN: usize = 20;
Expand Down Expand Up @@ -266,6 +268,93 @@ impl Launcher {
}
}

/// Start onion service
pub fn start_onion_service(&self, network_controller: NetworkController) {
if !self.args.config.network.onion_config.listen_on_onion {
info!("onion_config.listen_on_onion is false, CKB won't listen on the onion hidden netork");
return;
}
let mut onion_config = self.args.config.network.onion_config;
let onion_server: String = {
match (
onion_config.onion_server,
self.args.config.network.proxy_config.proxy_url,
) {
(Some(onion_server), _) => onion_server,
(None, Some(proxy_url)) => {
let proxy_url = Url::parse(&proxy_url)?;
match (proxy_url.host_str(), proxy_url.port()) {
(Some(host), Some(port)) => format!("{}:{}", host, port),
_ => {
error!("CKB tried to use the proxy url: {proxy_url} as onion server, but failed to parse it");
return;
}
}
}
_ => info!("Neither onion_server nor proxy_url is set in the config file, CKB won't listen on the onion hidden network"),
}
};

let onion_service_target: SocketAddr = {
match onion_config.onion_service_target {
Some(onion_service_target) => onion_service_target
.parse()
.map_err(|err| eprintln!("Parse onion_service_target error: {err}"))?,
None => SocketAddr::new(std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8115),
}
};

{
// check tor_controller is listening
let tor_controller_url = Url::parse(onion_config.tor_controller)
.map_err(|err| eprintln!("Parse tor_controller url error: {err}"))?;
let tor_controller_addr = onion_config.tor_controller.parse()?;
match std::net::TcpStream::connect_timeout(
tor_controller_addr,
std::time::Duration::from_secs(2),
) {
Ok(c) => {
info!(
"CKB has confirmed that onion_conifg.tor_controller is listening on {}, trying to listen on the onion hidden network by the tor_controller",
onion_config.tor_controller
);
}
Err(err) => {
eprintln!("tor_controller is not listening on {}, CKB won't try to listen on the onion hidden network", tor_controller_addr);
return;
}
}
}

let onion_service_config: OnionServiceConfig = OnionServiceConfig {
onion_server,
onion_private_key_path: onion_config.onion_private_key_path,
tor_controller: onion_config.tor_controller,
tor_password: onion_config.tor_password,
onion_service_target,
};
match ckb_onion::onion_service::OnionService::new(
self.async_handle.clone(),
onion_service_config,
) {
Ok(onion_service) => {
self.async_handle.spawn(async move {
match onion_service.start().await {
Ok(onion_service_addr) => {
info!("CKB has started listening on the onion hidden network, the onion service address is: {}", onion_service_addr);
network_controller.add_public_addr(onion_service_addr);
},
Err(err) => error!("CKB failed to start listening on the onion hidden network: {}", err),
}
});
}
Err(err) => {
eprintln!("Create onion service error: {err}");
return;
}
}
}

/// Start network service and rpc serve
pub fn start_network_and_rpc(
&self,
Expand Down
18 changes: 18 additions & 0 deletions util/onion/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use std::net::SocketAddr;

pub mod onion_service;
mod tests;

pub struct OnionServiceConfig {
// Tor server url: like: 127.0.0.1:9050
pub onion_server: String,
// path to store onion private key, default is ./data/network/onion/onion_private_key
pub onion_private_key_path: String,
// tor controllr url, example: 127.0.0.1:9050
pub tor_controller: String,
// tor controller hashed password
pub tor_password: Option<String>,
// onion service will bind to CKB's p2p listen address, default is "127.0.0.1:8115"
// if you want to use other address, you should set it to the address you want
pub onion_service_target: SocketAddr,
}
Loading

0 comments on commit 11d3c5e

Please sign in to comment.