@@ -6,7 +6,7 @@ use tokio::net::UdpSocket;
6
6
7
7
use crate :: message:: resource_record:: ResourceRecord ;
8
8
use crate :: message:: DnsMessage ;
9
-
9
+ use crate :: message :: rcode :: Rcode ;
10
10
11
11
/// Structure to represent a Name Server
12
12
#[ derive ( Debug ) ]
@@ -35,26 +35,52 @@ impl NameServer {
35
35
let socket_clone = self . shared_sock . clone ( ) ;
36
36
tokio:: spawn ( async move {
37
37
// Handle the request concurrently!!! Important
38
- NameServer :: handle_request ( socket_clone, data, src) . await ;
38
+ self . handle_request ( socket_clone, data, src) . await ;
39
39
} ) ;
40
40
}
41
41
}
42
42
43
- async fn handle_request ( socket : Arc < Mutex < UdpSocket > > ,
43
+ async fn handle_request ( & self , socket : Arc < Mutex < UdpSocket > > ,
44
44
data : Vec < u8 > ,
45
45
addr : std:: net:: SocketAddr ) {
46
- let message = DnsMessage :: from_bytes ( & data) . unwrap ( ) ;
47
- // respondemos lo mismo por el momento
48
- let response = message . to_bytes ( ) ;
46
+ let mut message = DnsMessage :: from_bytes ( & data) . expect ( "Error al parsear el mensaje" ) ;
47
+
48
+ let rrs_to_add = NameServer :: search_query ( & self . zone , & message ) ;
49
49
50
+ if rrs_to_add. len ( ) > 0 {
51
+ NameServer :: add_rrs ( & mut message, & rrs_to_add)
52
+ }
53
+ let response = message. to_bytes ( ) ;
50
54
// lock the socket and send the response
51
55
let mut sock = socket. lock ( ) . await ;
52
56
if let Err ( e) = sock. send_to ( & response, addr) . await {
53
57
eprintln ! ( "Failed to send response to {}: {}" , addr, e) ;
54
58
} else {
55
59
println ! ( "Sent response to {:?}" , addr) ;
56
60
}
57
- }
61
+ }
62
+
63
+ fn add_rrs ( msg : & mut DnsMessage , rrs : & Vec < ResourceRecord > ) {
64
+ msg. set_answer ( rrs. clone ( ) ) ;
65
+ let mut header = msg. get_header ( ) ;
66
+ header. set_aa ( true ) ;
67
+ header. set_rcode ( Rcode :: NOERROR ) ;
68
+ header. set_qr ( true ) ;
69
+ header. set_ancount ( rrs. len ( ) as u16 ) ;
70
+ msg. set_header ( header) ;
71
+ }
72
+
73
+ fn search_query ( zone : & Vec < ResourceRecord > , msg : & DnsMessage ) -> Vec < ResourceRecord > {
74
+ let qclass = msg. get_question ( ) . get_rclass ( ) ;
75
+ let qtype = msg. get_question ( ) . get_rrtype ( ) ;
76
+ let qname = msg. get_question ( ) . get_qname ( ) ;
77
+ zone. iter ( )
78
+ . filter ( |rr|
79
+ qclass == rr. get_rclass ( )
80
+ && qtype == rr. get_rtype ( )
81
+ && qname == rr. get_name ( ) )
82
+ . collect ( )
83
+ }
58
84
}
59
85
60
86
0 commit comments