tdns_cli/
update_message.rs

1use trust_dns::{
2    op::{Message, MessageType, OpCode, Query, UpdateMessage},
3    rr::{rdata::NULL, DNSClass, Name, RData, Record, RecordSet, RecordType},
4};
5
6// This code is taken from `update_message.rs` in the `trust_dns` crate, and
7// adapted to omit EDNS.
8pub fn create(rrset: RecordSet, zone_origin: Name) -> Message {
9    // TODO: assert non-empty rrset?
10    assert!(zone_origin.zone_of(rrset.name()));
11
12    // for updates, the query section is used for the zone
13    let mut zone = Query::new();
14    zone.set_name(zone_origin)
15        .set_query_class(rrset.dns_class())
16        .set_query_type(RecordType::SOA);
17
18    // build the message
19    let mut message: Message = Message::new();
20    message
21        .set_id(rand::random())
22        .set_message_type(MessageType::Query)
23        .set_op_code(OpCode::Update)
24        .set_recursion_desired(false);
25    message.add_zone(zone);
26
27    let mut prerequisite = Record::with(rrset.name().clone(), rrset.record_type(), 0);
28    prerequisite.set_dns_class(DNSClass::NONE);
29    message.add_pre_requisite(prerequisite);
30    message.add_updates(rrset);
31    message
32}
33
34pub fn append(rrset: RecordSet, zone_origin: Name, must_exist: bool) -> Message {
35    assert!(zone_origin.zone_of(rrset.name()));
36
37    // for updates, the query section is used for the zone
38    let mut zone: Query = Query::new();
39    zone.set_name(zone_origin)
40        .set_query_class(rrset.dns_class())
41        .set_query_type(RecordType::SOA);
42
43    // build the message
44    let mut message: Message = Message::new();
45    message
46        .set_id(rand::random())
47        .set_message_type(MessageType::Query)
48        .set_op_code(OpCode::Update)
49        .set_recursion_desired(false);
50    message.add_zone(zone);
51
52    if must_exist {
53        let mut prerequisite = Record::with(rrset.name().clone(), rrset.record_type(), 0);
54        prerequisite.set_dns_class(DNSClass::ANY);
55        message.add_pre_requisite(prerequisite);
56    }
57
58    message.add_updates(rrset);
59
60    message
61}
62
63pub fn delete_by_rdata(mut rrset: RecordSet, zone_origin: Name) -> Message {
64    assert!(zone_origin.zone_of(rrset.name()));
65
66    // for updates, the query section is used for the zone
67    let mut zone: Query = Query::new();
68    zone.set_name(zone_origin)
69        .set_query_class(rrset.dns_class())
70        .set_query_type(RecordType::SOA);
71
72    // build the message
73    let mut message: Message = Message::new();
74    message
75        .set_id(rand::random())
76        .set_message_type(MessageType::Query)
77        .set_op_code(OpCode::Update)
78        .set_recursion_desired(false);
79    message.add_zone(zone);
80
81    // the class must be none for delete
82    rrset.set_dns_class(DNSClass::NONE);
83    // the TTL should be 0
84    rrset.set_ttl(0);
85    message.add_updates(rrset);
86
87    message
88}
89
90pub fn delete_rrset(mut record: Record, zone_origin: Name) -> Message {
91    assert!(zone_origin.zone_of(record.name()));
92
93    // for updates, the query section is used for the zone
94    let mut zone: Query = Query::new();
95    zone.set_name(zone_origin)
96        .set_query_class(record.dns_class())
97        .set_query_type(RecordType::SOA);
98
99    // build the message
100    let mut message: Message = Message::new();
101    message
102        .set_id(rand::random())
103        .set_message_type(MessageType::Query)
104        .set_op_code(OpCode::Update)
105        .set_recursion_desired(false);
106    message.add_zone(zone);
107
108    // the class must be none for an rrset delete
109    record.set_dns_class(DNSClass::ANY);
110    // the TTL should be 0
111    record.set_ttl(0);
112    // the rdata must be null to delete all rrsets
113    record.set_rdata(RData::NULL(NULL::new()));
114    message.add_update(record);
115
116    message
117}
118
119pub fn delete_all(name_of_records: Name, zone_origin: Name, dns_class: DNSClass) -> Message {
120    assert!(zone_origin.zone_of(&name_of_records));
121
122    // for updates, the query section is used for the zone
123    let mut zone: Query = Query::new();
124    zone.set_name(zone_origin)
125        .set_query_class(dns_class)
126        .set_query_type(RecordType::SOA);
127
128    // build the message
129    let mut message: Message = Message::new();
130    message
131        .set_id(rand::random())
132        .set_message_type(MessageType::Query)
133        .set_op_code(OpCode::Update)
134        .set_recursion_desired(false);
135    message.add_zone(zone);
136
137    // the TTL should be 0
138    // the rdata must be null to delete all rrsets
139    // the record type must be any
140    let mut record = Record::with(name_of_records, RecordType::ANY, 0);
141
142    // the class must be none for an rrset delete
143    record.set_dns_class(DNSClass::ANY);
144
145    message.add_update(record);
146
147    message
148}