no-std-net fix
more network refactor
This commit is contained in:
parent
18a227717c
commit
909aa14fe2
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -16,3 +16,6 @@
|
|||||||
[submodule "external/netlink"]
|
[submodule "external/netlink"]
|
||||||
path = external/netlink
|
path = external/netlink
|
||||||
url = ../netlink.git
|
url = ../netlink.git
|
||||||
|
[submodule "external/no-std-net"]
|
||||||
|
path = external/no-std-net
|
||||||
|
url = git@gitlab.hackers.town:veilid/no-std-net.git
|
||||||
|
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@ -11,6 +11,13 @@
|
|||||||
"program": "${workspaceFolder}/target/debug/veilid-server",
|
"program": "${workspaceFolder}/target/debug/veilid-server",
|
||||||
"pid": "${command:pickMyProcess}"
|
"pid": "${command:pickMyProcess}"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Attach to veilid-flutter example",
|
||||||
|
"program": "${workspaceFolder}/veilid-flutter/example/build/linux/x64/debug/bundle/veilid_example",
|
||||||
|
"pid": "${command:pickMyProcess}"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "lldb",
|
"type": "lldb",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
|
742
Cargo.lock
generated
742
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
1
external/no-std-net
vendored
Submodule
1
external/no-std-net
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit c57e56ff4ee4653bf17f8bd35dc2fd0f56dc74e7
|
@ -80,7 +80,7 @@ wasm-bindgen-futures = "^0"
|
|||||||
wasm-logger = "^0"
|
wasm-logger = "^0"
|
||||||
hashbrown = "^0"
|
hashbrown = "^0"
|
||||||
lru = {version = "^0", features = ["hashbrown"] }
|
lru = {version = "^0", features = ["hashbrown"] }
|
||||||
no-std-net = "^0"
|
no-std-net = { path = "../external/no-std-net", features = ["serde"] }
|
||||||
keyvaluedb-web = { path = "../external/keyvaluedb/keyvaluedb-web" }
|
keyvaluedb-web = { path = "../external/keyvaluedb/keyvaluedb-web" }
|
||||||
data-encoding = { version = "^2", default_features = false, features = ["alloc"] }
|
data-encoding = { version = "^2", default_features = false, features = ["alloc"] }
|
||||||
serde = { version = "^1", default-features = false, features = ["derive", "alloc"] }
|
serde = { version = "^1", default-features = false, features = ["derive", "alloc"] }
|
||||||
|
@ -68,6 +68,7 @@ impl ConnectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(&self) {
|
pub async fn startup(&self) {
|
||||||
|
trace!("startup connection manager");
|
||||||
let mut inner = self.arc.inner.lock().await;
|
let mut inner = self.arc.inner.lock().await;
|
||||||
let cac = async_channel::bounded(CONNECTION_PROCESSOR_CHANNEL_SIZE); // xxx move to config
|
let cac = async_channel::bounded(CONNECTION_PROCESSOR_CHANNEL_SIZE); // xxx move to config
|
||||||
inner.connection_add_channel_tx = Some(cac.0);
|
inner.connection_add_channel_tx = Some(cac.0);
|
||||||
|
@ -389,7 +389,7 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(&self) -> Result<(), String> {
|
pub async fn startup(&self) -> Result<(), String> {
|
||||||
info!("starting network");
|
trace!("startup network");
|
||||||
|
|
||||||
// initialize interfaces
|
// initialize interfaces
|
||||||
let mut interfaces = NetworkInterfaces::new();
|
let mut interfaces = NetworkInterfaces::new();
|
||||||
@ -424,6 +424,7 @@ impl Network {
|
|||||||
if protocol_config.tcp_listen {
|
if protocol_config.tcp_listen {
|
||||||
self.start_tcp_listeners().await?;
|
self.start_tcp_listeners().await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// release caches of available listener ports
|
// release caches of available listener ports
|
||||||
// this releases the 'first bound' ports we use to guarantee
|
// this releases the 'first bound' ports we use to guarantee
|
||||||
// that we have ports available to us
|
// that we have ports available to us
|
||||||
|
@ -111,16 +111,12 @@ impl Network {
|
|||||||
];
|
];
|
||||||
Ok((port, ip_addrs))
|
Ok((port, ip_addrs))
|
||||||
} else {
|
} else {
|
||||||
|
// If no address is specified, but the port is, use ipv4 and ipv6 unspecified
|
||||||
// If the address is specified, only use the specified port and fail otherwise
|
// If the address is specified, only use the specified port and fail otherwise
|
||||||
let sockaddrs: Vec<SocketAddr> = listen_address
|
let sockaddrs = listen_address_to_socket_addrs(&listen_address)?;
|
||||||
.to_socket_addrs()
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("Unable to resolve address: {}\n{}", listen_address, e))?
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if sockaddrs.is_empty() {
|
if sockaddrs.is_empty() {
|
||||||
Err(format!("No valid listen address: {}", listen_address))
|
return Err(format!("No valid listen address: {}", listen_address));
|
||||||
} else {
|
}
|
||||||
let port = sockaddrs[0].port();
|
let port = sockaddrs[0].port();
|
||||||
if self.bind_first_udp_port(port) {
|
if self.bind_first_udp_port(port) {
|
||||||
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
||||||
@ -129,7 +125,6 @@ impl Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async fn allocate_tcp_port(
|
async fn allocate_tcp_port(
|
||||||
&self,
|
&self,
|
||||||
@ -144,16 +139,12 @@ impl Network {
|
|||||||
];
|
];
|
||||||
Ok((port, ip_addrs))
|
Ok((port, ip_addrs))
|
||||||
} else {
|
} else {
|
||||||
|
// If no address is specified, but the port is, use ipv4 and ipv6 unspecified
|
||||||
// If the address is specified, only use the specified port and fail otherwise
|
// If the address is specified, only use the specified port and fail otherwise
|
||||||
let sockaddrs: Vec<SocketAddr> = listen_address
|
let sockaddrs = listen_address_to_socket_addrs(&listen_address)?;
|
||||||
.to_socket_addrs()
|
|
||||||
.await
|
|
||||||
.map_err(|e| format!("Unable to resolve address: {}\n{}", listen_address, e))?
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if sockaddrs.is_empty() {
|
if sockaddrs.is_empty() {
|
||||||
Err(format!("No valid listen address: {}", listen_address))
|
return Err(format!("No valid listen address: {}", listen_address));
|
||||||
} else {
|
}
|
||||||
let port = sockaddrs[0].port();
|
let port = sockaddrs[0].port();
|
||||||
if self.bind_first_tcp_port(port) {
|
if self.bind_first_tcp_port(port) {
|
||||||
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
Ok((port, sockaddrs.iter().map(|s| s.ip()).collect()))
|
||||||
@ -162,11 +153,11 @@ impl Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub(super) async fn start_udp_listeners(&self) -> Result<(), String> {
|
pub(super) async fn start_udp_listeners(&self) -> Result<(), String> {
|
||||||
|
trace!("starting udp listeners");
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
let (listen_address, public_address) = {
|
let (listen_address, public_address) = {
|
||||||
let c = self.config.get();
|
let c = self.config.get();
|
||||||
@ -238,6 +229,7 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn start_ws_listeners(&self) -> Result<(), String> {
|
pub(super) async fn start_ws_listeners(&self) -> Result<(), String> {
|
||||||
|
trace!("starting ws listeners");
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
let (listen_address, url, path) = {
|
let (listen_address, url, path) = {
|
||||||
let c = self.config.get();
|
let c = self.config.get();
|
||||||
@ -332,6 +324,8 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn start_wss_listeners(&self) -> Result<(), String> {
|
pub(super) async fn start_wss_listeners(&self) -> Result<(), String> {
|
||||||
|
trace!("starting wss listeners");
|
||||||
|
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
let (listen_address, url) = {
|
let (listen_address, url) = {
|
||||||
let c = self.config.get();
|
let c = self.config.get();
|
||||||
@ -403,6 +397,8 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) async fn start_tcp_listeners(&self) -> Result<(), String> {
|
pub(super) async fn start_tcp_listeners(&self) -> Result<(), String> {
|
||||||
|
trace!("starting tcp listeners");
|
||||||
|
|
||||||
let routing_table = self.routing_table();
|
let routing_table = self.routing_table();
|
||||||
let (listen_address, public_address) = {
|
let (listen_address, public_address) = {
|
||||||
let c = self.config.get();
|
let c = self.config.get();
|
||||||
|
@ -329,13 +329,14 @@ impl NetworkInterfaces {
|
|||||||
// returns Ok(false) if refresh had no changes, Ok(true) if changes were present
|
// returns Ok(false) if refresh had no changes, Ok(true) if changes were present
|
||||||
pub async fn refresh(&mut self) -> Result<bool, String> {
|
pub async fn refresh(&mut self) -> Result<bool, String> {
|
||||||
self.valid = false;
|
self.valid = false;
|
||||||
|
eprintln!("a");
|
||||||
let last_interfaces = core::mem::take(&mut self.interfaces);
|
let last_interfaces = core::mem::take(&mut self.interfaces);
|
||||||
|
|
||||||
let mut platform_support = PlatformSupport::new().map_err(logthru_net!())?;
|
let mut platform_support = PlatformSupport::new().map_err(logthru_net!())?;
|
||||||
platform_support
|
platform_support
|
||||||
.get_interfaces(&mut self.interfaces)
|
.get_interfaces(&mut self.interfaces)
|
||||||
.await?;
|
.await?;
|
||||||
|
eprintln!("b");
|
||||||
|
|
||||||
self.valid = true;
|
self.valid = true;
|
||||||
|
|
||||||
@ -343,6 +344,8 @@ impl NetworkInterfaces {
|
|||||||
if changed {
|
if changed {
|
||||||
trace!("NetworkInterfaces refreshed: {:#?}?", self);
|
trace!("NetworkInterfaces refreshed: {:#?}?", self);
|
||||||
}
|
}
|
||||||
|
eprintln!("c");
|
||||||
|
xxx investigate why things get stuck here. threading and dart issue with logging ?
|
||||||
Ok(changed)
|
Ok(changed)
|
||||||
}
|
}
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
|
@ -54,6 +54,7 @@ impl LeaseManager {
|
|||||||
self.inner.lock().network_manager.clone()
|
self.inner.lock().network_manager.clone()
|
||||||
}
|
}
|
||||||
pub async fn startup(&self) -> Result<(), String> {
|
pub async fn startup(&self) -> Result<(), String> {
|
||||||
|
trace!("startup lease manager");
|
||||||
// Retrieve config
|
// Retrieve config
|
||||||
{
|
{
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
|
@ -197,6 +197,7 @@ impl ReceiptManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(&self) -> Result<(), String> {
|
pub async fn startup(&self) -> Result<(), String> {
|
||||||
|
trace!("startup receipt manager");
|
||||||
// Retrieve config
|
// Retrieve config
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
@ -319,9 +320,7 @@ impl ReceiptManager {
|
|||||||
callback,
|
callback,
|
||||||
)));
|
)));
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner
|
inner.receipts_by_nonce.insert(receipt.get_nonce(), record);
|
||||||
.receipts_by_nonce
|
|
||||||
.insert(receipt.get_nonce(), record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn record_single_shot_receipt(
|
pub fn record_single_shot_receipt(
|
||||||
@ -334,9 +333,7 @@ impl ReceiptManager {
|
|||||||
&receipt, expiration, eventual,
|
&receipt, expiration, eventual,
|
||||||
)));
|
)));
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
inner
|
inner.receipts_by_nonce.insert(receipt.get_nonce(), record);
|
||||||
.receipts_by_nonce
|
|
||||||
.insert(receipt.get_nonce(), record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_next_oldest_timestamp(inner: &mut ReceiptManagerInner) {
|
fn update_next_oldest_timestamp(inner: &mut ReceiptManagerInner) {
|
||||||
|
@ -1256,7 +1256,7 @@ impl RPCProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn startup(&self) -> Result<(), String> {
|
pub async fn startup(&self) -> Result<(), String> {
|
||||||
trace!("VeilidCore::startup init RPC processor");
|
trace!("startup rpc processor");
|
||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
// make local copy of node id for easy access
|
// make local copy of node id for easy access
|
||||||
let c = self.config.get();
|
let c = self.config.get();
|
||||||
|
@ -75,15 +75,13 @@ impl VeilidAPI {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
// Dump routing table bucket info
|
// Dump routing table bucket info
|
||||||
let rpc = self.rpc_processor()?;
|
let routing_table = self.network_manager()?.routing_table();
|
||||||
let routing_table = rpc.routing_table();
|
|
||||||
Ok(routing_table.debug_info_buckets(min_state))
|
Ok(routing_table.debug_info_buckets(min_state))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn debug_dialinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
|
async fn debug_dialinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
|
||||||
// Dump routing table dialinfo
|
// Dump routing table dialinfo
|
||||||
let rpc = self.rpc_processor()?;
|
let routing_table = self.network_manager()?.routing_table();
|
||||||
let routing_table = rpc.routing_table();
|
|
||||||
Ok(routing_table.debug_info_dialinfo())
|
Ok(routing_table.debug_info_dialinfo())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +105,7 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dump routing table entries
|
// Dump routing table entries
|
||||||
let rpc = self.rpc_processor()?;
|
let routing_table = self.network_manager()?.routing_table();
|
||||||
let routing_table = rpc.routing_table();
|
|
||||||
Ok(routing_table.debug_info_entries(limit, min_state))
|
Ok(routing_table.debug_info_entries(limit, min_state))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,15 +115,13 @@ impl VeilidAPI {
|
|||||||
let node_id = get_debug_argument_at(&args, 0, "debug_entry", "node_id", get_dht_key)?;
|
let node_id = get_debug_argument_at(&args, 0, "debug_entry", "node_id", get_dht_key)?;
|
||||||
|
|
||||||
// Dump routing table entry
|
// Dump routing table entry
|
||||||
let rpc = self.rpc_processor()?;
|
let routing_table = self.network_manager()?.routing_table();
|
||||||
let routing_table = rpc.routing_table();
|
|
||||||
Ok(routing_table.debug_info_entry(node_id))
|
Ok(routing_table.debug_info_entry(node_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn debug_nodeinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
|
async fn debug_nodeinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
|
||||||
// Dump routing table entry
|
// Dump routing table entry
|
||||||
let rpc = self.rpc_processor()?;
|
let routing_table = self.network_manager()?.routing_table();
|
||||||
let routing_table = rpc.routing_table();
|
|
||||||
Ok(routing_table.debug_info_nodeinfo())
|
Ok(routing_table.debug_info_nodeinfo())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,22 +136,26 @@ impl VeilidAPI {
|
|||||||
let (arg, rest) = args.split_once(' ').unwrap_or((args, ""));
|
let (arg, rest) = args.split_once(' ').unwrap_or((args, ""));
|
||||||
let rest = rest.trim_start().to_owned();
|
let rest = rest.trim_start().to_owned();
|
||||||
|
|
||||||
// Must be detached
|
|
||||||
if matches!(
|
|
||||||
self.get_state().await?.attachment,
|
|
||||||
AttachmentState::Detached | AttachmentState::Detaching
|
|
||||||
) {
|
|
||||||
return Err(VeilidAPIError::Internal {
|
|
||||||
message: "Must be detached to change config".to_owned(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// One argument is 'config get'
|
// One argument is 'config get'
|
||||||
if rest.is_empty() {
|
if rest.is_empty() {
|
||||||
return config
|
return config
|
||||||
.get_key_json(arg)
|
.get_key_json(arg)
|
||||||
.map_err(|e| VeilidAPIError::Internal { message: e });
|
.map_err(|e| VeilidAPIError::Internal { message: e });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// More than one argument is 'config set'
|
||||||
|
|
||||||
|
// Must be detached
|
||||||
|
if !matches!(
|
||||||
|
self.get_state().await?.attachment,
|
||||||
|
AttachmentState::Detached
|
||||||
|
) {
|
||||||
|
return Err(VeilidAPIError::Internal {
|
||||||
|
message: "Must be detached to change config".to_owned(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the config key
|
||||||
config
|
config
|
||||||
.set_key_json(arg, &rest)
|
.set_key_json(arg, &rest)
|
||||||
.map_err(|e| VeilidAPIError::Internal { message: e })?;
|
.map_err(|e| VeilidAPIError::Internal { message: e })?;
|
||||||
@ -225,6 +224,7 @@ impl VeilidAPI {
|
|||||||
|
|
||||||
pub async fn debug_help(&self, _args: String) -> Result<String, VeilidAPIError> {
|
pub async fn debug_help(&self, _args: String) -> Result<String, VeilidAPIError> {
|
||||||
Ok(r#">>> Debug commands:
|
Ok(r#">>> Debug commands:
|
||||||
|
help
|
||||||
buckets [dead|reliable]
|
buckets [dead|reliable]
|
||||||
dialinfo
|
dialinfo
|
||||||
entries [dead|reliable] [limit]
|
entries [dead|reliable] [limit]
|
||||||
@ -247,28 +247,28 @@ impl VeilidAPI {
|
|||||||
let (arg, rest) = args.split_once(' ').unwrap_or((args, ""));
|
let (arg, rest) = args.split_once(' ').unwrap_or((args, ""));
|
||||||
let rest = rest.trim_start().to_owned();
|
let rest = rest.trim_start().to_owned();
|
||||||
|
|
||||||
let mut out = String::new();
|
if arg == "help" {
|
||||||
if arg == "buckets" {
|
self.debug_help(rest).await
|
||||||
out += self.debug_buckets(rest).await?.as_str();
|
} else if arg == "buckets" {
|
||||||
|
self.debug_buckets(rest).await
|
||||||
} else if arg == "dialinfo" {
|
} else if arg == "dialinfo" {
|
||||||
out += self.debug_dialinfo(rest).await?.as_str();
|
self.debug_dialinfo(rest).await
|
||||||
} else if arg == "entries" {
|
} else if arg == "entries" {
|
||||||
out += self.debug_entries(rest).await?.as_str();
|
self.debug_entries(rest).await
|
||||||
} else if arg == "entry" {
|
} else if arg == "entry" {
|
||||||
out += self.debug_entry(rest).await?.as_str();
|
self.debug_entry(rest).await
|
||||||
} else if arg == "nodeinfo" {
|
} else if arg == "nodeinfo" {
|
||||||
out += self.debug_nodeinfo(rest).await?.as_str();
|
self.debug_nodeinfo(rest).await
|
||||||
} else if arg == "purge" {
|
} else if arg == "purge" {
|
||||||
out += self.debug_purge(rest).await?.as_str();
|
self.debug_purge(rest).await
|
||||||
} else if arg == "attach" {
|
} else if arg == "attach" {
|
||||||
out += self.debug_attach(rest).await?.as_str();
|
self.debug_attach(rest).await
|
||||||
} else if arg == "detach" {
|
} else if arg == "detach" {
|
||||||
out += self.debug_detach(rest).await?.as_str();
|
self.debug_detach(rest).await
|
||||||
} else if arg == "config" {
|
} else if arg == "config" {
|
||||||
out += self.debug_config(rest).await?.as_str();
|
self.debug_config(rest).await
|
||||||
} else {
|
} else {
|
||||||
out += ">>> Unknown command\n";
|
Ok(">>> Unknown command\n".to_owned())
|
||||||
}
|
}
|
||||||
Ok(out)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,23 +359,27 @@ impl VeilidConfig {
|
|||||||
|
|
||||||
pub fn get_key_json(&self, key: &str) -> Result<String, String> {
|
pub fn get_key_json(&self, key: &str) -> Result<String, String> {
|
||||||
let c = self.get();
|
let c = self.get();
|
||||||
// Split key into path parts
|
|
||||||
let keypath: Vec<&str> = key.split('.').collect();
|
|
||||||
|
|
||||||
// Generate json from whole config
|
// Generate json from whole config
|
||||||
let jc = serde_json::to_string(&*c).map_err(map_to_string)?;
|
let jc = serde_json::to_string(&*c).map_err(map_to_string)?;
|
||||||
let jvc = json::parse(&jc).map_err(map_to_string)?;
|
let jvc = json::parse(&jc).map_err(map_to_string)?;
|
||||||
|
|
||||||
// Find requested subkey
|
// Find requested subkey
|
||||||
|
if key.is_empty() {
|
||||||
|
Ok(jvc.to_string())
|
||||||
|
} else {
|
||||||
|
// Split key into path parts
|
||||||
|
let keypath: Vec<&str> = key.split('.').collect();
|
||||||
let mut out = &jvc;
|
let mut out = &jvc;
|
||||||
for k in keypath {
|
for k in keypath {
|
||||||
if !jvc.has_key(k) {
|
if !out.has_key(k) {
|
||||||
return Err(format!("invalid subkey '{}' in key '{}'", k, key));
|
return Err(format!("invalid subkey '{}' in key '{}'", k, key));
|
||||||
}
|
}
|
||||||
out = &jvc[k];
|
out = &out[k];
|
||||||
}
|
}
|
||||||
Ok(out.to_string())
|
Ok(out.to_string())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn set_key_json(&self, key: &str, value: &str) -> Result<(), String> {
|
pub fn set_key_json(&self, key: &str, value: &str) -> Result<(), String> {
|
||||||
let mut c = self.get_mut();
|
let mut c = self.get_mut();
|
||||||
|
|
||||||
@ -394,10 +398,10 @@ impl VeilidConfig {
|
|||||||
// Replace subkey
|
// Replace subkey
|
||||||
let mut out = &mut jvc;
|
let mut out = &mut jvc;
|
||||||
for k in objkeypath {
|
for k in objkeypath {
|
||||||
if !jvc.has_key(*k) {
|
if !out.has_key(*k) {
|
||||||
return Err(format!("invalid subkey '{}' in key '{}'", *k, key));
|
return Err(format!("invalid subkey '{}' in key '{}'", *k, key));
|
||||||
}
|
}
|
||||||
out = &mut jvc[*k];
|
out = &mut out[*k];
|
||||||
}
|
}
|
||||||
if !out.has_key(objkeyname) {
|
if !out.has_key(objkeyname) {
|
||||||
return Err(format!("invalid subkey '{}' in key '{}'", objkeyname, key));
|
return Err(format!("invalid subkey '{}' in key '{}'", objkeyname, key));
|
||||||
|
@ -135,3 +135,36 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn listen_address_to_socket_addrs(listen_address: &str) -> Result<Vec<SocketAddr>, String> {
|
||||||
|
// If no address is specified, but the port is, use ipv4 and ipv6 unspecified
|
||||||
|
// If the address is specified, only use the specified port and fail otherwise
|
||||||
|
let ip_addrs = vec![
|
||||||
|
IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
|
IpAddr::V6(Ipv6Addr::UNSPECIFIED),
|
||||||
|
];
|
||||||
|
|
||||||
|
Ok(if let Some(portstr) = listen_address.strip_prefix(':') {
|
||||||
|
let port = portstr.parse::<u16>().map_err(|_| {
|
||||||
|
format!(
|
||||||
|
"Invalid port format in udp listen address: {}",
|
||||||
|
listen_address
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
ip_addrs.iter().map(|a| SocketAddr::new(*a, port)).collect()
|
||||||
|
} else if let Ok(port) = listen_address.parse::<u16>() {
|
||||||
|
ip_addrs.iter().map(|a| SocketAddr::new(*a, port)).collect()
|
||||||
|
} else {
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(target_arch = "wasm32")] {
|
||||||
|
use core::str::FromStr;
|
||||||
|
vec![SocketAddr::from_str(listen_address).map_err(|_| format!("Unable to parse address: {}", listen_address))?]
|
||||||
|
} else {
|
||||||
|
listen_address
|
||||||
|
.to_socket_addrs()
|
||||||
|
.map_err(|_| format!("Unable to resolve address: {}", listen_address))?
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -12,6 +12,18 @@ import 'config.dart';
|
|||||||
// Loggy tools
|
// Loggy tools
|
||||||
const LogLevel traceLevel = LogLevel('trace', 1);
|
const LogLevel traceLevel = LogLevel('trace', 1);
|
||||||
|
|
||||||
|
class ConsolePrinter extends LoggyPrinter {
|
||||||
|
ConsolePrinter(this.childPrinter) : super();
|
||||||
|
|
||||||
|
final LoggyPrinter childPrinter;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onLog(LogRecord record) {
|
||||||
|
debugPrint(record.toString());
|
||||||
|
childPrinter.onLog(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension TraceLoggy on Loggy {
|
extension TraceLoggy on Loggy {
|
||||||
void trace(dynamic message, [Object? error, StackTrace? stackTrace]) =>
|
void trace(dynamic message, [Object? error, StackTrace? stackTrace]) =>
|
||||||
log(traceLevel, message, error, stackTrace);
|
log(traceLevel, message, error, stackTrace);
|
||||||
@ -25,13 +37,12 @@ LogOptions getLogOptions(LogLevel? level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setRootLogLevel(LogLevel? level) {
|
void setRootLogLevel(LogLevel? level) {
|
||||||
print("setRootLogLevel: $level");
|
|
||||||
Loggy('').level = getLogOptions(level);
|
Loggy('').level = getLogOptions(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initLoggy() {
|
void initLoggy() {
|
||||||
Loggy.initLoggy(
|
Loggy.initLoggy(
|
||||||
logPrinter: StreamPrinter(
|
logPrinter: ConsolePrinter(
|
||||||
const PrettyDeveloperPrinter(),
|
const PrettyDeveloperPrinter(),
|
||||||
),
|
),
|
||||||
logOptions: getLogOptions(null),
|
logOptions: getLogOptions(null),
|
||||||
|
@ -6,11 +6,12 @@ use parking_lot::*;
|
|||||||
|
|
||||||
use serde_derive::*;
|
use serde_derive::*;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::net::{SocketAddr, ToSocketAddrs};
|
use std::net::SocketAddr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
use veilid_core::xx::*;
|
||||||
|
|
||||||
pub fn load_default_config(cfg: &mut config::Config) -> Result<(), config::ConfigError> {
|
pub fn load_default_config(cfg: &mut config::Config) -> Result<(), config::ConfigError> {
|
||||||
let default_config = String::from(
|
let default_config = String::from(
|
||||||
@ -84,38 +85,38 @@ core:
|
|||||||
application:
|
application:
|
||||||
https:
|
https:
|
||||||
enabled: false
|
enabled: false
|
||||||
listen_address: '[::]:5150'
|
listen_address: ':5150'
|
||||||
path: 'app'
|
path: 'app'
|
||||||
# url: 'https://localhost:5150'
|
# url: 'https://localhost:5150'
|
||||||
http:
|
http:
|
||||||
enabled: false
|
enabled: false
|
||||||
listen_address: '[::]:5150'
|
listen_address: ':5150'
|
||||||
path: 'app'
|
path: 'app'
|
||||||
# url: 'http://localhost:5150'
|
# url: 'http://localhost:5150'
|
||||||
protocol:
|
protocol:
|
||||||
udp:
|
udp:
|
||||||
enabled: true
|
enabled: true
|
||||||
socket_pool_size: 0
|
socket_pool_size: 0
|
||||||
listen_address: '[::]:5150'
|
listen_address: ':5150'
|
||||||
# public_address: ''
|
# public_address: ''
|
||||||
tcp:
|
tcp:
|
||||||
connect: true
|
connect: true
|
||||||
listen: true
|
listen: true
|
||||||
max_connections: 32
|
max_connections: 32
|
||||||
listen_address: '[::]:5150'
|
listen_address: ':5150'
|
||||||
#'public_address: ''
|
#'public_address: ''
|
||||||
ws:
|
ws:
|
||||||
connect: true
|
connect: true
|
||||||
listen: true
|
listen: true
|
||||||
max_connections: 16
|
max_connections: 16
|
||||||
listen_address: '[::]:5150'
|
listen_address: ':5150'
|
||||||
path: 'ws'
|
path: 'ws'
|
||||||
# url: 'ws://localhost:5150/ws'
|
# url: 'ws://localhost:5150/ws'
|
||||||
wss:
|
wss:
|
||||||
connect: true
|
connect: true
|
||||||
listen: false
|
listen: false
|
||||||
max_connections: 16
|
max_connections: 16
|
||||||
listen_address: '[::]:5150'
|
listen_address: ':5150'
|
||||||
path: 'ws'
|
path: 'ws'
|
||||||
# url: ''
|
# url: ''
|
||||||
leases:
|
leases:
|
||||||
@ -323,10 +324,11 @@ pub struct NamedSocketAddrs {
|
|||||||
impl FromStr for NamedSocketAddrs {
|
impl FromStr for NamedSocketAddrs {
|
||||||
type Err = std::io::Error;
|
type Err = std::io::Error;
|
||||||
fn from_str(s: &str) -> Result<NamedSocketAddrs, std::io::Error> {
|
fn from_str(s: &str) -> Result<NamedSocketAddrs, std::io::Error> {
|
||||||
let addr_iter = s.to_socket_addrs()?;
|
let addr_iter = listen_address_to_socket_addrs(s)
|
||||||
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?;
|
||||||
Ok(NamedSocketAddrs {
|
Ok(NamedSocketAddrs {
|
||||||
name: s.to_owned(),
|
name: s.to_owned(),
|
||||||
addrs: addr_iter.collect(),
|
addrs: addr_iter,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1102,10 +1104,7 @@ mod tests {
|
|||||||
assert_eq!(s.client_api.listen_address.name, "localhost:5959");
|
assert_eq!(s.client_api.listen_address.name, "localhost:5959");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.client_api.listen_address.addrs,
|
s.client_api.listen_address.addrs,
|
||||||
"localhost:5959"
|
listen_address_to_socket_addrs("localhost:5959").unwrap()
|
||||||
.to_socket_addrs()
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<SocketAddr>>()
|
|
||||||
);
|
);
|
||||||
assert_eq!(s.auto_attach, true);
|
assert_eq!(s.auto_attach, true);
|
||||||
assert_eq!(s.logging.terminal.enabled, true);
|
assert_eq!(s.logging.terminal.enabled, true);
|
||||||
@ -1190,14 +1189,11 @@ mod tests {
|
|||||||
assert_eq!(s.core.network.application.https.enabled, false);
|
assert_eq!(s.core.network.application.https.enabled, false);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.application.https.listen_address.name,
|
s.core.network.application.https.listen_address.name,
|
||||||
"[::]:5150"
|
":5150"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.application.https.listen_address.addrs,
|
s.core.network.application.https.listen_address.addrs,
|
||||||
"[::]:5150"
|
listen_address_to_socket_addrs(":5150").unwrap()
|
||||||
.to_socket_addrs()
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<SocketAddr>>()
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.application.https.path,
|
s.core.network.application.https.path,
|
||||||
@ -1205,16 +1201,10 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(s.core.network.application.https.url, None);
|
assert_eq!(s.core.network.application.https.url, None);
|
||||||
assert_eq!(s.core.network.application.http.enabled, false);
|
assert_eq!(s.core.network.application.http.enabled, false);
|
||||||
assert_eq!(
|
assert_eq!(s.core.network.application.http.listen_address.name, ":5150");
|
||||||
s.core.network.application.http.listen_address.name,
|
|
||||||
"[::]:5150"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.application.http.listen_address.addrs,
|
s.core.network.application.http.listen_address.addrs,
|
||||||
"[::]:5150"
|
listen_address_to_socket_addrs(":5150").unwrap()
|
||||||
.to_socket_addrs()
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<SocketAddr>>()
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.application.http.path,
|
s.core.network.application.http.path,
|
||||||
@ -1227,10 +1217,7 @@ mod tests {
|
|||||||
assert_eq!(s.core.network.protocol.udp.listen_address.name, "[::]:5150");
|
assert_eq!(s.core.network.protocol.udp.listen_address.name, "[::]:5150");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.protocol.udp.listen_address.addrs,
|
s.core.network.protocol.udp.listen_address.addrs,
|
||||||
"[::]:5150"
|
listen_address_to_socket_addrs(":5150").unwrap()
|
||||||
.to_socket_addrs()
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<SocketAddr>>()
|
|
||||||
);
|
);
|
||||||
assert_eq!(s.core.network.protocol.udp.public_address, None);
|
assert_eq!(s.core.network.protocol.udp.public_address, None);
|
||||||
|
|
||||||
@ -1241,10 +1228,7 @@ mod tests {
|
|||||||
assert_eq!(s.core.network.protocol.tcp.listen_address.name, "[::]:5150");
|
assert_eq!(s.core.network.protocol.tcp.listen_address.name, "[::]:5150");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.protocol.tcp.listen_address.addrs,
|
s.core.network.protocol.tcp.listen_address.addrs,
|
||||||
"[::]:5150"
|
listen_address_to_socket_addrs(":5150").unwrap()
|
||||||
.to_socket_addrs()
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<SocketAddr>>()
|
|
||||||
);
|
);
|
||||||
assert_eq!(s.core.network.protocol.tcp.public_address, None);
|
assert_eq!(s.core.network.protocol.tcp.public_address, None);
|
||||||
|
|
||||||
@ -1255,10 +1239,7 @@ mod tests {
|
|||||||
assert_eq!(s.core.network.protocol.ws.listen_address.name, "[::]:5150");
|
assert_eq!(s.core.network.protocol.ws.listen_address.name, "[::]:5150");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.protocol.ws.listen_address.addrs,
|
s.core.network.protocol.ws.listen_address.addrs,
|
||||||
"[::]:5150"
|
listen_address_to_socket_addrs(":5150").unwrap()
|
||||||
.to_socket_addrs()
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<SocketAddr>>()
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.protocol.ws.path,
|
s.core.network.protocol.ws.path,
|
||||||
@ -1272,10 +1253,7 @@ mod tests {
|
|||||||
assert_eq!(s.core.network.protocol.wss.listen_address.name, "[::]:5150");
|
assert_eq!(s.core.network.protocol.wss.listen_address.name, "[::]:5150");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.protocol.wss.listen_address.addrs,
|
s.core.network.protocol.wss.listen_address.addrs,
|
||||||
"[::]:5150"
|
listen_address_to_socket_addrs(":5150").unwrap()
|
||||||
.to_socket_addrs()
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<SocketAddr>>()
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
s.core.network.protocol.wss.path,
|
s.core.network.protocol.wss.path,
|
||||||
|
Loading…
Reference in New Issue
Block a user