mirror of
https://github.com/aljazceru/pkdns.git
synced 2025-12-17 14:04:27 +01:00
before retainer
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -120,6 +120,12 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.79"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assert_approx_eq"
|
name = "assert_approx_eq"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -1158,6 +1164,7 @@ name = "pkdns"
|
|||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"any-dns",
|
"any-dns",
|
||||||
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ edition = "2021"
|
|||||||
ctrlc = "3.4.2"
|
ctrlc = "3.4.2"
|
||||||
simple-dns = "0.6.0"
|
simple-dns = "0.6.0"
|
||||||
pknames_core = "0.1.1"
|
pknames_core = "0.1.1"
|
||||||
pkarr = "1.0.4"
|
pkarr = { version = "1.0.4", features = ["dht", "async"]}
|
||||||
zbase32 = "0.1.2"
|
zbase32 = "0.1.2"
|
||||||
ttl_cache = "0.5.1"
|
ttl_cache = "0.5.1"
|
||||||
clap = "4.4.18"
|
clap = "4.4.18"
|
||||||
@@ -17,3 +17,4 @@ any-dns = "0.2.1"
|
|||||||
chrono = "0.4.33"
|
chrono = "0.4.33"
|
||||||
tokio = { version = "1.36.0", features = ["full"] }
|
tokio = { version = "1.36.0", features = ["full"] }
|
||||||
async-trait = "0.1.77"
|
async-trait = "0.1.77"
|
||||||
|
anyhow = "1.0.79"
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -23,12 +23,10 @@ impl MyHandler {
|
|||||||
}
|
}
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CustomHandler for MyHandler {
|
impl CustomHandler for MyHandler {
|
||||||
async fn lookup(
|
async fn lookup(&mut self,query: &Vec<u8>, _socket: DnsSocket) -> Result<Vec<u8>, CustomHandlerError> {
|
||||||
&mut self,
|
let result = self.pkarr.resolve(query).await;
|
||||||
query: &Vec<u8>,
|
|
||||||
_socket: DnsSocket,
|
match result {
|
||||||
) -> std::prelude::v1::Result<Vec<u8>, CustomHandlerError> {
|
|
||||||
match self.pkarr.resolve(query) {
|
|
||||||
Ok(reply) => Ok(reply),
|
Ok(reply) => Ok(reply),
|
||||||
Err(_) => Err(CustomHandlerError::Unhandled),
|
Err(_) => Err(CustomHandlerError::Unhandled),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
use crate::{packet_lookup::resolve_query, pkarr_cache::PkarrPacketTtlCache};
|
use crate::{packet_lookup::resolve_query, pkarr_cache::PkarrPacketTtlCache};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
@@ -49,20 +49,21 @@ impl PkarrResolver {
|
|||||||
trying.ok()
|
trying.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_pubkey_respect_cache(&mut self, pubkey: &PublicKey) -> Option<Vec<u8>> {
|
async fn resolve_pubkey_respect_cache(&mut self, pubkey: &PublicKey) -> Option<Vec<u8>> {
|
||||||
let mut cache = self.cache.lock().unwrap();
|
let cache = self.cache.lock().unwrap();
|
||||||
let cached_opt = cache.get(pubkey);
|
let cached_opt = cache.get(pubkey);
|
||||||
if cached_opt.is_some() {
|
if cached_opt.is_some() {
|
||||||
let reply_bytes = cached_opt.unwrap();
|
let reply_bytes = cached_opt.unwrap();
|
||||||
return Some(reply_bytes);
|
return Some(reply_bytes);
|
||||||
};
|
};
|
||||||
|
|
||||||
let packet_option = self.client.resolve(pubkey.clone());
|
let packet_option = self.client.resolve(pubkey.clone()).await;
|
||||||
if packet_option.is_none() {
|
if packet_option.is_none() {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let signed_packet = packet_option.unwrap();
|
let signed_packet = packet_option.unwrap();
|
||||||
let reply_bytes = signed_packet.packet().build_bytes_vec_compressed().unwrap();
|
let reply_bytes = signed_packet.packet().build_bytes_vec_compressed().unwrap();
|
||||||
|
let mut cache = self.cache.lock().unwrap();
|
||||||
cache.add(pubkey.clone(), reply_bytes.clone());
|
cache.add(pubkey.clone(), reply_bytes.clone());
|
||||||
Some(reply_bytes)
|
Some(reply_bytes)
|
||||||
}
|
}
|
||||||
@@ -70,29 +71,29 @@ impl PkarrResolver {
|
|||||||
/**
|
/**
|
||||||
* Resolves a domain with pkarr.
|
* Resolves a domain with pkarr.
|
||||||
*/
|
*/
|
||||||
pub fn resolve(&mut self, query: &Vec<u8>) -> std::prelude::v1::Result<Vec<u8>, Box<dyn Error>> {
|
pub async fn resolve(&mut self, query: &Vec<u8>) -> std::prelude::v1::Result<Vec<u8>, anyhow::Error> {
|
||||||
let request = Packet::parse(query)?;
|
let request = Packet::parse(query)?;
|
||||||
|
|
||||||
let question_opt = request.questions.first();
|
let question_opt = request.questions.first();
|
||||||
if question_opt.is_none() {
|
if question_opt.is_none() {
|
||||||
return Err("Missing question".into());
|
return Err(anyhow!("Missing question"));
|
||||||
}
|
}
|
||||||
let question = question_opt.unwrap();
|
let question = question_opt.unwrap();
|
||||||
let labels = question.qname.get_labels();
|
let labels = question.qname.get_labels();
|
||||||
if labels.len() == 0 {
|
if labels.len() == 0 {
|
||||||
return Err("No label in question.qname.".into());
|
return Err(anyhow!("No label in question.qname."));
|
||||||
};
|
};
|
||||||
|
|
||||||
let raw_pubkey = labels.last().unwrap().to_string();
|
let raw_pubkey = labels.last().unwrap().to_string();
|
||||||
let parsed_option = Self::parse_pkarr_uri(&raw_pubkey);
|
let parsed_option = Self::parse_pkarr_uri(&raw_pubkey);
|
||||||
if parsed_option.is_none() {
|
if parsed_option.is_none() {
|
||||||
return Err("Invalid pkarr pubkey".into());
|
return Err(anyhow!("Invalid pkarr pubkey"));
|
||||||
}
|
}
|
||||||
let pubkey = parsed_option.unwrap();
|
let pubkey = parsed_option.unwrap();
|
||||||
|
|
||||||
let packet_option = self.resolve_pubkey_respect_cache(&pubkey);
|
let packet_option = self.resolve_pubkey_respect_cache(&pubkey).await;
|
||||||
if packet_option.is_none() {
|
if packet_option.is_none() {
|
||||||
return Err("No pkarr packet found for pubkey".into());
|
return Err(anyhow!("No pkarr packet found for pubkey"));
|
||||||
}
|
}
|
||||||
let pkarr_packet = packet_option.unwrap();
|
let pkarr_packet = packet_option.unwrap();
|
||||||
let pkarr_packet = Packet::parse(&pkarr_packet).unwrap();
|
let pkarr_packet = Packet::parse(&pkarr_packet).unwrap();
|
||||||
@@ -123,7 +124,7 @@ mod tests {
|
|||||||
keypair
|
keypair
|
||||||
}
|
}
|
||||||
|
|
||||||
fn publish_record() {
|
async fn publish_record() {
|
||||||
let keypair = get_test_keypair();
|
let keypair = get_test_keypair();
|
||||||
// let uri = keypair.to_uri_string();
|
// let uri = keypair.to_uri_string();
|
||||||
// println!("Publish packet with pubkey {}", uri);
|
// println!("Publish packet with pubkey {}", uri);
|
||||||
@@ -147,13 +148,13 @@ mod tests {
|
|||||||
let signed_packet = SignedPacket::from_packet(&keypair, &packet).unwrap();
|
let signed_packet = SignedPacket::from_packet(&keypair, &packet).unwrap();
|
||||||
|
|
||||||
let client = PkarrClient::new();
|
let client = PkarrClient::new();
|
||||||
let result = client.publish(&signed_packet);
|
let result = client.publish(&signed_packet).await;
|
||||||
result.expect("Should have published.");
|
result.expect("Should have published.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn query_domain() {
|
async fn query_domain() {
|
||||||
publish_record();
|
publish_record().await;
|
||||||
|
|
||||||
let keypair = get_test_keypair();
|
let keypair = get_test_keypair();
|
||||||
let domain = format!("pknames.p2p.{}", keypair.to_z32());
|
let domain = format!("pknames.p2p.{}", keypair.to_z32());
|
||||||
@@ -168,7 +169,7 @@ mod tests {
|
|||||||
query.questions.push(question);
|
query.questions.push(question);
|
||||||
|
|
||||||
let mut resolver = PkarrResolver::new(0);
|
let mut resolver = PkarrResolver::new(0);
|
||||||
let result = resolver.resolve(&query.build_bytes_vec_compressed().unwrap());
|
let result = resolver.resolve(&query.build_bytes_vec_compressed().unwrap()).await;
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
let reply_bytes = result.unwrap();
|
let reply_bytes = result.unwrap();
|
||||||
let reply = Packet::parse(&reply_bytes).unwrap();
|
let reply = Packet::parse(&reply_bytes).unwrap();
|
||||||
@@ -179,9 +180,9 @@ mod tests {
|
|||||||
assert_eq!(answer.rdata.type_code(), pkarr::dns::TYPE::A);
|
assert_eq!(answer.rdata.type_code(), pkarr::dns::TYPE::A);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn query_pubkey() {
|
async fn query_pubkey() {
|
||||||
publish_record();
|
publish_record().await;
|
||||||
|
|
||||||
let keypair = get_test_keypair();
|
let keypair = get_test_keypair();
|
||||||
let domain = keypair.to_z32();
|
let domain = keypair.to_z32();
|
||||||
@@ -195,7 +196,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
query.questions.push(question);
|
query.questions.push(question);
|
||||||
let mut resolver = PkarrResolver::new(0);
|
let mut resolver = PkarrResolver::new(0);
|
||||||
let result = resolver.resolve(&query.build_bytes_vec_compressed().unwrap());
|
let result = resolver.resolve(&query.build_bytes_vec_compressed().unwrap()).await;
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
let reply_bytes = result.unwrap();
|
let reply_bytes = result.unwrap();
|
||||||
let reply = Packet::parse(&reply_bytes).unwrap();
|
let reply = Packet::parse(&reply_bytes).unwrap();
|
||||||
@@ -206,8 +207,8 @@ mod tests {
|
|||||||
assert_eq!(answer.rdata.type_code(), pkarr::dns::TYPE::A);
|
assert_eq!(answer.rdata.type_code(), pkarr::dns::TYPE::A);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn query_invalid_pubkey() {
|
async fn query_invalid_pubkey() {
|
||||||
let domain = "invalid_pubkey";
|
let domain = "invalid_pubkey";
|
||||||
let name = Name::new(&domain).unwrap();
|
let name = Name::new(&domain).unwrap();
|
||||||
let mut query = Packet::new_query(0);
|
let mut query = Packet::new_query(0);
|
||||||
@@ -219,7 +220,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
query.questions.push(question);
|
query.questions.push(question);
|
||||||
let mut resolver = PkarrResolver::new(0);
|
let mut resolver = PkarrResolver::new(0);
|
||||||
let result = resolver.resolve(&query.build_bytes_vec_compressed().unwrap());
|
let result = resolver.resolve(&query.build_bytes_vec_compressed().unwrap()).await;
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
// println!("{}", result.unwrap_err());
|
// println!("{}", result.unwrap_err());
|
||||||
}
|
}
|
||||||
@@ -239,20 +240,20 @@ mod tests {
|
|||||||
assert!(trying.is_err());
|
assert!(trying.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn pkarr_invalid_packet1() {
|
async fn pkarr_invalid_packet1() {
|
||||||
let pubkey = PkarrResolver::parse_pkarr_uri("7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy").unwrap();
|
let pubkey = PkarrResolver::parse_pkarr_uri("7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy").unwrap();
|
||||||
|
|
||||||
let mut resolver = PkarrResolver::new(0);
|
let mut resolver = PkarrResolver::new(0);
|
||||||
let _result = resolver.resolve_pubkey_respect_cache(&pubkey);
|
let _result = resolver.resolve_pubkey_respect_cache(&pubkey).await;
|
||||||
// assert!(result.is_some());
|
// assert!(result.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn pkarr_invalid_packet2() {
|
async fn pkarr_invalid_packet2() {
|
||||||
let pubkey = PkarrResolver::parse_pkarr_uri("7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy").unwrap();
|
let pubkey = PkarrResolver::parse_pkarr_uri("7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy").unwrap();
|
||||||
let client = PkarrClient::new();
|
let client = PkarrClient::new();
|
||||||
let signed_packet = client.resolve(pubkey).unwrap();
|
let signed_packet = client.resolve(pubkey).await.unwrap();
|
||||||
println!("Timestamp {}", signed_packet.chrono_timestamp());
|
println!("Timestamp {}", signed_packet.chrono_timestamp());
|
||||||
let reply_bytes = signed_packet.packet().build_bytes_vec_compressed().unwrap();
|
let reply_bytes = signed_packet.packet().build_bytes_vec_compressed().unwrap();
|
||||||
Packet::parse(&reply_bytes).unwrap();
|
Packet::parse(&reply_bytes).unwrap();
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
use crate::pkarr_resolver::PkarrResolver;
|
use crate::pkarr_resolver::PkarrResolver;
|
||||||
use pkarr::dns::{Name, Packet};
|
use pkarr::dns::{Name, Packet};
|
||||||
use pknames_core::resolve::resolve_standalone;
|
use pknames_core::resolve::resolve_standalone;
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PknamesResolver {
|
pub struct PknamesResolver {
|
||||||
@@ -20,10 +24,10 @@ impl PknamesResolver {
|
|||||||
* Resolve a regular pknames domain into a pkarr domain.
|
* Resolve a regular pknames domain into a pkarr domain.
|
||||||
* Example: `pknames.p2p` -> `pknames.p2p.7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy`.
|
* Example: `pknames.p2p` -> `pknames.p2p.7fmjpcuuzf54hw18bsgi3zihzyh4awseeuq5tmojefaezjbd64cy`.
|
||||||
*/
|
*/
|
||||||
fn predict_pknames_domain(&self, domain: &str) -> Result<String, Box<dyn std::error::Error>> {
|
fn predict_pknames_domain(&self, domain: &str) -> Result<String, anyhow::Error> {
|
||||||
let result = resolve_standalone(&domain, &self.config_dir_path);
|
let result = resolve_standalone(&domain, &self.config_dir_path);
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
return Err("Neither pkarr nor pknames domain.".into());
|
return Err(anyhow!("Neither pkarr nor pknames domain."));
|
||||||
};
|
};
|
||||||
|
|
||||||
let predictions = result.unwrap();
|
let predictions = result.unwrap();
|
||||||
@@ -36,10 +40,10 @@ impl PknamesResolver {
|
|||||||
Ok(full_domain)
|
Ok(full_domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve(&mut self, query: &Vec<u8>) -> std::prelude::v1::Result<Vec<u8>, Box<dyn std::error::Error>> {
|
pub async fn resolve(&mut self, query: &Vec<u8>) -> std::prelude::v1::Result<Vec<u8>, anyhow::Error> {
|
||||||
let original_query = Packet::parse(query)?;
|
let original_query = Packet::parse(query)?;
|
||||||
|
|
||||||
let pkarr_result = self.pkarr.resolve(&query.clone());
|
let pkarr_result = self.pkarr.resolve(&query.clone()).await;
|
||||||
if pkarr_result.is_ok() {
|
if pkarr_result.is_ok() {
|
||||||
return pkarr_result; // It was a pkarr hostname
|
return pkarr_result; // It was a pkarr hostname
|
||||||
}
|
}
|
||||||
@@ -47,7 +51,7 @@ impl PknamesResolver {
|
|||||||
let question = original_query
|
let question = original_query
|
||||||
.questions
|
.questions
|
||||||
.first()
|
.first()
|
||||||
.ok_or("Query does not include a question.")?;
|
.ok_or(anyhow!("Query does not include a question."))?;
|
||||||
let domain = question.qname.to_string();
|
let domain = question.qname.to_string();
|
||||||
let pkarr_domain = self.predict_pknames_domain(&domain)?;
|
let pkarr_domain = self.predict_pknames_domain(&domain)?;
|
||||||
|
|
||||||
@@ -55,7 +59,7 @@ impl PknamesResolver {
|
|||||||
let mut pkarr_query = original_query.clone();
|
let mut pkarr_query = original_query.clone();
|
||||||
pkarr_query.questions[0].qname = qname;
|
pkarr_query.questions[0].qname = qname;
|
||||||
let pkarr_query = pkarr_query.build_bytes_vec_compressed().unwrap();
|
let pkarr_query = pkarr_query.build_bytes_vec_compressed().unwrap();
|
||||||
let pkarr_reply = self.pkarr.resolve(&pkarr_query)?;
|
let pkarr_reply = self.pkarr.resolve(&pkarr_query).await?;
|
||||||
let pkarr_reply = Packet::parse(&pkarr_reply).unwrap();
|
let pkarr_reply = Packet::parse(&pkarr_reply).unwrap();
|
||||||
|
|
||||||
let mut reply = original_query.clone().into_reply();
|
let mut reply = original_query.clone().into_reply();
|
||||||
@@ -74,8 +78,8 @@ mod tests {
|
|||||||
|
|
||||||
use super::PknamesResolver;
|
use super::PknamesResolver;
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn query_pubkey() {
|
async fn query_pubkey() {
|
||||||
let mut pknames = PknamesResolver::new(1, "~/.pknames");
|
let mut pknames = PknamesResolver::new(1, "~/.pknames");
|
||||||
|
|
||||||
let mut query = Packet::new_query(0);
|
let mut query = Packet::new_query(0);
|
||||||
@@ -89,7 +93,7 @@ mod tests {
|
|||||||
query.questions.push(question);
|
query.questions.push(question);
|
||||||
let query_bytes = query.build_bytes_vec_compressed().unwrap();
|
let query_bytes = query.build_bytes_vec_compressed().unwrap();
|
||||||
|
|
||||||
let result = pknames.resolve(&query_bytes);
|
let result = pknames.resolve(&query_bytes).await;
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
eprintln!("{:?}", result.unwrap_err());
|
eprintln!("{:?}", result.unwrap_err());
|
||||||
assert!(false);
|
assert!(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user