fn follow_cname_2(
    zone: &Zone,
    qname: &Name,
    cname: Box<Name>,
    rr_type: Type,
    response: &mut Writer,
    mut owners_seen: PreviousOwners,
) -> ProcessingResult<()> {
    // NOTE: RFC 1034 § 3.4.2 indicates that we should restart the query
    // from the very beginning, even going into other available zones.
    // (A possible motivation behind this instruction is the possibility
    // that we might provide recursive service.) This is *not* the
    // procedure that we follow. Rather, we re-run the query within the
    // original QNAME's zone. This appears to be the behavior of some
    // other authoritative servers, such as Knot.
    //
    // There is a good reason for this decision. Even if we did follow
    // a CNAME chain into another zone for which we are authoritative,
    // resolvers likely don't know that we are also authoritative for
    // that other zone. A smart resolver, therefore, won't trust any
    // records from the other zone that we might include. (See e.g. the
    // scrub_sanitize subroutine in Unbound.)
    match zone.lookup(&cname, rr_type) {
        LookupResult::Found(rrset) => {
            response.add_answer_rrset(&cname, rrset)?;
            do_additional_section_processing(zone, rrset, response)
        }
        LookupResult::Cname(next_cname_rrset) => {
            // The CNAME chain continues. If the CNAME chain is getting
            // too long, we refuse to go any further; otherwise we
            // restart the CNAME-following process with the next CNAME
            // in the chain.
            if owners_seen.is_full() {
                Err(ProcessingError::ServFail)
            } else {
                response.add_answer_rrset(&cname, next_cname_rrset)?;
                owners_seen.push(cname);
                follow_cname_1(
                    zone,
                    qname,
                    next_cname_rrset,
                    rr_type,
                    response,
                    owners_seen,
                )
            }
        }
        LookupResult::Referral(child_zone, ns_rrset) => {
            do_referral(zone, child_zone, ns_rrset, response)
        }
        // Per RFC 6604 § 3, the RCODE is set based on the last query
        // cycle. Therefore, the no-records case should be NOERROR and
        // the nonexistent-name case should be NXDOMAIN. Note that this
        // seems to be a change from RFC 1034 § 3.4.2, whose step 3(c)
        // calls for an authoritative name error (NXDOMAIN) only when
        // the failed lookup is for the original QNAME.
        LookupResult::NoRecords => add_negative_caching_soa(zone, response),
        LookupResult::NxDomain => {
            response.set_rcode(Rcode::NxDomain);
            add_negative_caching_soa(zone, response)
        }
        LookupResult::WrongZone => Ok(()),
    }
}
/// Step 2 of the CNAME-following process. This is the point where we
/// actually re-run the query with the CNAME as the new QNAME.
Step 2 of the CNAME-following process. This is the point where we
actually re-run the query with the CNAME as the new QNAME.
Step 2 of the CNAME - following process . This is the point where we actually re - run the query with the CNAME as the new QNAME .
fn follow_cname_2(
    zone: &Zone,
    qname: &Name,
    cname: Box<Name>,
    rr_type: Type,
    response: &mut Writer,
    mut owners_seen: PreviousOwners,
) -> ProcessingResult<()> {
    // NOTE: RFC 1034 § 3.4.2 indicates that we should restart the query
    // from the very beginning, even going into other available zones.
    // (A possible motivation behind this instruction is the possibility
    // that we might provide recursive service.) This is *not* the
    // procedure that we follow. Rather, we re-run the query within the
    // original QNAME's zone. This appears to be the behavior of some
    // other authoritative servers, such as Knot.
    //
    // There is a good reason for this decision. Even if we did follow
    // a CNAME chain into another zone for which we are authoritative,
    // resolvers likely don't know that we are also authoritative for
    // that other zone. A smart resolver, therefore, won't trust any
    // records from the other zone that we might include. (See e.g. the
    // scrub_sanitize subroutine in Unbound.)
    match zone.lookup(&cname, rr_type) {
        LookupResult::Found(rrset) => {
            response.add_answer_rrset(&cname, rrset)?;
            do_additional_section_processing(zone, rrset, response)
        }
        LookupResult::Cname(next_cname_rrset) => {
            // The CNAME chain continues. If the CNAME chain is getting
            // too long, we refuse to go any further; otherwise we
            // restart the CNAME-following process with the next CNAME
            // in the chain.
            if owners_seen.is_full() {
                Err(ProcessingError::ServFail)
            } else {
                response.add_answer_rrset(&cname, next_cname_rrset)?;
                owners_seen.push(cname);
                follow_cname_1(
                    zone,
                    qname,
                    next_cname_rrset,
                    rr_type,
                    response,
                    owners_seen,
                )
            }
        }
        LookupResult::Referral(child_zone, ns_rrset) => {
            do_referral(zone, child_zone, ns_rrset, response)
        }
        // Per RFC 6604 § 3, the RCODE is set based on the last query
        // cycle. Therefore, the no-records case should be NOERROR and
        // the nonexistent-name case should be NXDOMAIN. Note that this
        // seems to be a change from RFC 1034 § 3.4.2, whose step 3(c)
        // calls for an authoritative name error (NXDOMAIN) only when
        // the failed lookup is for the original QNAME.
        LookupResult::NoRecords => add_negative_caching_soa(zone, response),
        LookupResult::NxDomain => {
            response.set_rcode(Rcode::NxDomain);
            add_negative_caching_soa(zone, response)
        }
        LookupResult::WrongZone => Ok(()),
    }
}
fn follow_cname_2 ( zone : & Zone , qname : & Name , cname : Box < Name > , rr_type : Type , response : & mut Writer , mut owners_seen : PreviousOwners , ) -> ProcessingResult < ( ) > { // NOTE: RFC 1034 § 3.4.2 indicates that we should restart the query // from the very beginning, even going into other available zones. // (A possible motivation behind this instruction is the possibility // that we might provide recursive service.) This is *not* the // procedure that we follow. Rather, we re-run the query within the // original QNAME's zone. This appears to be the behavior of some // other authoritative servers, such as Knot. // // There is a good reason for this decision. Even if we did follow // a CNAME chain into another zone for which we are authoritative, // resolvers likely don't know that we are also authoritative for // that other zone. A smart resolver, therefore, won't trust any // records from the other zone that we might include. (See e.g. the // scrub_sanitize subroutine in Unbound.) match zone . lookup ( & cname , rr_type ) { LookupResult :: Found ( rrset ) => { response . add_answer_rrset ( & cname , rrset ) ? ; do_additional_section_processing ( zone , rrset , response ) } LookupResult :: Cname ( next_cname_rrset ) => { // The CNAME chain continues. If the CNAME chain is getting // too long, we refuse to go any further; otherwise we // restart the CNAME-following process with the next CNAME // in the chain. if owners_seen . is_full ( ) { Err ( ProcessingError :: ServFail ) } else { response . add_answer_rrset ( & cname , next_cname_rrset ) ? ; owners_seen . push ( cname ) ; follow_cname_1 ( zone , qname , next_cname_rrset , rr_type , response , owners_seen , ) } } LookupResult :: Referral ( child_zone , ns_rrset ) => { do_referral ( zone , child_zone , ns_rrset , response ) } // Per RFC 6604 § 3, the RCODE is set based on the last query // cycle. Therefore, the no-records case should be NOERROR and // the nonexistent-name case should be NXDOMAIN. Note that this // seems to be a change from RFC 1034 § 3.4.2, whose step 3(c) // calls for an authoritative name error (NXDOMAIN) only when // the failed lookup is for the original QNAME. LookupResult :: NoRecords => add_negative_caching_soa ( zone , response ) , LookupResult :: NxDomain => { response . set_rcode ( Rcode :: NxDomain ) ; add_negative_caching_soa ( zone , response ) } LookupResult :: WrongZone => Ok ( ( ) ) , } }
Step 2 of the CNAME-following process.
Step 2 of the CNAME - following process .
zone
&Zone
qname
&Name
cname
Box<Name>
rr_type
Type
response
&mut Writer
owners_seen
PreviousOwners
zone
&Zone
qname
&Name
cname
Box<Name>
rr_type
Type
response
&mut Writer
owners_seen
PreviousOwners