Annotation of embedaddon/strongswan/src/libstrongswan/plugins/unbound/unbound_response.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2012 Reto Guadagnini
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include <resolver/resolver_response.h>
                     17: #include <resolver/rr.h>
                     18: #include "unbound_rr.h"
                     19: #include "unbound_response.h"
                     20: 
                     21: #include <library.h>
                     22: #include <utils/debug.h>
                     23: 
                     24: #include <unbound.h>
                     25: #include <ldns/ldns.h>
                     26: 
                     27: typedef struct private_unbound_response_t private_unbound_response_t;
                     28: 
                     29: /**
                     30:  * private data of an unbound_response_t object.
                     31:  */
                     32: struct private_unbound_response_t {
                     33: 
                     34:        /**
                     35:         * Public data
                     36:         */
                     37:        unbound_response_t public;
                     38: 
                     39:        /**
                     40:         * Original question string
                     41:         */
                     42:        char* query_name;
                     43: 
                     44:        /**
                     45:         * Canonical name of the response
                     46:         */
                     47:        char* canon_name;
                     48: 
                     49:        /**
                     50:         * Are the some RRs in the RRset of this response?
                     51:         */
                     52:        bool has_data;
                     53: 
                     54:        /*
                     55:         * Does the queried name exist?
                     56:         */
                     57:        bool query_name_exist;
                     58: 
                     59:        /**
                     60:         * DNSSEC security state
                     61:         */
                     62:        dnssec_status_t security_state;
                     63: 
                     64:        /**
                     65:         * RRset
                     66:         */
                     67:        rr_set_t *rr_set;
                     68: };
                     69: 
                     70: METHOD(resolver_response_t, get_query_name, char*,
                     71:        private_unbound_response_t *this)
                     72: {
                     73:        return this->query_name;
                     74: }
                     75: 
                     76: METHOD(resolver_response_t, get_canon_name, char*,
                     77:        private_unbound_response_t *this)
                     78: {
                     79:        return this->canon_name;
                     80: }
                     81: 
                     82: METHOD(resolver_response_t, has_data, bool,
                     83:        private_unbound_response_t *this)
                     84: {
                     85:        return this->has_data;
                     86: }
                     87: 
                     88: METHOD(resolver_response_t, query_name_exist, bool,
                     89:        private_unbound_response_t *this)
                     90: {
                     91:        return this->query_name_exist;
                     92: }
                     93: 
                     94: METHOD(resolver_response_t, get_security_state, dnssec_status_t,
                     95:        private_unbound_response_t *this)
                     96: {
                     97:        return this->security_state;
                     98: }
                     99: 
                    100: METHOD(resolver_response_t, get_rr_set, rr_set_t*,
                    101:        private_unbound_response_t *this)
                    102: {
                    103:        return this->rr_set;
                    104: }
                    105: 
                    106: METHOD(resolver_response_t, destroy, void,
                    107:        private_unbound_response_t *this)
                    108: {
                    109:        free(this->query_name);
                    110:        free(this->canon_name);
                    111:        DESTROY_IF(this->rr_set);
                    112:        free(this);
                    113: }
                    114: 
                    115: /*
                    116:  * Described in header.
                    117:  */
                    118: unbound_response_t *unbound_response_create_frm_libub_response(
                    119:                                                                                        struct ub_result *libub_response)
                    120: {
                    121:        private_unbound_response_t *this = NULL;
                    122: 
                    123:        INIT(this,
                    124:                .public = {
                    125:                        .interface = {
                    126:                                .get_query_name = _get_query_name,
                    127:                                .get_canon_name = _get_canon_name,
                    128:                                .has_data = _has_data,
                    129:                                .query_name_exist = _query_name_exist,
                    130:                                .get_security_state = _get_security_state,
                    131:                                .get_rr_set = _get_rr_set,
                    132:                                .destroy = _destroy,
                    133:                        },
                    134:                },
                    135:        );
                    136: 
                    137:        this->query_name = strdup(libub_response->qname);
                    138: 
                    139:        if (libub_response->canonname)
                    140:        {
                    141:                this->canon_name = strdup(libub_response->canonname);
                    142:        }
                    143: 
                    144:        this->has_data = libub_response->havedata;
                    145: 
                    146:        this->query_name_exist = !(libub_response->nxdomain);
                    147: 
                    148:        if (libub_response->secure)
                    149:        {
                    150:                this->security_state = SECURE;
                    151:        }
                    152:        else if (libub_response->bogus)
                    153:        {
                    154:                this->security_state = BOGUS;
                    155:        }
                    156:        else
                    157:        {
                    158:                this->security_state = INDETERMINATE;
                    159:        }
                    160: 
                    161:        /**
                    162:        * Create RRset
                    163:        */
                    164:        if (this->query_name_exist && this->has_data)
                    165:        {
                    166:                ldns_pkt *dns_pkt = NULL;
                    167:                ldns_rr_list *orig_rr_list = NULL;
                    168:                size_t orig_rr_count;
                    169:                ldns_rr *orig_rr = NULL;
                    170:                ldns_rdf *orig_rdf = NULL;
                    171:                ldns_status status;
                    172:                linked_list_t *rr_list = NULL, *rrsig_list = NULL;
                    173:                unbound_rr_t *rr = NULL;
                    174:                int i;
                    175: 
                    176:                /**Parse the received DNS packet using the ldns library */
                    177:                status = ldns_wire2pkt(&dns_pkt, libub_response->answer_packet,
                    178:                                                           libub_response->answer_len);
                    179: 
                    180:                if (status != LDNS_STATUS_OK)
                    181:                {
                    182:                        DBG1(DBG_LIB, "failed to parse DNS packet");
                    183:                        destroy(this);
                    184:                        return NULL;
                    185:                }
                    186: 
                    187:                /* Create a list with the queried RRs. If there are corresponding RRSIGs
                    188:                 * create also a list with these.
                    189:                 */
                    190:                rr_list = linked_list_create();
                    191: 
                    192:                orig_rr_list = ldns_pkt_answer(dns_pkt);
                    193:                orig_rr_count = ldns_rr_list_rr_count(orig_rr_list);
                    194: 
                    195:                for (i = 0; i < orig_rr_count; i++)
                    196:                {
                    197:                        orig_rr = ldns_rr_list_rr(orig_rr_list, i);
                    198: 
                    199:                        if (ldns_rr_get_type(orig_rr) == libub_response->qtype &&
                    200:                                ldns_rr_get_class(orig_rr) == libub_response->qclass)
                    201:                        {
                    202:                                /* RR is part of the queried RRset.
                    203:                                 * => add it to the list of Resource Records.
                    204:                                 */
                    205:                                rr = unbound_rr_create_frm_ldns_rr(orig_rr);
                    206:                                if (rr)
                    207:                                {
                    208:                                        rr_list->insert_last(rr_list, rr);
                    209:                                }
                    210:                                else
                    211:                                {
                    212:                                        DBG1(DBG_LIB, "failed to create RR");
                    213:                                }
                    214:                        }
                    215: 
                    216:                        if (ldns_rr_get_type(orig_rr) == LDNS_RR_TYPE_RRSIG)
                    217:                        {
                    218:                                orig_rdf = ldns_rr_rrsig_typecovered(orig_rr);
                    219:                                if (!orig_rdf)
                    220:                                {
                    221:                                        DBG1(DBG_LIB, "failed to get the type covered by an RRSIG");
                    222:                                }
                    223:                                else if (ldns_rdf2native_int16(orig_rdf) == libub_response->qtype)
                    224:                                {
                    225:                                        /* The current RR represent a signature (RRSIG)
                    226:                                         * which belongs to the queried RRset.
                    227:                                         * => add it to the list of signatures.
                    228:                                         */
                    229:                                        rr = unbound_rr_create_frm_ldns_rr(orig_rr);
                    230:                                        if (rr)
                    231:                                        {
                    232:                                                if (!rrsig_list)
                    233:                                                {
                    234:                                                        rrsig_list = linked_list_create();
                    235:                                                }
                    236:                                                rrsig_list->insert_last(rrsig_list, rr);
                    237:                                        }
                    238:                                        else
                    239:                                        {
                    240:                                                DBG1(DBG_LIB, "failed to create RRSIG");
                    241:                                        }
                    242:                                }
                    243:                                else
                    244:                                {
                    245:                                        DBG1(DBG_LIB, "failed to determine the RR type "
                    246:                                                                  "covered by RRSIG RR");
                    247:                                }
                    248:                        }
                    249:                }
                    250:                /**
                    251:                 * Create the RRset for which the query was performed.
                    252:                 */
                    253:                this->rr_set = rr_set_create(rr_list, rrsig_list);
                    254: 
                    255:                ldns_pkt_free(dns_pkt);
                    256:        }
                    257:        return &this->public;
                    258: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>