Annotation of embedaddon/strongswan/src/libstrongswan/plugins/unbound/unbound_response.c, revision 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>