unbound: Implementation of query method of unbound_resolver_t
[strongswan.git] / src / libstrongswan / plugins / unbound / unbound_resolver.c
1 /*
2 * Copyright (C) 2011-2012 Reto Guadagnini
3 * 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 <unbound.h>
17 #include <errno.h>
18 #include <ldns/ldns.h>
19 #include <string.h>
20
21 #include <library.h>
22 #include <utils/debug.h>
23
24 #include "unbound_resolver.h"
25 #include "unbound_response.h"
26
27 typedef struct private_resolver_t private_resolver_t;
28
29 /**
30 * private data of a unbound_resolver_t object.
31 */
32 struct private_resolver_t {
33
34 /**
35 * Public data
36 */
37 resolver_t public;
38
39 /**
40 * private unbound resolver handle (unbound context)
41 */
42 struct ub_ctx *ctx;
43 };
44
45 /**
46 * query method implementation
47 */
48 METHOD(resolver_t, query, resolver_response_t*,
49 private_resolver_t *this, char *domain, rr_class_t rr_class,
50 rr_type_t rr_type)
51 {
52 unbound_response_t *response = NULL;
53 struct ub_result *result = NULL;
54 int ub_retval;
55
56 ub_retval = ub_resolve(this->ctx, domain, rr_type, rr_class, &result);
57 if (ub_retval)
58 {
59 DBG1(DBG_LIB, "unbound resolver error: %s", ub_strerror(ub_retval));
60 ub_resolve_free(result);
61 return NULL;
62 }
63
64 response = unbound_response_create_frm_libub_response(result);
65 if (!response)
66 {
67 DBG1(DBG_LIB, "unbound_resolver: Could not create response.");
68 ub_resolve_free(result);
69 return NULL;
70 }
71 ub_resolve_free(result);
72 return (resolver_response_t*)response;
73 }
74
75 /**
76 * destroy method implementation
77 */
78 METHOD(resolver_t, destroy, void,
79 private_resolver_t *this)
80 {
81 ub_ctx_delete(this->ctx);
82 free(this);
83 }
84
85 /*
86 * Described in header.
87 */
88 resolver_t *unbound_resolver_create(char *resolv_conf, char *ta_file)
89 {
90 private_resolver_t *this;
91 int ub_retval = 0;
92
93 INIT(this,
94 .public = {
95 .query = _query,
96 .destroy = _destroy,
97 },
98 );
99
100 DBG1(DBG_LIB, "creating an unbound_resolver instance");
101
102 this->ctx = ub_ctx_create();
103 if (!this->ctx)
104 {
105 DBG1(DBG_LIB, "failed to create an unbound resolver context");
106 _destroy(this);
107 return NULL;
108 }
109
110 ub_retval = ub_ctx_resolvconf(this->ctx, resolv_conf);
111 if (ub_retval)
112 {
113 DBG1(DBG_LIB, "failed to read the resolver configuration file. "
114 "Unbound error: %s. errno says: %s", ub_strerror(ub_retval),
115 strerror(errno));
116 _destroy(this);
117 return NULL;
118 }
119
120 ub_retval = ub_ctx_add_ta_file(this->ctx, ta_file);
121 if (ub_retval)
122 {
123 DBG1(DBG_LIB, "failed to load trusted anchors from file %s. "
124 "Unbound error: %s. errno says: %s",
125 ta_file, ub_strerror(ub_retval), strerror(errno));
126 }
127
128 DBG1(DBG_LIB, "unbound resolver instance created");
129 return &this->public;
130 }
131