Return to unbound_response.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / unbound |
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: }