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>