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>