Skip to content

Commit

Permalink
Merge branch 'rfc-1123' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
FranciscaOrtegaG committed Jan 10, 2024
2 parents ccede5a + e220735 commit 2d07ae3
Show file tree
Hide file tree
Showing 14 changed files with 2,744 additions and 973 deletions.
435 changes: 419 additions & 16 deletions src/async_resolver.rs

Large diffs are not rendered by default.

127 changes: 101 additions & 26 deletions src/async_resolver/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ use crate::client::client_connection::ClientConnection;
use crate::message::class_qclass::Qclass;
use crate::message::type_qtype::Qtype;
use futures_util::{FutureExt,task::Waker};
use std::net::IpAddr;
use std::thread;
use std::time::Duration;
use std::pin::Pin;
use std::task::{Poll,Context};
use rand::{thread_rng, Rng};
Expand Down Expand Up @@ -62,7 +65,8 @@ impl Future for LookupFutureStub {
self.config.get_name_servers(),
self.waker.clone(),
referenced_query,
self.config.clone()));
self.config.clone())
);

return Poll::Pending;
},
Expand Down Expand Up @@ -192,28 +196,29 @@ pub async fn lookup_stub( //FIXME: podemos ponerle de nombre lookup_strategy y q
new_header.set_rcode(2);
new_header.set_qr(true);
response.set_header(new_header);
//FIXME:
let mut result_dns_msg = Ok(response.clone());

let mut retry_count = 0;

for (conn_udp,conn_tcp) in name_servers.iter() {
for connections in name_servers.iter() {

if retry_count > config.get_retry() {
break;
}
match config.get_protocol() {
ConnectionProtocol::UDP => {
let result_response = conn_udp.send(new_query.clone());
result_dns_msg = parse_response(result_response);
}
ConnectionProtocol::TCP => {
let result_response = conn_tcp.send(new_query.clone());
result_dns_msg = parse_response(result_response);
}
_ => continue,
}
retry_count = retry_count + 1;

result_dns_msg = send_query_resolver_by_protocol(config.get_protocol(),new_query.clone(), result_dns_msg.clone(), connections);
if result_dns_msg.is_err(){
retry_count = retry_count + 1;
}
else{
break;
}

//FIXME: try make async
let delay_duration = Duration::from_secs(6);
thread::sleep(delay_duration);

}

// Wake up task
Expand All @@ -238,6 +243,34 @@ pub async fn lookup_stub( //FIXME: podemos ponerle de nombre lookup_strategy y q
result_dns_msg
}

/// Sends a DNS query to a resolver using the specified connection protocol.
///
/// This function takes a DNS query, a result containing a DNS message,
/// and connection information. Depending on the specified protocol (UDP or TCP),
/// it sends the query using the corresponding connection and updates the result
/// with the parsed response.
fn send_query_resolver_by_protocol(protocol: ConnectionProtocol,query:DnsMessage,mut result_dns_msg: Result<DnsMessage, ResolverError>, connections: &(ClientUDPConnection , ClientTCPConnection))
-> Result<DnsMessage, ResolverError>{
let query_id = query.get_query_id();
match protocol{
ConnectionProtocol::UDP => {
let result_response = connections.0.send(query.clone());
result_dns_msg = parse_response(result_response,query_id);
}
ConnectionProtocol::TCP => {
let result_response = connections.1.send(query.clone());
result_dns_msg = parse_response(result_response,query_id);
}
_ => {},
}

result_dns_msg
}




/// Parse the received response datagram to a `DnsMessage`.
///
/// [RFC 1035]: https://datatracker.ietf.org/doc/html/rfc1035#section-7.3
Expand All @@ -257,9 +290,9 @@ pub async fn lookup_stub( //FIXME: podemos ponerle de nombre lookup_strategy y q
/// excessively long TTL, say greater than 1 week, either discard
/// the whole response, or limit all TTLs in the response to 1
/// week.
fn parse_response(response_result: Result<Vec<u8>, ClientError>) -> Result<DnsMessage, ResolverError> {
fn parse_response(response_result: Result<(Vec<u8>, IpAddr), ClientError>, query_id:u16) -> Result<DnsMessage, ResolverError> {
let dns_msg = response_result.map_err(Into::into)
.and_then(|response_message| {
.and_then(|(response_message , _ip)| {
DnsMessage::from_bytes(&response_message)
.map_err(|_| ResolverError::Parse("The name server was unable to interpret the query.".to_string()))
})?;
Expand All @@ -269,6 +302,13 @@ fn parse_response(response_result: Result<Vec<u8>, ClientError>) -> Result<DnsMe
header.format_check()
.map_err(|e| ResolverError::Parse(format!("Error formated Header: {}", e)))?;

// Check ID
if dns_msg.get_query_id() != query_id {
println!("[ID RESPONSE] {:?}",dns_msg.get_query_id());
println!("[ID QUERY] {:?}",query_id);
return Err(ResolverError::Parse("Error expected ID from query".to_string()))
}

if header.get_qr() {
return Ok(dns_msg);
}
Expand Down Expand Up @@ -363,6 +403,28 @@ mod async_resolver_test {

}

#[tokio::test]
async fn lookup_stub_ch_response() {
let domain_name = DomainName::new_from_string("example.com".to_string());
let waker = None;
let query = Arc::new(Mutex::new(future::err(ResolverError::EmptyQuery).boxed()));

let google_server:IpAddr = IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8));
let timeout: Duration = Duration::from_secs(20);

let conn_udp:ClientUDPConnection = ClientUDPConnection::new(google_server, timeout);
let conn_tcp:ClientTCPConnection = ClientTCPConnection::new(google_server, timeout);

let config = ResolverConfig::default();
let record_type = Qtype::A;
let record_class = Qclass::CH;
let name_servers = vec![(conn_udp,conn_tcp)];
let response = lookup_stub(domain_name,record_type,record_class, name_servers, waker,query,config).await.unwrap();


assert_eq!(response.get_header().get_qr(),true);
assert_eq!(response.get_answer().len(),0);
}
#[tokio::test] //se cae, y debería caerse, pero se cae con todos los max retiries y no solo con 0 //FIXME:
async fn lookup_stub_max_tries_0() {

Expand Down Expand Up @@ -536,15 +598,19 @@ mod async_resolver_test {
}

#[test]
#[ignore] //FIXME:
fn parse_response_ok() {
let bytes: [u8; 50] = [
//test passes with this one
0b00100100, 0b10010101, 0b10010010, 0b00000000, 0, 1, 0b00000000, 1, 0, 0, 0, 0, 4, 116,
101, 115, 116, 3, 99, 111, 109, 0, 0, 16, 0, 1, 3, 100, 99, 99, 2, 99, 108, 0, 0, 16, 0,
1, 0, 0, 0b00010110, 0b00001010, 0, 6, 5, 104, 101, 108, 108, 111,
];
let response_result: Result<Vec<u8>, ClientError> = Ok(bytes.to_vec());
let response_dns_msg = parse_response(response_result);
let query_id = 0b00100100;
let ip = IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8));
let response_result: Result<(Vec<u8>, IpAddr), ClientError> = Ok((bytes.to_vec(), ip));
let response_dns_msg = parse_response(response_result,query_id);
println!("[###############] {:?}",response_dns_msg);
assert!(response_dns_msg.is_ok());
if let Ok(dns_msg) = response_dns_msg {
assert_eq!(dns_msg.get_header().get_qr(), true); // response (1)
Expand All @@ -555,23 +621,26 @@ mod async_resolver_test {
}

#[test]
#[ignore]
fn parse_response_query() {
let bytes: [u8; 50] = [
//test passes with this one
0b10100101, 0b10010101, 0b00010010, 0b00000000, 0, 1, 0b00000000, 1, 0, 0, 0, 0, 4, 116,
101, 115, 116, 3, 99, 111, 109, 0, 0, 16, 0, 1, 3, 100, 99, 99, 2, 99, 108, 0, 0, 16, 0,
1, 0, 0, 0b00010110, 0b00001010, 0, 6, 5, 104, 101, 108, 108, 111,
];
let response_result: Result<Vec<u8>, ClientError> = Ok(bytes.to_vec());
let response_dns_msg = parse_response(response_result);
let query_id = 0b10100101;
let ip = IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8));
let response_result: Result<(Vec<u8>, IpAddr), ClientError> = Ok((bytes.to_vec(), ip));
let response_dns_msg = parse_response(response_result,query_id);
let err_msg = "Message is a query. A response was expected.".to_string();
if let Err(ResolverError::Parse(err)) = response_dns_msg {
assert_eq!(err, err_msg)
} else {
assert!(false);
}
}

#[test]
fn parse_error() {
let bytes: [u8; 50] = [
Expand All @@ -580,8 +649,10 @@ mod async_resolver_test {
101, 115, 116, 3, 99, 111, 109, 0, 0, 16, 0, 1, 3, 100, 99, 99, 2, 99, 45, 0, 0, 16, 0,
1, 0, 0, 0b00010110, 0b00001010, 0, 6, 5, 104, 101, 108, 108, 111,
];
let response_result: Result<Vec<u8>, ClientError> = Ok(bytes.to_vec());
let response_dns_msg = parse_response(response_result);
let query_id = 0b10100101;
let ip= IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8));
let response_result: Result<(Vec<u8>, IpAddr), ClientError> = Ok((bytes.to_vec(), ip));
let response_dns_msg = parse_response(response_result,query_id);
let err_msg = "The name server was unable to interpret the query.".to_string();
if let Err(ResolverError::Parse(err)) = response_dns_msg {
assert_eq!(err, err_msg)
Expand All @@ -598,8 +669,10 @@ mod async_resolver_test {
101, 115, 64, 3, 99, 111, 109, 0, 0, 16, 0, 1, 3, 100, 99, 99, 2, 99, 108, 0, 0, 16, 0,
1, 0, 0, 0b00010110, 0b00001010, 0, 6, 5, 104, 101, 108, 108, 111,
];
let response_result: Result<Vec<u8>, ClientError> = Ok(bytes.to_vec());
let response_dns_msg = parse_response(response_result);
let query_id = 0b10100101;
let ip = IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8));
let response_result: Result<(Vec<u8>, IpAddr), ClientError> = Ok((bytes.to_vec(), ip));
let response_dns_msg = parse_response(response_result,query_id);
let err_msg = "The name server was unable to interpret the query.".to_string();

if let Err(ResolverError::Parse(err)) = response_dns_msg {
Expand All @@ -608,4 +681,6 @@ mod async_resolver_test {
assert!(false);
}
}


}
Loading

0 comments on commit 2d07ae3

Please sign in to comment.