Branch data Line data Source code
1 : : // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
2 : : //
3 : : // Permission to use, copy, modify, and/or distribute this software for any
4 : : // purpose with or without fee is hereby granted, provided that the above
5 : : // copyright notice and this permission notice appear in all copies.
6 : : //
7 : : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
8 : : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9 : : // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
10 : : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11 : : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
12 : : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13 : : // PERFORMANCE OF THIS SOFTWARE.
14 : :
15 : : // $Id$
16 : :
17 : : #include "message_utility.h"
18 : : #include <dns/rcode.h>
19 : :
20 : : using namespace isc::dns;
21 : :
22 : : namespace isc {
23 : : namespace cache {
24 : : namespace MessageUtility{
25 : :
26 : : bool
27 : 14 : hasTheRecordInAuthoritySection(const isc::dns::Message& msg,
28 : : const isc::dns::RRType& type)
29 : : {
30 : : // isc::dns::Message provide one function hasRRset() should be used to
31 : : // determine whether the given section has an RRset matching the given
32 : : // name and type, but currently it is not const-qualified and cannot be
33 : : // used here
34 : : // TODO: use hasRRset() function when it is const qualified
35 [ + - ][ + - ]: 68 : for (RRsetIterator iter = msg.beginSection(Message::SECTION_AUTHORITY);
[ + + ]
36 [ + - ][ + - ]: 36 : iter != msg.endSection(Message::SECTION_AUTHORITY);
37 : : ++iter) {
38 [ + - ]: 13 : RRsetPtr rrset_ptr = *iter;
39 [ + - ][ + + ]: 13 : if (rrset_ptr->getType() == type) {
40 : 9 : return (true);
41 : : }
42 : : }
43 : 5 : return (false);
44 : : }
45 : :
46 : : bool
47 : 61 : isNegativeResponse(const isc::dns::Message& msg) {
48 [ + + ]: 61 : if (msg.getRcode() == Rcode::NXDOMAIN()) {
49 : : return (true);
50 [ + - ]: 55 : } else if (msg.getRcode() == Rcode::NOERROR()) {
51 : : // no data in the answer section
52 [ + + ]: 55 : if (msg.getRRCount(Message::SECTION_ANSWER) == 0) {
53 : : // NODATA type 1/ type 2 (ref sec2.2 of RFC2308)
54 [ + + ]: 6 : if (hasTheRecordInAuthoritySection(msg, RRType::SOA())) {
55 : : return (true);
56 [ + - ]: 4 : } else if (!hasTheRecordInAuthoritySection(msg, RRType::NS())) {
57 : : // NODATA type 3 (sec2.2 of RFC2308)
58 : : return (true);
59 : : }
60 : : }
61 : : }
62 : :
63 : 61 : return (false);
64 : : }
65 : :
66 : : bool
67 : 25 : canMessageBeCached(const isc::dns::Message& msg) {
68 : : // If the message is a negative response, but no SOA record is found in
69 : : // the authority section, the message cannot be cached
70 [ + + + + ]: 29 : if (isNegativeResponse(msg) &&
[ + + ]
71 : 4 : !hasTheRecordInAuthoritySection(msg, RRType::SOA())){
72 : : return (false);
73 : : }
74 : :
75 : 25 : return (true);
76 : : }
77 : :
78 : : } // namespace MessageUtility
79 : : } // namespace cache
80 : 3 : } // namespace isc
|