Merge branch 'opaque-ports'
[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 /* DNS resolver configuration and DNSSEC trust anchors */
28 #define RESOLV_CONF_FILE "/etc/resolv.conf"
29 #define TRUST_ANCHOR_FILE IPSEC_CONFDIR "/ipsec.d/dnssec.keys"
30
31 typedef struct private_resolver_t private_resolver_t;
32
33 /**
34 * private data of a unbound_resolver_t object.
35 */
36 struct private_resolver_t {
37
38 /**
39 * Public data
40 */
41 resolver_t public;
42
43 /**
44 * private unbound resolver handle (unbound context)
45 */
46 struct ub_ctx *ctx;
47 };
48
49 /**
50 * query method implementation
51 */
52 METHOD(resolver_t, query, resolver_response_t*,
53 private_resolver_t *this, char *domain, rr_class_t rr_class,
54 rr_type_t rr_type)
55 {
56 unbound_response_t *response = NULL;
57 struct ub_result *result = NULL;
58 int ub_retval;
59
60 ub_retval = ub_resolve(this->ctx, domain, rr_type, rr_class, &result);
61 if (ub_retval)
62 {
63 DBG1(DBG_LIB, "unbound resolver error: %s", ub_strerror(ub_retval));
64 ub_resolve_free(result);
65 return NULL;
66 }
67
68 response = unbound_response_create_frm_libub_response(result);
69 if (!response)
70 {
71 DBG1(DBG_LIB, "unbound resolver failed to create response");
72 ub_resolve_free(result);
73 return NULL;
74 }
75 ub_resolve_free(result);
76
77 return (resolver_response_t*)response;
78 }
79
80 /**
81 * destroy method implementation
82 */
83 METHOD(resolver_t, destroy, void,
84 private_resolver_t *this)
85 {
86 ub_ctx_delete(this->ctx);
87 free(this);
88 }
89
90 /*
91 * Described in header.
92 */
93 resolver_t *unbound_resolver_create(void)
94 {
95 private_resolver_t *this;
96 int ub_retval = 0;
97 char *resolv_conf_file;
98 char *trust_anchor_file;
99
100 resolv_conf_file = lib->settings->get_str(lib->settings,
101 "libstrongswan.plugins.unbound.resolv_conf",
102 RESOLV_CONF_FILE);
103
104 trust_anchor_file = lib->settings->get_str(lib->settings,
105 "libstrongswan.plugins.unbound.trust_anchors",
106 TRUST_ANCHOR_FILE);
107
108 INIT(this,
109 .public = {
110 .query = _query,
111 .destroy = _destroy,
112 },
113 );
114
115 this->ctx = ub_ctx_create();
116 if (!this->ctx)
117 {
118 DBG1(DBG_LIB, "failed to create unbound resolver context");
119 destroy(this);
120 return NULL;
121 }
122
123 DBG1(DBG_CFG, "loading unbound resolver config from '%s'", resolv_conf_file);
124 ub_retval = ub_ctx_resolvconf(this->ctx, resolv_conf_file);
125 if (ub_retval)
126 {
127 DBG1(DBG_CFG, "failed to read the resolver config: %s (%s)",
128 ub_strerror(ub_retval), strerror(errno));
129 destroy(this);
130 return NULL;
131 }
132
133 DBG1(DBG_CFG, "loading unbound trust anchors from '%s'", trust_anchor_file);
134 ub_retval = ub_ctx_add_ta_file(this->ctx, trust_anchor_file);
135 if (ub_retval)
136 {
137 DBG1(DBG_CFG, "failed to load trust anchors: %s (%s)",
138 ub_strerror(ub_retval), strerror(errno));
139 }
140
141 return &this->public;
142 }
143