Merge branch 'opaque-ports'
[strongswan.git] / src / libstrongswan / plugins / unbound / unbound_rr.c
1 /*
2 * Copyright (C) 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 <resolver/rr.h>
17
18 #include <library.h>
19 #include <utils/debug.h>
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "unbound_rr.h"
25
26 typedef struct private_unbound_rr_t private_unbound_rr_t;
27
28 /**
29 * private data of an unbound_rr_t object.
30 */
31 struct private_unbound_rr_t {
32
33 /**
34 * Public data
35 */
36 unbound_rr_t public;
37
38 /**
39 * Owner name
40 */
41 char* name;
42
43 /**
44 * Type
45 */
46 rr_type_t type;
47
48 /**
49 * Class
50 */
51 rr_class_t class;
52
53 /**
54 * TTL
55 */
56 uint32_t ttl;
57
58 /**
59 * Size of the rdata field in octets
60 */
61 uint16_t size;
62
63 /**
64 * RDATA field (array of bytes in network order)
65 */
66 u_char *rdata;
67 };
68
69 METHOD(rr_t, get_name, char *,
70 private_unbound_rr_t *this)
71 {
72 return this->name;
73 }
74
75 METHOD(rr_t, get_type, rr_type_t,
76 private_unbound_rr_t *this)
77 {
78 return this->type;
79 }
80
81 METHOD(rr_t, get_class, rr_class_t,
82 private_unbound_rr_t *this)
83 {
84 return this->class;
85 }
86
87 METHOD(rr_t, get_ttl, uint32_t,
88 private_unbound_rr_t *this)
89 {
90 return this->ttl;
91 }
92
93 METHOD(rr_t, get_rdata, chunk_t,
94 private_unbound_rr_t *this)
95 {
96 return chunk_create(this->rdata, this->size);
97 }
98
99 METHOD(rr_t, destroy, void,
100 private_unbound_rr_t *this)
101 {
102 free(this->name);
103 free(this->rdata);
104 free(this);
105 }
106
107 /*
108 * Described in header.
109 */
110 unbound_rr_t *unbound_rr_create_frm_ldns_rr(ldns_rr *rr)
111 {
112 private_unbound_rr_t *this;
113 ldns_status status;
114 ldns_buffer *buf;
115 int i;
116
117 INIT(this,
118 .public = {
119 .interface = {
120 .get_name = _get_name,
121 .get_type = _get_type,
122 .get_class = _get_class,
123 .get_ttl = _get_ttl,
124 .get_rdata = _get_rdata,
125 .destroy = _destroy,
126 },
127 },
128 );
129
130 this->name = ldns_rdf2str(ldns_rr_owner(rr));
131 if (!this->name)
132 {
133 DBG1(DBG_LIB, "failed to parse the owner name of a DNS RR");
134 _destroy(this);
135 return NULL;
136 }
137
138 this->type = ldns_rr_get_type(rr);
139 this->class = ldns_rr_get_class(rr);
140 this->ttl = ldns_rr_ttl(rr);
141 for(i = 0; i < ldns_rr_rd_count(rr); i++)
142 {
143 this->size += ldns_rdf_size(ldns_rr_rdf(rr, i));
144 }
145
146 /**
147 * The ldns library splits the RDATA field of a RR in various rdf.
148 * Here we reassemble these rdf to get the RDATA field of the RR.
149 */
150 buf = ldns_buffer_new(LDNS_MIN_BUFLEN);
151 /* The buffer will be resized automatically by ldns_rr_rdata2buffer_wire() */
152 status = ldns_rr_rdata2buffer_wire(buf, rr);
153
154 if (status != LDNS_STATUS_OK)
155 {
156 DBG1(DBG_LIB, "failed to get the RDATA field of a DNS RR");
157 _destroy(this);
158 return NULL;
159 }
160
161 this->rdata = ldns_buffer_export(buf);
162
163 return &this->public;
164 }