2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
16 #include "resolve_handler.h"
22 #include <threading/mutex.h>
24 typedef struct private_resolve_handler_t private_resolve_handler_t
;
27 * Private data of an resolve_handler_t object.
29 struct private_resolve_handler_t
{
32 * Public resolve_handler_t interface.
34 resolve_handler_t
public;
37 * resolv.conf file to use
42 * Mutex to access file exclusively
48 * Implementation of attribute_handler_t.handle
50 static bool handle(private_resolve_handler_t
*this, identification_t
*server
,
51 configuration_attribute_type_t type
, chunk_t data
)
61 case INTERNAL_IP4_DNS
:
62 addr
= host_create_from_chunk(AF_INET
, data
, 0);
64 case INTERNAL_IP6_DNS
:
65 addr
= host_create_from_chunk(AF_INET6
, data
, 0);
71 if (!addr
|| addr
->is_anyaddr(addr
))
76 this->mutex
->lock(this->mutex
);
78 in
= fopen(this->file
, "r");
79 /* allows us to stream from in to out */
81 out
= fopen(this->file
, "w");
84 fprintf(out
, "nameserver %H # by strongSwan, from %Y\n", addr
, server
);
85 DBG1(DBG_IKE
, "installing DNS server %H to %s", addr
, this->file
);
88 /* copy rest of the file */
91 while ((len
= fread(buf
, 1, sizeof(buf
), in
)))
93 ignore_result(fwrite(buf
, 1, len
, out
));
102 this->mutex
->unlock(this->mutex
);
107 DBG1(DBG_IKE
, "adding DNS server failed", this->file
);
113 * Implementation of attribute_handler_t.release
115 static void release(private_resolve_handler_t
*this, identification_t
*server
,
116 configuration_attribute_type_t type
, chunk_t data
)
119 char line
[1024], matcher
[512], *pos
;
125 case INTERNAL_IP4_DNS
:
128 case INTERNAL_IP6_DNS
:
135 this->mutex
->lock(this->mutex
);
137 in
= fopen(this->file
, "r");
140 /* allows us to stream from in to out */
142 out
= fopen(this->file
, "w");
145 addr
= host_create_from_chunk(family
, data
, 0);
146 snprintf(matcher
, sizeof(matcher
),
147 "nameserver %H # by strongSwan, from %Y\n",
150 /* copy all, but matching line */
151 while ((pos
= fgets(line
, sizeof(line
), in
)))
153 if (strneq(line
, matcher
, strlen(matcher
)))
155 DBG1(DBG_IKE
, "removing DNS server %H from %s",
169 this->mutex
->unlock(this->mutex
);
173 * Attribute enumerator implementation
176 /** implements enumerator_t interface */
178 /** virtual IP we are requesting */
180 } attribute_enumerator_t
;
183 * Implementation of create_attribute_enumerator().enumerate()
185 static bool attribute_enumerate(attribute_enumerator_t
*this,
186 configuration_attribute_type_t
*type
, chunk_t
*data
)
188 switch (this->vip
->get_family(this->vip
))
191 *type
= INTERNAL_IP4_DNS
;
194 *type
= INTERNAL_IP6_DNS
;
200 /* enumerate only once */
201 this->public.enumerate
= (void*)return_false
;
206 * Implementation of attribute_handler_t.create_attribute_enumerator
208 static enumerator_t
* create_attribute_enumerator(private_resolve_handler_t
*this,
209 identification_t
*server
, host_t
*vip
)
213 attribute_enumerator_t
*enumerator
;
215 enumerator
= malloc_thing(attribute_enumerator_t
);
216 enumerator
->public.enumerate
= (void*)attribute_enumerate
;
217 enumerator
->public.destroy
= (void*)free
;
218 enumerator
->vip
= vip
;
220 return &enumerator
->public;
222 return enumerator_create_empty();
226 * Implementation of resolve_handler_t.destroy.
228 static void destroy(private_resolve_handler_t
*this)
230 this->mutex
->destroy(this->mutex
);
237 resolve_handler_t
*resolve_handler_create()
239 private_resolve_handler_t
*this = malloc_thing(private_resolve_handler_t
);
241 this->public.handler
.handle
= (bool(*)(attribute_handler_t
*, identification_t
*, configuration_attribute_type_t
, chunk_t
))handle
;
242 this->public.handler
.release
= (void(*)(attribute_handler_t
*, identification_t
*, configuration_attribute_type_t
, chunk_t
))release
;
243 this->public.handler
.create_attribute_enumerator
= (enumerator_t
*(*)(attribute_handler_t
*, identification_t
*server
, host_t
*vip
))create_attribute_enumerator
;
244 this->public.destroy
= (void(*)(resolve_handler_t
*))destroy
;
246 this->mutex
= mutex_create(MUTEX_TYPE_DEFAULT
);
247 this->file
= lib
->settings
->get_str(lib
->settings
,
248 "%s.plugins.resolve.file", RESOLV_CONF
, hydra
->daemon
);
250 return &this->public;