Skip to content

Commit ba1ecb0

Browse files
committed
Improved report data types documentation
1 parent f12f1b4 commit ba1ecb0

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

src/report.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
use serde::{Deserialize, Serialize};
77
use std::net::IpAddr;
88

9+
/// The time range in UTC covered by messages in this report.
10+
/// Specified in seconds since epoch.
911
#[derive(Debug, Serialize, Deserialize)]
1012
pub struct DateRangeType {
1113
pub begin: u64,
1214
pub end: u64,
1315
}
1416

17+
/// Report generator metadata.
1518
#[derive(Debug, Serialize, Deserialize)]
1619
pub struct ReportMetadataType {
1720
pub org_name: String,
@@ -24,6 +27,7 @@ pub struct ReportMetadataType {
2427
pub error: Option<Vec<String>>,
2528
}
2629

30+
/// Alignment mode for DKIM and SPF.
2731
#[derive(Debug, Serialize, Deserialize, PartialEq)]
2832
pub enum AlignmentType {
2933
#[serde(rename = "r")]
@@ -32,51 +36,81 @@ pub enum AlignmentType {
3236
Strict,
3337
}
3438

39+
/// The policy actions specified by `p` and `sp` in the DMARC record.
3540
#[derive(Debug, Serialize, Deserialize, PartialEq)]
3641
#[serde(rename_all = "snake_case")]
3742
pub enum DispositionType {
3843
/// There is no preference on how a failed DMARC should be handled.
3944
None,
40-
/// The message should be quarantined. This usually means it will be placed in the `spam` folder of the user.
45+
/// The message should be quarantined.
46+
/// This usually means it will be placed in the spam folder of the user.
4147
Quarantine,
4248
/// The message should be rejected.
4349
Reject,
4450
}
4551

52+
/// The DMARC policy that applied to the messages in this report.
4653
#[derive(Debug, Serialize, Deserialize)]
4754
pub struct PolicyPublishedType {
55+
/// The domain at which the DMARC record was found.
4856
pub domain: String,
57+
/// The DKIM alignment mode.
4958
#[serde(skip_serializing_if = "Option::is_none")]
5059
pub adkim: Option<AlignmentType>,
60+
/// The SPF alignment mode.
5161
#[serde(skip_serializing_if = "Option::is_none")]
5262
pub aspf: Option<AlignmentType>,
63+
/// The policy to apply to messages from the domain.
5364
pub p: DispositionType,
65+
/// The policy to apply to messages from subdomains.
5466
#[serde(skip_serializing_if = "Option::is_none")]
5567
pub sp: Option<DispositionType>,
68+
/// The percent of messages to which policy applies.
5669
#[serde(skip_serializing_if = "Option::is_none")]
5770
pub pct: Option<u8>,
71+
/// Failure reporting options in effect.
5872
#[serde(skip_serializing_if = "Option::is_none")]
5973
pub fo: Option<String>,
6074
}
6175

76+
/// The DMARC-aligned authentication result.
6277
#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
6378
#[serde(rename_all = "snake_case")]
6479
pub enum DmarcResultType {
6580
Pass,
6681
Fail,
6782
}
6883

84+
/// Reasons that may affect DMARC disposition or execution thereof.
6985
#[derive(Debug, Serialize, Deserialize, PartialEq)]
7086
#[serde(rename_all = "snake_case")]
7187
pub enum PolicyOverrideType {
88+
/// The message was relayed via a known forwarder, or local
89+
/// heuristics identified the message as likely having been forwarded.
90+
/// There is no expectation that authentication would pass.
7291
Forwarded,
92+
/// The message was exempted from application of policy by
93+
/// the `pct` setting in the DMARC policy record.
7394
SampledOut,
95+
/// Message authentication failure was anticipated by
96+
/// other evidence linking the message to a locally maintained list of
97+
/// known and trusted forwarders.
7498
TrustedForwarder,
99+
/// Local heuristics determined that the message arrived
100+
/// via a mailing list, and thus authentication of the original
101+
/// message was not expected to succeed.
75102
MailingList,
103+
/// The Mail Receiver's local policy exempted the message from
104+
/// being subjected to the Domain Owner's requested policy action.
76105
LocalPolicy,
106+
/// Some policy exception not covered by the other entries in
107+
/// this list occurred. Additional detail can be found in the
108+
/// PolicyOverrideReason `comment` field.
77109
Other,
78110
}
79111

112+
/// How do we allow report generators to include new classes of override
113+
/// reasons if they want to be more specific than `other`?
80114
#[derive(Debug, Serialize, Deserialize, PartialEq)]
81115
pub struct PolicyOverrideReason {
82116
#[serde(rename = "type")]
@@ -85,6 +119,8 @@ pub struct PolicyOverrideReason {
85119
pub comment: Option<String>,
86120
}
87121

122+
/// Taking into account everything else in the record,
123+
/// the results of applying DMARC.
88124
#[derive(Debug, Serialize, Deserialize)]
89125
pub struct PolicyEvaluatedType {
90126
pub disposition: DispositionType,
@@ -98,20 +134,27 @@ pub struct PolicyEvaluatedType {
98134

99135
#[derive(Debug, Serialize, Deserialize)]
100136
pub struct RowType {
137+
/// The connecting IP.
101138
pub source_ip: IpAddr,
139+
/// The number of matching messages.
102140
pub count: usize,
141+
/// The DMARC disposition applying to matching messages.
103142
pub policy_evaluated: PolicyEvaluatedType,
104143
}
105144

106145
#[derive(Debug, Serialize, Deserialize)]
107146
pub struct IdentifierType {
147+
/// The envelope recipient domain.
108148
#[serde(skip_serializing_if = "Option::is_none")]
109149
pub envelope_to: Option<String>,
150+
/// The RFC5321.MailFrom domain.
110151
#[serde(skip_serializing_if = "Option::is_none")]
111152
pub envelope_from: Option<String>,
153+
/// The RFC5322.From domain.
112154
pub header_from: String,
113155
}
114156

157+
/// DKIM verification result, according to RFC 7001 Section 2.6.1.
115158
#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
116159
#[serde(rename_all = "snake_case")]
117160
pub enum DkimResultType {
@@ -128,11 +171,15 @@ pub enum DkimResultType {
128171

129172
#[derive(Debug, Serialize, Deserialize, PartialEq)]
130173
pub struct DkimAuthResultType {
174+
/// The `d` parameter in the signature.
131175
pub domain: String,
176+
/// The `s` parameter in the signature.
132177
#[serde(skip_serializing_if = "Option::is_none")]
133178
pub selector: Option<String>,
179+
/// The DKIM verification result.
134180
pub result: DkimResultType,
135181
#[serde(skip_serializing_if = "Option::is_none")]
182+
/// Any extra information.
136183
pub human_result: Option<String>,
137184
}
138185

@@ -161,19 +208,27 @@ pub enum SpfResultType {
161208

162209
#[derive(Debug, Serialize, Deserialize, PartialEq)]
163210
pub struct SpfAuthResultType {
211+
/// The checked domain.
164212
pub domain: String,
213+
/// The scope of the checked domain.
165214
#[serde(skip_serializing_if = "Option::is_none")]
166215
pub scope: Option<SpfDomainScope>,
216+
/// The SPF verification result.
167217
pub result: SpfResultType,
168218
}
169219

220+
/// This element contains DKIM and SPF results, uninterpreted with respect to DMARC.
170221
#[derive(Debug, Serialize, Deserialize)]
171222
pub struct AuthResultType {
223+
/// There may be no DKIM signatures, or multiple DKIM signatures.
172224
#[serde(skip_serializing_if = "Option::is_none")]
173225
pub dkim: Option<Vec<DkimAuthResultType>>,
226+
/// There will always be at least one SPF result.
174227
pub spf: Vec<SpfAuthResultType>,
175228
}
176229

230+
/// This element contains all the authentication results that were
231+
/// evaluated by the receiving system for the given set of messages.
177232
#[derive(Debug, Serialize, Deserialize)]
178233
pub struct RecordType {
179234
pub row: RowType,

0 commit comments

Comments
 (0)